reset migrations and manage working copy vs published revision

This commit is contained in:
Fred 2017-09-20 21:19:33 +02:00
parent 9d6c21e27a
commit ac9f0aa0fc
28 changed files with 902 additions and 517 deletions

View File

@ -39,7 +39,6 @@ INSTALLED_APPS = [
'django.contrib.staticfiles',
'evolus',
'jci',
'crispy_forms',
'simple_history',
'process'
]

Binary file not shown.

View File

@ -1,7 +1,6 @@
from django.contrib import admin
from simple_history.admin import SimpleHistoryAdmin
from .models import Audience, Document, DocumentType, Version, Site, Structure
from .models import Audience, Document, DocumentType, Version, Site, Structure, Revision
class DocumentAdmin(admin.ModelAdmin):
@ -18,3 +17,4 @@ admin.site.register(Structure)
admin.site.register(Document, DocumentAdmin)
admin.site.register(DocumentType, DocumentTypeAdmin)
admin.site.register(Version)
admin.site.register(Revision)

View File

@ -1,7 +1,8 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.5 on 2017-09-15 07:12
# Generated by Django 1.11.5 on 2017-09-20 18:56
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
@ -11,34 +12,168 @@ class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('jci', '0014_auto_20170920_1436'),
]
operations = [
migrations.CreateModel(
name='JCI',
name='Audience',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=50)),
('parent', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='evolus.JCI')),
('parent', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='evolus.Audience')),
],
options={
'ordering': ('name',),
},
),
migrations.CreateModel(
name='AudienceClosure',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('depth', models.IntegerField()),
('child', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='audienceclosure_parents', to='evolus.Audience')),
('parent', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='audienceclosure_children', to='evolus.Audience')),
],
options={
'db_table': 'evolus_audienceclosure',
},
),
migrations.CreateModel(
name='Document',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=255)),
('overview', models.TextField(blank=True, null=True)),
('created_at', models.DateTimeField(auto_now_add=True)),
('revised_at', models.DateTimeField(blank=True, null=True)),
('audiences', models.ManyToManyField(to='evolus.Audience')),
],
),
migrations.CreateModel(
name='DocumentType',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=50)),
('level', models.IntegerField()),
('template', models.FileField(blank=True, null=True, upload_to='documents_templates/')),
],
options={
'ordering': ['level'],
},
),
migrations.CreateModel(
name='HistoricalDocument',
fields=[
('id', models.IntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')),
('title', models.CharField(max_length=255)),
('overview', models.TextField(blank=True, null=True)),
('created_at', models.DateTimeField(blank=True, editable=False)),
('revised_at', models.DateTimeField(blank=True, null=True)),
('history_id', models.AutoField(primary_key=True, serialize=False)),
('history_date', models.DateTimeField()),
('history_change_reason', models.CharField(max_length=100, null=True)),
('history_type', models.CharField(choices=[('+', 'Created'), ('~', 'Changed'), ('-', 'Deleted')], max_length=1)),
('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
('type', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='evolus.DocumentType')),
],
options={
'ordering': ('-history_date', '-history_id'),
'get_latest_by': 'history_date',
'verbose_name': 'historical document',
},
),
migrations.CreateModel(
name='Revision',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('revision', models.FileField(upload_to='revisions/')),
('created_at', models.DateTimeField(auto_now_add=True)),
('minor', models.PositiveIntegerField()),
],
options={
'ordering': ('-minor',),
},
),
migrations.CreateModel(
name='Site',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=50)),
],
options={
'ordering': ['name'],
},
),
migrations.CreateModel(
name='Structure',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=50)),
('acronym', models.CharField(blank=True, max_length=20, null=True)),
('parent', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='evolus.Structure')),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='JCIClosure',
name='StructureClosure',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('depth', models.IntegerField()),
('child', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='jciclosure_parents', to='evolus.JCI')),
('parent', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='jciclosure_children', to='evolus.JCI')),
('child', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='structureclosure_parents', to='evolus.Structure')),
('parent', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='structureclosure_children', to='evolus.Structure')),
],
options={
'db_table': 'evolus_jciclosure',
'db_table': 'evolus_structureclosure',
},
),
migrations.CreateModel(
name='Version',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('major', models.PositiveIntegerField()),
('document', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='evolus.Document')),
('published', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='published_version+', to='evolus.Revision')),
],
),
migrations.AddField(
model_name='revision',
name='version',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='revisions', to='evolus.Version'),
),
migrations.AddField(
model_name='document',
name='sites',
field=models.ManyToManyField(to='evolus.Site'),
),
migrations.AddField(
model_name='document',
name='standards',
field=models.ManyToManyField(related_name='documents', to='jci.Standard'),
),
migrations.AddField(
model_name='document',
name='structures',
field=models.ManyToManyField(to='evolus.Structure'),
),
migrations.AddField(
model_name='document',
name='type',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='evolus.DocumentType'),
),
migrations.AlterUniqueTogether(
name='jciclosure',
name='version',
unique_together=set([('document', 'major')]),
),
migrations.AlterUniqueTogether(
name='structureclosure',
unique_together=set([('parent', 'child')]),
),
migrations.AlterUniqueTogether(
name='audienceclosure',
unique_together=set([('parent', 'child')]),
),
]

View File

@ -1,83 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.5 on 2017-09-15 07:25
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('evolus', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='Audience',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=50)),
('parent', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='evolus.Audience')),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='AudienceClosure',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('depth', models.IntegerField()),
('child', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='audienceclosure_parents', to='evolus.Audience')),
('parent', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='audienceclosure_children', to='evolus.Audience')),
],
options={
'db_table': 'evolus_audienceclosure',
},
),
migrations.CreateModel(
name='Document',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('audience', models.ManyToManyField(to='evolus.Audience')),
('jci', models.ManyToManyField(to='evolus.JCI')),
],
),
migrations.CreateModel(
name='Structure',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=50)),
('parent', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='evolus.Structure')),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='StructureClosure',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('depth', models.IntegerField()),
('child', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='structureclosure_parents', to='evolus.Structure')),
('parent', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='structureclosure_children', to='evolus.Structure')),
],
options={
'db_table': 'evolus_structureclosure',
},
),
migrations.AddField(
model_name='document',
name='structure',
field=models.ManyToManyField(to='evolus.Structure'),
),
migrations.AlterUniqueTogether(
name='structureclosure',
unique_together=set([('parent', 'child')]),
),
migrations.AlterUniqueTogether(
name='audienceclosure',
unique_together=set([('parent', 'child')]),
),
]

View File

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.5 on 2017-09-20 19:00
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('evolus', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='version',
name='published',
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='published_version+', to='evolus.Revision'),
),
]

View File

@ -1,37 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.5 on 2017-09-15 07:49
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('evolus', '0002_auto_20170915_0925'),
]
operations = [
migrations.AddField(
model_name='jci',
name='acronym',
field=models.CharField(default='', max_length=50),
preserve_default=False,
),
migrations.AlterField(
model_name='audience',
name='parent',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='evolus.Audience'),
),
migrations.AlterField(
model_name='jci',
name='parent',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='evolus.JCI'),
),
migrations.AlterField(
model_name='structure',
name='parent',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='evolus.Structure'),
),
]

View File

@ -1,47 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.5 on 2017-09-15 07:54
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('jci', '0001_initial'),
('evolus', '0003_auto_20170915_0949'),
]
operations = [
migrations.RemoveField(
model_name='jci',
name='parent',
),
migrations.AlterUniqueTogether(
name='jciclosure',
unique_together=set([]),
),
migrations.RemoveField(
model_name='jciclosure',
name='child',
),
migrations.RemoveField(
model_name='jciclosure',
name='parent',
),
migrations.RemoveField(
model_name='document',
name='jci',
),
migrations.AddField(
model_name='document',
name='standards',
field=models.ManyToManyField(to='jci.Standard'),
),
migrations.DeleteModel(
name='JCI',
),
migrations.DeleteModel(
name='JCIClosure',
),
]

View File

@ -1,27 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.5 on 2017-09-18 10:51
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('evolus', '0004_auto_20170915_0954'),
]
operations = [
migrations.CreateModel(
name='Site',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=50)),
],
),
migrations.AddField(
model_name='document',
name='sites',
field=models.ManyToManyField(to='evolus.Site'),
),
]

View File

@ -1,25 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.5 on 2017-09-18 10:54
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('evolus', '0005_auto_20170918_1251'),
]
operations = [
migrations.AlterModelOptions(
name='site',
options={'ordering': ['name']},
),
migrations.AddField(
model_name='document',
name='title',
field=models.CharField(default='', max_length=255),
preserve_default=False,
),
]

View File

@ -1,20 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.5 on 2017-09-18 10:56
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('evolus', '0006_auto_20170918_1254'),
]
operations = [
migrations.AddField(
model_name='document',
name='overview',
field=models.TextField(blank=True, null=True),
),
]

View File

@ -1,25 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.5 on 2017-09-18 11:05
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('evolus', '0007_document_overview'),
]
operations = [
migrations.RenameField(
model_name='document',
old_name='audience',
new_name='audiences',
),
migrations.RenameField(
model_name='document',
old_name='structure',
new_name='structures',
),
]

View File

@ -1,29 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.5 on 2017-09-18 13:14
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('evolus', '0008_auto_20170918_1305'),
]
operations = [
migrations.CreateModel(
name='DocumentType',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=50)),
('template', models.FileField(blank=True, null=True, upload_to='documents_templates/')),
],
),
migrations.AddField(
model_name='document',
name='type',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='evolus.DocumentType'),
),
]

View File

@ -1,21 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.5 on 2017-09-18 13:18
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('evolus', '0009_auto_20170918_1514'),
]
operations = [
migrations.AddField(
model_name='documenttype',
name='level',
field=models.IntegerField(default=1),
preserve_default=False,
),
]

View File

@ -1,24 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.5 on 2017-09-18 13:44
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('evolus', '0010_documenttype_level'),
]
operations = [
migrations.AlterModelOptions(
name='documenttype',
options={'ordering': ['level']},
),
migrations.AddField(
model_name='structure',
name='acronym',
field=models.CharField(blank=True, max_length=20, null=True),
),
]

View File

@ -1,20 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.5 on 2017-09-19 14:19
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('evolus', '0011_auto_20170918_1544'),
]
operations = [
migrations.AlterField(
model_name='document',
name='standards',
field=models.ManyToManyField(related_name='documents', to='jci.Standard'),
),
]

View File

@ -1,55 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.5 on 2017-09-20 12:36
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('evolus', '0012_auto_20170919_1619'),
]
operations = [
migrations.CreateModel(
name='HistoricalDocument',
fields=[
('id', models.IntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')),
('title', models.CharField(max_length=255)),
('overview', models.TextField(blank=True, null=True)),
('created_at', models.DateTimeField(blank=True, editable=False)),
('revised_at', models.DateTimeField(blank=True, null=True)),
('history_id', models.AutoField(primary_key=True, serialize=False)),
('history_date', models.DateTimeField()),
('history_change_reason', models.CharField(max_length=100, null=True)),
('history_type', models.CharField(choices=[('+', 'Created'), ('~', 'Changed'), ('-', 'Deleted')], max_length=1)),
('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
('type', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='evolus.DocumentType')),
],
options={
'verbose_name': 'historical document',
'ordering': ('-history_date', '-history_id'),
'get_latest_by': 'history_date',
},
),
migrations.AlterModelOptions(
name='audience',
options={'ordering': ('name',)},
),
migrations.AddField(
model_name='document',
name='created_at',
field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
preserve_default=False,
),
migrations.AddField(
model_name='document',
name='revised_at',
field=models.DateTimeField(blank=True, null=True),
),
]

View File

@ -1,31 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.5 on 2017-09-20 13:02
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('evolus', '0013_auto_20170920_1436'),
]
operations = [
migrations.CreateModel(
name='Version',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('major', models.IntegerField()),
('minor', models.IntegerField()),
('patch', models.IntegerField()),
('created_at', models.DateTimeField(auto_now_add=True)),
('document', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='evolus.Document')),
],
),
migrations.AlterUniqueTogether(
name='version',
unique_together=set([('document', 'major', 'minor', 'patch')]),
),
]

View File

@ -63,6 +63,22 @@ class Document(models.Model):
revised_at = models.DateTimeField(null=True, blank=True)
history = HistoricalRecords()
@property
def last_published_version(self):
try:
return self.versions.filter(published__isnull=False).first().revisions.first()
except Version.DoesNotExist:
return 'None'
except Exception:
return 'None'
@property
def last_working_version(self):
try:
return self.versions.filter(published__isnull=True).first().revisions.first()
except Version.DoesNotExist:
return 'None'
def __str__(self):
return self.title
@ -74,14 +90,32 @@ class Document(models.Model):
class Version(models.Model):
document = models.ForeignKey(Document)
major = models.IntegerField()
minor = models.IntegerField()
patch = models.IntegerField()
created_at = models.DateTimeField(auto_now_add=True)
document = models.ForeignKey(Document, related_name='versions')
major = models.PositiveIntegerField()
published = models.OneToOneField('Revision', related_name='published_version+', null=True, blank=True)
class Meta:
unique_together = ('document', 'major', 'minor', 'patch')
unique_together = ('document', 'major')
@property
def status(self):
return 'Published' if self.published else 'Draft'
def __str__(self):
return '{} v{}.{}.{}'.format(self.document, self.major, self.minor, self.patch)
return '{} v{} ({})'.format(self.document, self.major, self.status)
def publish(self):
pass
class Revision(models.Model):
revision = models.FileField(upload_to='revisions/')
created_at = models.DateTimeField(auto_now_add=True)
version = models.ForeignKey(Version, related_name='revisions')
minor = models.PositiveIntegerField()
class Meta:
ordering = ('-minor',)
def __str__(self):
return '{} rev {}'.format(self.version, self.minor)

1
fixtures/jci.json Normal file

File diff suppressed because one or more lines are too long

View File

@ -1,9 +1,10 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.5 on 2017-09-20 13:06
# Generated by Django 1.11.5 on 2017-09-20 18:56
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
import process.models
class Migration(migrations.Migration):
@ -11,7 +12,7 @@ class Migration(migrations.Migration):
initial = True
dependencies = [
('evolus', '0014_auto_20170920_1502'),
('evolus', '0001_initial'),
]
operations = [
@ -19,6 +20,7 @@ class Migration(migrations.Migration):
name='Process',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('process_type', models.CharField(max_length=50)),
],
),
migrations.CreateModel(
@ -26,6 +28,7 @@ class Migration(migrations.Migration):
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('assigned_to', models.EmailField(max_length=254)),
('status', models.IntegerField(choices=[(1, 'Created'), (3, 'Completed')])),
],
),
migrations.CreateModel(
@ -33,28 +36,28 @@ class Migration(migrations.Migration):
fields=[
('process_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='process.Process')),
],
bases=('process.process',),
bases=('process.process', process.models.DraftProcessMixin),
),
migrations.CreateModel(
name='GatherComments',
fields=[
('process_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='process.Process')),
],
bases=('process.process',),
bases=('process.process', process.models.DraftProcessMixin),
),
migrations.CreateModel(
name='Knowledge',
fields=[
('process_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='process.Process')),
],
bases=('process.process',),
bases=('process.process', process.models.PublishedProcessMixin),
),
migrations.CreateModel(
name='Review',
fields=[
('process_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='process.Process')),
],
bases=('process.process',),
bases=('process.process', process.models.PublishedProcessMixin),
),
migrations.AddField(
model_name='task',

View File

@ -1,21 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.5 on 2017-09-20 13:32
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('process', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='process',
name='process_type',
field=models.CharField(default='default process', max_length=50),
preserve_default=False,
),
]

View File

@ -1,21 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.5 on 2017-09-20 13:41
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('process', '0002_process_process_type'),
]
operations = [
migrations.AddField(
model_name='task',
name='status',
field=models.IntegerField(choices=[(1, 'Created'), (3, 'Completed')], default=1),
preserve_default=False,
),
]

View File

@ -24,6 +24,9 @@ class Process(models.Model):
def allow_tasks_delegation(self):
return True
def save(self):
raise NotImplemented('is_valid has to be implemented on the subprocess')
TASK_STATUS = (
(1, 'Created'),
@ -40,22 +43,36 @@ class Task(models.Model):
return '{} - {}'.format(self.process, self.assigned_to)
class Review(Process):
class PublishedProcessMixin(object):
def save(self, *args, **kwargs):
if self.document_version.status == 'Draft':
raise TypeError('Review flow cant apply to draft documents')
return super().save(*args, **kwargs)
class DraftProcessMixin(object):
def save(self, *args, **kwargs):
if self.document_version.status == 'Published':
raise TypeError('Review flow cant apply to published documents')
return super().save(*args, **kwargs)
class Review(Process, PublishedProcessMixin):
PROCESS_TYPE = 'Review'
def __str__(self):
return 'Review: {}'.format(self.document_version)
class Approval(Process):
class Approval(Process, DraftProcessMixin):
PROCESS_TYPE = 'Approval'
class GatherComments(Process):
class GatherComments(Process, DraftProcessMixin):
PROCESS_TYPE = 'GatherComments'
class Knowledge(Process):
class Knowledge(Process, PublishedProcessMixin):
PROCESS_TYPE = 'Knowledge'
def allow_tasks_delegation(self):

View File

@ -2,3 +2,4 @@ django<1.12
django-closuretree<1.2
django-filter==1.0.4
django-simple-history==1.9.0
django-simple-history==1.9.0

654
revisions/101792167.pdf Normal file
View File

@ -0,0 +1,654 @@
%PDF-1.3
%ÿÿÿÿ
1 0 obj
<< /Creator <feff0050007200610077006e>
/Producer <feff0050007200610077006e>
>>
endobj
2 0 obj
<< /Type /Catalog
/Pages 3 0 R
>>
endobj
3 0 obj
<< /Type /Pages
/Count 1
/Kids [5 0 R]
>>
endobj
4 0 obj
<< /Length 6358
>>
stream
q
BT
36 738.05 Td
/F2.0 25 Tf
[<4469676974616c4f6365616e>] TJ
ET
BT
36 717.634 Td
/F1.0 12 Tf
[<3130312041> 40 <76> 25 <656e> 10 <7565206f662074686520416d6572> -15 <69636173> 15 <2c203130746820466c6f6f72>] TJ
ET
BT
36 703.762 Td
/F1.0 12 Tf
[<4e65> 20 <772059> 140 <6f72> -15 <6b2c204e59203130303133>] TJ
ET
BT
36 689.8899999999999 Td
/F1.0 12 Tf
[<56> 80 <41> 120 <542049443a204555353238303032323234>] TJ
ET
BT
405.525 673.8639999999998 Td
/F1.0 15 Tf
[<44617465204973737565643a204d61> 30 <7920312c2032303137>] TJ
ET
BT
410.385 656.5239999999998 Td
/F1.0 15 Tf
[<50> 50 <6572> -15 <696f643a20417072> -15 <696c2031202d2033302c2032303137>] TJ
ET
BT
425.43600000000004 641.3379999999997 Td
/F1.0 12 Tf
[<496e> 20 <76> 25 <6f696365204e756d626572> -30 <3a20313031373932313637>] TJ
ET
/DeviceRGB cs
0.949 0.949 0.949 scn
36.000 592.210 240.000 23.872 re
f
0.000 0.000 0.000 scn
0.949 0.949 0.949 scn
276.000 592.210 60.000 23.872 re
f
0.000 0.000 0.000 scn
0.949 0.949 0.949 scn
336.000 592.210 80.000 23.872 re
f
0.000 0.000 0.000 scn
0.949 0.949 0.949 scn
416.000 592.210 80.000 23.872 re
f
0.000 0.000 0.000 scn
0.949 0.949 0.949 scn
496.000 592.210 70.000 23.872 re
f
0.000 0.000 0.000 scn
1 w
/DeviceRGB CS
0.800 0.800 0.800 SCN
36.000 592.210 m
276.000 592.210 l
S
[ ] 0 d
1 w
0.800 0.800 0.800 SCN
36.000 616.082 m
276.000 616.082 l
S
[ ] 0 d
1 w
0.000 0.000 0.000 SCN
BT
41 599.8379999999996 Td
/F1.0 12 Tf
[<4465736372> -15 <697074696f6e>] TJ
ET
1 w
0.800 0.800 0.800 SCN
276.000 592.210 m
336.000 592.210 l
S
[ ] 0 d
1 w
0.800 0.800 0.800 SCN
276.000 616.082 m
336.000 616.082 l
S
[ ] 0 d
1 w
0.000 0.000 0.000 SCN
BT
281.0 599.8379999999996 Td
/F1.0 12 Tf
[<486f757273>] TJ
ET
1 w
0.800 0.800 0.800 SCN
336.000 592.210 m
416.000 592.210 l
S
[ ] 0 d
1 w
0.800 0.800 0.800 SCN
336.000 616.082 m
416.000 616.082 l
S
[ ] 0 d
1 w
0.000 0.000 0.000 SCN
BT
341.0 599.8379999999996 Td
/F1.0 12 Tf
[<53746172> -40 <74>] TJ
ET
1 w
0.800 0.800 0.800 SCN
416.000 592.210 m
496.000 592.210 l
S
[ ] 0 d
1 w
0.800 0.800 0.800 SCN
416.000 616.082 m
496.000 616.082 l
S
[ ] 0 d
1 w
0.000 0.000 0.000 SCN
BT
421.0 599.8379999999996 Td
/F1.0 12 Tf
[<456e64>] TJ
ET
1 w
0.800 0.800 0.800 SCN
496.000 592.210 m
566.000 592.210 l
S
[ ] 0 d
1 w
0.800 0.800 0.800 SCN
496.000 616.082 m
566.000 616.082 l
S
[ ] 0 d
1 w
0.000 0.000 0.000 SCN
BT
501.0 599.8379999999996 Td
/F1.0 12 Tf
[<555344>] TJ
ET
1 w
0.800 0.800 0.800 SCN
36.000 570.650 m
276.000 570.650 l
S
[ ] 0 d
1 w
0.000 0.000 0.000 SCN
BT
41 577.4019999999997 Td
/F1.0 10 Tf
[<4173686c65> 20 <794879706572> -40 <7465> 30 <787420283438474229>] TJ
ET
1 w
0.800 0.800 0.800 SCN
276.000 570.650 m
336.000 570.650 l
S
[ ] 0 d
1 w
0.000 0.000 0.000 SCN
BT
281.0 577.4019999999997 Td
/F1.0 10 Tf
[<3737>] TJ
ET
1 w
0.800 0.800 0.800 SCN
336.000 570.650 m
416.000 570.650 l
S
[ ] 0 d
1 w
0.000 0.000 0.000 SCN
BT
341.0 577.4019999999997 Td
/F1.0 10 Tf
[<30342d32372030393a3439>] TJ
ET
1 w
0.800 0.800 0.800 SCN
416.000 570.650 m
496.000 570.650 l
S
[ ] 0 d
1 w
0.000 0.000 0.000 SCN
BT
421.0 577.4019999999997 Td
/F1.0 10 Tf
[<30342d33302031343a3536>] TJ
ET
1 w
0.800 0.800 0.800 SCN
496.000 570.650 m
566.000 570.650 l
S
[ ] 0 d
1 w
0.000 0.000 0.000 SCN
BT
501.0 577.4019999999997 Td
/F1.0 10 Tf
[<2435352e3030>] TJ
ET
1 w
0.800 0.800 0.800 SCN
36.000 549.090 m
276.000 549.090 l
S
[ ] 0 d
1 w
0.000 0.000 0.000 SCN
BT
41 555.8419999999998 Td
/F1.0 10 Tf
[<4173686c65> 20 <796465> 30 <762d706c6163653120283438474229>] TJ
ET
1 w
0.800 0.800 0.800 SCN
276.000 549.090 m
336.000 549.090 l
S
[ ] 0 d
1 w
0.000 0.000 0.000 SCN
BT
281.0 555.8419999999998 Td
/F1.0 10 Tf
[<3737>] TJ
ET
1 w
0.800 0.800 0.800 SCN
336.000 549.090 m
416.000 549.090 l
S
[ ] 0 d
1 w
0.000 0.000 0.000 SCN
BT
341.0 555.8419999999998 Td
/F1.0 10 Tf
[<30342d32372031303a3331>] TJ
ET
1 w
0.800 0.800 0.800 SCN
416.000 549.090 m
496.000 549.090 l
S
[ ] 0 d
1 w
0.000 0.000 0.000 SCN
BT
421.0 555.8419999999998 Td
/F1.0 10 Tf
[<30342d33302031353a3130>] TJ
ET
1 w
0.800 0.800 0.800 SCN
496.000 549.090 m
566.000 549.090 l
S
[ ] 0 d
1 w
0.000 0.000 0.000 SCN
BT
501.0 555.8419999999998 Td
/F1.0 10 Tf
[<2435352e3030>] TJ
ET
1 w
0.800 0.800 0.800 SCN
36.000 527.530 m
276.000 527.530 l
S
[ ] 0 d
1 w
0.000 0.000 0.000 SCN
BT
41 534.2819999999997 Td
/F1.0 10 Tf
[<4173686c65> 20 <7949535020283332474229>] TJ
ET
1 w
0.800 0.800 0.800 SCN
276.000 527.530 m
336.000 527.530 l
S
[ ] 0 d
1 w
0.000 0.000 0.000 SCN
BT
281.0 534.2819999999997 Td
/F1.0 10 Tf
[<3734>] TJ
ET
1 w
0.800 0.800 0.800 SCN
336.000 527.530 m
416.000 527.530 l
S
[ ] 0 d
1 w
0.000 0.000 0.000 SCN
BT
341.0 534.2819999999997 Td
/F1.0 10 Tf
[<30342d32372031333a3235>] TJ
ET
1 w
0.800 0.800 0.800 SCN
416.000 527.530 m
496.000 527.530 l
S
[ ] 0 d
1 w
0.000 0.000 0.000 SCN
BT
421.0 534.2819999999997 Td
/F1.0 10 Tf
[<30342d33302031353a3237>] TJ
ET
1 w
0.800 0.800 0.800 SCN
496.000 527.530 m
566.000 527.530 l
S
[ ] 0 d
1 w
0.000 0.000 0.000 SCN
BT
501.0 534.2819999999997 Td
/F1.0 10 Tf
[<2433352e3234>] TJ
ET
1 w
0.800 0.800 0.800 SCN
36.000 505.970 m
276.000 505.970 l
S
[ ] 0 d
1 w
0.000 0.000 0.000 SCN
BT
41 512.7219999999998 Td
/F1.0 10 Tf
[<56> 80 <41> 120 <542042656c6769756d>] TJ
ET
1 w
0.800 0.800 0.800 SCN
276.000 505.970 m
336.000 505.970 l
S
[ ] 0 d
1 w
0.000 0.000 0.000 SCN
1 w
0.800 0.800 0.800 SCN
336.000 505.970 m
416.000 505.970 l
S
[ ] 0 d
1 w
0.000 0.000 0.000 SCN
BT
341.0 512.7219999999998 Td
/F1.0 10 Tf
[<30342d30312030303a3030>] TJ
ET
1 w
0.800 0.800 0.800 SCN
416.000 505.970 m
496.000 505.970 l
S
[ ] 0 d
1 w
0.000 0.000 0.000 SCN
BT
421.0 512.7219999999998 Td
/F1.0 10 Tf
[<30342d33302032333a3539>] TJ
ET
1 w
0.800 0.800 0.800 SCN
496.000 505.970 m
566.000 505.970 l
S
[ ] 0 d
1 w
0.000 0.000 0.000 SCN
BT
501.0 512.7219999999998 Td
/F1.0 10 Tf
[<2433302e3530>] TJ
ET
BT
477.99 480.19999999999976 Td
/F2.0 15 Tf
[<54> 80 <6f74616c3a20243137352e3734>] TJ
ET
BT
36 439.50399999999973 Td
/F2.0 12 Tf
[<42696c6c2054> 80 <6f3a>] TJ
ET
BT
36 424.7319999999997 Td
/F3.0 12 Tf
<6670617563686574203c667061756368657440676d61696c2e636f6d3e> Tj
ET
BT
98.05799999999999 385.83599999999973 Td
/F1.0 12 Tf
[<49662079> 20 <6f75206861> 20 <76> 25 <652061206372656469742063617264206f6e2066696c652069742077696c6c206265206175746f6d61746963616c6c7920636861726765642077697468696e20323420686f757273> 15 <2e>] TJ
ET
Q
endstream
endobj
5 0 obj
<< /Type /Page
/Parent 3 0 R
/MediaBox [0 0 612.0 792.0]
/Contents 4 0 R
/Resources << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]
/Font << /F2.0 6 0 R
/F1.0 7 0 R
/F3.0 8 0 R
>>
>>
>>
endobj
6 0 obj
<< /Type /Font
/Subtype /Type1
/BaseFont /Helvetica-Bold
/Encoding /WinAnsiEncoding
>>
endobj
7 0 obj
<< /Type /Font
/Subtype /Type1
/BaseFont /Helvetica
/Encoding /WinAnsiEncoding
>>
endobj
8 0 obj
<< /Type /Font
/BaseFont /AAAAAA+DejaVuSans
/Subtype /TrueType
/FontDescriptor 10 0 R
/FirstChar 32
/LastChar 255
/Widths 12 0 R
/ToUnicode 11 0 R
>>
endobj
9 0 obj
<< /Length1 21308
/Length 8382
/Filter [/FlateDecode]
>>
stream
xœí{ |Seº÷{ÎsNšžnIh<49>ZZN[ÊÚNËJÒ6…Е6lz<6C>Û4IÛ@›„$™Ê€ã§¸ÃŒŠ3ŠÈu¹L][Gge.2WÇ原ÞÏ ÇñNe˜¹èh-§÷yßsÒ¤¥ .÷÷ûÒœó.Ïò÷9!I¤<49>ˆd‡«ÍHÉ.­Â‘·áLͭ뚊F¾{¯O"½Óêw9Gweì!$ñ%\3±¥-|Íò?Iëñþ3¼¯liñ8»tn$X†÷ãÚœ×<>ñ+ñ¾ïåšú¢ÏsLIxÞ/ øCan¿ïßÁû…>gÃB's<ñr¤·ù“<19> '07îoxY<78>óbKS ¹mõ´5H¿v >êZ‰7s6!‹ç¡Ì
Žq„ê‡⥎|鋺" H_òÒ<38><12>_R2I1à<31>Ñôå|¿ÁOš”­B“¸Š#—Y…/ˆî N/nàRpøÕžïë=¯öŽ0fó²<C3B3>ÙMé AFßÊÖ¸äÏþÔMB˜ÞD¬öiŸ"×ó\:-úpoAOáÌâ´Ü7_yEQpÝäûâ›Â.Ä¥Ê2™ß'Ð/žu"Ù¦KD<4B>çˆ<08>èŽãx2NÈ<4E>CRE³Q<C2B3>S=£fVÔ/<2F>>Ž3èµ<C3A8>ðñŠœx><3E>Ήo~ñ™ ïUDN*?VîÜϽ¼{™ â[c™¢ÛFtÈY܆|É6ŽçtÛDÏs%:x"
<EFBFBD>pÇéøq¡Œçõ b¬qT?zä<b:GY¿!ò½Š ƒ“û•‚]JÁ~®<>a»IÙ·Z|<7C>$<24>Jr·¥ht"ÄïNOˀݕ)ÓŠSöîž™¶wÜUÅÓ².#MºÑ‰/5Ñnš2y¢Ý|y•á­ž¾ƒrZ™÷¼á„Ñ4
óêa:ôñ«Ï~{¢Èpø„qöìBRÑï¨èLt\UÑi ?FЩŽ«–"UýÏ"Uø¶Ì2ÎœµÂŸR=¶º z~µÀ]Í¥Ž,.š1}ÚøÜ—Ìå挟>mFqÑÈQÓ<C393>Wp8>aü8œB@ÒRM£F
¸xæ(<28><>3nÂx~ú4ÓÌ㊄QY\š<> w\Ûqû¬ÛÌgÏ»¯yïüñÑæms7ÿä¡ùåµÎŽ÷î,ÔæåRï¿îó+×+oü´[éÚ¸ñÆ›~xWwèUnUGE<47>òkåÏ|úæŸï¼ã¶‡v* «ìŸ9Ò[QyýiyäÛ<C3A4>­:X{ý­VK“òËçPþkeKÛ²Å~góõë×söCû¹Eë7lÚ·£ñOÊçÊK:ŠGÿûÂT¡ƒH$<24>´LH0*>™ì¥ëN6Ê7Ž=0¦;·ËxÛ¨D2
F'ÅëÆ‚>Õ6ÝíÅW{ŠŠŒîÃÇOõ<4F>ê1< 0Û8Û4»Ðâ+Ì,Ì*[(fæÌŸ`É´dYÆZdK¶%§6³6«vl­\]S;!0á†ÌMYÆn7eß<65>³eÂŽ ''dE¶F6E64d5Œm<C592>²Y<>±9<>½1kãØ<C3A3>òÆìÑW£™rtiÌR—s3<73>¹Ó ­Z.nú<1A>æí½×ùÖÝÕ5ÿàM{<7B>žþ㾧a¿ÃóÌ•ÿ}/nêh ½ñä¤ÊÓ×íir>÷à¡gMnÍÏß3aB<1F>ÕýïLjU:™oÉ 7r7 É7&Ý$u…îQÒeq˜©¦Ú.3ô/¢Yá8¢œ:aøäD¡%!%Ã<>±1cKÆŽ …MËGù4<C3B9>g¦Qa‰Ñ@²F‡Õ÷×>ñüóOÔÞ_]õÐÕ§•×¹©œnɃÂô½S¦¼ìØûS¦ì7Ž»=ÑÄÍÉe1„r P®TAq$<24>¿Q˜»¹§GwºoÆëÓô¤7¥ØÆ ÆpQÅ<n@ÛNÑø)´LšŸÈÜùRæÉLq>™ÏÍçç§ÍÏÍqúx³ä'~ÎÏûÓüñW¯¦ªdgq-dªEq‰cêÅ úO<öÔÊ]/­RN)/p“úÞãâºø‡nº·;™ÿþ•Ï¼0mÚ¾Éfn'q#¸Rå?ßóä¾íëTì3]*AVXƈ.Q¿[Çm"÷$ëˆ8/ê“R*S }<15>cy7fˬ<15>ÉìºÿÙY+æîwø0ËÇ0#œ(ÂBn¿%­6mG è(d&—<>mÌE—)¦îÂÖéªâ
”—»;;÷Ò¥þ¬¶Åµ¹¯^Þ\ýô£ke©p%b<>@&EÜôÄÌxÓ<78>#Fv§@÷øÜ® ã»S]9><3E>èèL&Ù6ÉÐw±.*b<>ÒsüÔatŠ×X¦*Üß0yãäQdNªúÃ(Ÿ<>3~Âtëå,åðFƒIM9ðàCwßõÐCwÝýP—¢ô:÷.^¼½î—OÎ~üÚß÷õýþÚÇgwñ—­#/¼õÖ_”÷”<C3B7>2³ž0O>ô««\<5C>Ü8<>ÓèÚCñ=@ˆàføN³¤C<<3C>dN·)ÙØ•x<E280A2>ÄñzRMc½<•+§è!5¯å6š0Ç?Þ<>Æ¡¼ˆ˜*2^Ð<ˆÒ î®k¯½{owwÉíÏ=Ïï<ýOüö¶?³óô&]êéí÷_©¯>‡Ì×!_zN±$ëž#yÓ ¤\OŠÓñ¾ŒC¼%¾6¾!><10>˜2JË}® _BÃ;t©Q=¢ôrž"÷𜞔œ«–$ƒh1 žu*$ Ký¼Gà .m™C®´Œ×™âG§]f\Zâ¦Lº2¦âˆ1E¯×Õõ)µcFë/+Ï¥€ôõõõ°È)˜7ïø©y‡{Š0…ãjÇÆm·ß¿÷ö¸þqñˆÃ&-¯(pi*p“lÏþèÏtÛ7ïꮽ}Ww÷üÎu?xn¾vÍ'ïQÿe…‘ßþà}¿úùéMBþæÆkÉ@ì·3…þ8B×m"݉]¦ÛFÇRƒ)Í6š…º<C2BA>0åÎOï º qôâ7H:7$mHÞ<48>²Á°ÁØaÚ~2Ý“MéùVD£ZÍP|讽<C2AE>Þ}çÞ½wžäLʉ“SþÊáí÷»ÿ|ä…<C3A4>¶)G”åc ôÙÏ©Ü,&㌙<C592><>Œ!WX2.ë&É©Ý¢¾+ù6îÌ4šŒˆž/Ϥð©Ògr%ŽoÈÚ˜µ#ë<>,<ŒóPCixLñ±<C3B1>Ã…º»ç<Öñ"éï±ã1~ÖÃ?ùÉÃôóÈé}:i<>Û©T>Ã÷A'÷—£~x?CŽÌD!ÿ.nÇX˜eIOõ)°›¹ƒúMR><½Á”Lc<4C>%”"OzT»c 5hI9—æ”ñÓi61rk¹冊СC¯=¸i“¸]ùõæÓ;n®¾÷<C2BE>?ð ›¹+TûíCû-<1A>w*™k<13>ÄÛ$î`jW"ÆajB5Fdy5äl5>ŽEÂñIÚ³i<º6F¡j0¼ÐŽ?n Èíê*}¬ý¹#Ü¿sø]§<><ðÌN¾ã{\'á*E¾g<C2BE> ÙÇùx<C3B9>¯åVÂ.ø=ôÕÂᤘ/„c¤‰¿E¾•¼©{¼A?zB6 ¡‰¬zÈjþeR ¦’Õ¢‰àg“çè'î(9 |€c©ää™8·<38>>6ĵ)™Xó¿÷<C2BF>×{'‡<HăŽŒ™BZði„Gï±d(¤‰-ø-`QœÌm¡b±ø34cú ÿ<>Ÿ Ð <<3C>æ÷ÿ<C3B7>œî—„†I”tm“Í<E2809C>´äþ~]ª’ÊÝ×ƽÿáúûûµzŸ½úöy`¡<>6F2d“\RFÊÉBb'HV°5¤Ôz²Œ,ÇUé\Ñ€^?e»8!%-Ä;uœ# Ümœ##¹W´ÜGÚ8OôÜÇÚ8àúO´q #ùȘ@øÚ¸€ãÙÚ¸Hù™Ú¸HFó¥Ú¸Žù«´k=^·jkô$‡_¯<5F>'<27>m<<3C>ÌájãI¦ûùOµñ¤¼9iwjãÉdÚœcÚx2i™y4<E28099>„¹^mÜ@FÎ kãF"̽E7ýÜ;Jý<4A>uAosKXžèš$Ë<>ëäo8zœmfÙîsåËÖÖV¹Ž®
Éuž<EFBFBD>'¸ÆãΗÎØ:ƒnu8×´­ôûšågËY6yV:—¶Ë®§¯Ù<>A<EFBFBD>ìõÉ<C3B5>öÆV¯KvûÛœ^ŸDJ‰ŸÈ:Œ/iFo O™„ßE¤ßÅxÕˆ+dRkÂ$„Ÿ ñ'i#fµ®ÏÇ++iÅ·Œ^¡bwüöàž5øÓ<C3B8>+χ댮ä´y­Ä=>\Måp➯Ʊ ¯Vâ¾¥¤W¸p­“Qó°ŒT|ø3€k‘®×ɸß<C2B8>Ü<EFBFBD>l.i½ÓB²ž •øý«P@,$ɪ/]ü¥ z!¯ß'åªRñ31P±"2ÝÊ^STZ””FµÉïCw£w ¡ÝÄö«P…UC¶„Ã<E2809E>9nܹ¦=?äoº<Mþ`³'ßç 3\Èʬ\ •Ø$<>DüøD¤<Œp<C592><61> <$\ÎD ŽG]wÀÛå‰!<21>Gnô´ú×NÊ—ÏÃMóå­ë-!ÙÛð÷Üô·ÉÖ g<C2A0>¦f„ v5,bÙHR”;ê”UÑbKšzΗtfžwËC8{CS<07>nO3¸Jö7 ¥"Iµž`7Ä,ï É-ž y5<07>>TÝŒº£Z¸ C ™å°_vúÖÉôÜào #b^„À)»Ph W†[<œ\.[—Óᤎ({|!D/‡A3 ‰¹eg(äwy<77>ÈOrû]ím¦ò4y[ÑH)E¶A®÷7…×"ü9“˜$AO èw·»<ŒŒÛŠyÛÃ*ƒ4hƒÍìjmwSIÖzÃ-þö0
ÓæÕQAJ$ÛÂõT³Üæ¡ZKÌAB-æfʳÀ”C´®ö¢¨šúCXSá<53>l€£µ-èXgl fhjú<>¡‡mtûå<C3BB>ß,‡ÚWz\a:Bõkò·¢³Q…\~ŸÛKõÍ‘$s6ú×x˜ª1œÀç£Bê(µJ êêœjq¶¶J<C2B6> 5£Ä9HO¿ý"(·ùƒžaÕÃëž&'2ÊW…<Ûæ\‡Ñ‚ÛÝÞ&/u4gk]/<2F>¨Óífš«ÐÑuQ®öVgP¢ŒÜž<C39C>·ÙÇÄhVc7Q<75>HˆîˆÈʉ<E28099>ÌÙ:<mODŽ(5Ï׺NöƸ¹DÕ zh ™­¥!
$µK$<<èsž Û´Öt‡äœ<C3A4>8Ì¡¼#R ÛZ¦R—FF¥ÚŽ6 ˜¬ñ{ó\ƈ<CB86><E28098>†—³±ÕC'TÝ<32>¢Fiq†åg)z|ƒ0¡^õn·ÜîskGE•˜pª†ç²jÈßJ£š™<C5A1>É)·Òì<C392>±YpºV9Q1ŒCŸ_¢®úÕœj+LX(¢§µ‰
µÐ&—×T;äúšrÇ2k<32>×˵u5Kíe¶29ÇZ<C387>÷9fy™Ý±°f‰CÆuÖjÇ
¹¦\¶V¯<56>+ìÕefÙ¶¼¶ÎV_/ÕÔÉöªÚJ» ÇìÕ¥•KÊìÕ äÜW]ã<>+íUvuÔ°­)»­ž«²Õ•.Ä[k‰½ÒîXaÊíŽj¤‰ÂÕÉV¹ÖZç°—.©´ÖɵKêjkêmH£ ÉVÛ«Ëë<C38B>­Ê†J ¡ÒšÚ fÜäÀA³ä¨³Ùª¬uf‰Õ Êu2[<>R" Ù¶”n®_h­¬”KìŽzG<7A>ÍZE×RtT×TÙ¤òš%ÕeV‡½¦Z.±¡*ÖJ*ªRZiµW™å2k•uU'„.SÕ‰Â!Ñ lÕ¶:k¥Y®¯µ•Úéâh¯³•:ØJĨdâÖT×Û\aa-´1¨€ÿ•2ɘúÕ¨.¥ã¨©s ˆ²Ì^o3ËÖ:{=µHy] ŠKíYSÎ<` âI<C3A2>W­ÉKmDÇÎô\Ewk
Ù¬•H°žŠ<EFBFBD>Ò µè]¶k\ž@˜ú¶ÜjjdiTÍ<54>fæµj@^àÃÀUÇØ%KYìÔQ³[ôÀ¦Ç±YM½,} wãI¤¦^÷M%þ ä§Éd­7Ä"<1D>À6¿zæÉ!g+2Ã]4ŠØ*Ì•ÎVÜsP@IÃ0ôâµAo“‰ìlÇÑ ÷Ú1ÔŽ)¦<>Õ€r‰& 'ÀSÊ»ÆÓº.×éYÆ$ñú°ÊkÓTgð¹Âs"¥BXnfÄÝþ°„µ`¾,I¬âºèÒé|`.M$©u<C2A9>|!u<>­ƒä ¬ƒ¤3ë -É»¥Pä̦@<40>,ÒÅÔJr¤V¾µ¤Úák«•$5`/ªV.a­$Ek%ùk%iP]pµt¶ZI>ÿZIŠ©•bÃwP¹„ç9&‰KU.IZ¹$_T¹$ —=7^êIòùå.™¤KZ2IZÉ$_xÉ$ -™ä )™¤aK&ù«”Lú´jQ Ûºð‚ª#)ªùÅTGR¤:/¦:b«#ù‚ª#iØêH¾˜êˆ:ë @(|¤³>òW(|¤s>òy>+|×_^Є#ë-¬h<C2AC>òñ+Ÿ”ÇôÁ" ÀHòÌV'<27>£MEkLzH+î^kiòÒ4×´°<C2B4> °¦Z˜52iï.ÈvÐÖ'¥ºfH?o¨Ñæiû æéÙ´ð=œîjïщW±¨<C2B1>ÙÆ•ÈÔxKçÕ¾ô éáíÕÙ3»
³ÚmcX¯Â1?ZàËd¡šÕ2zmŒZ´ëe2µ°9<C2B0>¦W3ãâÓ¬nÖì®ZKå¦ú˜Úl53¹üÌú>¶? uŠUÖ|Ì«y<C2AB>“ÑP4ša&ÅPr±uÔ
tµ*»êËÚ¯Ö|/'ÆKr˜åè^7û1¹\¸Ç©é'±(p¡‡¶1*a6Á§ ¯ZµHš8 c”í•SùÃ迪÷SŽQLèH€E<E282AC>9¸Øîˆ4n¦A˜ùZ#Ά٬ÊC:³Í.”¬<E2809D>QQ1YË| …µÄÃ2ml,V£ˆÁA^©JÛÎ04ÇX‡^·1{ª¶b2HwÏ¢‡y@ÏAdFY<46>•¶WCu°õÏ­u9UÚÀ€G‡™\Q¯j´áÑv^"ÑÐÄþKÁ§iè‰áèf?)3û¦H¬Ä.FO]±õãV-³E,äb¼ÝLb¯&é<16>M:'Rô³ÌµAl.Š"pf&ðáú° ¡Ak#±E,6Äî“™ÎN&¹Äró`_SÑPÏç9ìégÿ#k¶ocßÑüq>¶³“ˆþ·ŽSÓ(RçÚK1Y§<59>-*wŠy“Ñ­yR+óÓàÀˆ*)ÅÔcóX¯œ Nv"zYÎhewÒ€Fn&)µ—/<06>æAçªÊ)C<E28099>Ì{Tß<54>ðŠOèKuŠH)iD=ÌÉltþ æ3<14>ád3köneû¼gÉæÒ€u,Ï:Y^‰Ò<E280B0>Œ„<2/CO<0F>ç<L§µL+7ÛŸ3Ìy˜3 ÷ÐÎENÛœ/Sc¦rÈùÒÈâÝ#k»?Yƒ³Þaó<>kÎ>-øVO/'˨ž<C2A8>±vWeŽŒHÃFJ Ëð2ûi2z˜'<27>ÍO"¹n¸Üíf'<27><>Ù=¯áP•b<E280A2>µá…ÆjˆeÍÈY<1D>¶H$ÑÊ¡u öj;S 0<>^…?5©ç!õ*i «~<7E>™êìZ5j1ÖÎæ¤ãSCªñŽò©Á;Y†ud›³ã˜Ì~ ¦Q·cÝoõ‹•ÍÐù<16>ËðšR¬!K-•Fþ¤´¥-³{zW<7A>ë«Ýk#ËR«GÉjðšÒ®ÂÑJü¶iëèŽRY÷ôz¡U¨Ê¯w9XìÐ}TURŽG¹ÊÎ8F$«Â»:¤¿Pµ"m;£Gå7³úˆ^WkrªÈÕ1ê#J™Ò,E‰*Ù]ßµ¸®žáie:«ÒV3Êq^ÕÅÆ$P-¡JTÊ~iår0('‡¶ÒÌìHõ)cû)×
¶J•¬F³2½ŽRÉ×°Tå ø/à\Ïô¯Ä·ÌôwàˆƒÙÆŠô#t#¾³€Q rK <0C>%L?+á†q(aë(ŠÏÊ<01>«±J)ÃÚ<E280B9>J^Æ8Y"õÃj¡k<>á¼Cà°€égcHU²Õõˆ£ ×ÛFT´3]K5¬Ušªß«>Qƒn)ÓZv1rµi>eeØ ÖÚi“?ª…j«ö³4³¨õ«5ëFäq0ÎŽaPYÆbÑÆVY™­ëb¤œÅo•&ù’‹æ€%šÖ H6ßH<45>OîPiEx¶`ó§JMÂúÒ9誹ˆçš=ç„òöà“;¶jŒV£±u§9&×ÆVj^ÀÖ¶ YÔ3+ú¬[» ÷„y:VkùHÕ­>ÔÜ­>ÅV½nVŸ«5`h *ñ³:Ð?P™¬e³Ñ3= õNüƒžó(g';ûͼ"gQ”ZW:Yµ@¹…†Aóì'”tÆ“a€<61>÷*—µì:¬U&T¿vm-ÿÁ<C3BF>§áHÿçLÈÃÚ ¢Ëp•C,þAfï€ö,åeÓz2_£$‘ç²(&õ—¾Ú†X=ê}”Ú2´«@1hŽÜÍ°ˆú d”§ÄòU¤Çõíw<C3AD>.õ/$~—úAÒ ~ÐÐÊëëëIÃöƒäo¸$<24>W?hp%)Ú눬<¿êpé[ë+Égô•¤ÿßWŠé+E; ÿ;ûJÒ öÛë+IÃ<­}úJÒ°}¥¨FßL_I:G¿àé+Iä«ö•¢ÿët)ûJÑxÜW:Ûé{öî’ú|®VßµîDw—†ïn|3Ý%éèÊ1~·»Ló±3«™o¾Ë$}‡»LÒ<4C>.SôY÷ì2I_Úe¿±.“ôºLò×ÖeKê"&­Š¶翹Þ4¬Í¿­ÞtFïHþÖzGÒY{GÑÐ×ß;¾Bïè\t¿ÞÞQ$³žýD9³ã#]@Ç'¶Ks);>ÒEu|Î|f»°Ž<C2B0>Óñ9WßáRthÂgз<C390>h§Ab|è]þ9ÿZ°`­w•·Àës{®É´
´_½ð?"ÄÕËUø)`ú¸Y¥•ÏjÞŽ ªà¾Òh²¿Öå-äG÷ôµýsʼOÈX=ûóÝÃKÿøiäû¯ŸŸŒ_ÂþšX{uñ-ý_(Л
ŸçÁgEð<EFBFBD>­ði2|¢À)þ;þž
'ó௷XÅ¿*pb+|¼zzá/½ð_
|4þ\*ð§"øàx½øÁV8Ž <0B>×Ãûïˆï÷Â{ð®ï(ðvü¿TøÏ­ðošàÿ®‡7ž†?*ð:.}=¼öêñµõðêâ+
ü!^Và%þ]<5D>ß+pl+¼x4K|Q<>£YðoEð;ž¿Á(>?~;~­Às
<«À¯xF<78>C
Tài¡ûÆ<±[<5B>®§ž»xjÿÕâSOÃS…ý¿Ì÷_mé‡ýá—yð¤Ol…ÇxL<78>N~¡À>7ük2ì}4OÜë†G÷˜ÄGó`<60> v£Ð»{áV`—™`§?0Yüy<˜ ÿ↸dÇVx@<40>í÷'ŠÛ¸?¶Ý—.nsÃ}÷ÄûÒá^üLŸ*pÏÖ$ñ¶&Áݸéî­p×<70>Éâ]áÎdøI/üxËÓâ<C393>زùjqËÓ°e£°ùŽ<qóÕ°Ù"Ü‘·+pÛ­ùâm
Üš· š·XáæÄSá¦Ø„Üp#"ucÜ`„ÿ£Àõ?2Š×+ð##\§ÀF6(`éÿáúõâX¿®uC‡#Mìȃ(°N<C2B0>kam"¬‘ ]<5D>p/„z!Ø «{! €_Ÿ­Ù°J<C2B0>•Æqe=xhYÍxÓ¤€G·.<70>†^ø~"\­ÀU
\©ÀŠå’¸¢K°ldº¸¬9/)GÔs±~4Ô¥ÂâE#ÄÅ
Ô&@<40>ÕU±Z<C2B1>*T*P<>3
ÄE#Àž™$Ú °0 (P¾l[¡L<C2A1>R~ªXÚ %Oƒµ,
ÌWàŠËMâ©pù¼ñrÌ››$γô§ÀÜ$˜£ÀlfÍLgõÂÌqf*̘ž Î0Àô˜ÅIPô½±H<C2B1>ï%@aAX˜ <09>?5^Ì7ÀÔx0Á”Éyâ7Lžd'çÁ$<4C>'N´Â„<Ÿ— ŽO<C5BD>¼§@®9)<29><>zf@vÃØ^ÈB²Ü<C2B2>cÁ1
dôÂe%<25>Ž7é
ŒvÃ(Dj”#qÓÈtHS U<>
˜p<EFBFBD>I#êj,ÃzHqC²I‰#Å$quâHHP@2@¼z\¦W .tnpR@Hx¼ç§g¢×Źo¸<6F>ò¿áE¾mÎùÊ|*N'
ˆ.1ˆN>Ïîî´,^.Y=Õ<äV6ÄÉ<C384>¤¶3i<33>ÜÕß_»\ÈWtŠc:!Oß)äå¾{¶Éw§š+j—Ë<E28094>§meU[CŽÕ/ÇKz‡Ã8n+cs”i§˜‡ÿì <0A>²«E¾ÅpKîœ[ ž9S 7<>t£ø~Žì!Û¸]xׄGÅjÙÁ?NnÀ3¨ü†;ÊÝÌOű]ä$yWn"Ga<47>@¸G yCäÉ)ÎAžD³¹TnvœN Bµð¤P't 
ÇÈL!$W ŠKÅ]ø™ ¿åMäwd,éâÞÆcð|ÅpP(ÉÛp ö<><0F>€ô<E282AC>Íd'é@YR9?ÙÀwðu8òxŒÜo?Îã¶s¯ t¸ëÉkä§ ð Évî5Ôë(ù”\~!PÌ7¡ü/ ­c¸ÿ^ˆø'…Ÿc(=òjd?3aªø{Ÿ$<1B>³ƒìÔuéRãr El÷®Gw'ÙA^<5E>Õð&wƒ<77>+<",$U <>lFÚ÷Ò=º&nêNß”:¿Vhàö<C3A0><C3B6>„†¸F¤ý[ªò|¯C<C2AF>šÈAü¬ÕP§¹Ü p3JJg3ɱ¸EBîG
qëQkBü0<EFBFBD>>dyœL…­d3RbúêfŠŸâÎm»¨ófîvþSr ÊÈ$Ò$œ@¬I*![ ùöênŠ
endstream
endobj
10 0 obj
<< /Type /FontDescriptor
/FontName /AAAAAA+DejaVuSans
/FontFile2 9 0 R
/FontBBox [-1020 -356 1680 1166]
/Flags 4
/StemV 0
/ItalicAngle 0.0
/Ascent 759
/Descent -240
/CapHeight 759
/XHeight 0
>>
endobj
11 0 obj
<< /Length 1286
/Filter [/FlateDecode]
>>
stream
xœe×ËnÛF†á½®BËtHs&Ã@n¼èu{stÔ’ + ß}ù½¤i Æ/‰œy¾_Ã!uøôôÓÓùtß~»]ês¿ïÇéÜnýíòåVû¾ô—Óygì¾<C3AC>êýë+þÖ×|ݶ“Ÿßßîýõé<.û‡‡Ýá÷í÷ûí}ÿáÇv)ý‡Ýá×[ë·ÓùeÿáÏOÏÛëç/×ë_ýµŸïûãîñqßúØú9_ɯ}à´<C3A0>Omûütÿ¸<C3BF>óϼ_ûÞòÚLL½´þv͵ßòù¥ïŽÇLJ1wýÜþó9ç)eÔÏù6=nÿ·ÒPÒªt”N¥§ô*eP)£ÊD™T.”Ê•rU™)³ÊBYTVʪ²Q6•<36>²«”[¢ƒ×Èkðy ^#¯Ákä5x<35>¼¯×à5ò¼F^ƒ×Èkðy ^#¯Ákä5x<35>¼¯×à5ò¼F^×ÊkñZy-^+¯Åkåµx­¼¯•×âµòZ¼V^×ÊkñZy-^+¯Åkåµx­¼¯•×âµòZ¼V^‡×Éëð:y^'¯Ãëäux<75>¼¯“×áuò:¼N^‡×Éëð:y^'¯Ãëäux<75>¼¯“×áuò:¼N^<5E>×Ëëñzy=^/¯Çëåõx½¼¯—×ãõòz¼^^<5E>×Ëëñzy=^/¯Çëåõx½¼¯—×ãõòz¼^Þ€7ÈðyÞ oÀä xƒ¼o<>7à ò¼AÞ€7ÈðyÞ oÀä xƒ¼o<>7à ò¼AÞˆñFy#Þ(oÄ»ýÕnóuWùß.I•$$*I$ITH¨$$QI"I¢DD%‰$‰JI•$$*I$ITH¨$‰$III$$%I$Iê|ÂäMx“¼ o7áMò&¼IÞ„7Éð&yÞ$oÂäMx“¼ o7áMò.xy¼U†oÕÄ ÞªÙ¼M<C2BC>¼MÈoÓl ÞÎx;ãâí
¿àíJ¼àíê÷31ÞÎÄx;ãí
¿âíJ¼âíJ¼â특âíâ¬x»¯x»¯x‡<78>+Þ!Êw¹âB®x‡b®x‡<78><>ïrÅ;àà2äÍkçÎœñJ¼Y³e¼Y†Œ7+|œÆx oSŠŒ7+[ÆךyÞ¢oVûòæµ -ã­Œ‹·é€"¯åþR¦W<C2A6>*Ó4Xq”êC™^Jú[(£à®^ƒ1»¢y]•¡Èk¹}¼YM-x ¥úëÈVæz<C3A6>·ÌþÊ[YEãV¼Y³ÕÙ_}/7×*¯Y%«ê¯eã­Ó«q+ýÝ:÷Ý.â¿7™JãÈÛE¡/‰3Y(Y™*AˆW RõÝVJSƒª¶á:(u@c¡ðD±]a*Õíf)¤9J­ñæ)¥o,#Ú\ØZ>M<>U¡Û\ØjPSã {HSãçMª•ôj»ˆ·{fk”Œ°yGá‰m[z*EïsaëÝ>Š&îÓ«Óúôj%u¼Üî; ¥2^<5E><>ÆWÃ[Õßήòvú[¾Ïþ2î쯲uú[•¢³Pš:ÙçÂVÌ¡§Õ…> ¼M†ÁBi2 .Ħ‰ÇÜèÔ‡!¯áñdÈk¹`†¼–=oÌ qWÞ•wdJF(”L164ÞU Ñ)™x0Eú~êñZ?¾=¶×/·ÛöÄίÕõ<C395>~:÷o?$®—«ÎÒÿ¿ç†óO
endstream
endobj
12 0 obj
[317 600 600 600 600 600 600 600 600 600 600 600 600 600 317 600 600 600 600 600 600 600 600 600 600 600 600 600 837 600 837 600 1000 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 612 600 549 600 615 352 634 633 277 600 600 277 974 600 611 634 600 600 600 392 633 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600]
endobj
xref
0 13
0000000000 65535 f
0000000015 00000 n
0000000109 00000 n
0000000158 00000 n
0000000215 00000 n
0000006625 00000 n
0000006827 00000 n
0000006929 00000 n
0000007026 00000 n
0000007191 00000 n
0000015663 00000 n
0000015873 00000 n
0000017235 00000 n
trailer
<< /Size 13
/Root 2 0 R
/Info 1 0 R
>>
startxref
18150
%%EOF

BIN
revisions/mozilla.pdf Normal file

Binary file not shown.

View File

@ -1,9 +1,15 @@
{% load crispy_forms_tags %}
<form action="" method="get">
{{ filter.form.as_p }}
<input type="submit" />
</form>
<ul>
{% for obj in filter.qs %}
{{ obj }}<br />
{% endfor %}
<li>{{ obj }}
<ul>
<li>Dernière copie publiée: {{ obj.last_published_version }}</li>
<li>Dernière copie en cours de travail: {{ obj.last_working_version }}</li>
</ul>
</li>
{% endfor %}
</ul>