summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--archaeological_context_records/forms.py60
-rw-r--r--archaeological_context_records/locale/django.pot268
-rw-r--r--archaeological_context_records/migrations/0033_auto_20181203_1442.py590
-rw-r--r--archaeological_context_records/models.py20
-rw-r--r--archaeological_context_records/templates/ishtar/forms/qa_operation_contextrecord.html28
-rw-r--r--archaeological_context_records/templates/ishtar/sheet_contextrecord.html4
-rw-r--r--archaeological_context_records/urls.py6
-rw-r--r--archaeological_context_records/views.py25
-rw-r--r--archaeological_files/ishtar_menu.py4
-rw-r--r--archaeological_files/locale/django.pot15
-rw-r--r--archaeological_files/migrations/0016_auto_20181203_1442.py433
-rw-r--r--archaeological_files/wizards.py4
-rw-r--r--archaeological_finds/admin.py20
-rw-r--r--archaeological_finds/fixtures/initial_data-fr.json32
-rw-r--r--archaeological_finds/forms.py519
-rw-r--r--archaeological_finds/forms_treatments.py210
-rw-r--r--archaeological_finds/ishtar_menu.py84
-rw-r--r--archaeological_finds/locale/django.pot1309
-rw-r--r--archaeological_finds/migrations/0039_auto_20181115_1649.py36
-rw-r--r--archaeological_finds/migrations/0040_auto_20181120_1027.py33
-rw-r--r--archaeological_finds/migrations/0041_auto_20181121_1225.py24
-rw-r--r--archaeological_finds/migrations/0042_auto_20181129_1755.py30
-rw-r--r--archaeological_finds/migrations/0043_auto_20181130_1310.py34
-rw-r--r--archaeological_finds/migrations/0044_auto_20181201_1854.py36
-rw-r--r--archaeological_finds/migrations/0045_migrate_current_container_to_ref_container.py40
-rw-r--r--archaeological_finds/migrations/0046_treatmentfiletype_treatment_type.py21
-rw-r--r--archaeological_finds/migrations/0047_auto_20181203_1442.py1523
-rw-r--r--archaeological_finds/migrations/0048_auto_20181203_1746.py25
-rw-r--r--archaeological_finds/migrations/0049_auto_20181210_1518.py64
-rw-r--r--archaeological_finds/migrations/0050_auto_20181211_1509.py51
-rw-r--r--archaeological_finds/migrations/0051_auto_20181211_1530.py22
-rw-r--r--archaeological_finds/migrations/0052_auto_20181211_1558.py33
-rw-r--r--archaeological_finds/models_finds.py306
-rw-r--r--archaeological_finds/models_treatments.py346
-rw-r--r--archaeological_finds/templates/ishtar/blocks/window_find_nav.html21
-rw-r--r--archaeological_finds/templates/ishtar/forms/qa_find_treatment.html14
-rw-r--r--archaeological_finds/templates/ishtar/forms/qa_findbasket_duplicate.html22
-rw-r--r--archaeological_finds/templates/ishtar/sheet_basefind.html14
-rw-r--r--archaeological_finds/templates/ishtar/sheet_find.html590
-rw-r--r--archaeological_finds/templates/ishtar/sheet_findbasket.html3
-rw-r--r--archaeological_finds/templates/ishtar/sheet_treatment.html177
-rw-r--r--archaeological_finds/templates/ishtar/sheet_treatmentfile.html1
-rw-r--r--archaeological_finds/templates/ishtar/wizard/wizard_findbasket_deletion.html25
-rw-r--r--archaeological_finds/templates/ishtar/wizard/wizard_simplefind.html13
-rw-r--r--archaeological_finds/templates/ishtar/wizard/wizard_treatement_deletion.html27
-rw-r--r--archaeological_finds/tests.py142
-rw-r--r--archaeological_finds/urls.py45
-rw-r--r--archaeological_finds/views.py500
-rw-r--r--archaeological_finds/wizards.py294
-rw-r--r--archaeological_operations/forms.py40
-rw-r--r--archaeological_operations/ishtar_menu.py5
-rw-r--r--archaeological_operations/locale/django.pot765
-rw-r--r--archaeological_operations/migrations/0041_auto_20181203_1442.py1117
-rw-r--r--archaeological_operations/models.py113
-rw-r--r--archaeological_operations/templates/ishtar/sheet_operation.html16
-rw-r--r--archaeological_operations/templates/ishtar/sheet_site.html4
-rw-r--r--archaeological_operations/views.py26
-rw-r--r--archaeological_operations/wizards.py2
-rw-r--r--archaeological_warehouse/forms.py5
-rw-r--r--archaeological_warehouse/ishtar_menu.py8
-rw-r--r--archaeological_warehouse/locale/django.pot170
-rw-r--r--archaeological_warehouse/migrations/0026_auto_20181203_1442.py374
-rw-r--r--archaeological_warehouse/models.py17
-rw-r--r--archaeological_warehouse/urls.py10
-rw-r--r--archaeological_warehouse/views.py31
-rw-r--r--archaeological_warehouse/wizards.py13
-rw-r--r--docs/fr/source/_static/interface-generale.pngbin89216 -> 89012 bytes
-rw-r--r--docs/fr/source/annexe-1-rattachement.rst23
-rw-r--r--docs/fr/source/annexe-2-permission-action.rst17
-rw-r--r--docs/fr/source/annexe-3-ex-flux-ope.rst92
-rw-r--r--docs/fr/source/index.rst3
-rw-r--r--docs/fr/source/interface-administrateur.rst250
-rw-r--r--docs/fr/source/interface-utilisateur.rst15
-rw-r--r--docs/fr/source/media-src/interface-generale.xcfbin278527 -> 276491 bytes
-rw-r--r--docs/fr/source/principes.rst8
m---------drassm_app0
-rw-r--r--fixtures/initial_data-auth-fr.json65
-rw-r--r--ishtar_common/forms.py58
-rw-r--r--ishtar_common/forms_common.py2
-rw-r--r--ishtar_common/locale/django.pot992
-rw-r--r--ishtar_common/management/commands/ishtar_import.py37
-rw-r--r--ishtar_common/management/commands/reassociate_similar_images.py2
-rw-r--r--ishtar_common/management/commands/regenerate_search_vector_cached_label.py22
-rw-r--r--ishtar_common/migrations/0076_migrate_treatmentfile_permissions.py33
-rw-r--r--ishtar_common/migrations/0077_auto_20181129_1755.py20
-rw-r--r--ishtar_common/migrations/0078_auto_20181203_1442.py1832
-rw-r--r--ishtar_common/migrations/0079_migrate-importers.py70
-rw-r--r--ishtar_common/models.py76
-rw-r--r--ishtar_common/models_imports.py3
-rw-r--r--ishtar_common/static/bootstrap/bootstrap.css2
-rw-r--r--ishtar_common/static/js/ishtar.js23
-rw-r--r--ishtar_common/templates/actions.html4
-rw-r--r--ishtar_common/templates/base.html38
-rw-r--r--ishtar_common/templates/blocks/CentimeterMeterWidget.html21
-rw-r--r--ishtar_common/templates/blocks/DataTables.html20
-rw-r--r--ishtar_common/templates/blocks/GramKilogramWidget.html21
-rw-r--r--ishtar_common/templates/blocks/action_list.html4
-rw-r--r--ishtar_common/templates/blocks/bs_field_snippet.html2
-rw-r--r--ishtar_common/templates/ishtar/blocks/sheet_json.html2
-rw-r--r--ishtar_common/templates/ishtar/blocks/window_field_flex_multiple_full.html8
-rw-r--r--ishtar_common/templates/ishtar/blocks/window_nav.html38
-rw-r--r--ishtar_common/templates/ishtar/form.html3
-rw-r--r--ishtar_common/templates/ishtar/forms/qa_base.html3
-rw-r--r--ishtar_common/templates/ishtar/wizard/confirm_wizard.html8
-rw-r--r--ishtar_common/templatetags/ishtar_helpers.py19
-rw-r--r--ishtar_common/templatetags/window_field.py8
-rw-r--r--ishtar_common/templatetags/window_header.py29
-rw-r--r--ishtar_common/tests.py8
-rw-r--r--ishtar_common/urls.py2
-rw-r--r--ishtar_common/utils.py10
-rw-r--r--ishtar_common/views.py51
-rw-r--r--ishtar_common/views_item.py182
-rw-r--r--ishtar_common/widgets.py49
-rw-r--r--ishtar_common/wizards.py58
-rw-r--r--scss/custom.scss11
-rw-r--r--translations/de/ishtar_common.po992
-rw-r--r--translations/fr/archaeological_context_records.po272
-rw-r--r--translations/fr/archaeological_files.po19
-rw-r--r--translations/fr/archaeological_finds.po1396
-rw-r--r--translations/fr/archaeological_operations.po767
-rw-r--r--translations/fr/archaeological_warehouse.po172
-rw-r--r--translations/fr/ishtar_common.po1012
-rw-r--r--version.py4
123 files changed, 15002 insertions, 4735 deletions
diff --git a/archaeological_context_records/forms.py b/archaeological_context_records/forms.py
index a4577df40..8bd3db9f5 100644
--- a/archaeological_context_records/forms.py
+++ b/archaeological_context_records/forms.py
@@ -28,7 +28,13 @@ from django.core import validators
from django.forms.formsets import formset_factory
from django.utils.translation import ugettext_lazy as _
-import models
+from ishtar_common.models import valid_id, IshtarSiteProfile, Town
+from archaeological_context_records import models
+
+from ishtar_common.forms import FinalForm, FormSet, \
+ reverse_lazy, get_form_selection, TableSelect, ManageOldType, CustomForm, \
+ FieldType, CustomFormSearch, IshtarForm
+from ishtar_common.forms_common import get_town_field
from archaeological_operations.forms import OperationSelect, ParcelField, \
RecordRelationsForm as OpeRecordRelationsForm, RecordRelationsFormSetBase
from archaeological_operations.models import Period, Parcel, Operation, \
@@ -36,11 +42,6 @@ from archaeological_operations.models import Period, Parcel, Operation, \
from archaeological_operations.widgets import OAWidget
from bootstrap_datepicker.widgets import DatePicker
from ishtar_common import widgets
-from ishtar_common.forms import FinalForm, FormSet, \
- reverse_lazy, get_form_selection, TableSelect, ManageOldType, CustomForm, \
- FieldType, CustomFormSearch
-from ishtar_common.forms_common import get_town_field
-from ishtar_common.models import valid_id, IshtarSiteProfile, Town
class OperationFormSelection(CustomForm, forms.Form):
@@ -154,6 +155,8 @@ class RecordFormGeneral(CustomForm, ManageOldType):
)
label = forms.CharField(label=_(u"ID"),
validators=[validators.MaxLengthValidator(200)])
+ unit = forms.ChoiceField(label=_(u"Context record type"), required=False,
+ choices=[])
description = forms.CharField(label=_(u"Description"),
widget=forms.Textarea, required=False)
comment = forms.CharField(label=_(u"General comment"),
@@ -167,8 +170,6 @@ class RecordFormGeneral(CustomForm, ManageOldType):
depth = forms.FloatField(label=_(u"Depth (m)"), required=False)
depth_of_appearance = forms.FloatField(
label=_(u"Depth of appearance (m)"), required=False)
- unit = forms.ChoiceField(label=_(u"Context record type"), required=False,
- choices=[])
opening_date = forms.DateField(label=_(u"Opening date"),
widget=DatePicker, required=False)
closing_date = forms.DateField(label=_(u"Closing date"),
@@ -374,3 +375,46 @@ class RecordDeletionForm(FinalForm):
confirm_msg = " "
confirm_end_msg = _(u"Would you like to delete this context record?")
+
+class QAOperationCR(IshtarForm):
+ town = forms.ChoiceField(label=_(u"Town"), choices=[])
+ archaeological_site = forms.ChoiceField(
+ label=" ", choices=[], required=False,
+ help_text=_(u"Only the items associated to the operation can be "
+ u"selected.")
+ )
+ label = forms.CharField(label=_(u"ID"),
+ validators=[validators.MaxLengthValidator(200)])
+ unit = forms.ChoiceField(label=_(u"Context record type"), required=False,
+ choices=[])
+
+ TYPES = [
+ FieldType('unit', models.Unit),
+ ]
+
+ def __init__(self, *args, **kwargs):
+ self.items = kwargs.pop('items')
+ super(QAOperationCR, self).__init__(*args, **kwargs)
+ site_label = IshtarSiteProfile.get_default_site_label()
+ self.fields['archaeological_site'].label = site_label
+ self.fields['archaeological_site'].choices = [('', '--')]
+
+ if not self.items:
+ return
+ operation = self.items[0]
+ self.fields['town'].choices = [(t.pk, unicode(t))
+ for t in operation.towns.all()]
+ self.fields['archaeological_site'].choices += [
+ (site.pk, unicode(site))
+ for site in operation.archaeological_sites.all()
+ ]
+
+ def save(self, items):
+ operation = items[0]
+ cr = models.ContextRecord.objects.create(
+ town_id=self.cleaned_data['town'], operation=operation,
+ archaeological_site_id=
+ self.cleaned_data['archaeological_site'] or None,
+ label=self.cleaned_data['label'],
+ unit_id=self.cleaned_data['unit'] or None
+ )
diff --git a/archaeological_context_records/locale/django.pot b/archaeological_context_records/locale/django.pot
index fbd1d8d86..e76ef5dc7 100644
--- a/archaeological_context_records/locale/django.pot
+++ b/archaeological_context_records/locale/django.pot
@@ -13,242 +13,242 @@ msgstr ""
msgid "Point"
msgstr ""
-#: admin.py:51 models.py:410
+#: admin.py:51 models.py:427
msgid "Multi polygon"
msgstr ""
-#: forms.py:47 forms.py:53 models.py:352 wizards.py:81
+#: forms.py:48 forms.py:54 models.py:369 wizards.py:81
msgid "Operation"
msgstr ""
-#: forms.py:48
+#: forms.py:49
msgid "Context record - 010 - Operation choice"
msgstr ""
-#: forms.py:63
+#: forms.py:64
msgid "Context record - 001 - Search"
msgstr ""
-#: forms.py:66
+#: forms.py:67
msgid "Full text search"
msgstr ""
-#: forms.py:69 forms.py:155 models.py:357 models.py:737
+#: forms.py:70 forms.py:156 forms.py:386 models.py:374 models.py:754
msgid "ID"
msgstr ""
-#: forms.py:75
+#: forms.py:76
msgid "Code PATRIARCHE"
msgstr ""
-#: forms.py:76
+#: forms.py:77
msgid "Operation's year"
msgstr ""
-#: forms.py:78
+#: forms.py:79
msgid "Operation's number (index by year)"
msgstr ""
-#: forms.py:80 models.py:355
+#: forms.py:81 models.py:372
msgid "Archaeological site"
msgstr ""
-#: forms.py:86
+#: forms.py:87
msgid "Search within related operations"
msgstr ""
-#: forms.py:87 forms.py:288 models.py:66
+#: forms.py:88 forms.py:289 models.py:66
msgid "Period"
msgstr ""
-#: forms.py:88
+#: forms.py:89
msgid "Unit type"
msgstr ""
-#: forms.py:89 forms.py:148 models.py:231 models.py:232 models.py:347
-#: models.py:739
+#: forms.py:90 forms.py:149 models.py:248 models.py:249 models.py:364
+#: models.py:756
msgid "Parcel"
msgstr ""
-#: forms.py:91
+#: forms.py:92
msgid "Search within relations"
msgstr ""
-#: forms.py:115 views.py:95
+#: forms.py:116 views.py:99
msgid "Context record search"
msgstr ""
-#: forms.py:130
+#: forms.py:131
msgid "You should at least select one context record."
msgstr ""
-#: forms.py:136
+#: forms.py:137
msgid "General"
msgstr ""
-#: forms.py:137
+#: forms.py:138
msgid "Context record - 020 - General"
msgstr ""
-#: forms.py:149 models.py:228 models.py:229 models.py:350
+#: forms.py:150 forms.py:380 models.py:245 models.py:246 models.py:367
msgid "Town"
msgstr ""
-#: forms.py:152
+#: forms.py:153 forms.py:383
msgid "Only the items associated to the operation can be selected."
msgstr ""
-#: forms.py:157 models.py:358 models.py:740
+#: forms.py:158 forms.py:388 models.py:396 models.py:755
+msgid "Context record type"
+msgstr ""
+
+#: forms.py:160 models.py:375 models.py:757
#: templates/ishtar/sheet_contextrecord.html:45
msgid "Description"
msgstr ""
-#: forms.py:159 models.py:359
+#: forms.py:162 models.py:376
msgid "General comment"
msgstr ""
-#: forms.py:162 models.py:405
+#: forms.py:165 models.py:422
msgid "Excavation technique"
msgstr ""
-#: forms.py:163 models.py:363
+#: forms.py:166 models.py:380
msgid "Length (m)"
msgstr ""
-#: forms.py:164 models.py:364
+#: forms.py:167 models.py:381
msgid "Width (m)"
msgstr ""
-#: forms.py:165 models.py:365
+#: forms.py:168 models.py:382
msgid "Thickness (m)"
msgstr ""
-#: forms.py:166 models.py:367
+#: forms.py:169 models.py:384
msgid "Diameter (m)"
msgstr ""
-#: forms.py:167 models.py:368
+#: forms.py:170 models.py:385
msgid "Depth (m)"
msgstr ""
-#: forms.py:169 models.py:370
+#: forms.py:172 models.py:387
msgid "Depth of appearance (m)"
msgstr ""
-#: forms.py:170 models.py:379 models.py:738
-msgid "Context record type"
-msgstr ""
-
-#: forms.py:172 models.py:360
+#: forms.py:173 models.py:377
msgid "Opening date"
msgstr ""
-#: forms.py:174 models.py:362 templates/ishtar/sheet_contextrecord.html:140
+#: forms.py:175 models.py:379 templates/ishtar/sheet_contextrecord.html:140
msgid "Closing date"
msgstr ""
-#: forms.py:177
+#: forms.py:178
msgid "Documentation"
msgstr ""
-#: forms.py:180 models.py:372
+#: forms.py:181 models.py:389
msgid "Location"
msgstr ""
-#: forms.py:273
+#: forms.py:274
msgid "This ID already exists for this operation."
msgstr ""
-#: forms.py:277
+#: forms.py:278
msgid "You have to choose a town or a parcel."
msgstr ""
-#: forms.py:283 forms.py:304 models.py:77
+#: forms.py:284 forms.py:305 models.py:77
msgid "Dating"
msgstr ""
-#: forms.py:289 models.py:67
+#: forms.py:290 models.py:67
msgid "Start date"
msgstr ""
-#: forms.py:290 models.py:68
+#: forms.py:291 models.py:68
msgid "End date"
msgstr ""
-#: forms.py:291 models.py:71
+#: forms.py:292 models.py:71
msgid "Quality"
msgstr ""
-#: forms.py:292 models.py:45 models.py:69
+#: forms.py:293 models.py:45 models.py:69
msgid "Dating type"
msgstr ""
-#: forms.py:305
+#: forms.py:306
msgid "Context record - 030 - Dating"
msgstr ""
-#: forms.py:315 ishtar_menu.py:29 models.py:91
+#: forms.py:316 ishtar_menu.py:29 models.py:108 views.py:185
msgid "Context record"
msgstr ""
-#: forms.py:331
+#: forms.py:332
msgid "Relations"
msgstr ""
-#: forms.py:332
+#: forms.py:333
msgid "Context record - 050 - Relations"
msgstr ""
-#: forms.py:337 forms.py:348 models.py:382
+#: forms.py:338 forms.py:349 models.py:399
#: templates/ishtar/sheet_contextrecord.html:64
msgid "Interpretation"
msgstr ""
-#: forms.py:338
+#: forms.py:339
msgid "Context record - 040 - Interpretation"
msgstr ""
-#: forms.py:344
+#: forms.py:345
msgid "Comments on dating"
msgstr ""
-#: forms.py:346 models.py:381
+#: forms.py:347 models.py:398
msgid "Filling"
msgstr ""
-#: forms.py:350 models.py:402
+#: forms.py:351 models.py:419
msgid "Activity"
msgstr ""
-#: forms.py:352 models.py:400
+#: forms.py:353 models.py:417
msgid "Identification"
msgstr ""
-#: forms.py:354 models.py:385
+#: forms.py:355 models.py:402
msgid "TAQ"
msgstr ""
-#: forms.py:355 models.py:389
+#: forms.py:356 models.py:406
msgid "Estimated TAQ"
msgstr ""
-#: forms.py:357 models.py:392
+#: forms.py:358 models.py:409
msgid "TPQ"
msgstr ""
-#: forms.py:358 models.py:396
+#: forms.py:359 models.py:413
msgid "Estimated TPQ"
msgstr ""
-#: forms.py:368
+#: forms.py:369
msgid "Operation search"
msgstr ""
-#: forms.py:370
+#: forms.py:371
msgid "You should select an operation."
msgstr ""
-#: forms.py:375
+#: forms.py:376
msgid "Would you like to delete this context record?"
msgstr ""
@@ -288,263 +288,273 @@ msgstr ""
msgid "Datings"
msgstr ""
-#: models.py:98
+#: models.py:115
msgid "Find"
msgstr ""
-#: models.py:117 models.py:136 models.py:152
+#: models.py:134 models.py:153 models.py:169
msgid "Order"
msgstr ""
-#: models.py:119
+#: models.py:136
msgid "Parent context record type"
msgstr ""
-#: models.py:123
+#: models.py:140
msgid "Context record Type"
msgstr ""
-#: models.py:124
+#: models.py:141
msgid "Context record Types"
msgstr ""
-#: models.py:139
+#: models.py:156
msgid "Activity Type"
msgstr ""
-#: models.py:140
+#: models.py:157
msgid "Activity Types"
msgstr ""
-#: models.py:155
+#: models.py:172
msgid "Identification Type"
msgstr ""
-#: models.py:156
+#: models.py:173
msgid "Identification Types"
msgstr ""
-#: models.py:169
+#: models.py:186
msgid "Excavation technique type"
msgstr ""
-#: models.py:170
+#: models.py:187
msgid "Excavation technique types"
msgstr ""
-#: models.py:180
+#: models.py:197
msgid "Documentation type"
msgstr ""
-#: models.py:181
+#: models.py:198
msgid "Documentation types"
msgstr ""
-#: models.py:222 models.py:741
+#: models.py:239 models.py:758
msgid "Periods"
msgstr ""
-#: models.py:223
+#: models.py:240
msgid "Datings (period)"
msgstr ""
-#: models.py:224
+#: models.py:241
msgid "Related context records"
msgstr ""
-#: models.py:225
+#: models.py:242
msgid "Operation (Patriarche code)"
msgstr ""
-#: models.py:226
+#: models.py:243
msgid "Operation (name)"
msgstr ""
-#: models.py:227
+#: models.py:244
msgid "Parcel (external ID)"
msgstr ""
-#: models.py:230
+#: models.py:247
msgid "Parcel (year)"
msgstr ""
-#: models.py:265
+#: models.py:282
msgctxt "key for text search"
msgid "id"
msgstr ""
-#: models.py:269
+#: models.py:286
msgctxt "key for text search"
msgid "town"
msgstr ""
-#: models.py:273
+#: models.py:290
msgctxt "key for text search"
msgid "operation-year"
msgstr ""
-#: models.py:277
+#: models.py:294
msgctxt "key for text search"
msgid "patriarche"
msgstr ""
-#: models.py:281
+#: models.py:298
msgctxt "key for text search"
msgid "operation-code"
msgstr ""
-#: models.py:285 models.py:327
+#: models.py:302 models.py:344
msgctxt "key for text search"
msgid "operation"
msgstr ""
-#: models.py:289 models.py:330
+#: models.py:306 models.py:347
msgctxt "key for text search"
msgid "site"
msgstr ""
-#: models.py:293
+#: models.py:310
msgctxt "key for text search"
msgid "operation-relation-type"
msgstr ""
-#: models.py:297
+#: models.py:314
msgctxt "key for text search"
msgid "period"
msgstr ""
-#: models.py:301
+#: models.py:318
msgctxt "key for text search"
msgid "unit-type"
msgstr ""
-#: models.py:305
+#: models.py:322
msgctxt "key for text search"
msgid "parcel"
msgstr ""
-#: models.py:309
+#: models.py:326
msgctxt "key for text search"
msgid "record-relation-type"
msgstr ""
-#: models.py:343
+#: models.py:360
msgid "External ID"
msgstr ""
-#: models.py:345
+#: models.py:362
msgid "External ID is set automatically"
msgstr ""
-#: models.py:373
+#: models.py:390
msgid "A short description of the location of the context record"
msgstr ""
-#: models.py:377
+#: models.py:394
msgid "Comment on datings"
msgstr ""
-#: models.py:386
+#: models.py:403
msgid ""
"\"Terminus Ante Quem\" the context record can't have been created after this "
"date"
msgstr ""
-#: models.py:390
+#: models.py:407
msgid "Estimation of a \"Terminus Ante Quem\""
msgstr ""
-#: models.py:393
+#: models.py:410
msgid ""
"\"Terminus Post Quem\" the context record can't have been created before "
"this date"
msgstr ""
-#: models.py:397
+#: models.py:414
msgid "Estimation of a \"Terminus Post Quem\""
msgstr ""
-#: models.py:408
+#: models.py:425
msgid "Point (2D)"
msgstr ""
-#: models.py:409
+#: models.py:426
msgid "Point (3D)"
msgstr ""
-#: models.py:413
+#: models.py:430
msgid "Documents"
msgstr ""
-#: models.py:415
+#: models.py:432
msgid "Cached name"
msgstr ""
-#: models.py:419 models.py:420 templates/ishtar/sheet_contextrecord.html:4
+#: models.py:436 models.py:437 templates/ishtar/sheet_contextrecord.html:4
msgid "Context Record"
msgstr ""
-#: models.py:439
+#: models.py:456
msgctxt "short"
msgid "Context record"
msgstr ""
-#: models.py:668 models.py:691 models.py:736
+#: models.py:685 models.py:708 models.py:753
msgid "Relation type"
msgstr ""
-#: models.py:669
+#: models.py:686
msgid "Relation types"
msgstr ""
-#: models.py:686
+#: models.py:703
msgid "ID (left)"
msgstr ""
-#: models.py:687
+#: models.py:704
msgid "Context record type (left)"
msgstr ""
-#: models.py:688
+#: models.py:705
msgid "Parcel (left)"
msgstr ""
-#: models.py:689
+#: models.py:706
msgid "Description (left)"
msgstr ""
-#: models.py:690
+#: models.py:707
msgid "Periods (left)"
msgstr ""
-#: models.py:692
+#: models.py:709
msgid "ID (right)"
msgstr ""
-#: models.py:693
+#: models.py:710
msgid "Context record type (right)"
msgstr ""
-#: models.py:694
+#: models.py:711
msgid "Parcel (right)"
msgstr ""
-#: models.py:695
+#: models.py:712
msgid "Description (right)"
msgstr ""
-#: models.py:696
+#: models.py:713
msgid "Periods (right)"
msgstr ""
-#: models.py:705
+#: models.py:722
msgid "Record relation"
msgstr ""
-#: models.py:706
+#: models.py:723
msgid "Record relations"
msgstr ""
+#: templates/ishtar/forms/qa_operation_contextrecord.html:11
+msgid "Quick add context record"
+msgstr ""
+
+#: templates/ishtar/forms/qa_operation_contextrecord.html:25
+msgid ""
+"To put more information to the context record use the full form on the top "
+"menu: \\"
+msgstr ""
+
#: templates/ishtar/sheet_contextrecord.html:75
msgid "Datations"
msgstr ""
@@ -613,18 +623,22 @@ msgstr ""
msgid "Documents from associated finds"
msgstr ""
-#: views.py:109
+#: views.py:113
msgid "New context record"
msgstr ""
-#: views.py:125
+#: views.py:129
msgid "Context record modification"
msgstr ""
-#: views.py:136
+#: views.py:140
msgid "You don't have sufficient permissions to do this action."
msgstr ""
-#: views.py:149
+#: views.py:153
msgid "Context record deletion"
msgstr ""
+
+#: views.py:190
+msgid "Add context record"
+msgstr ""
diff --git a/archaeological_context_records/migrations/0033_auto_20181203_1442.py b/archaeological_context_records/migrations/0033_auto_20181203_1442.py
new file mode 100644
index 000000000..0497d68e3
--- /dev/null
+++ b/archaeological_context_records/migrations/0033_auto_20181203_1442.py
@@ -0,0 +1,590 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.10 on 2018-12-03 14:42
+from __future__ import unicode_literals
+
+from django.conf import settings
+import django.contrib.gis.db.models.fields
+import django.contrib.postgres.search
+import django.core.validators
+from django.db import migrations, models
+import django.db.models.deletion
+import ishtar_common.models
+import re
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('archaeological_context_records', '0032_auto_20181017_1854'),
+ ]
+
+ operations = [
+ migrations.AlterModelOptions(
+ name='activitytype',
+ options={'ordering': ('order',), 'verbose_name': "Type d'activit\xe9", 'verbose_name_plural': "Types d'activit\xe9"},
+ ),
+ migrations.AlterModelOptions(
+ name='contextrecord',
+ options={'ordering': ('cached_label',), 'permissions': (('view_contextrecord', 'Can view all Context Records'), ('view_own_contextrecord', 'Can view own Context Record'), ('add_own_contextrecord', 'Can add own Context Record'), ('change_own_contextrecord', 'Can change own Context Record'), ('delete_own_contextrecord', 'Can delete own Context Record')), 'verbose_name': "Unit\xe9 d'Enregistrement", 'verbose_name_plural': "Unit\xe9 d'Enregistrement"},
+ ),
+ migrations.AlterModelOptions(
+ name='dating',
+ options={'verbose_name': 'Datation', 'verbose_name_plural': 'Datations'},
+ ),
+ migrations.AlterModelOptions(
+ name='datingquality',
+ options={'ordering': ('label',), 'verbose_name': 'Type de qualit\xe9 de datation', 'verbose_name_plural': 'Types de qualit\xe9 de datation'},
+ ),
+ migrations.AlterModelOptions(
+ name='datingtype',
+ options={'ordering': ('label',), 'verbose_name': 'Type de datation', 'verbose_name_plural': 'Types de datation'},
+ ),
+ migrations.AlterModelOptions(
+ name='documentationtype',
+ options={'ordering': ('label',), 'verbose_name': 'Type de documentation', 'verbose_name_plural': 'Types de documentation'},
+ ),
+ migrations.AlterModelOptions(
+ name='excavationtechnictype',
+ options={'ordering': ('label',), 'verbose_name': 'Type de m\xe9thode de fouille', 'verbose_name_plural': 'Types de m\xe9thode de fouille'},
+ ),
+ migrations.AlterModelOptions(
+ name='historicalcontextrecord',
+ options={'get_latest_by': 'history_date', 'ordering': ('-history_date', '-history_id'), 'verbose_name': "historical Unit\xe9 d'Enregistrement"},
+ ),
+ migrations.AlterModelOptions(
+ name='identificationtype',
+ options={'ordering': ('order', 'label'), 'verbose_name': "Type d'identification", 'verbose_name_plural': "Types d'identification"},
+ ),
+ migrations.AlterModelOptions(
+ name='recordrelations',
+ options={'permissions': [('view_recordrelation', 'Can view all Context record relations')], 'verbose_name': "Relation entre Unit\xe9s d'Enregistrement", 'verbose_name_plural': "Relations entre Unit\xe9s d'Enregistrement"},
+ ),
+ migrations.AlterModelOptions(
+ name='relationtype',
+ options={'ordering': ('order', 'label'), 'verbose_name': 'Type de relation', 'verbose_name_plural': 'Types de relation'},
+ ),
+ migrations.AlterModelOptions(
+ name='unit',
+ options={'ordering': ('order', 'label'), 'verbose_name': "Type d'Unit\xe9 d'Enregistrement", 'verbose_name_plural': "Types d'Unit\xe9 d'Enregistrement"},
+ ),
+ migrations.AlterField(
+ model_name='activitytype',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='activitytype',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='activitytype',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='activitytype',
+ name='order',
+ field=models.IntegerField(verbose_name='Ordre'),
+ ),
+ migrations.AlterField(
+ model_name='activitytype',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ migrations.AlterField(
+ model_name='contextrecord',
+ name='activity',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='archaeological_context_records.ActivityType', verbose_name='Activit\xe9'),
+ ),
+ migrations.AlterField(
+ model_name='contextrecord',
+ name='archaeological_site',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='context_records', to='archaeological_operations.ArchaeologicalSite', verbose_name='Entit\xe9 (EA)'),
+ ),
+ migrations.AlterField(
+ model_name='contextrecord',
+ name='auto_external_id',
+ field=models.BooleanField(default=False, verbose_name="L'identifiant est attribu\xe9 automatiquement"),
+ ),
+ migrations.AlterField(
+ model_name='contextrecord',
+ name='cached_label',
+ field=models.TextField(blank=True, db_index=True, null=True, verbose_name='Nom en cache'),
+ ),
+ migrations.AlterField(
+ model_name='contextrecord',
+ name='closing_date',
+ field=models.DateField(blank=True, null=True, verbose_name='Date de cl\xf4ture'),
+ ),
+ migrations.AlterField(
+ model_name='contextrecord',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire g\xe9n\xe9ral'),
+ ),
+ migrations.AlterField(
+ model_name='contextrecord',
+ name='datings_comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire relatif aux datations'),
+ ),
+ migrations.AlterField(
+ model_name='contextrecord',
+ name='depth',
+ field=models.FloatField(blank=True, null=True, verbose_name='Profondeur (m)'),
+ ),
+ migrations.AlterField(
+ model_name='contextrecord',
+ name='depth_of_appearance',
+ field=models.FloatField(blank=True, null=True, verbose_name="Profondeur d'apparition (m)"),
+ ),
+ migrations.AlterField(
+ model_name='contextrecord',
+ name='diameter',
+ field=models.FloatField(blank=True, null=True, verbose_name='Diam\xe8tre (m)'),
+ ),
+ migrations.AlterField(
+ model_name='contextrecord',
+ name='excavation_technic',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='archaeological_context_records.ExcavationTechnicType', verbose_name='M\xe9thode de fouille'),
+ ),
+ migrations.AlterField(
+ model_name='contextrecord',
+ name='external_id',
+ field=models.TextField(blank=True, null=True, verbose_name='Identifiant'),
+ ),
+ migrations.AlterField(
+ model_name='contextrecord',
+ name='filling',
+ field=models.TextField(blank=True, null=True, verbose_name='Remplissage'),
+ ),
+ migrations.AlterField(
+ model_name='contextrecord',
+ name='history_creator',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Cr\xe9ateur'),
+ ),
+ migrations.AlterField(
+ model_name='contextrecord',
+ name='history_modifier',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Dernier \xe9diteur'),
+ ),
+ migrations.AlterField(
+ model_name='contextrecord',
+ name='interpretation',
+ field=models.TextField(blank=True, null=True, verbose_name='Interpr\xe9tation'),
+ ),
+ migrations.AlterField(
+ model_name='contextrecord',
+ name='label',
+ field=models.CharField(max_length=200, verbose_name='Identifiant'),
+ ),
+ migrations.AlterField(
+ model_name='contextrecord',
+ name='length',
+ field=models.FloatField(blank=True, null=True, verbose_name='Taille (m)'),
+ ),
+ migrations.AlterField(
+ model_name='contextrecord',
+ name='location',
+ field=models.TextField(blank=True, help_text="Une courte description de la localisation de l'Unit\xe9 d'Enregistrement", null=True, verbose_name='Localisation'),
+ ),
+ migrations.AlterField(
+ model_name='contextrecord',
+ name='multi_polygon',
+ field=django.contrib.gis.db.models.fields.MultiPolygonField(blank=True, null=True, srid=4326, verbose_name='Polygones multi-parties'),
+ ),
+ migrations.AlterField(
+ model_name='contextrecord',
+ name='opening_date',
+ field=models.DateField(blank=True, null=True, verbose_name="Date d'ouverture"),
+ ),
+ migrations.AlterField(
+ model_name='contextrecord',
+ name='operation',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='context_record', to='archaeological_operations.Operation', verbose_name='Op\xe9ration'),
+ ),
+ migrations.AlterField(
+ model_name='contextrecord',
+ name='parcel',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='context_record', to='archaeological_operations.Parcel', verbose_name='Parcelle'),
+ ),
+ migrations.AlterField(
+ model_name='contextrecord',
+ name='relation_image',
+ field=models.FileField(blank=True, null=True, upload_to=ishtar_common.models.get_image_path, verbose_name='Image des relations (SVG g\xe9n\xe9r\xe9)'),
+ ),
+ migrations.AlterField(
+ model_name='contextrecord',
+ name='search_vector',
+ field=django.contrib.postgres.search.SearchVectorField(blank=True, help_text='Auto-rempli \xe0 la sauvegarde', null=True, verbose_name='Vecteur de recherche'),
+ ),
+ migrations.AlterField(
+ model_name='contextrecord',
+ name='taq',
+ field=models.IntegerField(blank=True, help_text="\xab Terminus Ante Quem \xbb. L'Unit\xe9 d'Enregistrement ne peut avoir \xe9t\xe9 cr\xe9\xe9e apr\xe8s cette date.", null=True, verbose_name='TAQ'),
+ ),
+ migrations.AlterField(
+ model_name='contextrecord',
+ name='taq_estimated',
+ field=models.IntegerField(blank=True, help_text="Estimation d'un \xab Terminus Ante Quem \xbb.", null=True, verbose_name='TAQ estim\xe9'),
+ ),
+ migrations.AlterField(
+ model_name='contextrecord',
+ name='thickness',
+ field=models.FloatField(blank=True, null=True, verbose_name='\xc9paisseur (m)'),
+ ),
+ migrations.AlterField(
+ model_name='contextrecord',
+ name='town',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='context_record', to='ishtar_common.Town', verbose_name='Commune'),
+ ),
+ migrations.AlterField(
+ model_name='contextrecord',
+ name='tpq',
+ field=models.IntegerField(blank=True, help_text="\xab Terminus Post Quem \xbb. L'Unit\xe9 d'Enregistrement ne peut avoir \xe9t\xe9 cr\xe9\xe9e avant cette date.", null=True, verbose_name='TPQ'),
+ ),
+ migrations.AlterField(
+ model_name='contextrecord',
+ name='tpq_estimated',
+ field=models.IntegerField(blank=True, help_text="Estimation d'un \xab Terminus Post Quem \xbb.", null=True, verbose_name='TPQ estim\xe9'),
+ ),
+ migrations.AlterField(
+ model_name='contextrecord',
+ name='unit',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='archaeological_context_records.Unit', verbose_name="Type d'Unit\xe9 d'Enregistrement"),
+ ),
+ migrations.AlterField(
+ model_name='contextrecord',
+ name='width',
+ field=models.FloatField(blank=True, null=True, verbose_name='Largeur (m)'),
+ ),
+ migrations.AlterField(
+ model_name='dating',
+ name='dating_type',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='archaeological_context_records.DatingType', verbose_name='Type de datation'),
+ ),
+ migrations.AlterField(
+ model_name='dating',
+ name='end_date',
+ field=models.IntegerField(blank=True, null=True, verbose_name='Date de fin'),
+ ),
+ migrations.AlterField(
+ model_name='dating',
+ name='period',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='archaeological_operations.Period', verbose_name='P\xe9riode'),
+ ),
+ migrations.AlterField(
+ model_name='dating',
+ name='precise_dating',
+ field=models.TextField(blank=True, null=True, verbose_name='Datation pr\xe9cise'),
+ ),
+ migrations.AlterField(
+ model_name='dating',
+ name='quality',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='archaeological_context_records.DatingQuality', verbose_name='Qualit\xe9'),
+ ),
+ migrations.AlterField(
+ model_name='dating',
+ name='start_date',
+ field=models.IntegerField(blank=True, null=True, verbose_name='Date de d\xe9but'),
+ ),
+ migrations.AlterField(
+ model_name='datingquality',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='datingquality',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='datingquality',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='datingquality',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ migrations.AlterField(
+ model_name='datingtype',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='datingtype',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='datingtype',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='datingtype',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ migrations.AlterField(
+ model_name='documentationtype',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='documentationtype',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='documentationtype',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='documentationtype',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ migrations.AlterField(
+ model_name='excavationtechnictype',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='excavationtechnictype',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='excavationtechnictype',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='excavationtechnictype',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ migrations.AlterField(
+ model_name='historicalcontextrecord',
+ name='auto_external_id',
+ field=models.BooleanField(default=False, verbose_name="L'identifiant est attribu\xe9 automatiquement"),
+ ),
+ migrations.AlterField(
+ model_name='historicalcontextrecord',
+ name='cached_label',
+ field=models.TextField(blank=True, db_index=True, null=True, verbose_name='Nom en cache'),
+ ),
+ migrations.AlterField(
+ model_name='historicalcontextrecord',
+ name='closing_date',
+ field=models.DateField(blank=True, null=True, verbose_name='Date de cl\xf4ture'),
+ ),
+ migrations.AlterField(
+ model_name='historicalcontextrecord',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire g\xe9n\xe9ral'),
+ ),
+ migrations.AlterField(
+ model_name='historicalcontextrecord',
+ name='datings_comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire relatif aux datations'),
+ ),
+ migrations.AlterField(
+ model_name='historicalcontextrecord',
+ name='depth',
+ field=models.FloatField(blank=True, null=True, verbose_name='Profondeur (m)'),
+ ),
+ migrations.AlterField(
+ model_name='historicalcontextrecord',
+ name='depth_of_appearance',
+ field=models.FloatField(blank=True, null=True, verbose_name="Profondeur d'apparition (m)"),
+ ),
+ migrations.AlterField(
+ model_name='historicalcontextrecord',
+ name='diameter',
+ field=models.FloatField(blank=True, null=True, verbose_name='Diam\xe8tre (m)'),
+ ),
+ migrations.AlterField(
+ model_name='historicalcontextrecord',
+ name='external_id',
+ field=models.TextField(blank=True, null=True, verbose_name='Identifiant'),
+ ),
+ migrations.AlterField(
+ model_name='historicalcontextrecord',
+ name='filling',
+ field=models.TextField(blank=True, null=True, verbose_name='Remplissage'),
+ ),
+ migrations.AlterField(
+ model_name='historicalcontextrecord',
+ name='interpretation',
+ field=models.TextField(blank=True, null=True, verbose_name='Interpr\xe9tation'),
+ ),
+ migrations.AlterField(
+ model_name='historicalcontextrecord',
+ name='label',
+ field=models.CharField(max_length=200, verbose_name='Identifiant'),
+ ),
+ migrations.AlterField(
+ model_name='historicalcontextrecord',
+ name='length',
+ field=models.FloatField(blank=True, null=True, verbose_name='Taille (m)'),
+ ),
+ migrations.AlterField(
+ model_name='historicalcontextrecord',
+ name='location',
+ field=models.TextField(blank=True, help_text="Une courte description de la localisation de l'Unit\xe9 d'Enregistrement", null=True, verbose_name='Localisation'),
+ ),
+ migrations.AlterField(
+ model_name='historicalcontextrecord',
+ name='multi_polygon',
+ field=django.contrib.gis.db.models.fields.MultiPolygonField(blank=True, null=True, srid=4326, verbose_name='Polygones multi-parties'),
+ ),
+ migrations.AlterField(
+ model_name='historicalcontextrecord',
+ name='opening_date',
+ field=models.DateField(blank=True, null=True, verbose_name="Date d'ouverture"),
+ ),
+ migrations.AlterField(
+ model_name='historicalcontextrecord',
+ name='relation_image',
+ field=models.TextField(blank=True, max_length=100, null=True, verbose_name='Image des relations (SVG g\xe9n\xe9r\xe9)'),
+ ),
+ migrations.AlterField(
+ model_name='historicalcontextrecord',
+ name='search_vector',
+ field=django.contrib.postgres.search.SearchVectorField(blank=True, help_text='Auto-rempli \xe0 la sauvegarde', null=True, verbose_name='Vecteur de recherche'),
+ ),
+ migrations.AlterField(
+ model_name='historicalcontextrecord',
+ name='taq',
+ field=models.IntegerField(blank=True, help_text="\xab Terminus Ante Quem \xbb. L'Unit\xe9 d'Enregistrement ne peut avoir \xe9t\xe9 cr\xe9\xe9e apr\xe8s cette date.", null=True, verbose_name='TAQ'),
+ ),
+ migrations.AlterField(
+ model_name='historicalcontextrecord',
+ name='taq_estimated',
+ field=models.IntegerField(blank=True, help_text="Estimation d'un \xab Terminus Ante Quem \xbb.", null=True, verbose_name='TAQ estim\xe9'),
+ ),
+ migrations.AlterField(
+ model_name='historicalcontextrecord',
+ name='thickness',
+ field=models.FloatField(blank=True, null=True, verbose_name='\xc9paisseur (m)'),
+ ),
+ migrations.AlterField(
+ model_name='historicalcontextrecord',
+ name='tpq',
+ field=models.IntegerField(blank=True, help_text="\xab Terminus Post Quem \xbb. L'Unit\xe9 d'Enregistrement ne peut avoir \xe9t\xe9 cr\xe9\xe9e avant cette date.", null=True, verbose_name='TPQ'),
+ ),
+ migrations.AlterField(
+ model_name='historicalcontextrecord',
+ name='tpq_estimated',
+ field=models.IntegerField(blank=True, help_text="Estimation d'un \xab Terminus Post Quem \xbb.", null=True, verbose_name='TPQ estim\xe9'),
+ ),
+ migrations.AlterField(
+ model_name='historicalcontextrecord',
+ name='width',
+ field=models.FloatField(blank=True, null=True, verbose_name='Largeur (m)'),
+ ),
+ migrations.AlterField(
+ model_name='identificationtype',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='identificationtype',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='identificationtype',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='identificationtype',
+ name='order',
+ field=models.IntegerField(verbose_name='Ordre'),
+ ),
+ migrations.AlterField(
+ model_name='identificationtype',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ migrations.AlterField(
+ model_name='relationtype',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='relationtype',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='relationtype',
+ name='inverse_relation',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='archaeological_context_records.RelationType', verbose_name='Relation inverse'),
+ ),
+ migrations.AlterField(
+ model_name='relationtype',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='relationtype',
+ name='logical_relation',
+ field=models.CharField(blank=True, choices=[(b'above', 'Au-dessus'), (b'bellow', 'En dessous'), (b'equal', '\xc9gal')], max_length=10, null=True, verbose_name='Relation logique'),
+ ),
+ migrations.AlterField(
+ model_name='relationtype',
+ name='order',
+ field=models.IntegerField(default=1, verbose_name='Ordre'),
+ ),
+ migrations.AlterField(
+ model_name='relationtype',
+ name='symmetrical',
+ field=models.BooleanField(verbose_name='Sym\xe9trique'),
+ ),
+ migrations.AlterField(
+ model_name='relationtype',
+ name='tiny_label',
+ field=models.CharField(blank=True, max_length=50, null=True, verbose_name='D\xe9nomination courte'),
+ ),
+ migrations.AlterField(
+ model_name='relationtype',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ migrations.AlterField(
+ model_name='unit',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='unit',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='unit',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='unit',
+ name='order',
+ field=models.IntegerField(verbose_name='Ordre'),
+ ),
+ migrations.AlterField(
+ model_name='unit',
+ name='parent',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='archaeological_context_records.Unit', verbose_name="Type d'UE parent"),
+ ),
+ migrations.AlterField(
+ model_name='unit',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ ]
diff --git a/archaeological_context_records/models.py b/archaeological_context_records/models.py
index 89f3edee4..d7d7a618d 100644
--- a/archaeological_context_records/models.py
+++ b/archaeological_context_records/models.py
@@ -84,6 +84,23 @@ class Dating(models.Model):
return unicode(self.period)
return u"%s (%s-%s)" % (self.period, start_date, end_date)
+ @classmethod
+ def is_identical(cls, dating_1, dating_2):
+ """
+ Compare two dating attribute by attribute and return True if all
+ attribute is identical
+ """
+ for attr in ["period", "start_date", "end_date", "dating_type",
+ "quality", "precise_dating"]:
+ value1 = getattr(dating_1, attr)
+ value2 = getattr(dating_2, attr)
+ if attr == "precise_dating":
+ value1 = value1.strip()
+ value2 = value2.strip()
+ if value1 != value2:
+ return False
+ return True
+
def context_records_lbl(self):
return u" - ".join(
[cr.cached_label for cr in self.context_records.all()]
@@ -521,6 +538,9 @@ class ContextRecord(BulkUpdatedItem, BaseHistorizedItem,
def get_query_owns(cls, ishtaruser):
q = cls._construct_query_own(
'operation__', Operation._get_query_owns_dicts(ishtaruser)
+ ) | cls._construct_query_own(
+ 'base_finds__find__basket__',
+ [{"shared_with": ishtaruser, "shared_write_with": ishtaruser}]
) | cls._construct_query_own('', [
{'history_creator': ishtaruser.user_ptr},
{'operation__end_date__isnull': True}
diff --git a/archaeological_context_records/templates/ishtar/forms/qa_operation_contextrecord.html b/archaeological_context_records/templates/ishtar/forms/qa_operation_contextrecord.html
new file mode 100644
index 000000000..c782832ff
--- /dev/null
+++ b/archaeological_context_records/templates/ishtar/forms/qa_operation_contextrecord.html
@@ -0,0 +1,28 @@
+{% extends "ishtar/forms/qa_base.html" %}
+{% load i18n inline_formset table_form %}
+
+{% block main_form %}
+{% if form.non_field_errors %}
+<div class="alert alert-danger" role="alert">
+ {{form.non_field_errors}}
+</div>
+{% endif %}
+
+<h4>{% trans "Quick add context record" %}</h4>
+
+{% for hidden in form.hidden_fields %}{{hidden}}
+{% if hidden.errors %}<div class="invalid-feedback">
+ {{ hidden.errors }}
+</div>{% endif %}
+{% endfor %}
+{% with force_large_col=True %}{% for field in form %}
+<div class="form-row">
+ {% include "blocks/bs_field_snippet.html" %}
+</div>
+{% endfor %}{% endwith %}
+
+<div class="alert alert-info">
+ {% trans "To put more information to the context record use the full form on the top menu: \"Context record > Add\"." %}
+</div>
+{% endblock %}
+
diff --git a/archaeological_context_records/templates/ishtar/sheet_contextrecord.html b/archaeological_context_records/templates/ishtar/sheet_contextrecord.html
index 2ad74b7d2..af5da11dd 100644
--- a/archaeological_context_records/templates/ishtar/sheet_contextrecord.html
+++ b/archaeological_context_records/templates/ishtar/sheet_contextrecord.html
@@ -171,9 +171,11 @@
{% endif %}
{% trans "Document from this context record" as cr_docs %}
+{% if permission_view_own_document or permission_view_document %}
{% if item.documents.count %}
{% dynamic_table_document cr_docs 'documents' 'context_records' item.pk '' output %}
{% endif %}
+{% endif %}
{% trans "Finds" as finds %}
{% if item.base_finds.count %}
@@ -181,8 +183,10 @@
{% endif %}
{% trans "Documents from associated finds" as finds_docs %}
+{% if permission_view_own_document or permission_view_document %}
{% if item.find_docs_q.count %}
{% dynamic_table_document finds_docs 'documents' 'finds__base_finds__context_record' item.pk '' output %}
{% endif %}
+{% endif %}
{% endblock %}
diff --git a/archaeological_context_records/urls.py b/archaeological_context_records/urls.py
index c05cff87e..175c87482 100644
--- a/archaeological_context_records/urls.py
+++ b/archaeological_context_records/urls.py
@@ -82,4 +82,10 @@ urlpatterns = [
url(r'get-contextrecordrelationdetail/(?P<type>.+)?$',
views.get_contextrecordrelationdetail,
name='get-contextrecordrelationdetail'),
+
+ url(r'^operation-qa-contextrecord/(?P<pks>[0-9]+)/$',
+ check_rights(['add_contextrecord', 'add_own_contextrecord'])(
+ views.QAOperationContextRecordView.as_view()),
+ name='operation-qa-contextrecord'),
+
]
diff --git a/archaeological_context_records/views.py b/archaeological_context_records/views.py
index 771a2ed71..6a01a48f0 100644
--- a/archaeological_context_records/views.py
+++ b/archaeological_context_records/views.py
@@ -26,11 +26,15 @@ from django.shortcuts import redirect
from django.utils.translation import ugettext_lazy as _
from django.views.generic import RedirectView
+from ishtar_common.models import QuickAction
+from archaeological_operations.models import Operation
from archaeological_context_records import models
+
from archaeological_operations.views import site_extra_context
from archaeological_context_records import forms
from ishtar_common.utils import put_session_message
-from ishtar_common.views import IshtarMixin, LoginRequiredMixin
+
+from ishtar_common.views import IshtarMixin, LoginRequiredMixin, QAItemForm
from ishtar_common.views_item import display_item, get_item, show_item, \
revert_item
from archaeological_context_records import wizards
@@ -171,4 +175,21 @@ class GenerateRelationImage(IshtarMixin, LoginRequiredMixin, RedirectView):
except models.ContextRecord.DoesNotExist:
raise Http404()
self.context_record.generate_relation_image()
- return super(GenerateRelationImage, self).get(request, *args, **kwargs) \ No newline at end of file
+ return super(GenerateRelationImage, self).get(request, *args, **kwargs)
+
+
+class QAOperationContextRecordView(QAItemForm):
+ template_name = 'ishtar/forms/qa_operation_contextrecord.html'
+ model = Operation
+ form_class = forms.QAOperationCR
+ page_name = _(u"Context record")
+
+ def get_quick_action(self):
+ return QuickAction(
+ url="operation-qa-contextrecord", icon_class="fa fa-plus",
+ text=_(u"Add context record"), target="one",
+ rights=['add_contextrecord', 'add_own_contextrecord'])
+
+ def form_valid(self, form):
+ form.save(self.items)
+ return HttpResponseRedirect(reverse("success"))
diff --git a/archaeological_files/ishtar_menu.py b/archaeological_files/ishtar_menu.py
index 21e59a6af..bd41f3782 100644
--- a/archaeological_files/ishtar_menu.py
+++ b/archaeological_files/ishtar_menu.py
@@ -73,10 +73,6 @@ MENU_SECTIONS = [
_(u"Deletion"),
model=AdministrativeAct,
access_controls=['change_administrativeact']),
- MenuItem('file_administrativeact_document',
- _(u"Documents"),
- model=AdministrativeAct,
- access_controls=['change_administrativeact']),
],)]),),
(100,
SectionItem(
diff --git a/archaeological_files/locale/django.pot b/archaeological_files/locale/django.pot
index cb5d930f3..d223864b9 100644
--- a/archaeological_files/locale/django.pot
+++ b/archaeological_files/locale/django.pot
@@ -6,7 +6,6 @@
# Étienne Loks <etienne.loks@iggdrasil.net>, 2016. #zanata
# Valérie-Emma Leroux <emma@iggdrasil.net>, 2017. #zanata
# Valérie-Emma Leroux <emma@iggdrasil.net>, 2018. #zanata
-# Étienne Loks <etienne.loks@iggdrasil.net>, 2018. #zanata
msgid ""
msgstr ""
@@ -298,19 +297,15 @@ msgstr ""
msgid "Administrative act"
msgstr ""
-#: ishtar_menu.py:77 models.py:321
-msgid "Documents"
-msgstr ""
-
-#: ishtar_menu.py:83
+#: ishtar_menu.py:79
msgid "Dashboard"
msgstr ""
-#: ishtar_menu.py:86
+#: ishtar_menu.py:82
msgid "General informations"
msgstr ""
-#: ishtar_menu.py:89 models.py:339
+#: ishtar_menu.py:85 models.py:339
#: templates/ishtar/dashboards/dashboard_file.html:7
msgid "Archaeological files"
msgstr ""
@@ -481,6 +476,10 @@ msgstr ""
msgid "Research archaeology comment"
msgstr ""
+#: models.py:321
+msgid "Documents"
+msgstr ""
+
#: models.py:324
msgid "Cached name"
msgstr ""
diff --git a/archaeological_files/migrations/0016_auto_20181203_1442.py b/archaeological_files/migrations/0016_auto_20181203_1442.py
new file mode 100644
index 000000000..08f1c01ea
--- /dev/null
+++ b/archaeological_files/migrations/0016_auto_20181203_1442.py
@@ -0,0 +1,433 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.10 on 2018-12-03 14:42
+from __future__ import unicode_literals
+
+import datetime
+from django.conf import settings
+import django.contrib.postgres.search
+import django.core.validators
+from django.db import migrations, models
+import django.db.models.deletion
+import ishtar_common.utils
+import re
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('archaeological_files', '0015_auto_20181017_1854'),
+ ]
+
+ operations = [
+ migrations.AlterModelOptions(
+ name='file',
+ options={'ordering': ('cached_label',), 'permissions': (('view_file', 'Can view all Archaeological files'), ('view_own_file', 'Can view own Archaeological file'), ('add_own_file', 'Can add own Archaeological file'), ('change_own_file', 'Can change own Archaeological file'), ('delete_own_file', 'Can delete own Archaeological file'), ('close_file', 'Can close File')), 'verbose_name': 'Dossier', 'verbose_name_plural': 'Dossiers'},
+ ),
+ migrations.AlterModelOptions(
+ name='filetype',
+ options={'ordering': ('label',), 'verbose_name': 'Type de dossier arch\xe9ologique', 'verbose_name_plural': 'Types de dossier arch\xe9ologique'},
+ ),
+ migrations.AlterModelOptions(
+ name='historicalfile',
+ options={'get_latest_by': 'history_date', 'ordering': ('-history_date', '-history_id'), 'verbose_name': 'historical Dossier'},
+ ),
+ migrations.AlterModelOptions(
+ name='permittype',
+ options={'ordering': ('label',), 'verbose_name': 'Type de permis', 'verbose_name_plural': 'Types de permis'},
+ ),
+ migrations.AlterField(
+ model_name='file',
+ name='address',
+ field=models.TextField(blank=True, null=True, verbose_name='Adresse des terrains'),
+ ),
+ migrations.AlterField(
+ model_name='file',
+ name='auto_external_id',
+ field=models.BooleanField(default=False, verbose_name="L'identifiant est attribu\xe9 automatiquement"),
+ ),
+ migrations.AlterField(
+ model_name='file',
+ name='cached_label',
+ field=models.TextField(blank=True, db_index=True, null=True, verbose_name='Nom en cache'),
+ ),
+ migrations.AlterField(
+ model_name='file',
+ name='classified_area',
+ field=models.NullBooleanField(verbose_name="Au sein d'un site class\xe9"),
+ ),
+ migrations.AlterField(
+ model_name='file',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='file',
+ name='corporation_general_contractor',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='general_contractor_files', to='ishtar_common.Organization', verbose_name="Organisation de l'am\xe9nageur"),
+ ),
+ migrations.AlterField(
+ model_name='file',
+ name='creation_date',
+ field=models.DateField(blank=True, default=datetime.date.today, null=True, verbose_name='Date de cr\xe9ation'),
+ ),
+ migrations.AlterField(
+ model_name='file',
+ name='departments',
+ field=models.ManyToManyField(blank=True, to='ishtar_common.Department', verbose_name='D\xe9partements'),
+ ),
+ migrations.AlterField(
+ model_name='file',
+ name='end_date',
+ field=models.DateField(blank=True, null=True, verbose_name='Date de cl\xf4ture'),
+ ),
+ migrations.AlterField(
+ model_name='file',
+ name='external_id',
+ field=models.CharField(blank=True, max_length=120, null=True, verbose_name='Identifiant'),
+ ),
+ migrations.AlterField(
+ model_name='file',
+ name='file_type',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='archaeological_files.FileType', verbose_name='Type de dossier'),
+ ),
+ migrations.AlterField(
+ model_name='file',
+ name='general_contractor',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='general_contractor_files', to='ishtar_common.Person', verbose_name='Am\xe9nageur'),
+ ),
+ migrations.AlterField(
+ model_name='file',
+ name='history_creator',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Cr\xe9ateur'),
+ ),
+ migrations.AlterField(
+ model_name='file',
+ name='history_modifier',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Dernier \xe9diteur'),
+ ),
+ migrations.AlterField(
+ model_name='file',
+ name='imported_line',
+ field=models.TextField(blank=True, null=True, verbose_name='Ligne import\xe9e'),
+ ),
+ migrations.AlterField(
+ model_name='file',
+ name='in_charge',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='file_responsability', to='ishtar_common.Person', verbose_name='Dossier suivi par'),
+ ),
+ migrations.AlterField(
+ model_name='file',
+ name='instruction_deadline',
+ field=models.DateField(blank=True, null=True, verbose_name="Date limite d'instruction"),
+ ),
+ migrations.AlterField(
+ model_name='file',
+ name='internal_reference',
+ field=models.CharField(blank=True, max_length=60, null=True, verbose_name='R\xe9f\xe9rence interne'),
+ ),
+ migrations.AlterField(
+ model_name='file',
+ name='locality',
+ field=models.CharField(blank=True, max_length=100, null=True, verbose_name='Lieu-dit'),
+ ),
+ migrations.AlterField(
+ model_name='file',
+ name='main_town',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='file_main', to='ishtar_common.Town', verbose_name='Commune principale'),
+ ),
+ migrations.AlterField(
+ model_name='file',
+ name='name',
+ field=models.TextField(blank=True, null=True, verbose_name='Nom'),
+ ),
+ migrations.AlterField(
+ model_name='file',
+ name='numeric_reference',
+ field=models.IntegerField(blank=True, null=True, verbose_name='R\xe9f\xe9rence num\xe9rique'),
+ ),
+ migrations.AlterField(
+ model_name='file',
+ name='organization',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='files', to='ishtar_common.Organization', verbose_name='Organisation'),
+ ),
+ migrations.AlterField(
+ model_name='file',
+ name='permit_reference',
+ field=models.TextField(blank=True, null=True, verbose_name='R\xe9f\xe9rence du permis'),
+ ),
+ migrations.AlterField(
+ model_name='file',
+ name='permit_type',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='archaeological_files.PermitType', verbose_name='Type de permis'),
+ ),
+ migrations.AlterField(
+ model_name='file',
+ name='planning_service',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='planning_service_files', to='ishtar_common.Organization', verbose_name='Service instructeur'),
+ ),
+ migrations.AlterField(
+ model_name='file',
+ name='postal_code',
+ field=models.CharField(blank=True, max_length=10, null=True, verbose_name='Adresse des terrains - code postal'),
+ ),
+ migrations.AlterField(
+ model_name='file',
+ name='protected_area',
+ field=models.NullBooleanField(verbose_name="Au sein d'un secteur sauvegard\xe9"),
+ ),
+ migrations.AlterField(
+ model_name='file',
+ name='raw_general_contractor',
+ field=models.CharField(blank=True, max_length=200, null=True, verbose_name='Am\xe9nageur (brut)'),
+ ),
+ migrations.AlterField(
+ model_name='file',
+ name='raw_town_planning_service',
+ field=models.CharField(blank=True, max_length=200, null=True, verbose_name='Service instructeur (brut)'),
+ ),
+ migrations.AlterField(
+ model_name='file',
+ name='reception_date',
+ field=models.DateField(blank=True, null=True, verbose_name='Date de r\xe9ception'),
+ ),
+ migrations.AlterField(
+ model_name='file',
+ name='related_file',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='archaeological_files.File', verbose_name='Dossier li\xe9 \xe0'),
+ ),
+ migrations.AlterField(
+ model_name='file',
+ name='requested_operation_type',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='ishtar_common.OperationType', verbose_name="Type d'op\xe9ration demand\xe9e"),
+ ),
+ migrations.AlterField(
+ model_name='file',
+ name='research_comment',
+ field=models.TextField(blank=True, null=True, verbose_name="Commentaire relatif \xe0 l'arch\xe9ologie programm\xe9e"),
+ ),
+ migrations.AlterField(
+ model_name='file',
+ name='responsible_town_planning_service',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='responsible_town_planning_service_files', to='ishtar_common.Person', verbose_name='Responsable pour le service instructeur'),
+ ),
+ migrations.AlterField(
+ model_name='file',
+ name='scientist',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='scientist', to='ishtar_common.Person', verbose_name='Responsable scientifique'),
+ ),
+ migrations.AlterField(
+ model_name='file',
+ name='search_vector',
+ field=django.contrib.postgres.search.SearchVectorField(blank=True, help_text='Auto-rempli \xe0 la sauvegarde', null=True, verbose_name='Vecteur de recherche'),
+ ),
+ migrations.AlterField(
+ model_name='file',
+ name='total_developed_surface',
+ field=models.FloatField(blank=True, null=True, verbose_name='Surface totale am\xe9nag\xe9e (m2)'),
+ ),
+ migrations.AlterField(
+ model_name='file',
+ name='total_surface',
+ field=models.FloatField(blank=True, null=True, verbose_name='Surface totale des terrains (m2)'),
+ ),
+ migrations.AlterField(
+ model_name='file',
+ name='towns',
+ field=models.ManyToManyField(blank=True, related_name='file', to='ishtar_common.Town', verbose_name='Communes'),
+ ),
+ migrations.AlterField(
+ model_name='file',
+ name='year',
+ field=models.IntegerField(default=ishtar_common.utils.get_current_year, verbose_name='Ann\xe9e'),
+ ),
+ migrations.AlterField(
+ model_name='filetype',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='filetype',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='filetype',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='filetype',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfile',
+ name='address',
+ field=models.TextField(blank=True, null=True, verbose_name='Adresse des terrains'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfile',
+ name='auto_external_id',
+ field=models.BooleanField(default=False, verbose_name="L'identifiant est attribu\xe9 automatiquement"),
+ ),
+ migrations.AlterField(
+ model_name='historicalfile',
+ name='cached_label',
+ field=models.TextField(blank=True, db_index=True, null=True, verbose_name='Nom en cache'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfile',
+ name='classified_area',
+ field=models.NullBooleanField(verbose_name="Au sein d'un site class\xe9"),
+ ),
+ migrations.AlterField(
+ model_name='historicalfile',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfile',
+ name='creation_date',
+ field=models.DateField(blank=True, default=datetime.date.today, null=True, verbose_name='Date de cr\xe9ation'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfile',
+ name='end_date',
+ field=models.DateField(blank=True, null=True, verbose_name='Date de cl\xf4ture'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfile',
+ name='external_id',
+ field=models.CharField(blank=True, max_length=120, null=True, verbose_name='Identifiant'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfile',
+ name='imported_line',
+ field=models.TextField(blank=True, null=True, verbose_name='Ligne import\xe9e'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfile',
+ name='instruction_deadline',
+ field=models.DateField(blank=True, null=True, verbose_name="Date limite d'instruction"),
+ ),
+ migrations.AlterField(
+ model_name='historicalfile',
+ name='internal_reference',
+ field=models.CharField(blank=True, max_length=60, null=True, verbose_name='R\xe9f\xe9rence interne'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfile',
+ name='locality',
+ field=models.CharField(blank=True, max_length=100, null=True, verbose_name='Lieu-dit'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfile',
+ name='name',
+ field=models.TextField(blank=True, null=True, verbose_name='Nom'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfile',
+ name='numeric_reference',
+ field=models.IntegerField(blank=True, null=True, verbose_name='R\xe9f\xe9rence num\xe9rique'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfile',
+ name='permit_reference',
+ field=models.TextField(blank=True, null=True, verbose_name='R\xe9f\xe9rence du permis'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfile',
+ name='postal_code',
+ field=models.CharField(blank=True, max_length=10, null=True, verbose_name='Adresse des terrains - code postal'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfile',
+ name='protected_area',
+ field=models.NullBooleanField(verbose_name="Au sein d'un secteur sauvegard\xe9"),
+ ),
+ migrations.AlterField(
+ model_name='historicalfile',
+ name='raw_general_contractor',
+ field=models.CharField(blank=True, max_length=200, null=True, verbose_name='Am\xe9nageur (brut)'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfile',
+ name='raw_town_planning_service',
+ field=models.CharField(blank=True, max_length=200, null=True, verbose_name='Service instructeur (brut)'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfile',
+ name='reception_date',
+ field=models.DateField(blank=True, null=True, verbose_name='Date de r\xe9ception'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfile',
+ name='research_comment',
+ field=models.TextField(blank=True, null=True, verbose_name="Commentaire relatif \xe0 l'arch\xe9ologie programm\xe9e"),
+ ),
+ migrations.AlterField(
+ model_name='historicalfile',
+ name='search_vector',
+ field=django.contrib.postgres.search.SearchVectorField(blank=True, help_text='Auto-rempli \xe0 la sauvegarde', null=True, verbose_name='Vecteur de recherche'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfile',
+ name='total_developed_surface',
+ field=models.FloatField(blank=True, null=True, verbose_name='Surface totale am\xe9nag\xe9e (m2)'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfile',
+ name='total_surface',
+ field=models.FloatField(blank=True, null=True, verbose_name='Surface totale des terrains (m2)'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfile',
+ name='year',
+ field=models.IntegerField(default=ishtar_common.utils.get_current_year, verbose_name='Ann\xe9e'),
+ ),
+ migrations.AlterField(
+ model_name='permittype',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='permittype',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='permittype',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='permittype',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ migrations.AlterField(
+ model_name='saisinetype',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='saisinetype',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='saisinetype',
+ name='delay',
+ field=models.IntegerField(default=30, verbose_name='D\xe9lai (en jours)'),
+ ),
+ migrations.AlterField(
+ model_name='saisinetype',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='saisinetype',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ ]
diff --git a/archaeological_files/wizards.py b/archaeological_files/wizards.py
index 106008192..c9b1ba9c2 100644
--- a/archaeological_files/wizards.py
+++ b/archaeological_files/wizards.py
@@ -43,8 +43,8 @@ class FileWizard(OperationWizard):
town_step_keys = ['towns-']
wizard_done_window = reverse_lazy('show-file')
- def get_extra_model(self, dct, form_list):
- dct = super(FileWizard, self).get_extra_model(dct, form_list)
+ def get_extra_model(self, dct, m2m, form_list):
+ dct = super(FileWizard, self).get_extra_model(dct, m2m, form_list)
if not dct.get('numeric_reference'):
current_ref = models.File.objects.filter(year=dct['year'])\
.aggregate(Max('numeric_reference'))["numeric_reference__max"]
diff --git a/archaeological_finds/admin.py b/archaeological_finds/admin.py
index 1513c7eeb..45050eb2e 100644
--- a/archaeological_finds/admin.py
+++ b/archaeological_finds/admin.py
@@ -156,8 +156,13 @@ admin_site.register(models.CommunicabilityType, HierarchicalTypeAdmin)
class TreatmentTypeAdmin(GeneralTypeAdmin):
- list_display = HierarchicalTypeAdmin.list_display + [
- 'order', 'virtual', 'upstream_is_many', 'downstream_is_many']
+ list_display = HierarchicalTypeAdmin.list_display[:-1] + ['order'] + \
+ [HierarchicalTypeAdmin.list_display[-1]]
+ list_filter = [
+ 'virtual', 'destructive', 'create_new_find', 'upstream_is_many',
+ 'downstream_is_many', 'destructive', 'change_reference_location',
+ 'change_current_location', 'restore_reference_location'
+ ]
model = models.TreatmentType
@@ -177,10 +182,19 @@ class ConservatoryStateAdmin(GeneralTypeAdmin):
list_display = GeneralTypeAdmin.list_display + ['order']
+@admin.register(models.TreatmentFileType, site=admin_site)
+class TreatmentFileType(GeneralTypeAdmin):
+ list_display = GeneralTypeAdmin.list_display + ["treatment_type"]
+
+
+@admin.register(models.TreatmentState, site=admin_site)
+class TreatmentState(GeneralTypeAdmin):
+ list_display = GeneralTypeAdmin.list_display[:-1] + ["order", "executed"]
+
+
general_models = [
models.RemarkabilityType,
models.IntegrityType,
- models.TreatmentFileType, models.TreatmentState,
models.BatchType, models.AlterationCauseType, models.AlterationType,
models.TreatmentEmergencyType, models.ObjectTypeQualityType,
models.MaterialTypeQualityType
diff --git a/archaeological_finds/fixtures/initial_data-fr.json b/archaeological_finds/fixtures/initial_data-fr.json
index a346da9ab..3125ab8da 100644
--- a/archaeological_finds/fixtures/initial_data-fr.json
+++ b/archaeological_finds/fixtures/initial_data-fr.json
@@ -890,6 +890,38 @@
}
},
{
+ "model": "archaeological_finds.treatmenttype",
+ "fields": {
+ "label": "Pr\u00eat",
+ "txt_idx": "loan",
+ "comment": "Un pr\u00eat est un changement temporaire de contenant pour du mobilier.",
+ "available": true,
+ "parent": null,
+ "order": 10,
+ "virtual": false,
+ "destructive": false,
+ "create_new_find": false,
+ "upstream_is_many": false,
+ "downstream_is_many": false
+ }
+},
+{
+ "model": "archaeological_finds.treatmenttype",
+ "fields": {
+ "label": "Retour de pr\u00eat",
+ "txt_idx": "loan-return",
+ "comment": "Retour de mobilier dans son contenant de r\u00e9f\u00e9rence.",
+ "available": true,
+ "parent": null,
+ "order": 10,
+ "virtual": false,
+ "destructive": false,
+ "create_new_find": false,
+ "upstream_is_many": false,
+ "downstream_is_many": false
+ }
+},
+{
"model": "archaeological_finds.treatmentstate",
"fields": {
"label": "Pr\u00e9vu",
diff --git a/archaeological_finds/forms.py b/archaeological_finds/forms.py
index 5ca8618d5..ae592d013 100644
--- a/archaeological_finds/forms.py
+++ b/archaeological_finds/forms.py
@@ -43,8 +43,8 @@ from archaeological_finds.forms_treatments import TreatmentSelect, \
AdministrativeActTreatmentFileForm, \
AdministrativeActTreatmentFileFormSelection, \
AdministrativeActTreatmentFileModifForm, \
- DashboardForm as DashboardTreatmentForm, \
- DashboardTreatmentFileForm, QAFindTreatmentForm
+ DashboardForm as DashboardTreatmentForm, N1TreatmentForm,\
+ DashboardTreatmentFileForm, QAFindTreatmentForm, OneNTreatmentForm
from archaeological_operations.models import Period, ArchaeologicalSite, \
RelationType as OpeRelationType
from archaeological_operations.widgets import OAWidget
@@ -53,10 +53,11 @@ from bootstrap_datepicker.widgets import DatePicker
from ishtar_common import widgets
from ishtar_common.forms import CustomForm, CustomFormSearch, FormSet, \
FloatField, reverse_lazy, TableSelect, get_now, FinalForm, \
- ManageOldType, FieldType, IshtarForm, FormHeader, QAForm, HistorySelect
+ ManageOldType, FieldType, IshtarForm, FormHeader, QAForm, HistorySelect, \
+ PkWizardSearch
from ishtar_common.forms_common import get_town_field
from ishtar_common.models import valid_id, valid_ids, get_current_profile, \
- SpatialReferenceSystem, Area, OperationType
+ SpatialReferenceSystem, Area, OperationType, IshtarUser
from ishtar_common.utils import convert_coordinates_to_point
__all__ = [
@@ -71,17 +72,21 @@ __all__ = [
'AdministrativeActTreatmentFormSelection',
'AdministrativeActTreatmentFileModifForm',
'DashboardTreatmentForm', 'DashboardTreatmentFileForm',
- 'RecordFormSelection', 'FindForm', 'DateForm', 'DatingFormSet',
- 'PreservationForm', 'FindBasketFormSelection', 'FindBasketForm',
- 'FindSelect', 'FindFormSelection', 'FindFormSelectionWarehouseModule',
- 'MultipleFindFormSelection', 'MultipleFindFormSelectionWarehouseModule',
- 'FindMultipleFormSelection', 'check_form', 'check_exist', 'check_not_exist',
+ 'RecordFormSelection', 'FindForm', 'SimpleFindForm', 'DateForm',
+ 'DatingFormSet', 'PreservationForm', 'FindBasketFormSelection',
+ 'FindBasketForWriteFormSelection',
+ 'FindBasketForm', 'FindSelect', 'FindFormSelection',
+ 'FindFormSelectionWarehouseModule', 'MultipleFindFormSelection',
+ 'MultipleFindFormSelectionWarehouseModule', 'FindMultipleFormSelection',
+ 'check_form', 'check_exist', 'check_not_exist',
'check_value', 'check_type_field', 'check_type_not_field',
'check_treatment', 'ResultFindForm', 'ResultFindFormSet',
'FindDeletionForm', 'UpstreamFindFormSelection', 'NewFindBasketForm',
- 'SelectFindBasketForm', 'DeleteFindBasketForm', 'FindBasketAddItemForm',
+ 'SelectFindBasketForm', 'FindBasketAddItemForm',
'QAFindFormSingle', 'QAFindFormMulti', 'QAFindBasketForm',
- 'QAFindTreatmentForm'
+ 'QAFindTreatmentForm', 'QAFindbasketDuplicateForm',
+ 'N1TreatmentForm', 'OneNTreatmentForm', 'ResultingFindForm',
+ 'ResultingFindsForm', 'SingleUpstreamFindFormSelection'
]
logger = logging.getLogger(__name__)
@@ -121,23 +126,33 @@ class RecordFormSelection(CustomForm, forms.Form):
cr.operation.pk)
-class FindForm(CustomForm, ManageOldType):
+class BaseFindForm(CustomForm, ManageOldType):
+ """
+ Base find form with no field related to base_find
+ """
file_upload = True
form_label = _("Find")
- form_admin_name = _(u"Find - 020 - General")
- form_slug = "find-020-general"
- base_models = ['get_first_base_find', 'object_type', 'material_type',
- 'communicabilitie']
+ form_admin_name = _(u"Simple find - 020 - General")
+ form_slug = "simplefind-020-general"
+ base_models = ['object_type', 'material_type', 'communicabilitie']
associated_models = {
'material_type': models.MaterialType,
'object_type': models.ObjectType,
'communicabilitie': models.CommunicabilityType,
- 'get_first_base_find__batch': models.BatchType,
- 'get_first_base_find__spatial_reference_system': SpatialReferenceSystem,
'material_type_quality': models.MaterialTypeQualityType,
'object_type_quality': models.ObjectTypeQualityType,
'checked_type': models.CheckedType,
}
+ field_order = [
+ 'label', 'denomination', 'previous_id', 'museum_id', 'seal_number',
+ 'mark', 'description', 'is_complete', 'material_type',
+ 'material_type_quality', 'object_type', 'object_type_quality',
+ 'find_number', 'min_number_of_individuals', 'inscription',
+ 'manufacturing_place', 'communicabilitie', 'comment', 'dating_comment',
+ 'length', 'width', 'height', 'thickness', 'diameter', 'circumference',
+ 'volume', 'weight', 'clutter_long_side', 'clutter_short_side',
+ 'clutter_height', 'dimensions_comment', 'checked_type', 'check_date'
+ ]
HEADERS = {}
HEADERS['label'] = FormHeader(_(u"Identification"))
@@ -146,8 +161,6 @@ class FindForm(CustomForm, ManageOldType):
validators=[validators.MaxLengthValidator(60)])
denomination = forms.CharField(label=_(u"Denomination"), required=False)
previous_id = forms.CharField(label=_("Previous ID"), required=False)
- get_first_base_find__excavation_id = forms.CharField(
- label=_(u"Excavation ID"), required=False)
museum_id = forms.CharField(label=_(u"Museum ID"), required=False)
seal_number = forms.CharField(label=_(u"Seal number"), required=False)
mark = forms.CharField(label=_(u"Mark"), required=False)
@@ -155,14 +168,6 @@ class FindForm(CustomForm, ManageOldType):
HEADERS['description'] = FormHeader(_(u"Description"))
description = forms.CharField(label=_(u"Description"),
widget=forms.Textarea, required=False)
- get_first_base_find__discovery_date = forms.DateField(
- label=_(u"Discovery date (exact or TPQ)"), widget=DatePicker,
- required=False)
- get_first_base_find__discovery_date_taq = forms.DateField(
- label=_(u"Discovery date (TAQ)"), widget=DatePicker, required=False)
- get_first_base_find__batch = forms.ChoiceField(
- label=_(u"Batch/object"), choices=[],
- required=False)
is_complete = forms.NullBooleanField(label=_(u"Is complete?"),
required=False)
material_type = widgets.Select2MultipleField(
@@ -194,24 +199,115 @@ class FindForm(CustomForm, ManageOldType):
label=_(u"Comment on dating"), required=False, widget=forms.Textarea)
HEADERS['length'] = FormHeader(_(u"Dimensions"))
- length = FloatField(label=_(u"Length (cm)"), required=False)
- width = FloatField(label=_(u"Width (cm)"), required=False)
- height = FloatField(label=_(u"Height (cm)"), required=False)
- diameter = FloatField(label=_(u"Diameter (cm)"), required=False)
- thickness = FloatField(label=_(u"Thickness (cm)"), required=False)
+ length = FloatField(label=_(u"Length (cm)"),
+ widget=widgets.CentimeterMeterWidget, required=False)
+ width = FloatField(label=_(u"Width (cm)"), required=False,
+ widget=widgets.CentimeterMeterWidget)
+ height = FloatField(label=_(u"Height (cm)"),
+ widget=widgets.CentimeterMeterWidget, required=False)
+ thickness = FloatField(label=_(u"Thickness (cm)"),
+ widget=widgets.CentimeterMeterWidget, required=False)
+ diameter = FloatField(label=_(u"Diameter (cm)"),
+ widget=widgets.CentimeterMeterWidget, required=False)
+ circumference = FloatField(
+ label=_(u"Circumference (cm)"), widget=widgets.CentimeterMeterWidget,
+ required=False)
volume = FloatField(label=_(u"Volume (l)"), required=False)
- weight = FloatField(label=_(u"Weight (g)"), required=False)
+ weight = FloatField(label=_(u"Weight (g)"),
+ widget=widgets.GramKilogramWidget, required=False)
clutter_long_side = FloatField(
- label=_(u"Clutter long side (cm)"), required=False)
+ label=_(u"Clutter long side (cm)"),
+ widget=widgets.CentimeterMeterWidget, required=False)
clutter_short_side = FloatField(
- label=_(u"Clutter short side (cm)"), required=False)
+ label=_(u"Clutter short side (cm)"),
+ widget=widgets.CentimeterMeterWidget, required=False)
clutter_height = FloatField(
- label=_(u"Clutter height (cm)"), required=False)
+ label=_(u"Clutter height (cm)"),
+ widget=widgets.CentimeterMeterWidget, required=False)
dimensions_comment = forms.CharField(
label=_(u"Dimensions comment"), required=False, widget=forms.Textarea)
- HEADERS['get_first_base_find__x'] = FormHeader(
- _(u"Coordinates"))
+ HEADERS['checked_type'] = FormHeader(_(u"Sheet"))
+ checked_type = forms.ChoiceField(label=_(u"Check"), required=False)
+ check_date = forms.DateField(
+ initial=get_now, label=_(u"Check date"), widget=DatePicker)
+
+ TYPES = [
+ FieldType('material_type', models.MaterialType, is_multiple=True),
+ FieldType('material_type_quality', models.MaterialTypeQualityType),
+ FieldType('object_type', models.ObjectType, is_multiple=True),
+ FieldType('object_type_quality', models.ObjectTypeQualityType),
+ FieldType('communicabilitie', models.CommunicabilityType,
+ is_multiple=True),
+ FieldType('checked_type', models.CheckedType, is_multiple=True),
+ ]
+
+ def __init__(self, *args, **kwargs):
+ context_record = kwargs.pop('context_record')
+ super(BaseFindForm, self).__init__(*args, **kwargs)
+ if not context_record or \
+ not context_record.operation.operation_type.judiciary:
+ self.fields.pop('seal_number')
+
+ def clean(self):
+ clutter_long_side = self.cleaned_data.get('clutter_long_side', None)
+ clutter_short_side = self.cleaned_data.get('clutter_short_side', None)
+
+ if clutter_long_side and clutter_short_side and \
+ clutter_short_side > clutter_long_side:
+ raise forms.ValidationError(
+ unicode(_(
+ u"Clutter: short side cannot be bigger than the long side."
+ ))
+ )
+ return self.cleaned_data
+
+
+class FindForm(BaseFindForm):
+ file_upload = True
+ form_label = _("Find")
+ form_admin_name = _(u"Find - 020 - General")
+ form_slug = "find-020-general"
+ base_models = ['get_first_base_find'] + BaseFindForm.base_models
+ associated_models = BaseFindForm.associated_models.copy()
+ associated_models.update({
+ 'get_first_base_find__batch': models.BatchType,
+ 'get_first_base_find__spatial_reference_system': SpatialReferenceSystem,
+ })
+ field_order = [
+ 'label', 'denomination', 'previous_id',
+ 'get_first_base_find__excavation_id', 'museum_id', 'seal_number',
+ 'mark', 'description', 'get_first_base_find__discovery_date',
+ 'get_first_base_find__discovery_date_taq', 'get_first_base_find__batch',
+ 'is_complete', 'material_type', 'material_type_quality', 'object_type',
+ 'object_type_quality', 'find_number', 'min_number_of_individuals',
+ 'inscription', 'manufacturing_place', 'communicabilitie', 'comment',
+ 'dating_comment', 'length', 'width', 'height', 'thickness', 'diameter',
+ 'circumference',
+ 'volume', 'weight', 'clutter_long_side', 'clutter_short_side',
+ 'clutter_height', 'dimensions_comment', 'get_first_base_find__x',
+ 'get_first_base_find__estimated_error_x', 'get_first_base_find__y',
+ 'get_first_base_find__estimated_error_y', 'get_first_base_find__z',
+ 'get_first_base_find__estimated_error_z',
+ 'get_first_base_find__spatial_reference_system',
+ 'get_first_base_find__topographic_localisation', 'checked_type',
+ 'check_date',
+ ]
+
+ HEADERS = BaseFindForm.HEADERS.copy()
+ get_first_base_find__excavation_id = forms.CharField(
+ label=_(u"Excavation ID"), required=False)
+
+ get_first_base_find__discovery_date = forms.DateField(
+ label=_(u"Discovery date (exact or TPQ)"), widget=DatePicker,
+ required=False)
+ get_first_base_find__discovery_date_taq = forms.DateField(
+ label=_(u"Discovery date (TAQ)"), widget=DatePicker, required=False)
+ get_first_base_find__batch = forms.ChoiceField(
+ label=_(u"Batch/object"), choices=[],
+ required=False)
+
+ HEADERS['get_first_base_find__x'] = FormHeader(_(u"Coordinates"))
get_first_base_find__x = forms.FloatField(label=_(u"X"), required=False)
get_first_base_find__estimated_error_x = \
forms.FloatField(label=_(u"Estimated error for X"), required=False)
@@ -229,22 +325,10 @@ class FindForm(CustomForm, ManageOldType):
required=False, max_length=120
)
- HEADERS['checked_type'] = FormHeader(_(u"Sheet"))
- checked_type = forms.ChoiceField(label=_(u"Check"), required=False)
- check_date = forms.DateField(
- initial=get_now, label=_(u"Check date"), widget=DatePicker)
-
- TYPES = [
- FieldType('material_type', models.MaterialType, is_multiple=True),
- FieldType('material_type_quality', models.MaterialTypeQualityType),
- FieldType('object_type', models.ObjectType, is_multiple=True),
- FieldType('object_type_quality', models.ObjectTypeQualityType),
- FieldType('communicabilitie', models.CommunicabilityType,
- is_multiple=True),
+ TYPES = BaseFindForm.TYPES + [
FieldType('get_first_base_find__batch', models.BatchType),
FieldType('get_first_base_find__spatial_reference_system',
SpatialReferenceSystem),
- FieldType('checked_type', models.CheckedType, is_multiple=True),
]
PROFILE_FILTER = {
'mapping': [
@@ -256,14 +340,8 @@ class FindForm(CustomForm, ManageOldType):
],
}
- def __init__(self, *args, **kwargs):
- context_record = kwargs.pop('context_record')
- super(FindForm, self).__init__(*args, **kwargs)
- if not context_record or \
- not context_record.operation.operation_type.judiciary:
- self.fields.pop('seal_number')
-
def clean(self):
+ self.cleaned_data = super(FindForm, self).clean()
taq = self.cleaned_data.get('get_first_base_find__discovery_date_taq',
None)
tpq = self.cleaned_data.get('get_first_base_find__discovery_date',
@@ -280,17 +358,6 @@ class FindForm(CustomForm, ManageOldType):
unicode(_(u"Discovery date: TAQ date must be older than TPQ "
u"date.")))
- clutter_long_side = self.cleaned_data.get('clutter_long_side', None)
- clutter_short_side = self.cleaned_data.get('clutter_short_side', None)
-
- if clutter_long_side and clutter_short_side and \
- clutter_short_side > clutter_long_side:
- raise forms.ValidationError(
- unicode(_(
- u"Clutter: short side cannot be bigger than the long side."
- ))
- )
-
if not get_current_profile().mapping:
return self.cleaned_data
x = self.cleaned_data.get('get_first_base_find__x', None)
@@ -318,6 +385,154 @@ class FindForm(CustomForm, ManageOldType):
return self.cleaned_data
+class SimpleFindForm(BaseFindForm):
+ def __init__(self, *args, **kwargs):
+ self.base_finds = kwargs.pop('base_finds')
+ super(SimpleFindForm, self).__init__(*args, **kwargs)
+
+
+class ResultingFindForm(CustomForm, ManageOldType):
+ file_upload = True
+ form_label = _("Resulting find")
+ form_admin_name = _(u"Treatment n-1 - 030 - Resulting find")
+ form_slug = "treatmentn1-030-resulting-find"
+
+ associated_models = {
+ 'resulting_material_type': models.MaterialType,
+ 'resulting_object_type': models.ObjectType,
+ 'resulting_communicabilitie': models.CommunicabilityType,
+ 'resulting_material_type_quality': models.MaterialTypeQualityType,
+ 'resulting_object_type_quality': models.ObjectTypeQualityType,
+ 'resulting_checked_type': models.CheckedType,
+ }
+ HEADERS = {}
+ HEADERS['resulting_label'] = FormHeader(_(u"Identification"))
+
+ resulting_label = forms.CharField(
+ label=_(u"Free ID"),
+ validators=[validators.MaxLengthValidator(60)])
+ resulting_denomination = forms.CharField(label=_(u"Denomination"),
+ required=False)
+
+ HEADERS['resulting_description'] = FormHeader(_(u"Description"))
+ resulting_description = forms.CharField(
+ label=_(u"Description"), widget=forms.Textarea, required=False)
+ resulting_is_complete = forms.NullBooleanField(
+ label=_(u"Is complete?"), required=False)
+ resulting_material_type = widgets.Select2MultipleField(
+ label=_(u"Material types"), required=False
+ )
+ resulting_material_type_quality = forms.ChoiceField(
+ label=_(u"Material type quality"), required=False, choices=[])
+ resulting_object_type = widgets.Select2MultipleField(
+ label=_(u"Object types"), required=False,
+ )
+ resulting_object_type_quality = forms.ChoiceField(
+ label=_(u"Object type quality"), required=False, choices=[])
+ resulting_find_number = forms.IntegerField(
+ label=_(u"Find number"), required=False)
+ resulting_min_number_of_individuals = forms.IntegerField(
+ label=_(u"Minimum number of individuals (MNI)"), required=False)
+
+ resulting_decoration = forms.CharField(
+ label=_(u"Decoration"), widget=forms.Textarea, required=False)
+ resulting_inscription = forms.CharField(
+ label=_(u"Inscription"), widget=forms.Textarea, required=False)
+ resulting_manufacturing_place = forms.CharField(
+ label=_(u"Manufacturing place"), required=False)
+ resulting_communicabilitie = widgets.Select2MultipleField(
+ label=_(u"Communicability"), required=False
+ )
+ resulting_comment = forms.CharField(label=_(u"Comment"), required=False,
+ widget=forms.Textarea)
+ resulting_dating_comment = forms.CharField(
+ label=_(u"Comment on dating"), required=False, widget=forms.Textarea)
+
+ HEADERS['resulting_length'] = FormHeader(_(u"Dimensions"))
+ resulting_length = FloatField(label=_(u"Length (cm)"), required=False)
+ resulting_width = FloatField(label=_(u"Width (cm)"), required=False)
+ resulting_height = FloatField(label=_(u"Height (cm)"), required=False)
+ resulting_diameter = FloatField(label=_(u"Diameter (cm)"), required=False)
+ resulting_circumference = FloatField(label=_(u"Circumference (cm)"),
+ required=False)
+ resulting_thickness = FloatField(label=_(u"Thickness (cm)"), required=False)
+ resulting_volume = FloatField(label=_(u"Volume (l)"), required=False)
+ resulting_weight = FloatField(label=_(u"Weight (g)"), required=False)
+ resulting_clutter_long_side = FloatField(
+ label=_(u"Clutter long side (cm)"), required=False)
+ resulting_clutter_short_side = FloatField(
+ label=_(u"Clutter short side (cm)"), required=False)
+ resulting_clutter_height = FloatField(
+ label=_(u"Clutter height (cm)"), required=False)
+ resulting_dimensions_comment = forms.CharField(
+ label=_(u"Dimensions comment"), required=False, widget=forms.Textarea)
+
+ HEADERS['resulting_checked_type'] = FormHeader(_(u"Sheet"))
+ resulting_checked_type = forms.ChoiceField(label=_(u"Check"),
+ required=False)
+ resulting_check_date = forms.DateField(
+ initial=get_now, label=_(u"Check date"), widget=DatePicker)
+
+ TYPES = [
+ FieldType('resulting_material_type', models.MaterialType,
+ is_multiple=True),
+ FieldType('resulting_material_type_quality',
+ models.MaterialTypeQualityType),
+ FieldType('resulting_object_type', models.ObjectType,
+ is_multiple=True),
+ FieldType('resulting_object_type_quality',
+ models.ObjectTypeQualityType),
+ FieldType('resulting_communicabilitie', models.CommunicabilityType,
+ is_multiple=True),
+ FieldType('resulting_checked_type', models.CheckedType,
+ is_multiple=True),
+ ]
+
+
+class ResultingFindsForm(CustomForm, ManageOldType):
+ form_label = _("Resulting finds")
+ form_admin_name = _(u"Treatment 1-n - 030 - Resulting finds")
+ form_slug = "treatment1n-030-resulting-finds"
+ associated_models = {}
+
+ resultings_number = forms.IntegerField(
+ label=_(u"Number of resulting finds"),
+ min_value=1
+ )
+ resultings_label = forms.CharField(
+ label=_(u"Prefix label for resulting finds"),
+ validators=[validators.MaxLengthValidator(200)],
+ help_text=_(
+ u'E.g.: with a prefix "item-", each resulting item will be named '
+ u'"item-1", "item-2", "item-3"')
+ )
+ resultings_start_number = forms.IntegerField(
+ label=_(u"Numbering starting from"), initial=1, min_value=0
+ )
+ resultings_basket_name = forms.CharField(
+ label=_(u"Name of the new basket containing the resulting items"),
+ max_length=200
+ )
+
+ def __init__(self, *args, **kwargs):
+ self.user = None
+ if 'user' in kwargs:
+ self.user = kwargs.pop('user')
+ if hasattr(self.user, 'ishtaruser'):
+ self.user = self.user.ishtaruser
+ super(ResultingFindsForm, self).__init__(*args, **kwargs)
+ if not self.user:
+ return
+
+ def clean(self):
+ q = models.FindBasket.objects.filter(
+ user=self.user, label=self.cleaned_data['resultings_basket_name'])
+ if q.count():
+ raise forms.ValidationError(_(u"A basket with this label already "
+ u"exists."))
+ return self.cleaned_data
+
+
class QAFindFormMulti(QAForm):
form_admin_name = _(u"Find - Quick action - Modify")
form_slug = "find-quickaction-modify"
@@ -333,19 +548,20 @@ class QAFindFormMulti(QAForm):
MULTI = True
REPLACE_FIELDS = [
- 'qa_ue', 'qa_manufacturing_place', 'qa_checked_type', 'qa_check_date'
+ 'qa_denomination', 'qa_ue', 'qa_manufacturing_place', 'qa_checked_type',
+ 'qa_check_date'
]
HEADERS = {
'qa_ue': FormHeader(_(u"Context record")),
- 'qa_label': FormHeader(_(u"Identification")),
+ 'qa_denomination': FormHeader(_(u"Identification")),
'qa_description': FormHeader(_(u"Description")),
'qa_checked_type': FormHeader(_(u"Sheet")),
'qa_period': FormHeader(_(u"Datation")),
}
SINGLE_FIELDS = [
- 'qa_label', 'qa_denomination', 'qa_previous_id',
+ 'qa_label', 'qa_previous_id',
'qa_get_first_base_find__excavation_id', 'qa_museum_id',
'qa_seal_number', 'qa_mark'
]
@@ -494,6 +710,35 @@ class QAFindBasketForm(IshtarForm):
basket.items.add(item)
+class QAFindbasketDuplicateForm(IshtarForm):
+ label = forms.CharField(label="", max_length=None, required=True)
+
+ def __init__(self, *args, **kwargs):
+ self.user = None
+ if 'user' in kwargs:
+ self.user = kwargs.pop('user')
+ if hasattr(self.user, 'ishtaruser'):
+ self.user = self.user.ishtaruser
+ self.basket = kwargs.pop('items')[0]
+ super(QAFindbasketDuplicateForm, self).__init__(*args, **kwargs)
+ self.fields['label'].initial = self.basket.label + unicode(
+ _(u" - duplicate"))
+
+ def clean(self):
+ label = self.cleaned_data['label'].strip()
+ if not label:
+ raise forms.ValidationError(_(u"A label is required."))
+ if models.FindBasket.objects.filter(user=self.user,
+ label=label).count():
+ raise forms.ValidationError(_(u"A basket with this label already "
+ u"exists."))
+ return self.cleaned_data
+
+ def save(self):
+ self.basket.duplicate(label=self.cleaned_data['label'],
+ ishtaruser=self.user)
+
+
class PreservationForm(CustomForm, ManageOldType):
form_label = _("Preservation")
form_admin_name = _(u"Find - 030 - Preservation")
@@ -654,6 +899,10 @@ class FindSelect(HistorySelect):
label=_(u"Batch/object"), choices=[])
checked_type = forms.ChoiceField(label=_("Check"))
documents__image__isnull = forms.NullBooleanField(label=_(u"Has an image?"))
+ loan = forms.NullBooleanField(label=_(u"Loan?"))
+ treatments_file_end_date = forms.DateField(
+ label=_(u"Treatment file end date before"), widget=DatePicker
+ )
TYPES = [
FieldType('datings__period', Period),
@@ -683,7 +932,8 @@ class FindSelect(HistorySelect):
if self.current_user:
self.fields['basket'].choices += [
(b.pk, b.label) for b in models.FindBasket.objects.filter(
- user=self.current_user).all()]
+ models.FindBasket.get_query_owns(self.current_user)
+ ).all()]
def get_input_ids(self):
ids = super(FindSelect, self).get_input_ids()
@@ -699,20 +949,36 @@ class FindSelect(HistorySelect):
class FindSelectWarehouseModule(FindSelect):
+ container_ref__location = forms.IntegerField(
+ label=_(u"Reference container - Warehouse (location)"),
+ widget=widgets.JQueryAutoComplete(
+ reverse_lazy('autocomplete-warehouse'),
+ associated_model=Warehouse),
+ validators=[valid_id(Warehouse)])
+ container_ref__responsible = forms.IntegerField(
+ label=_(u"Reference container - Warehouse (responsible)"),
+ widget=widgets.JQueryAutoComplete(
+ reverse_lazy('autocomplete-warehouse'),
+ associated_model=Warehouse),
+ validators=[valid_id(Warehouse)])
+ container_ref__index = forms.IntegerField(
+ label=_(u"Reference container ID"))
+ container_ref__reference = forms.CharField(
+ label=_(u"Reference container ref."))
container__location = forms.IntegerField(
- label=_(u"Warehouse (location)"),
+ label=_(u"Current container - Warehouse (location)"),
widget=widgets.JQueryAutoComplete(
reverse_lazy('autocomplete-warehouse'),
associated_model=Warehouse),
validators=[valid_id(Warehouse)])
container__responsible = forms.IntegerField(
- label=_(u"Warehouse (responsible)"),
+ label=_(u"Current container - Warehouse (responsible)"),
widget=widgets.JQueryAutoComplete(
reverse_lazy('autocomplete-warehouse'),
associated_model=Warehouse),
validators=[valid_id(Warehouse)])
- container__index = forms.IntegerField(label=_(u"Container ID"))
- container__reference = forms.CharField(label=_(u"Container ref."))
+ container__index = forms.IntegerField(label=_(u"Current container ID"))
+ container__reference = forms.CharField(label=_(u"Current container ref."))
class FindFormSelection(CustomFormSearch):
@@ -725,7 +991,7 @@ class FindFormSelection(CustomFormSearch):
label="", required=False,
widget=widgets.DataTable(
reverse_lazy('get-find'),
- FindSelect, models.Find,
+ FindSelect, models.Find,
source_full=reverse_lazy('get-find-full')),
validators=[valid_id(models.Find)])
@@ -910,8 +1176,19 @@ class FindDeletionForm(FinalForm):
confirm_end_msg = _(u"Would you like to delete this find?")
-class UpstreamFindFormSelection(FindFormSelection):
- form_label = _(u"Upstream find")
+class UpstreamFindFormSelection(PkWizardSearch, FindFormSelection):
+ form_label = _(u"Upstream finds")
+ current_model = models.Find
+ pk_key = 'resulting_pk'
+
+ pk = forms.CharField(
+ label="", required=False,
+ widget=widgets.DataTable(
+ reverse_lazy('get-find'),
+ FindSelect, current_model,
+ multiple_select=True,
+ source_full=reverse_lazy('get-find-full')),
+ validators=[valid_ids(current_model)])
def __init__(self, *args, **kwargs):
super(UpstreamFindFormSelection, self).__init__(*args, **kwargs)
@@ -919,6 +1196,17 @@ class UpstreamFindFormSelection(FindFormSelection):
self.fields['resulting_pk'] = self.fields.pop('pk')
+class SingleUpstreamFindFormSelection(UpstreamFindFormSelection):
+ current_model = models.Find
+ pk = forms.CharField(
+ label="", required=False,
+ widget=widgets.DataTable(
+ reverse_lazy('get-find'),
+ FindSelect, current_model,
+ source_full=reverse_lazy('get-find-full')),
+ validators=[valid_ids(current_model)])
+
+
class FindBasketSelect(CustomForm, TableSelect):
_model = models.FindBasket
@@ -947,19 +1235,57 @@ class FindBasketFormSelection(CustomFormSearch):
validators=[valid_id(models.FindBasket)])
+class FindBasketForWriteFormSelection(CustomFormSearch):
+ SEARCH_AND_SELECT = True
+ form_label = _("Basket search")
+ associated_models = {'pk': models.FindBasket}
+ currents = {'pk': models.FindBasket}
+
+ pk = forms.IntegerField(
+ label="", required=False,
+ widget=widgets.DataTable(
+ reverse_lazy('get-findbasket-write'),
+ FindBasketSelect, models.FindBasket,
+ ),
+ validators=[valid_id(models.FindBasket)])
+
+
class FindBasketForm(IshtarForm):
form_label = _(u"Find basket")
+ associated_models = {"shared_with": IshtarUser,
+ "shared_write_with": IshtarUser}
label = forms.CharField(
label=_(u"Label"),
validators=[validators.MaxLengthValidator(1000)])
comment = forms.CharField(label=_(u"Comment"),
widget=forms.Textarea, required=False)
+ shared_with = widgets.Select2MultipleField(
+ model=IshtarUser, remote=True,
+ label=_(u"Shared (read) with"),
+ required=False, long_widget=True
+ )
+ shared_write_with = widgets.Select2MultipleField(
+ model=IshtarUser, remote=True,
+ label=_(u"Shared (read/edit) with"),
+ required=False, long_widget=True
+ )
-class NewFindBasketForm(forms.ModelForm):
+class NewFindBasketForm(forms.ModelForm, IshtarForm):
+ shared_with = widgets.Select2MultipleField(
+ model=IshtarUser, remote=True,
+ label=_(u"Shared (read) with"),
+ required=False, long_widget=True
+ )
+ shared_write_with = widgets.Select2MultipleField(
+ model=IshtarUser, remote=True,
+ label=_(u"Shared (read/edit) with"),
+ required=False, long_widget=True
+ )
+
class Meta:
model = models.FindBasket
- fields = ('label', 'comment')
+ fields = ('label', 'comment', 'shared_with', 'shared_write_with')
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user')
@@ -995,22 +1321,15 @@ class SelectFindBasketForm(IshtarForm):
super(SelectFindBasketForm, self).__init__(*args, **kwargs)
if not self.user:
return
- self.fields['basket'].choices = [('', '--')] + [
- (b.pk, unicode(b))
- for b in models.FindBasket.objects.filter(
- Q(user=self.user) | Q(shared_with=self.user)
- )]
+ self.fields['basket'].choices = self.get_basket_choices()
-
-class DeleteFindBasketForm(SelectFindBasketForm):
- def save(self):
- try:
- models.FindBasket.objects.get(pk=self.cleaned_data['basket'],
- user=self.user).delete()
- except models.FindBasket.DoesNotExist:
- # something strange... TODO: log it
- pass
- return
+ def get_basket_choices(self):
+ return [('', u'--')] + [
+ (str(b.pk), unicode(b))
+ for b in models.FindBasket.objects.filter(
+ Q(user=self.user) | Q(shared_write_with=self.user)
+ )
+ ]
class FindBasketAddItemForm(forms.Form):
@@ -1020,8 +1339,8 @@ class FindBasketAddItemForm(forms.Form):
def save(self, user):
try:
basket = models.FindBasket.objects.filter(
- Q(user=user) | Q(shared_with=user)
- ).get(pk=self.cleaned_data['basket_id'])
+ Q(user=user) | Q(shared_with=user) | Q(shared_write_with=user)
+ ).distinct().get(pk=self.cleaned_data['basket_id'])
item = models.Find.objects.get(
pk=self.cleaned_data['item_id'])
except models.FindBasket.DoesNotExist or\
diff --git a/archaeological_finds/forms_treatments.py b/archaeological_finds/forms_treatments.py
index 7ada0f4bc..10c4527ef 100644
--- a/archaeological_finds/forms_treatments.py
+++ b/archaeological_finds/forms_treatments.py
@@ -23,10 +23,9 @@ from collections import OrderedDict
from django import forms
from django.core import validators
-from django.forms.formsets import formset_factory
from django.utils.translation import ugettext_lazy as _
-import models
+from archaeological_finds import models
from archaeological_operations.forms import AdministrativeActForm, \
AdministrativeActOpeFormSelection, AdministrativeActModifForm
from archaeological_operations.models import ActType, AdministrativeAct
@@ -80,7 +79,9 @@ class TreatmentFormSelection(forms.Form):
class BaseTreatmentForm(CustomForm, ManageOldType):
- form_label = _(u"Base treatment")
+ UPSTREAM_IS_MANY = False
+ DOWNSTREAM_IS_MANY = False
+ form_label = _(u"Treatment")
form_admin_name = _(u"Treatment - 020 - General")
form_slug = "treatment-020-general"
base_models = ['treatment_type']
@@ -94,20 +95,20 @@ class BaseTreatmentForm(CustomForm, ManageOldType):
file_upload = True
need_user_for_initialization = True
- label = forms.CharField(label=_(u"Label"),
- max_length=200, required=False)
- other_reference = forms.CharField(
- label=_(u"Other ref."), max_length=200, required=False)
+ treatment_type = widgets.Select2MultipleField(
+ label=_(u"Treatment type"), choices=[],
+ widget=widgets.CheckboxSelectMultiple)
+ treatment_state = forms.ChoiceField(label=_(u"State"), choices=[])
year = forms.IntegerField(label=_("Year"),
initial=lambda: datetime.datetime.now().year,
validators=[validators.MinValueValidator(1000),
validators.MaxValueValidator(2100)])
- treatment_type = forms.MultipleChoiceField(
- label=_(u"Treatment type"), choices=[],
- widget=widgets.CheckboxSelectMultiple)
- treatment_state = forms.ChoiceField(label=_(u"State"),
- choices=[], required=False)
- target_is_basket = forms.NullBooleanField(label=_(u"Target"))
+ location = forms.IntegerField(
+ label=_(u"Location"),
+ widget=widgets.JQueryAutoComplete(
+ reverse_lazy('autocomplete-warehouse'), associated_model=Warehouse,
+ new=True),
+ validators=[valid_id(Warehouse)])
person = forms.IntegerField(
label=_(u"Responsible"),
widget=widgets.JQueryAutoComplete(
@@ -120,30 +121,29 @@ class BaseTreatmentForm(CustomForm, ManageOldType):
reverse_lazy('autocomplete-organization'),
associated_model=Organization, new=True),
validators=[valid_id(Organization)], required=False)
- location = forms.IntegerField(
- label=_(u"Location"),
- widget=widgets.JQueryAutoComplete(
- reverse_lazy('autocomplete-warehouse'), associated_model=Warehouse,
- new=True),
- validators=[valid_id(Warehouse)])
+ label = forms.CharField(label=_(u"Label"),
+ max_length=200, required=False)
+ other_reference = forms.CharField(
+ label=_(u"Other ref."), max_length=200, required=False)
+ # external_id = forms.CharField(
+ # label=_(u"External ref."), max_length=200, required=False)
+ start_date = forms.DateField(label=_(u"Start date"), required=False,
+ widget=DatePicker, initial=datetime.date.today)
+ end_date = forms.DateField(label=_(u"Closing date"), required=False,
+ widget=DatePicker)
container = forms.IntegerField(
- label=_(u"Container (relevant for packaging)"),
+ label=_(u"Destination container (relevant for treatment that change "
+ u"location)"),
widget=widgets.JQueryAutoComplete(
reverse_lazy('autocomplete-container'),
associated_model=Container, new=True),
validators=[valid_id(Container)], required=False)
- external_id = forms.CharField(
- label=_(u"External ref."), max_length=200, required=False)
goal = forms.CharField(label=_(u"Goal"),
widget=forms.Textarea, required=False)
description = forms.CharField(label=_(u"Description"),
widget=forms.Textarea, required=False)
comment = forms.CharField(label=_(u"Comment"),
widget=forms.Textarea, required=False)
- start_date = forms.DateField(label=_(u"Start date"), required=False,
- widget=DatePicker)
- end_date = forms.DateField(label=_(u"Closing date"), required=False,
- widget=DatePicker)
estimated_cost = forms.FloatField(label=_(u"Estimated cost ({currency})"),
required=False)
quoted_cost = forms.FloatField(label=_(u"Quoted cost ({currency})"),
@@ -152,12 +152,15 @@ class BaseTreatmentForm(CustomForm, ManageOldType):
required=False)
insurance_cost = forms.FloatField(label=_(u"Insurance cost ({currency})"),
required=False)
+ executed = forms.BooleanField(required=False, disabled=True,
+ widget=forms.HiddenInput)
TYPES = [
- FieldType('treatment_state', models.TreatmentState),
- FieldType('treatment_type', models.TreatmentType, is_multiple=True,
- extra_args={'dct': {'upstream_is_many': False,
- 'downstream_is_many': False}})
+ FieldType('treatment_state', models.TreatmentState, True),
+ FieldType(
+ 'treatment_type', models.TreatmentType, is_multiple=True,
+ extra_args={'dct': {'upstream_is_many': False,
+ 'downstream_is_many': False}})
]
def __init__(self, *args, **kwargs):
@@ -170,14 +173,20 @@ class BaseTreatmentForm(CustomForm, ManageOldType):
self.fields[key].label = self.fields[key].label.format(
currency=currency)
+ initial = kwargs.get('initial', {})
+ if initial.get('executed', False):
+ self.fields['treatment_state'].choices = \
+ models.TreatmentState.get_types(empty_first=False,
+ dct={'executed': True})
+
q = Person.objects.filter(ishtaruser__pk=user.pk)
if q.count():
person = q.all()[0]
self.fields['person'].initial = person.pk
if person.attached_to:
self.fields['organization'].initial = person.attached_to.pk
- self.fields['target_is_basket'].widget.choices = \
- ((False, _(u"Single find")), (True, _(u"Basket")))
+ # self.fields['target_is_basket'].widget.choices = \
+ # ((False, _(u"Single find")), (True, _(u"Basket")))
# TODO
"""
self.fields['basket'].required = False
@@ -194,38 +203,97 @@ class BaseTreatmentForm(CustomForm, ManageOldType):
def clean(self, *args, **kwargs):
data = self.cleaned_data
- packaging = models.TreatmentType.get_cache('packaging')
- if not packaging:
- logger.warning("No 'packaging' treatment type defined")
- return
+
+ try:
+ treatment_types = [
+ models.TreatmentType.objects.get(
+ pk=pk, available=True,
+ upstream_is_many=self.UPSTREAM_IS_MANY,
+ downstream_is_many=self.DOWNSTREAM_IS_MANY)
+ for pk in data.get('treatment_type', [])]
+ except models.TreatmentType.DoesNotExist:
+ raise forms.ValidationError(_(u"Unknow treatment type"))
+
+
+ change_current_location = [
+ unicode(tp) for tp in treatment_types
+ if tp.change_current_location
+ ]
+ restore_reference_location = [
+ unicode(tp) for tp in treatment_types
+ if tp.restore_reference_location
+ ]
+ change_ref_location = [
+ unicode(tp) for tp in treatment_types
+ if tp.change_reference_location
+ ]
+
+ if (change_ref_location or change_current_location
+ ) and restore_reference_location:
+ if change_ref_location:
+ raise forms.ValidationError(
+ unicode(
+ _(u"{} is not compatible with {} "
+ u"treatment(s).")).format(
+ u' ; '.join(restore_reference_location),
+ u' ; '.join(change_ref_location),
+ )
+ )
+ else:
+ raise forms.ValidationError(
+ unicode(
+ _(u"{} is not compatible with {} "
+ u"treatment(s).")).format(
+ u' ; '.join(restore_reference_location),
+ u' ; '.join(change_current_location)
+ )
+ )
+
if data.get('container', None) \
- and str(packaging.pk) not in data.get('treatment_type', []):
+ and not change_ref_location\
+ and not change_current_location:
raise forms.ValidationError(
- _(u"The container field is attached to the treatment. If "
- u"no packaging treatment is done it is not relevant."))
- if not data.get('container', None) \
- and str(packaging.pk) in data.get('treatment_type', []):
+ _(u"The container field is attached to the treatment but "
+ u"no treatment with container change is defined."))
+ if not data.get('container', None) and (
+ change_ref_location or change_current_location):
raise forms.ValidationError(
- _(u"If a packaging treatment is done, the container field "
- u"must be filled."))
+ _(u"A treatment with location change is defined, the container "
+ u"field must be filled."))
if not data.get('person', None) and not data.get('organization', None):
raise forms.ValidationError(
_(u"A responsible or an organization must be defined."))
return data
- # TODO
- """
- for treatment_type in self.cleaned_data.get('treatment_type', []):
- try:
- treatment = models.TreatmentType.objects.get(
- pk=treatment_type, available=True)
- except models.TreatmentType.DoesNotExist:
- raise forms.ValidationError(_(u"This treatment type is not "
- u"available."))
- if treatment.upstream_is_many and \
- not self.cleaned_data.get('basket'):
- raise forms.ValidationError(_(u"This treatment needs a "
- u"basket."))
- """
+
+
+class N1TreatmentForm(BaseTreatmentForm):
+ UPSTREAM_IS_MANY = True
+ form_admin_name = _(u"Treatment n-1 - 020 - General")
+ form_slug = "treatmentn1-020-general"
+
+ TYPES = [
+ FieldType('treatment_state', models.TreatmentState, True,
+ extra_args={'dct': {"executed": True}}),
+ FieldType(
+ 'treatment_type', models.TreatmentType, is_multiple=True,
+ extra_args={'dct': {'upstream_is_many': True,
+ 'downstream_is_many': False}})
+ ]
+
+
+class OneNTreatmentForm(BaseTreatmentForm):
+ DOWNSTREAM_IS_MANY = True
+ form_admin_name = _(u"Treatment 1-n - 020 - General")
+ form_slug = "treatment1n-020-general"
+
+ TYPES = [
+ FieldType('treatment_state', models.TreatmentState, True,
+ extra_args={'dct': {"executed": True}}),
+ FieldType(
+ 'treatment_type', models.TreatmentType, is_multiple=True,
+ extra_args={'dct': {'upstream_is_many': False,
+ 'downstream_is_many': True}})
+ ]
class TreatmentModifyForm(BaseTreatmentForm):
@@ -240,7 +308,7 @@ class TreatmentModifyForm(BaseTreatmentForm):
fields[key] = value
if key == 'year':
fields['index'] = idx
- fields.pop('target_is_basket')
+ # fields.pop('target_is_basket')
self.fields = fields
def clean(self, *args, **kwargs):
@@ -287,6 +355,11 @@ class QAFindTreatmentForm(IshtarForm):
reverse_lazy('autocomplete-container'),
associated_model=Container, new=True),
validators=[valid_id(Container)])
+ reference_container = forms.BooleanField(
+ label=_(u"Change the reference container"), required=False,
+ widget=widgets.CheckboxInput, initial=True,
+ help_text=_(u"If unchecked the current container will be changed")
+ )
create_treatment = forms.BooleanField(
label=_(u"Create a treatment"), required=False,
widget=widgets.CheckboxInput
@@ -344,8 +417,9 @@ class QAFindTreatmentForm(IshtarForm):
container = Container.objects.get(pk=self.cleaned_data['container'])
if self.cleaned_data['create_treatment']:
packaging, created = models.TreatmentType.objects.get_or_create(
- label=u"Conditionnement",
- txt_idx='packaging'
+ txt_idx='packaging',
+ defaults={"label": _(u"Packaging"),
+ "change_reference_location": True}
)
t = models.Treatment.objects.create(
container=container,
@@ -359,10 +433,13 @@ class QAFindTreatmentForm(IshtarForm):
t.treatment_types.add(packaging)
t.save(items=items)
return
+ container_attr = 'container'
+ if self.cleaned_data.get('reference_container', False):
+ container_attr = 'container_ref'
for find in items:
- if find.container == container:
+ if getattr(find, container_attr) == container:
continue
- find.container = container
+ setattr(find, container_attr, container)
find.save()
@@ -542,7 +619,9 @@ class TreatmentFileForm(ManageOldType):
base_models = ['treatment_type_type']
associated_models = {
'type': models.TreatmentFileType, 'in_charge': Person,
- 'applicant': Person, 'applicant_organisation': Organization}
+ 'applicant': Person, 'applicant_organisation': Organization,
+ 'associated_basket': models.FindBasket
+ }
need_user_for_initialization = True
name = forms.CharField(label=_(u"Name"),
@@ -575,6 +654,11 @@ class TreatmentFileForm(ManageOldType):
reverse_lazy('autocomplete-organization'),
associated_model=Organization, new=True),
validators=[valid_id(Organization)], required=False)
+ associated_basket = forms.IntegerField(
+ _(u"Associated basket"),
+ widget=widgets.JQueryAutoComplete(
+ reverse_lazy('autocomplete-findbasket'),
+ associated_model=models.FindBasket), required=False)
comment = forms.CharField(label=_(u"Comment"),
widget=forms.Textarea, required=False)
creation_date = forms.DateField(label=_(u"Start date"), required=False,
diff --git a/archaeological_finds/ishtar_menu.py b/archaeological_finds/ishtar_menu.py
index afd624b74..21a582a18 100644
--- a/archaeological_finds/ishtar_menu.py
+++ b/archaeological_finds/ishtar_menu.py
@@ -99,23 +99,23 @@ MENU_SECTIONS = [
MenuItem('treatmentfle_search',
_(u"Search"),
model=models.TreatmentFile,
- access_controls=['view_filetreatment',
- 'view_own_filetreatment']),
+ access_controls=['view_treatmentfile',
+ 'view_own_treatmentfile']),
MenuItem('treatmentfle_creation',
_(u"Creation"),
model=models.TreatmentFile,
- access_controls=['change_filetreatment',
- 'change_own_filetreatment']),
+ access_controls=['change_treatmentfile',
+ 'change_own_treatmentfile']),
MenuItem('treatmentfle_modification',
_(u"Modification"),
model=models.TreatmentFile,
- access_controls=['change_filetreatment',
- 'change_own_filetreatment']),
+ access_controls=['change_treatmentfile',
+ 'change_own_treatmentfile']),
MenuItem('treatmentfle_deletion',
_(u"Deletion"),
model=models.TreatmentFile,
- access_controls=['change_filetreatment',
- 'change_own_filetreatment']),
+ access_controls=['change_treatmentfile',
+ 'change_own_treatmentfile']),
SectionItem(
'admin_act_fletreatments', _(u"Administrative act"),
childs=[
@@ -134,10 +134,6 @@ MENU_SECTIONS = [
_(u"Deletion"),
model=AdministrativeAct,
access_controls=['change_administrativeact']),
- MenuItem('treatmentfle_administrativeact_document',
- _(u"Documents"),
- model=AdministrativeAct,
- access_controls=['change_administrativeact']),
]
),
]
@@ -148,41 +144,47 @@ MENU_SECTIONS = [
profile_restriction='warehouse',
css='menu-warehouse',
childs=[
- SectionItem(
- 'find_treatments', _(u"Simple treatments"),
- childs=[
- MenuItem('treatment_search',
- _(u"Search"),
- model=models.Treatment,
- access_controls=['view_treatment',
- 'view_own_treatment']),
- MenuItem('treatment_creation',
- _(u"Creation"),
- model=models.Treatment,
- access_controls=['change_treatment',
- 'change_own_treatment']),
- MenuItem('treatment_modification',
- _(u"Modification"),
- model=models.Treatment,
- access_controls=['change_treatment',
- 'change_own_treatment']),
- MenuItem('treatment_deletion',
- _(u"Deletion"),
- model=models.Treatment,
- access_controls=['change_treatment',
- 'change_own_treatment']),
- ]),
- SectionItem(
+ MenuItem('treatment_search',
+ _(u"Search"),
+ model=models.Treatment,
+ access_controls=['view_treatment',
+ 'view_own_treatment']),
+ MenuItem(
+ 'treatment_creation',
+ _(u"Simple treatment - creation"),
+ model=models.Treatment,
+ access_controls=['change_find', 'change_own_find']),
+ MenuItem(
+ 'treatment_creation_n1',
+ _(u"Treatment many to one - creation"),
+ model=models.Treatment,
+ access_controls=['change_find', 'change_own_find']),
+ MenuItem(
+ 'treatment_creation_1n',
+ _(u"Treatment one to many - creation"),
+ model=models.Treatment,
+ access_controls=['change_find', 'change_own_find']),
+ MenuItem('treatment_modification',
+ _(u"Modification"),
+ model=models.Treatment,
+ access_controls=['change_treatment',
+ 'change_own_treatment']),
+ MenuItem('treatment_deletion',
+ _(u"Deletion"),
+ model=models.Treatment,
+ access_controls=['change_treatment',
+ 'change_own_treatment']),
+ SectionItem(
'admin_act_treatments', _(u"Administrative act"),
childs=[
MenuItem('treatment_admacttreatment_search',
_(u"Search"),
model=AdministrativeAct,
- access_controls=['change_administrativeact']),
+ access_controls=['view_administrativeact']),
MenuItem('treatment_admacttreatment',
_(u"Creation"),
model=AdministrativeAct,
- access_controls=['change_administrativeact']),
+ access_controls=['add_administrativeact']),
MenuItem(
'treatment_admacttreatment_modification',
_(u"Modification"), model=AdministrativeAct,
@@ -191,10 +193,6 @@ MENU_SECTIONS = [
_(u"Deletion"),
model=AdministrativeAct,
access_controls=['change_administrativeact']),
- MenuItem('treatment_administrativeact_document',
- _(u"Documents"),
- model=AdministrativeAct,
- access_controls=['change_administrativeact']),
]),
]
)),
diff --git a/archaeological_finds/locale/django.pot b/archaeological_finds/locale/django.pot
index 4ca54a290..65b0b22ba 100644
--- a/archaeological_finds/locale/django.pot
+++ b/archaeological_finds/locale/django.pot
@@ -9,853 +9,961 @@
msgid ""
msgstr ""
-#: admin.py:39 models_finds.py:288
+#: admin.py:39 models_finds.py:303
msgid "Point (2D)"
msgstr ""
-#: admin.py:41 models_finds.py:290
+#: admin.py:41 models_finds.py:305
msgid "Line"
msgstr ""
-#: admin.py:43 models_finds.py:291
+#: admin.py:43 models_finds.py:306
msgid "Multi polygon"
msgstr ""
-#: forms.py:91 forms.py:97 forms.py:340 forms.py:353 forms.py:631
-#: models_finds.py:660 models_finds.py:1213 wizards.py:75
+#: forms.py:96 forms.py:102 forms.py:556 forms.py:569 forms.py:876
+#: models_finds.py:722 models_finds.py:1337 wizards.py:86
msgid "Context record"
msgstr ""
-#: forms.py:92
+#: forms.py:97
msgid "Find - 010 - Context record choice"
msgstr ""
-#: forms.py:126 ishtar_menu.py:32 models_finds.py:1089 models_finds.py:1717
-#: models_treatments.py:349 templates/ishtar/sheet_find.html:4
+#: forms.py:134 forms.py:268 ishtar_menu.py:32 models_finds.py:1192
+#: models_finds.py:1959 models_treatments.py:585
+#: templates/ishtar/sheet_find.html:4
msgid "Find"
msgstr ""
-#: forms.py:127
-msgid "Find - 020 - General"
+#: forms.py:135
+msgid "Simple find - 020 - General"
msgstr ""
-#: forms.py:142 forms.py:341 templates/ishtar/sheet_find.html:40
+#: forms.py:157 forms.py:409 forms.py:557 templates/ishtar/sheet_find.html:110
msgid "Identification"
msgstr ""
-#: forms.py:145 forms.py:360 forms.py:600 forms.py:889 models_finds.py:253
-#: models_finds.py:968
+#: forms.py:160 forms.py:412 forms.py:576 forms.py:845 forms.py:1155
+#: models_finds.py:268 models_finds.py:1060
msgid "Free ID"
msgstr ""
-#: forms.py:147 forms.py:362 forms.py:601 forms.py:932 models_finds.py:969
+#: forms.py:162 forms.py:414 forms.py:578 forms.py:846 forms.py:1220
+#: models_finds.py:1061
msgid "Denomination"
msgstr ""
-#: forms.py:148 forms.py:363 models_finds.py:1042
+#: forms.py:163 forms.py:579 models_finds.py:1141
msgid "Previous ID"
msgstr ""
-#: forms.py:150 forms.py:365 models_finds.py:257
-msgid "Excavation ID"
-msgstr ""
-
-#: forms.py:151 forms.py:366 models_finds.py:970
+#: forms.py:164 forms.py:582 models_finds.py:1062
msgid "Museum ID"
msgstr ""
-#: forms.py:152 forms.py:367 models_finds.py:965
+#: forms.py:165 forms.py:583 models_finds.py:1057
msgid "Seal number"
msgstr ""
-#: forms.py:153 forms.py:368 models_finds.py:1038
+#: forms.py:166 forms.py:584 models_finds.py:1137
msgid "Mark"
msgstr ""
-#: forms.py:155 forms.py:156 forms.py:342 forms.py:371 forms.py:652
-#: forms_treatments.py:139 models_finds.py:258 models_finds.py:971
-#: models_treatments.py:146 templates/ishtar/sheet_find.html:58
+#: forms.py:168 forms.py:169 forms.py:417 forms.py:419 forms.py:558
+#: forms.py:587 forms.py:897 forms_treatments.py:141 models_finds.py:273
+#: models_finds.py:1063 models_treatments.py:164
+#: templates/ishtar/sheet_find.html:128
msgid "Description"
msgstr ""
-#: forms.py:159 models_finds.py:265
-msgid "Discovery date (exact or TPQ)"
-msgstr ""
-
-#: forms.py:162 models_finds.py:267 templates/ishtar/sheet_basefind.html:29
-msgid "Discovery date (TAQ)"
-msgstr ""
-
-#: forms.py:164 forms.py:654 models_finds.py:269
-msgid "Batch/object"
-msgstr ""
-
-#: forms.py:166 models_finds.py:1003
+#: forms.py:171 forms.py:421 models_finds.py:1100
msgid "Is complete?"
msgstr ""
-#: forms.py:169 forms.py:373 models_finds.py:57 models_finds.py:685
-#: models_finds.py:977
+#: forms.py:174 forms.py:423 forms.py:589 models_finds.py:57
+#: models_finds.py:748 models_finds.py:1069
msgid "Material types"
msgstr ""
-#: forms.py:172 models_finds.py:982
+#: forms.py:177 forms.py:426 models_finds.py:1074
msgid "Material type quality"
msgstr ""
-#: forms.py:174 forms.py:376 models_finds.py:152 models_finds.py:686
-#: models_finds.py:1006
+#: forms.py:179 forms.py:428 forms.py:592 models_finds.py:167
+#: models_finds.py:749 models_finds.py:1103
msgid "Object types"
msgstr ""
-#: forms.py:177 models_finds.py:1011
+#: forms.py:182 forms.py:431 models_finds.py:1108
msgid "Object type quality"
msgstr ""
-#: forms.py:178 forms.py:896 models_finds.py:989
+#: forms.py:183 forms.py:433 forms.py:1162 models_finds.py:1081
msgid "Find number"
msgstr ""
-#: forms.py:180 models_finds.py:1024
+#: forms.py:185 forms.py:435 models_finds.py:1121
msgid "Minimum number of individuals (MNI)"
msgstr ""
-#: forms.py:182 models_finds.py:972
+#: forms.py:187 forms.py:438 models_finds.py:1064
msgid "Decoration"
msgstr ""
-#: forms.py:184 models_finds.py:973
+#: forms.py:189 forms.py:440 models_finds.py:1065
msgid "Inscription"
msgstr ""
-#: forms.py:187 forms.py:379 models_finds.py:975
+#: forms.py:192 forms.py:442 forms.py:595 models_finds.py:1067
msgid "Manufacturing place"
msgstr ""
-#: forms.py:189 forms.py:381 models_finds.py:1021
+#: forms.py:194 forms.py:444 forms.py:597 models_finds.py:1118
msgid "Communicability"
msgstr ""
-#: forms.py:191 forms.py:384 forms.py:955 forms_treatments.py:141
-#: forms_treatments.py:578 models_finds.py:259 models_finds.py:1039
-#: models_treatments.py:145 models_treatments.py:609
+#: forms.py:196 forms.py:446 forms.py:600 forms.py:1260 forms_treatments.py:143
+#: forms_treatments.py:657 models_finds.py:274 models_finds.py:1138
+#: models_treatments.py:163 models_treatments.py:847
msgid "Comment"
msgstr ""
-#: forms.py:194 forms.py:394 models_finds.py:1040
+#: forms.py:199 forms.py:449 forms.py:610 models_finds.py:1139
msgid "Comment on dating"
msgstr ""
-#: forms.py:196 templates/ishtar/sheet_find.html:76
+#: forms.py:201 forms.py:451 templates/ishtar/sheet_find.html:146
msgid "Dimensions"
msgstr ""
-#: forms.py:197 models_finds.py:1025
+#: forms.py:202 forms.py:452 models_finds.py:1122
msgid "Length (cm)"
msgstr ""
-#: forms.py:198 models_finds.py:1026
+#: forms.py:204 forms.py:453 models_finds.py:1123
msgid "Width (cm)"
msgstr ""
-#: forms.py:199 models_finds.py:1027
+#: forms.py:206 forms.py:454 models_finds.py:1124
msgid "Height (cm)"
msgstr ""
-#: forms.py:200 models_finds.py:1028
+#: forms.py:208 forms.py:458 models_finds.py:1128
+msgid "Thickness (cm)"
+msgstr ""
+
+#: forms.py:210 forms.py:455 models_finds.py:1125
msgid "Diameter (cm)"
msgstr ""
-#: forms.py:201 models_finds.py:1029
-msgid "Thickness (cm)"
+#: forms.py:213 forms.py:456 models_finds.py:1126
+msgid "Circumference (cm)"
msgstr ""
-#: forms.py:202 forms.py:894 models_finds.py:985
+#: forms.py:215 forms.py:459 forms.py:1160 models_finds.py:1077
msgid "Volume (l)"
msgstr ""
-#: forms.py:203 forms.py:895 templates/ishtar/sheet_find.html:84
+#: forms.py:216 forms.py:460 forms.py:1161 templates/ishtar/sheet_find.html:155
msgid "Weight (g)"
msgstr ""
-#: forms.py:205
+#: forms.py:219 forms.py:462
msgid "Clutter long side (cm)"
msgstr ""
-#: forms.py:207
+#: forms.py:222 forms.py:464
msgid "Clutter short side (cm)"
msgstr ""
-#: forms.py:209
+#: forms.py:225 forms.py:466
msgid "Clutter height (cm)"
msgstr ""
-#: forms.py:211 models_finds.py:1036
+#: forms.py:228 forms.py:468 models_finds.py:1135
msgid "Dimensions comment"
msgstr ""
-#: forms.py:214 templates/ishtar/sheet_basefind.html:46
-#: templates/ishtar/sheet_basefind.html:50
+#: forms.py:230 forms.py:470 forms.py:559
+#: templates/ishtar/sheet_basefind.html:70 templates/ishtar/sheet_find.html:164
+msgid "Sheet"
+msgstr ""
+
+#: forms.py:231 forms.py:471 forms.py:603 forms.py:900 models_finds.py:1143
+msgid "Check"
+msgstr ""
+
+#: forms.py:233 forms.py:474 forms.py:605 models_finds.py:1145
+msgid "Check date"
+msgstr ""
+
+#: forms.py:260
+msgid "Clutter: short side cannot be bigger than the long side."
+msgstr ""
+
+#: forms.py:269
+msgid "Find - 020 - General"
+msgstr ""
+
+#: forms.py:299 forms.py:581 models_finds.py:272
+msgid "Excavation ID"
+msgstr ""
+
+#: forms.py:302 models_finds.py:280
+msgid "Discovery date (exact or TPQ)"
+msgstr ""
+
+#: forms.py:305 models_finds.py:282 templates/ishtar/sheet_basefind.html:33
+msgid "Discovery date (TAQ)"
+msgstr ""
+
+#: forms.py:307 forms.py:899 models_finds.py:284
+msgid "Batch/object"
+msgstr ""
+
+#: forms.py:310 templates/ishtar/sheet_basefind.html:50
+#: templates/ishtar/sheet_basefind.html:54
msgid "Coordinates"
msgstr ""
-#: forms.py:215 models_finds.py:276
+#: forms.py:311 models_finds.py:291
msgid "X"
msgstr ""
-#: forms.py:217 models_finds.py:279
+#: forms.py:313 models_finds.py:294
msgid "Estimated error for X"
msgstr ""
-#: forms.py:218 models_finds.py:277
+#: forms.py:314 models_finds.py:292
msgid "Y"
msgstr ""
-#: forms.py:220 models_finds.py:281
+#: forms.py:316 models_finds.py:296
msgid "Estimated error for Y"
msgstr ""
-#: forms.py:221 models_finds.py:278
+#: forms.py:317 models_finds.py:293
msgid "Z"
msgstr ""
-#: forms.py:223 models_finds.py:283
+#: forms.py:319 models_finds.py:298
msgid "Estimated error for Z"
msgstr ""
-#: forms.py:225 models_finds.py:286
+#: forms.py:321 models_finds.py:301
msgid "Spatial Reference System"
msgstr ""
-#: forms.py:228 models_finds.py:274
+#: forms.py:324 models_finds.py:289
msgid "Point of topographic reference"
msgstr ""
-#: forms.py:232 forms.py:343 templates/ishtar/sheet_basefind.html:66
-#: templates/ishtar/sheet_find.html:93
-msgid "Sheet"
+#: forms.py:352
+msgid ""
+"Discovery date: if a TAQ date is provided a TPQ date has to be informed. If "
+"you have a precise date fill only the TPQ - discovery date field."
msgstr ""
-#: forms.py:233 forms.py:387 forms.py:655 models_finds.py:1044
-msgid "Check"
+#: forms.py:358
+msgid "Discovery date: TAQ date must be older than TPQ date."
msgstr ""
-#: forms.py:235 forms.py:389 models_finds.py:1046
-msgid "Check date"
+#: forms.py:374
+msgid "You should at least provide X, Y and the spatial reference system used."
msgstr ""
-#: forms.py:274
-msgid ""
-"Discovery date: if a TAQ date is provided a TPQ date has to be informed. If "
-"you have a precise date fill only the TPQ - discovery date field."
+#: forms.py:383
+msgid "Coordinates are not relevant for the spatial reference system used: {}."
msgstr ""
-#: forms.py:280
-msgid "Discovery date: TAQ date must be older than TPQ date."
+#: forms.py:396 forms.py:1152
+msgid "Resulting find"
msgstr ""
-#: forms.py:290
-msgid "Clutter: short side cannot be bigger than the long side."
+#: forms.py:397
+msgid "Treatment n-1 - 030 - Resulting find"
msgstr ""
-#: forms.py:307
-msgid "You should at least provide X, Y and the spatial reference system used."
+#: forms.py:493 forms.py:1171
+msgid "Resulting finds"
msgstr ""
-#: forms.py:316
-msgid "Coordinates are not relevant for the spatial reference system used: {}."
+#: forms.py:494
+msgid "Treatment 1-n - 030 - Resulting finds"
msgstr ""
-#: forms.py:322
+#: forms.py:499
+msgid "Number of resulting finds"
+msgstr ""
+
+#: forms.py:503
+msgid "Prefix label for resulting finds"
+msgstr ""
+
+#: forms.py:506
+msgid ""
+"E.g.: with a prefix \"item-\", each resulting item will be named \"item-1\", "
+"\"item-2\", \"item-3\""
+msgstr ""
+
+#: forms.py:510
+msgid "Numbering starting from"
+msgstr ""
+
+#: forms.py:513
+msgid "Name of the new basket containing the resulting items"
+msgstr ""
+
+#: forms.py:531 forms.py:697 forms.py:733
+msgid "A basket with this label already exists."
+msgstr ""
+
+#: forms.py:537
msgid "Find - Quick action - Modify"
msgstr ""
-#: forms.py:344
+#: forms.py:560
msgid "Datation"
msgstr ""
-#: forms.py:392 forms.py:565 forms.py:641 templates/ishtar/sheet_find.html:123
+#: forms.py:608 forms.py:810 forms.py:886 templates/ishtar/sheet_find.html:196
msgid "Period"
msgstr ""
-#: forms.py:436
+#: forms.py:652
msgid "Find - Quick action - Modify single"
msgstr ""
-#: forms.py:449
+#: forms.py:665
msgid "Create"
msgstr ""
-#: forms.py:450
+#: forms.py:666
msgid "Update"
msgstr ""
-#: forms.py:452 forms.py:636 forms.py:982 forms.py:986 forms_treatments.py:180
-#: ishtar_menu.py:57 models_finds.py:926
-#: templates/ishtar/sheet_findbasket.html:4 views.py:646
+#: forms.py:668 forms.py:881 forms.py:1308 forms.py:1312 ishtar_menu.py:57
+#: models_finds.py:605 models_finds.py:1018
+#: templates/ishtar/sheet_findbasket.html:4 views.py:824 wizards.py:360
msgid "Basket"
msgstr ""
-#: forms.py:474
+#: forms.py:690
msgid "On update, you have to select a basket."
msgstr ""
-#: forms.py:478
+#: forms.py:694 forms.py:730
msgid "A label is required."
msgstr ""
-#: forms.py:481
-msgid "A basket with this label already exists."
+#: forms.py:725
+msgid " - duplicate"
msgstr ""
-#: forms.py:498 templates/ishtar/sheet_find.html:102
+#: forms.py:743 templates/ishtar/sheet_find.html:175
msgid "Preservation"
msgstr ""
-#: forms.py:499
+#: forms.py:744
msgid "Find - 030 - Preservation"
msgstr ""
-#: forms.py:513 forms.py:648 models_finds.py:1015
+#: forms.py:758 forms.py:893 models_finds.py:1112
msgid "Integrity / interest"
msgstr ""
-#: forms.py:516 forms.py:650 models_finds.py:1018
+#: forms.py:761 forms.py:895 models_finds.py:1115
msgid "Remarkability"
msgstr ""
-#: forms.py:518 forms.py:646 models_finds.py:1056
+#: forms.py:763 forms.py:891 models_finds.py:1155
msgid "Conservatory state"
msgstr ""
-#: forms.py:521 models_finds.py:1065
+#: forms.py:766 models_finds.py:1164
msgid "Alteration"
msgstr ""
-#: forms.py:524 models_finds.py:1069
+#: forms.py:769 models_finds.py:1168
msgid "Alteration cause"
msgstr ""
-#: forms.py:527 models_finds.py:1062
+#: forms.py:772 models_finds.py:1161
msgid "Recommended treatments"
msgstr ""
-#: forms.py:529 models_finds.py:1073
+#: forms.py:774 models_finds.py:1172
msgid "Treatment emergency"
msgstr ""
-#: forms.py:531 models_finds.py:1048
+#: forms.py:776 models_finds.py:1147
msgid "Estimated value"
msgstr ""
-#: forms.py:532 models_finds.py:1076
+#: forms.py:777 models_finds.py:1175
msgid "Insurance value"
msgstr ""
-#: forms.py:534 models_finds.py:1078
+#: forms.py:779 models_finds.py:1177
msgid "Appraisal date"
msgstr ""
-#: forms.py:536 models_finds.py:1058
+#: forms.py:781 models_finds.py:1157
msgid "Conservatory comment"
msgstr ""
-#: forms.py:560 forms.py:584 models_finds.py:997
-#: templates/ishtar/sheet_find.html:119
+#: forms.py:805 forms.py:829 models_finds.py:1089
+#: templates/ishtar/sheet_find.html:192
msgid "Dating"
msgstr ""
-#: forms.py:566 forms_treatments.py:143 forms_treatments.py:370
-#: forms_treatments.py:580 models_finds.py:1722 models_treatments.py:148
-#: models_treatments.py:360 templates/ishtar/sheet_find.html:124
-#: templates/ishtar/sheet_find.html:185 templates/ishtar/sheet_find.html:223
+#: forms.py:811 forms_treatments.py:128 forms_treatments.py:442
+#: forms_treatments.py:659 models_finds.py:1964 models_treatments.py:166
+#: models_treatments.py:596 templates/ishtar/sheet_find.html:197
+#: templates/ishtar/sheet_find.html:265 templates/ishtar/sheet_find.html:302
+#: templates/ishtar/sheet_find.html:340
msgid "Start date"
msgstr ""
-#: forms.py:568 models_finds.py:1723 models_treatments.py:361
-#: templates/ishtar/sheet_find.html:125 templates/ishtar/sheet_find.html:186
-#: templates/ishtar/sheet_find.html:224
+#: forms.py:813 models_finds.py:1965 models_treatments.py:597
+#: templates/ishtar/sheet_find.html:198 templates/ishtar/sheet_find.html:266
+#: templates/ishtar/sheet_find.html:303 templates/ishtar/sheet_find.html:341
msgid "End date"
msgstr ""
-#: forms.py:569 templates/ishtar/sheet_find.html:127
+#: forms.py:814 templates/ishtar/sheet_find.html:200
msgid "Quality"
msgstr ""
-#: forms.py:571 templates/ishtar/sheet_find.html:126
+#: forms.py:816 templates/ishtar/sheet_find.html:199
msgid "Dating type"
msgstr ""
-#: forms.py:573 templates/ishtar/sheet_find.html:128
+#: forms.py:818 templates/ishtar/sheet_find.html:201
msgid "Precise dating"
msgstr ""
-#: forms.py:585
+#: forms.py:830
msgid "Find - 040 - Dating"
msgstr ""
-#: forms.py:592
+#: forms.py:837
msgid "Find - 001 - Search"
msgstr ""
-#: forms.py:595 forms.py:928 forms_treatments.py:50 forms_treatments.py:419
-#: forms_treatments.py:493 forms_treatments.py:686
+#: forms.py:840 forms.py:1216 forms_treatments.py:49 forms_treatments.py:491
+#: forms_treatments.py:565 forms_treatments.py:765
msgid "Full text search"
msgstr ""
-#: forms.py:598 models_finds.py:294
+#: forms.py:843 models_finds.py:309
msgid "Short ID"
msgstr ""
-#: forms.py:599 models_finds.py:297
+#: forms.py:844 models_finds.py:312
msgid "Complete ID"
msgstr ""
-#: forms.py:604 forms_treatments.py:56 forms_treatments.py:101
-#: forms_treatments.py:295 forms_treatments.py:423 forms_treatments.py:498
-#: forms_treatments.py:550 forms_treatments.py:690 models_treatments.py:122
-#: models_treatments.py:582
+#: forms.py:849 forms_treatments.py:55 forms_treatments.py:100
+#: forms_treatments.py:363 forms_treatments.py:495 forms_treatments.py:570
+#: forms_treatments.py:624 forms_treatments.py:769 models_treatments.py:137
+#: models_treatments.py:820
msgid "Year"
msgstr ""
-#: forms.py:606
+#: forms.py:851
msgid "Operation's number (index by year)"
msgstr ""
-#: forms.py:609
+#: forms.py:854
msgid "Code PATRIARCHE"
msgstr ""
-#: forms.py:613
+#: forms.py:858
msgid "Operation type"
msgstr ""
-#: forms.py:616
+#: forms.py:861
msgid "Areas"
msgstr ""
-#: forms.py:619
+#: forms.py:864
msgid "Archaeological site (attached to the operation)"
msgstr ""
-#: forms.py:625
+#: forms.py:870
msgid "Archaeological site (attached to the context record)"
msgstr ""
-#: forms.py:638
+#: forms.py:883
msgid "Search within related operations"
msgstr ""
-#: forms.py:640
+#: forms.py:885
msgid "Search within related context records"
msgstr ""
-#: forms.py:642 forms.py:893 models_finds.py:56
+#: forms.py:887 forms.py:1159 models_finds.py:56
msgid "Material type"
msgstr ""
-#: forms.py:643 models_finds.py:151
+#: forms.py:888 models_finds.py:166
msgid "Object type"
msgstr ""
-#: forms.py:645
+#: forms.py:890
msgid "Preservation type"
msgstr ""
-#: forms.py:656 forms_treatments.py:59
+#: forms.py:901 forms_treatments.py:58
msgid "Has an image?"
msgstr ""
-#: forms.py:703
-msgid "Warehouse (location)"
+#: forms.py:902
+msgid "Loan?"
+msgstr ""
+
+#: forms.py:904
+msgid "Treatment file end date before"
+msgstr ""
+
+#: forms.py:953
+msgid "Reference container - Warehouse (location)"
+msgstr ""
+
+#: forms.py:959
+msgid "Reference container - Warehouse (responsible)"
msgstr ""
-#: forms.py:709
-msgid "Warehouse (responsible)"
+#: forms.py:965
+msgid "Reference container ID"
msgstr ""
-#: forms.py:714
-msgid "Container ID"
+#: forms.py:967
+msgid "Reference container ref."
msgstr ""
-#: forms.py:715
-msgid "Container ref."
+#: forms.py:969
+msgid "Current container - Warehouse (location)"
msgstr ""
-#: forms.py:720 forms.py:744 views.py:185
+#: forms.py:975
+msgid "Current container - Warehouse (responsible)"
+msgstr ""
+
+#: forms.py:980
+msgid "Current container ID"
+msgstr ""
+
+#: forms.py:981
+msgid "Current container ref."
+msgstr ""
+
+#: forms.py:986 forms.py:1010 views.py:241
msgid "Find search"
msgstr ""
-#: forms.py:769 models_treatments.py:258
-#: templates/ishtar/sheet_treatment.html:56
+#: forms.py:1035 forms.py:1180 models_treatments.py:280
+#: templates/ishtar/sheet_treatment.html:102
msgid "Upstream finds"
msgstr ""
-#: forms.py:771 models_finds.py:1090
+#: forms.py:1037 models_finds.py:1193
#: templates/ishtar/forms/qa_find_treatment.html:11
+#: templates/ishtar/sheet_treatment.html:24
msgid "Finds"
msgstr ""
-#: forms.py:783
+#: forms.py:1049
msgid "You should at least select one archaeological find."
msgstr ""
-#: forms.py:886
-msgid "Resulting find"
-msgstr ""
-
-#: forms.py:891
+#: forms.py:1157
msgid "Precise description"
msgstr ""
-#: forms.py:905
-msgid "Resulting finds"
-msgstr ""
-
-#: forms.py:910
+#: forms.py:1176
msgid "Would you like to delete this find?"
msgstr ""
-#: forms.py:914 models_treatments.py:68
-msgid "Upstream find"
-msgstr ""
-
-#: forms.py:925
+#: forms.py:1213
msgid "Find basket - 001 - Search"
msgstr ""
-#: forms.py:937 views.py:122
+#: forms.py:1225 forms.py:1240 views.py:164
msgid "Basket search"
msgstr ""
-#: forms.py:951
+#: forms.py:1254
msgid "Find basket"
msgstr ""
-#: forms.py:953 forms_treatments.py:54 forms_treatments.py:97
-#: models_treatments.py:118 templates/ishtar/sheet_find.html:179
-#: templates/ishtar/sheet_find.html:217
+#: forms.py:1258 forms_treatments.py:53 forms_treatments.py:122
+#: models_treatments.py:133
+#: templates/ishtar/forms/qa_findbasket_duplicate.html:15
+#: templates/ishtar/sheet_find.html:259 templates/ishtar/sheet_find.html:296
+#: templates/ishtar/sheet_find.html:334
msgid "Label"
msgstr ""
-#: forms.py:972
+#: forms.py:1264 forms.py:1277
+msgid "Shared (read) with"
+msgstr ""
+
+#: forms.py:1269 forms.py:1282
+msgid "Shared (read/edit) with"
+msgstr ""
+
+#: forms.py:1298
msgid "Another basket already exists with this name."
msgstr ""
-#: forms_treatments.py:55 forms_treatments.py:100 models_treatments.py:120
+#: forms_treatments.py:54 forms_treatments.py:125 models_treatments.py:135
msgid "Other ref."
msgstr ""
-#: forms_treatments.py:57 forms_treatments.py:232 forms_treatments.py:424
-#: forms_treatments.py:486 forms_treatments.py:499 forms_treatments.py:603
-#: forms_treatments.py:691 forms_treatments.py:758 models_treatments.py:123
-#: models_treatments.py:583
+#: forms_treatments.py:56 forms_treatments.py:295 forms_treatments.py:496
+#: forms_treatments.py:558 forms_treatments.py:571 forms_treatments.py:682
+#: forms_treatments.py:770 forms_treatments.py:837 models_treatments.py:138
+#: models_treatments.py:821
msgid "Index"
msgstr ""
-#: forms_treatments.py:58 forms_treatments.py:106 forms_treatments.py:378
-#: forms_treatments.py:440 models_finds.py:106 models_treatments.py:128
-#: models_treatments.py:359
+#: forms_treatments.py:57 forms_treatments.py:97 forms_treatments.py:450
+#: forms_treatments.py:512 models_finds.py:121 models_treatments.py:143
+#: models_treatments.py:595
msgid "Treatment type"
msgstr ""
-#: forms_treatments.py:71 views.py:420
+#: forms_treatments.py:70 views.py:479
msgid "Treatment search"
msgstr ""
-#: forms_treatments.py:83
-msgid "Base treatment"
+#: forms_treatments.py:82 ishtar_menu.py:143 models_treatments.py:187
+#: models_treatments.py:587 templates/ishtar/sheet_treatment.html:4
+#: templates/ishtar/sheet_treatment.html:17
+msgid "Treatment"
msgstr ""
-#: forms_treatments.py:84
+#: forms_treatments.py:83
msgid "Treatment - 020 - General"
msgstr ""
-#: forms_treatments.py:108 models_treatments.py:70 models_treatments.py:130
-#: templates/ishtar/sheet_find.html:181 templates/ishtar/sheet_find.html:219
+#: forms_treatments.py:99 models_treatments.py:83 models_treatments.py:145
+#: templates/ishtar/sheet_find.html:261 templates/ishtar/sheet_find.html:298
+#: templates/ishtar/sheet_find.html:336
msgid "State"
msgstr ""
-#: forms_treatments.py:110
-msgid "Target"
+#: forms_treatments.py:105 models_treatments.py:151 models_treatments.py:598
+msgid "Location"
msgstr ""
-#: forms_treatments.py:112 forms_treatments.py:301 forms_treatments.py:561
-#: models_treatments.py:71 models_treatments.py:138
+#: forms_treatments.py:111 forms_treatments.py:369 forms_treatments.py:635
+#: models_treatments.py:84 models_treatments.py:156
msgid "Responsible"
msgstr ""
-#: forms_treatments.py:118 forms_treatments.py:307 models_treatments.py:141
+#: forms_treatments.py:117 forms_treatments.py:375 models_treatments.py:159
msgid "Organization"
msgstr ""
-#: forms_treatments.py:124 models_treatments.py:133 models_treatments.py:362
-msgid "Location"
-msgstr ""
-
-#: forms_treatments.py:130
-msgid "Container (relevant for packaging)"
+#: forms_treatments.py:130 forms_treatments.py:442 forms_treatments.py:665
+#: forms_treatments.py:718 models_treatments.py:167 models_treatments.py:841
+msgid "Closing date"
msgstr ""
-#: forms_treatments.py:136 forms_treatments.py:557
-msgid "External ref."
+#: forms_treatments.py:133
+msgid "Destination container (relevant for treatment that change location)"
msgstr ""
-#: forms_treatments.py:137 models_treatments.py:147
+#: forms_treatments.py:139 models_treatments.py:165
msgid "Goal"
msgstr ""
-#: forms_treatments.py:145 forms_treatments.py:370 forms_treatments.py:586
-#: forms_treatments.py:639 models_treatments.py:149 models_treatments.py:603
-msgid "Closing date"
-msgstr ""
-
-#: forms_treatments.py:147
+#: forms_treatments.py:145
#, python-brace-format
msgid "Estimated cost ({currency})"
msgstr ""
-#: forms_treatments.py:149
+#: forms_treatments.py:147
#, python-brace-format
msgid "Quoted cost ({currency})"
msgstr ""
-#: forms_treatments.py:151
+#: forms_treatments.py:149
#, python-brace-format
msgid "Realized cost ({currency})"
msgstr ""
-#: forms_treatments.py:153
+#: forms_treatments.py:151
#, python-brace-format
msgid "Insurance cost ({currency})"
msgstr ""
-#: forms_treatments.py:180
-msgid "Single find"
+#: forms_treatments.py:212
+msgid "Unknow treatment type"
msgstr ""
-#: forms_treatments.py:204
+#: forms_treatments.py:233 forms_treatments.py:242
+msgid "{} is not compatible with {} treatment(s)."
+msgstr ""
+
+#: forms_treatments.py:253
msgid ""
-"The container field is attached to the treatment. If no packaging treatment "
-"is done it is not relevant."
+"The container field is attached to the treatment but no treatment with "
+"container change is defined."
msgstr ""
-#: forms_treatments.py:209
-msgid "If a packaging treatment is done, the container field must be filled."
+#: forms_treatments.py:258
+msgid ""
+"A treatment with location change is defined, the container field must be "
+"filled."
msgstr ""
-#: forms_treatments.py:213
+#: forms_treatments.py:262
msgid "A responsible or an organization must be defined."
msgstr ""
-#: forms_treatments.py:256
+#: forms_treatments.py:267
+msgid "Treatment n-1 - 020 - General"
+msgstr ""
+
+#: forms_treatments.py:281
+msgid "Treatment 1-n - 020 - General"
+msgstr ""
+
+#: forms_treatments.py:319
msgid "Another treatment with this index exists for {}."
msgstr ""
-#: forms_treatments.py:262 models_treatments.py:126
+#: forms_treatments.py:325 models_treatments.py:141
msgid "Associated request"
msgstr ""
-#: forms_treatments.py:263
+#: forms_treatments.py:326
msgid "Treatment - 010 - Request choice"
msgstr ""
-#: forms_treatments.py:268 forms_treatments.py:541 ishtar_menu.py:95
-#: models_treatments.py:618 models_treatments.py:646
-#: templates/ishtar/sheet_treatmentfile.html:4 wizards.py:207
+#: forms_treatments.py:331 forms_treatments.py:613 ishtar_menu.py:95
+#: models_treatments.py:860 models_treatments.py:882
+#: templates/ishtar/sheet_treatmentfile.html:4 wizards.py:465
msgid "Treatment request"
msgstr ""
-#: forms_treatments.py:277
+#: forms_treatments.py:340
msgid ""
"Are you sure you want to delete this treatment? All changes made to the "
"associated finds since this treatment record will be lost!"
msgstr ""
-#: forms_treatments.py:280
+#: forms_treatments.py:343
msgid "Would you like to delete this treatment?"
msgstr ""
-#: forms_treatments.py:285 models_finds.py:683 models_finds.py:1000
-#: models_treatments.py:150 models_treatments.py:363
-#: templates/ishtar/sheet_find.html:184 templates/ishtar/sheet_find.html:222
+#: forms_treatments.py:348 models_finds.py:1092 models_treatments.py:169
+#: models_treatments.py:599 templates/ishtar/sheet_find.html:264
+#: templates/ishtar/sheet_find.html:301 templates/ishtar/sheet_find.html:339
msgid "Container"
msgstr ""
-#: forms_treatments.py:291
+#: forms_treatments.py:354 templates/ishtar/forms/qa_find_treatment.html:31
+msgid "Change the reference container"
+msgstr ""
+
+#: forms_treatments.py:356
+msgid "If unchecked the current container will be changed"
+msgstr ""
+
+#: forms_treatments.py:359
msgid "Create a treatment"
msgstr ""
-#: forms_treatments.py:298
+#: forms_treatments.py:366
msgid "Precise date"
msgstr ""
-#: forms_treatments.py:340
+#: forms_treatments.py:408
msgid "At least a year is required."
msgstr ""
-#: forms_treatments.py:369
+#: forms_treatments.py:416 models_finds.py:1022 models_finds.py:1304
+#: templates/ishtar/forms/qa_find_treatment.html:16 views.py:844
+msgid "Packaging"
+msgstr ""
+
+#: forms_treatments.py:441
msgid "months"
msgstr ""
-#: forms_treatments.py:369
+#: forms_treatments.py:441
msgid "years"
msgstr ""
-#: forms_treatments.py:374 forms_treatments.py:643
+#: forms_treatments.py:446 forms_treatments.py:722
msgid "Slicing"
msgstr ""
-#: forms_treatments.py:377 forms_treatments.py:646
+#: forms_treatments.py:449 forms_treatments.py:725
msgid "Date get from"
msgstr ""
-#: forms_treatments.py:380 forms_treatments.py:649
+#: forms_treatments.py:452 forms_treatments.py:728
msgid "Date after"
msgstr ""
-#: forms_treatments.py:382 forms_treatments.py:651
+#: forms_treatments.py:454 forms_treatments.py:730
msgid "Date before"
msgstr ""
-#: forms_treatments.py:425 forms_treatments.py:475 forms_treatments.py:692
-#: forms_treatments.py:747
+#: forms_treatments.py:497 forms_treatments.py:547 forms_treatments.py:771
+#: forms_treatments.py:826
msgid "Act type"
msgstr ""
-#: forms_treatments.py:426 forms_treatments.py:693
+#: forms_treatments.py:498 forms_treatments.py:772
msgid "Indexed?"
msgstr ""
-#: forms_treatments.py:427 forms_treatments.py:694
+#: forms_treatments.py:499 forms_treatments.py:773
msgid "Object"
msgstr ""
-#: forms_treatments.py:431 forms_treatments.py:698
+#: forms_treatments.py:503 forms_treatments.py:777
msgid "Signature date after"
msgstr ""
-#: forms_treatments.py:433 forms_treatments.py:700
+#: forms_treatments.py:505 forms_treatments.py:779
msgid "Signature date before"
msgstr ""
-#: forms_treatments.py:435
+#: forms_treatments.py:507
msgid "Treatment name"
msgstr ""
-#: forms_treatments.py:436
+#: forms_treatments.py:508
msgid "Treatment year"
msgstr ""
-#: forms_treatments.py:437
+#: forms_treatments.py:509
msgid "Treatment index"
msgstr ""
-#: forms_treatments.py:439
+#: forms_treatments.py:511
msgid "Treatment internal reference"
msgstr ""
-#: forms_treatments.py:443 forms_treatments.py:714
+#: forms_treatments.py:515 forms_treatments.py:793
msgid "Modified by"
msgstr ""
-#: forms_treatments.py:473
+#: forms_treatments.py:545
msgid "Treatment - Administrative act - General"
msgstr ""
-#: forms_treatments.py:496 forms_treatments.py:548 models_treatments.py:588
+#: forms_treatments.py:568 forms_treatments.py:622 models_treatments.py:826
msgid "Name"
msgstr ""
-#: forms_treatments.py:497 forms_treatments.py:555
+#: forms_treatments.py:569 forms_treatments.py:629
msgid "Internal ref."
msgstr ""
-#: forms_treatments.py:500 forms_treatments.py:559 models_treatments.py:69
-#: templates/ishtar/sheet_find.html:180 templates/ishtar/sheet_find.html:218
+#: forms_treatments.py:572 forms_treatments.py:633 models_treatments.py:82
+#: templates/ishtar/sheet_find.html:260 templates/ishtar/sheet_find.html:297
+#: templates/ishtar/sheet_find.html:335
msgid "Type"
msgstr ""
-#: forms_treatments.py:503
+#: forms_treatments.py:575
msgid "In charge"
msgstr ""
-#: forms_treatments.py:509 forms_treatments.py:567 models_treatments.py:597
-#: templates/ishtar/sheet_treatmentfile.html:45
+#: forms_treatments.py:581 forms_treatments.py:641 models_treatments.py:835
+#: templates/ishtar/sheet_treatmentfile.html:46
msgid "Applicant"
msgstr ""
-#: forms_treatments.py:515 forms_treatments.py:573 models_treatments.py:601
-#: templates/ishtar/sheet_treatmentfile.html:53
+#: forms_treatments.py:587 forms_treatments.py:647 models_treatments.py:839
+#: templates/ishtar/sheet_treatmentfile.html:54
msgid "Applicant organisation"
msgstr ""
-#: forms_treatments.py:529 views.py:524
+#: forms_treatments.py:601 views.py:681
msgid "Treatment request search"
msgstr ""
-#: forms_treatments.py:584 forms_treatments.py:638 models_treatments.py:607
+#: forms_treatments.py:631
+msgid "External ref."
+msgstr ""
+
+#: forms_treatments.py:653
+msgid "Associated basket"
+msgstr ""
+
+#: forms_treatments.py:663 forms_treatments.py:717 models_treatments.py:845
msgid "Reception date"
msgstr ""
-#: forms_treatments.py:626
+#: forms_treatments.py:705
msgid "Another treatment request with this index exists for {}."
msgstr ""
-#: forms_treatments.py:632
+#: forms_treatments.py:711
msgid "Are you sure you want to delete this treatment request?"
msgstr ""
-#: forms_treatments.py:633
+#: forms_treatments.py:712
msgid "Would you like to delete this treatment request?"
msgstr ""
-#: forms_treatments.py:637 models_treatments.py:605
+#: forms_treatments.py:716 models_treatments.py:843
msgid "Creation date"
msgstr ""
-#: forms_treatments.py:647 forms_treatments.py:711 models_treatments.py:519
-#: models_treatments.py:590
+#: forms_treatments.py:726 forms_treatments.py:790 models_treatments.py:757
+#: models_treatments.py:828
msgid "Treatment request type"
msgstr ""
-#: forms_treatments.py:703
+#: forms_treatments.py:782
msgid "Treatment request name"
msgstr ""
-#: forms_treatments.py:705
+#: forms_treatments.py:784
msgid "Treatment request year"
msgstr ""
-#: forms_treatments.py:707
+#: forms_treatments.py:786
msgid "Treatment request index"
msgstr ""
-#: forms_treatments.py:709
+#: forms_treatments.py:788
msgid "Treatment request internal reference"
msgstr ""
-#: forms_treatments.py:745
+#: forms_treatments.py:824
msgid "Treatment request - Administrative act - General"
msgstr ""
#: ishtar_menu.py:37 ishtar_menu.py:60 ishtar_menu.py:100 ishtar_menu.py:123
-#: ishtar_menu.py:155 ishtar_menu.py:179
+#: ishtar_menu.py:148 ishtar_menu.py:181
msgid "Search"
msgstr ""
#: ishtar_menu.py:42 ishtar_menu.py:65 ishtar_menu.py:105 ishtar_menu.py:127
-#: ishtar_menu.py:160 ishtar_menu.py:183
+#: ishtar_menu.py:185
msgid "Creation"
msgstr ""
#: ishtar_menu.py:47 ishtar_menu.py:70 ishtar_menu.py:110 ishtar_menu.py:131
-#: ishtar_menu.py:165 ishtar_menu.py:188
+#: ishtar_menu.py:168 ishtar_menu.py:190
msgid "Modification"
msgstr ""
#: ishtar_menu.py:52 ishtar_menu.py:82 ishtar_menu.py:115 ishtar_menu.py:134
-#: ishtar_menu.py:170 ishtar_menu.py:191
+#: ishtar_menu.py:173 ishtar_menu.py:193
msgid "Deletion"
msgstr ""
@@ -863,22 +971,20 @@ msgstr ""
msgid "Manage items"
msgstr ""
-#: ishtar_menu.py:120 ishtar_menu.py:176 models_finds.py:1719
+#: ishtar_menu.py:120 ishtar_menu.py:178 models_finds.py:1961
msgid "Administrative act"
msgstr ""
-#: ishtar_menu.py:138 ishtar_menu.py:195 models_finds.py:1081
-#: models_treatments.py:163 models_treatments.py:611
-msgid "Documents"
+#: ishtar_menu.py:154
+msgid "Simple treatment - creation"
msgstr ""
-#: ishtar_menu.py:147 models_treatments.py:170 models_treatments.py:351
-#: templates/ishtar/sheet_treatment.html:4
-msgid "Treatment"
+#: ishtar_menu.py:159
+msgid "Treatment many to one - creation"
msgstr ""
-#: ishtar_menu.py:152
-msgid "Simple treatments"
+#: ishtar_menu.py:164
+msgid "Treatment one to many - creation"
msgstr ""
#: models_finds.py:51
@@ -889,9 +995,9 @@ msgstr ""
msgid "Recommendation"
msgstr ""
-#: models_finds.py:66 models_finds.py:79 models_finds.py:92 models_finds.py:138
-#: models_finds.py:161 models_finds.py:218 models_finds.py:967
-#: models_treatments.py:355
+#: models_finds.py:66 models_finds.py:79 models_finds.py:92 models_finds.py:153
+#: models_finds.py:176 models_finds.py:233 models_finds.py:1059
+#: models_treatments.py:45 models_treatments.py:591
msgid "Order"
msgstr ""
@@ -904,12 +1010,10 @@ msgid "Material type quality types"
msgstr ""
#: models_finds.py:82
-#| msgid "Conservatory state"
msgid "Conservatory state type"
msgstr ""
#: models_finds.py:83
-#| msgid "Conservatory states"
msgid "Conservatory state types"
msgstr ""
@@ -917,573 +1021,697 @@ msgstr ""
msgid "Virtual"
msgstr ""
-#: models_finds.py:95
-msgid "Upstream is many"
+#: models_finds.py:94
+msgid "Destructive"
+msgstr ""
+
+#: models_finds.py:96
+msgid "Create a new find"
msgstr ""
#: models_finds.py:97
-msgid "Check this if for this treatment from many finds you'll get one."
+msgid ""
+"If True when this treatment is applied a new version of the object will be "
+"created."
msgstr ""
#: models_finds.py:100
-msgid "Downstream is many"
+msgid "Upstream is many"
msgstr ""
#: models_finds.py:102
+msgid "Check this if for this treatment from many finds you'll get one."
+msgstr ""
+
+#: models_finds.py:105
+msgid "Downstream is many"
+msgstr ""
+
+#: models_finds.py:107
msgid "Check this if for this treatment from one find you'll get many."
msgstr ""
-#: models_finds.py:107 models_treatments.py:240
-msgid "Treatment types"
+#: models_finds.py:110
+msgid "Change reference location"
+msgstr ""
+
+#: models_finds.py:111
+msgid "The treatment change the reference location."
+msgstr ""
+
+#: models_finds.py:113
+msgid "Change current location"
+msgstr ""
+
+#: models_finds.py:114
+msgid "The treatment change the current location."
+msgstr ""
+
+#: models_finds.py:116
+msgid "Restore the reference location"
msgstr ""
#: models_finds.py:117
+msgid ""
+"The treatment change restore reference location to the current location."
+msgstr ""
+
+#: models_finds.py:122 models_treatments.py:262
+msgid "Treatment types"
+msgstr ""
+
+#: models_finds.py:132
msgid "Integrity / interest type"
msgstr ""
-#: models_finds.py:118
+#: models_finds.py:133
msgid "Integrity / interest types"
msgstr ""
-#: models_finds.py:128
+#: models_finds.py:143
msgid "Remarkability type"
msgstr ""
-#: models_finds.py:129
+#: models_finds.py:144
msgid "Remarkability types"
msgstr ""
-#: models_finds.py:140
+#: models_finds.py:155
msgid "Batch type"
msgstr ""
-#: models_finds.py:141
+#: models_finds.py:156
msgid "Batch types"
msgstr ""
-#: models_finds.py:164
+#: models_finds.py:179
msgid "Object type quality type"
msgstr ""
-#: models_finds.py:165
+#: models_finds.py:180
msgid "Object type quality types"
msgstr ""
-#: models_finds.py:175
+#: models_finds.py:190
msgid "Alteration type"
msgstr ""
-#: models_finds.py:176
+#: models_finds.py:191
msgid "Alteration types"
msgstr ""
-#: models_finds.py:186
+#: models_finds.py:201
msgid "Alteration cause type"
msgstr ""
-#: models_finds.py:187
+#: models_finds.py:202
msgid "Alteration cause types"
msgstr ""
-#: models_finds.py:197
+#: models_finds.py:212
msgid "Treatment emergency type"
msgstr ""
-#: models_finds.py:198
+#: models_finds.py:213
msgid "Treatment emergency types"
msgstr ""
-#: models_finds.py:208
+#: models_finds.py:223
msgid "Communicability type"
msgstr ""
-#: models_finds.py:209
+#: models_finds.py:224
msgid "Communicability types"
msgstr ""
-#: models_finds.py:221
+#: models_finds.py:236
msgid "Checked type"
msgstr ""
-#: models_finds.py:222
+#: models_finds.py:237
msgid "Checked types"
msgstr ""
-#: models_finds.py:254 models_finds.py:960 models_treatments.py:143
-#: models_treatments.py:586
+#: models_finds.py:269 models_finds.py:1052 models_treatments.py:161
+#: models_treatments.py:824
msgid "External ID"
msgstr ""
-#: models_finds.py:256 models_finds.py:962
+#: models_finds.py:271 models_finds.py:1054
msgid "External ID is set automatically"
msgstr ""
-#: models_finds.py:260
+#: models_finds.py:275
msgid "Special interest"
msgstr ""
-#: models_finds.py:264
+#: models_finds.py:279
msgid "Context Record"
msgstr ""
-#: models_finds.py:272
+#: models_finds.py:287
msgid "Material index"
msgstr ""
-#: models_finds.py:289
+#: models_finds.py:304
msgid "Point (3D)"
msgstr ""
-#: models_finds.py:295 models_finds.py:298
+#: models_finds.py:310 models_finds.py:313
msgid "Cached value - do not edit"
msgstr ""
-#: models_finds.py:308 models_finds.py:958
+#: models_finds.py:323 models_finds.py:1050
msgid "Base find"
msgstr ""
-#: models_finds.py:309
+#: models_finds.py:324
msgid "Base finds"
msgstr ""
-#: models_finds.py:565
+#: models_finds.py:589
msgid "g"
msgstr ""
-#: models_finds.py:566
+#: models_finds.py:590
msgid "kg"
msgstr ""
-#: models_finds.py:592 views.py:301
+#: models_finds.py:600 views.py:863 views.py:882
+msgid "Duplicate"
+msgstr ""
+
+#: models_finds.py:626 views.py:379
msgid "Manage basket"
msgstr ""
-#: models_finds.py:661
+#: models_finds.py:633 models_finds.py:1299
+msgid "Add treatment"
+msgstr ""
+
+#: models_finds.py:723
msgid "Base find - Short ID"
msgstr ""
-#: models_finds.py:662
+#: models_finds.py:724
msgid "Base find - Complete ID"
msgstr ""
-#: models_finds.py:664
+#: models_finds.py:726
msgid "Operation (code)"
msgstr ""
-#: models_finds.py:666
+#: models_finds.py:728
msgid "Town"
msgstr ""
-#: models_finds.py:668
+#: models_finds.py:730
msgid "Operation (name)"
msgstr ""
-#: models_finds.py:672
+#: models_finds.py:734
msgid "Parcel"
msgstr ""
-#: models_finds.py:673
+#: models_finds.py:735
msgid "Batch"
msgstr ""
-#: models_finds.py:674
+#: models_finds.py:736
msgid "Base find - Comment"
msgstr ""
-#: models_finds.py:675
+#: models_finds.py:737
msgid "Base find - Description"
msgstr ""
-#: models_finds.py:676
+#: models_finds.py:738
msgid "Base find - Topographic localisation"
msgstr ""
-#: models_finds.py:678
+#: models_finds.py:740
msgid "Base find - Special interest"
msgstr ""
-#: models_finds.py:680
+#: models_finds.py:742
msgid "Base find - Discovery date (exact or TPQ)"
msgstr ""
-#: models_finds.py:682
+#: models_finds.py:744
msgid "Base find - Discovery date (TAQ)"
msgstr ""
-#: models_finds.py:684
+#: models_finds.py:745
+msgid "Current container"
+msgstr ""
+
+#: models_finds.py:746 models_finds.py:1097
+msgid "Reference container"
+msgstr ""
+
+#: models_finds.py:747
msgid "Periods"
msgstr ""
-#: models_finds.py:760
+#: models_finds.py:823
msgctxt "key for text search"
msgid "short-id"
msgstr ""
-#: models_finds.py:764
+#: models_finds.py:827
msgctxt "key for text search"
msgid "complete-id"
msgstr ""
-#: models_finds.py:768
+#: models_finds.py:831
msgctxt "key for text search"
msgid "free-id"
msgstr ""
-#: models_finds.py:772
+#: models_finds.py:835
msgctxt "key for text search"
msgid "denomination"
msgstr ""
-#: models_finds.py:776
+#: models_finds.py:839
msgctxt "key for text search"
msgid "town"
msgstr ""
-#: models_finds.py:780 models_treatments.py:87 models_treatments.py:551
+#: models_finds.py:843 models_treatments.py:102 models_treatments.py:789
msgctxt "key for text search"
msgid "year"
msgstr ""
-#: models_finds.py:784
+#: models_finds.py:847
msgctxt "key for text search"
msgid "operation-code"
msgstr ""
-#: models_finds.py:788
+#: models_finds.py:851
msgctxt "key for text search"
msgid "code-patriarche"
msgstr ""
-#: models_finds.py:792
+#: models_finds.py:855
msgctxt "key for text search"
msgid "operation-type"
msgstr ""
-#: models_finds.py:797
+#: models_finds.py:860
msgctxt "key for text search"
msgid "area"
msgstr ""
-#: models_finds.py:801
+#: models_finds.py:864
msgctxt "key for text search"
msgid "site"
msgstr ""
-#: models_finds.py:806 models_finds.py:945
+#: models_finds.py:869 models_finds.py:1037
msgctxt "key for text search"
msgid "context-record-site"
msgstr ""
-#: models_finds.py:811 models_finds.py:939
+#: models_finds.py:874 models_finds.py:1031
msgctxt "key for text search"
msgid "context-record"
msgstr ""
-#: models_finds.py:815
+#: models_finds.py:878
msgctxt "key for text search"
msgid "operation-relation-type"
msgstr ""
-#: models_finds.py:819
+#: models_finds.py:882
msgctxt "key for text search"
msgid "context-record-relation-type"
msgstr ""
-#: models_finds.py:823
+#: models_finds.py:886
msgctxt "key for text search"
msgid "period"
msgstr ""
-#: models_finds.py:827
+#: models_finds.py:890
msgctxt "key for text search"
msgid "material"
msgstr ""
-#: models_finds.py:831
+#: models_finds.py:894
msgctxt "key for text search"
msgid "object-type"
msgstr ""
-#: models_finds.py:835
+#: models_finds.py:898
msgctxt "key for text search"
msgid "preservation"
msgstr ""
-#: models_finds.py:839
+#: models_finds.py:902
msgctxt "key for text search"
msgid "conservatory"
msgstr ""
-#: models_finds.py:843
+#: models_finds.py:906
msgctxt "key for text search"
msgid "integrity"
msgstr ""
-#: models_finds.py:847
+#: models_finds.py:910
msgctxt "key for text search"
msgid "remarkability"
msgstr ""
-#: models_finds.py:851
+#: models_finds.py:914
msgctxt "key for text search"
msgid "description"
msgstr ""
-#: models_finds.py:855
+#: models_finds.py:918
msgctxt "key for text search"
msgid "batch"
msgstr ""
-#: models_finds.py:859
+#: models_finds.py:922
msgctxt "key for text search"
msgid "checked"
msgstr ""
-#: models_finds.py:863 models_treatments.py:95
+#: models_finds.py:926 models_treatments.py:110
msgctxt "key for text search"
msgid "has-image"
msgstr ""
-#: models_finds.py:867 models_finds.py:942
+#: models_finds.py:930 models_finds.py:1034
msgctxt "key for text search"
msgid "location"
msgstr ""
-#: models_finds.py:871
+#: models_finds.py:934
msgctxt "key for text search"
msgid "warehouse"
msgstr ""
-#: models_finds.py:875
+#: models_finds.py:938
msgctxt "key for text search"
msgid "container-index"
msgstr ""
-#: models_finds.py:879
+#: models_finds.py:942
msgctxt "key for text search"
msgid "container-ref"
msgstr ""
-#: models_finds.py:883
+#: models_finds.py:946
+msgctxt "key for text search"
+msgid "current-location"
+msgstr ""
+
+#: models_finds.py:950
+msgctxt "key for text search"
+msgid "current-warehouse"
+msgstr ""
+
+#: models_finds.py:954
+msgctxt "key for text search"
+msgid "current-container-index"
+msgstr ""
+
+#: models_finds.py:958
+msgctxt "key for text search"
+msgid "current-container-ref"
+msgstr ""
+
+#: models_finds.py:962 wizards.py:399
msgctxt "key for text search"
msgid "basket"
msgstr ""
-#: models_finds.py:887 models_finds.py:936
+#: models_finds.py:966 models_finds.py:1028
msgctxt "key for text search"
msgid "operation"
msgstr ""
-#: models_finds.py:891
+#: models_finds.py:970
msgctxt "key for text search"
msgid "last-modified-by"
msgstr ""
-#: models_finds.py:895
+#: models_finds.py:974
msgctxt "key for text search"
msgid "modified-since"
msgstr ""
-#: models_finds.py:919
-msgid "Bulk update"
+#: models_finds.py:978
+msgctxt "key for text search"
+msgid "created-by"
msgstr ""
-#: models_finds.py:930 models_finds.py:1180
-#: templates/ishtar/forms/qa_find_treatment.html:16 views.py:666
-msgid "Packaging"
+#: models_finds.py:982
+msgctxt "key for text search"
+msgid "loan"
msgstr ""
#: models_finds.py:986
+msgctxt "key for text search"
+msgid "treatment-end-date-before"
+msgstr ""
+
+#: models_finds.py:1011
+msgid "Bulk update"
+msgstr ""
+
+#: models_finds.py:1078
msgid "Weight"
msgstr ""
-#: models_finds.py:987
+#: models_finds.py:1079
msgid "Weight unit"
msgstr ""
-#: models_finds.py:993 templates/ishtar/sheet_find.html:174
+#: models_finds.py:1085 templates/ishtar/sheet_find.html:291
msgid "Upstream treatment"
msgstr ""
-#: models_finds.py:996 templates/ishtar/sheet_find.html:212
+#: models_finds.py:1088 templates/ishtar/sheet_find.html:329
msgid "Downstream treatment"
msgstr ""
-#: models_finds.py:1031
+#: models_finds.py:1130
msgid "Clutter - long side (cm)"
msgstr ""
-#: models_finds.py:1033
+#: models_finds.py:1132
msgid "Clutter - short side (cm)"
msgstr ""
-#: models_finds.py:1035
+#: models_finds.py:1134
msgid "Clutter - height (cm)"
msgstr ""
-#: models_finds.py:1051
+#: models_finds.py:1150
msgid "Collection"
msgstr ""
-#: models_finds.py:1083 models_treatments.py:165 models_treatments.py:613
+#: models_finds.py:1180 models_treatments.py:180 models_treatments.py:849
+#: templates/ishtar/sheet_find.html:56 templates/ishtar/sheet_treatment.html:32
+msgid "Documents"
+msgstr ""
+
+#: models_finds.py:1183 models_treatments.py:188
+#: templates/ishtar/sheet_find.html:254
+#: templates/ishtar/sheet_treatmentfile.html:62
+msgid "Treatments"
+msgstr ""
+
+#: models_finds.py:1185
+msgid "Related treatments when no new find is created"
+msgstr ""
+
+#: models_finds.py:1186 models_treatments.py:182 models_treatments.py:855
msgid "Cached name"
msgstr ""
-#: models_finds.py:1105
+#: models_finds.py:1208
msgid "FIND"
msgstr ""
-#: models_finds.py:1174
+#: models_finds.py:1296
msgid "Add to basket"
msgstr ""
-#: models_finds.py:1222 wizards.py:74 wizards.py:219
+#: models_finds.py:1346 wizards.py:85 wizards.py:477
msgid "Operation"
msgstr ""
-#: models_finds.py:1544
+#: models_finds.py:1738
+msgid "No reference container have been set - the localisation cannot be set."
+msgstr ""
+
+#: models_finds.py:1742
msgid "No container have been set - the localisation cannot be set."
msgstr ""
-#: models_finds.py:1550
+#: models_finds.py:1748
msgid "The division number {} have not been set for the warehouse {}."
msgstr ""
-#: models_finds.py:1720
+#: models_finds.py:1962
msgid "Person"
msgstr ""
-#: models_finds.py:1726
+#: models_finds.py:1968
msgid "Property"
msgstr ""
-#: models_finds.py:1727
+#: models_finds.py:1969
msgid "Properties"
msgstr ""
-#: models_treatments.py:42
+#: models_treatments.py:44
+msgid "Treatment is executed"
+msgstr ""
+
+#: models_treatments.py:48
msgid "Treatment state type"
msgstr ""
-#: models_treatments.py:43
+#: models_treatments.py:49
msgid "Treatment state types"
msgstr ""
-#: models_treatments.py:67
+#: models_treatments.py:80
msgid "Downstream find"
msgstr ""
-#: models_treatments.py:79
+#: models_treatments.py:81
+msgid "Upstream find"
+msgstr ""
+
+#: models_treatments.py:94
msgctxt "key for text search"
msgid "label"
msgstr ""
-#: models_treatments.py:83
+#: models_treatments.py:98
msgctxt "key for text search"
msgid "other-reference"
msgstr ""
-#: models_treatments.py:91 models_treatments.py:555
+#: models_treatments.py:106 models_treatments.py:793
msgctxt "key for text search"
msgid "index"
msgstr ""
-#: models_treatments.py:99 models_treatments.py:559
+#: models_treatments.py:114 models_treatments.py:797
msgctxt "key for text search"
msgid "type"
msgstr ""
-#: models_treatments.py:135
+#: models_treatments.py:149
+msgid "Treatment have been executed"
+msgstr ""
+
+#: models_treatments.py:153
msgid "Location where the treatment is done. Target warehouse for a move."
msgstr ""
-#: models_treatments.py:152
+#: models_treatments.py:171
msgid "Estimated cost"
msgstr ""
-#: models_treatments.py:154
+#: models_treatments.py:173
msgid "Quoted cost"
msgstr ""
-#: models_treatments.py:156
+#: models_treatments.py:175
msgid "Realized cost"
msgstr ""
-#: models_treatments.py:158
+#: models_treatments.py:177
msgid "Insurance cost"
msgstr ""
-#: models_treatments.py:160
-msgid "Target a basket"
+#: models_treatments.py:208
+msgid "TREATMENT"
msgstr ""
-#: models_treatments.py:171 templates/ishtar/sheet_find.html:171
-#: templates/ishtar/sheet_treatmentfile.html:61
-msgid "Treatments"
+#: models_treatments.py:271 templates/ishtar/sheet_treatment.html:107
+msgid "Downstream finds"
msgstr ""
-#: models_treatments.py:190
-msgid "TREATMENT"
+#: models_treatments.py:289 models_treatments.py:911
+msgid "Add associated administrative act"
msgstr ""
-#: models_treatments.py:249 templates/ishtar/sheet_treatment.html:61
-msgid "Downstream finds"
+#: models_treatments.py:290 models_treatments.py:912
+msgid "admin. act"
msgstr ""
-#: models_treatments.py:364 templates/ishtar/sheet_find.html:183
-#: templates/ishtar/sheet_find.html:221
+#: models_treatments.py:600 templates/ishtar/sheet_find.html:263
+#: templates/ishtar/sheet_find.html:300 templates/ishtar/sheet_find.html:338
msgid "Doer"
msgstr ""
-#: models_treatments.py:365 models_treatments.py:366
+#: models_treatments.py:601 models_treatments.py:602
+#: templates/ishtar/sheet_treatment.html:97
msgid "Related finds"
msgstr ""
-#: models_treatments.py:508
+#: models_treatments.py:744
msgid "Is upstream"
msgstr ""
-#: models_treatments.py:520
+#: models_treatments.py:758
msgid "Treatment request types"
msgstr ""
-#: models_treatments.py:543
+#: models_treatments.py:781
msgctxt "key for text search"
msgid "name"
msgstr ""
-#: models_treatments.py:547
+#: models_treatments.py:785
msgctxt "key for text search"
msgid "reference"
msgstr ""
-#: models_treatments.py:563
+#: models_treatments.py:801
msgctxt "key for text search"
msgid "in-charge"
msgstr ""
-#: models_treatments.py:567
+#: models_treatments.py:805
msgctxt "key for text search"
msgid "applicant"
msgstr ""
-#: models_treatments.py:571
+#: models_treatments.py:809
msgctxt "key for text search"
msgid "applicant-organisation"
msgstr ""
-#: models_treatments.py:584
+#: models_treatments.py:822
msgid "Internal reference"
msgstr ""
-#: models_treatments.py:593
+#: models_treatments.py:831
msgid "Person in charge"
msgstr ""
-#: models_treatments.py:619
+#: models_treatments.py:861
msgid "Treatment requests"
msgstr ""
+#: models_treatments.py:924
+msgid "Add associated treatment"
+msgstr ""
+
+#: templates/ishtar/blocks/window_find_nav.html:9
+msgid "Baskets"
+msgstr ""
+
#: templates/ishtar/forms/qa_find_basket.html:22
msgid "New"
msgstr ""
@@ -1492,49 +1720,54 @@ msgstr ""
msgid "Add"
msgstr ""
-#: templates/ishtar/forms/qa_find_treatment.html:31
+#: templates/ishtar/forms/qa_find_treatment.html:37
msgid "Associate a treatment"
msgstr ""
-#: templates/ishtar/sheet_basefind.html:6
+#: templates/ishtar/forms/qa_findbasket_duplicate.html:6
+msgid ""
+"Items of the basket will be attached to the new basket but not the shares."
+msgstr ""
+
+#: templates/ishtar/sheet_basefind.html:10
msgid "Internal ID"
msgstr ""
-#: templates/ishtar/sheet_basefind.html:21
+#: templates/ishtar/sheet_basefind.html:25
msgid "Discovery date"
msgstr ""
-#: templates/ishtar/sheet_basefind.html:24
+#: templates/ishtar/sheet_basefind.html:28
msgid "Discovery year"
msgstr ""
-#: templates/ishtar/sheet_basefind.html:27
+#: templates/ishtar/sheet_basefind.html:31
msgid "Discovery date (TPQ)"
msgstr ""
-#: templates/ishtar/sheet_basefind.html:52
+#: templates/ishtar/sheet_basefind.html:56
msgid "X:"
msgstr ""
-#: templates/ishtar/sheet_basefind.html:53
-#: templates/ishtar/sheet_basefind.html:55
#: templates/ishtar/sheet_basefind.html:57
+#: templates/ishtar/sheet_basefind.html:59
+#: templates/ishtar/sheet_basefind.html:61
msgid "error:"
msgstr ""
-#: templates/ishtar/sheet_basefind.html:54
+#: templates/ishtar/sheet_basefind.html:58
msgid "Y:"
msgstr ""
-#: templates/ishtar/sheet_basefind.html:56
+#: templates/ishtar/sheet_basefind.html:60
msgid "Z:"
msgstr ""
-#: templates/ishtar/sheet_basefind.html:60
+#: templates/ishtar/sheet_basefind.html:64
msgid "SRID"
msgstr ""
-#: templates/ishtar/sheet_basefind.html:75
+#: templates/ishtar/sheet_basefind.html:79
msgid "Last modified by"
msgstr ""
@@ -1544,65 +1777,85 @@ msgid ""
"the find."
msgstr ""
-#: templates/ishtar/sheet_find.html:29
-msgid "Associated base finds"
+#: templates/ishtar/sheet_find.html:23
+msgid "Image / Base find"
+msgstr ""
+
+#: templates/ishtar/sheet_find.html:30
+msgid "Identification / Description / Dimensions"
+msgstr ""
+
+#: templates/ishtar/sheet_find.html:38
+msgid "Datings / Preservation"
+msgstr ""
+
+#: templates/ishtar/sheet_find.html:47
+msgid "Warehouse / Treatments"
+msgstr ""
+
+#: templates/ishtar/sheet_find.html:64
+msgid "Custom fields"
msgstr ""
-#: templates/ishtar/sheet_find.html:53
+#: templates/ishtar/sheet_find.html:123
msgid "Administrative index"
msgstr ""
-#: templates/ishtar/sheet_find.html:95
+#: templates/ishtar/sheet_find.html:166
msgid "Checked"
msgstr ""
-#: templates/ishtar/sheet_find.html:160
-msgid "Warehouse"
+#: templates/ishtar/sheet_find.html:233
+msgid "Warehouse - reference container"
msgstr ""
-#: templates/ishtar/sheet_find.html:178 templates/ishtar/sheet_find.html:216
+#: templates/ishtar/sheet_find.html:243
+msgid "Warehouse - current container"
+msgstr ""
+
+#: templates/ishtar/sheet_find.html:258 templates/ishtar/sheet_find.html:295
+#: templates/ishtar/sheet_find.html:333
msgid "Year - index"
msgstr ""
-#: templates/ishtar/sheet_find.html:182 templates/ishtar/sheet_find.html:220
+#: templates/ishtar/sheet_find.html:262 templates/ishtar/sheet_find.html:299
+#: templates/ishtar/sheet_find.html:337
msgid "Related finds (max. 15 displayed)"
msgstr ""
-#: templates/ishtar/sheet_find.html:208
+#: templates/ishtar/sheet_find.html:325
msgid "Export as CSV"
msgstr ""
-#: templates/ishtar/sheet_find.html:208 templates/ishtar/sheet_find.html:247
+#: templates/ishtar/sheet_find.html:325 templates/ishtar/sheet_find.html:364
msgid "CSV"
msgstr ""
-#: templates/ishtar/sheet_find.html:252
+#: templates/ishtar/sheet_find.html:371
+#: templates/ishtar/sheet_treatment.html:124
msgid "Associated documents"
msgstr ""
-#: templates/ishtar/sheet_findbasket.html:19
+#: templates/ishtar/sheet_findbasket.html:20
msgid "Content"
msgstr ""
-#: templates/ishtar/sheet_treatment.html:25
+#: templates/ishtar/sheet_treatment.html:41
+#: templates/ishtar/sheet_treatment.html:132
+#: templates/ishtar/sheet_treatmentfile.html:74
+msgid "Administrative acts"
+msgstr ""
+
+#: templates/ishtar/sheet_treatment.html:63
msgctxt "Treatment"
msgid "Closed"
msgstr ""
-#: templates/ishtar/sheet_treatment.html:27
+#: templates/ishtar/sheet_treatment.html:65
msgctxt "Treatment"
msgid "Active"
msgstr ""
-#: templates/ishtar/sheet_treatment.html:66
-msgid "Related operations"
-msgstr ""
-
-#: templates/ishtar/sheet_treatment.html:77
-#: templates/ishtar/sheet_treatmentfile.html:73
-msgid "Administrative acts"
-msgstr ""
-
#: templates/ishtar/sheet_treatmentfile.html:24
msgctxt "Treatment request"
msgid "Closed"
@@ -1613,86 +1866,132 @@ msgctxt "Treatment request"
msgid "Active"
msgstr ""
-#: views.py:132
+#: templates/ishtar/wizard/wizard_findbasket_deletion.html:8
+msgid "This basket is attached to treatments requests:"
+msgstr ""
+
+#: templates/ishtar/wizard/wizard_findbasket_deletion.html:12
+msgid "Are you sure you want to delete this basket?"
+msgstr ""
+
+#: templates/ishtar/wizard/wizard_findbasket_deletion.html:16
+msgid "Items inside the basket (these items will not be deleted):"
+msgstr ""
+
+#: templates/ishtar/wizard/wizard_findbasket_deletion.html:23
+msgid "Basket informations:"
+msgstr ""
+
+#: templates/ishtar/wizard/wizard_simplefind.html:6
+msgid ""
+"This find is related to many base finds. To edit field related to base finds "
+"edit the corresponding find between theses:"
+msgstr ""
+
+#: templates/ishtar/wizard/wizard_treatement_deletion.html:8
+msgid "Are you sure you want to delete this treatment?"
+msgstr ""
+
+#: templates/ishtar/wizard/wizard_treatement_deletion.html:10
+msgid "The following finds will be deleted and restored to a previous version."
+msgstr ""
+
+#: templates/ishtar/wizard/wizard_treatement_deletion.html:16
+msgid ""
+"All changes made to the associated finds since this treatment record will be "
+"lost!"
+msgstr ""
+
+#: templates/ishtar/wizard/wizard_treatement_deletion.html:21
+msgid "Treatment informations:"
+msgstr ""
+
+#: views.py:175
msgid "Basket modify"
msgstr ""
-#: views.py:173
+#: views.py:198
+msgid "Basket deletion"
+msgstr ""
+
+#: views.py:229
msgid "New find"
msgstr ""
-#: views.py:209
+#: views.py:281
msgid "Find modification"
msgstr ""
-#: views.py:238
+#: views.py:316
msgid "Find deletion"
msgstr ""
-#: views.py:251
+#: views.py:329
msgid "New basket"
msgstr ""
-#: views.py:280
+#: views.py:358
msgid "Manage items in basket"
msgstr ""
-#: views.py:389
-msgid "Delete basket"
-msgstr ""
-
-#: views.py:441
+#: views.py:484 views.py:497 views.py:510
msgid "New treatment"
msgstr ""
-#: views.py:449
+#: views.py:518
msgid "Treatment modification"
msgstr ""
-#: views.py:466
+#: views.py:609
msgid "Treatment deletion"
msgstr ""
-#: views.py:473
+#: views.py:616
msgid "Treatment: search administrative act"
msgstr ""
-#: views.py:482
+#: views.py:625
msgid "Treatment: new administrative act"
msgstr ""
-#: views.py:492
+#: views.py:635
msgid "Treatment: administrative act modification"
msgstr ""
-#: views.py:501
+#: views.py:644
msgid "Treatment: administrative act deletion"
msgstr ""
-#: views.py:534
+#: views.py:691
msgid "New treatment request"
msgstr ""
-#: views.py:541
+#: views.py:700
msgid "Treatment request modification"
msgstr ""
-#: views.py:557
+#: views.py:716
msgid "Treatment request deletion"
msgstr ""
-#: views.py:564
+#: views.py:723
msgid "Treatment request: search administrative act"
msgstr ""
-#: views.py:574
+#: views.py:734
msgid "Treatment request: new administrative act"
msgstr ""
-#: views.py:584
+#: views.py:744
msgid "Treatment request: administrative act modification"
msgstr ""
-#: views.py:593
+#: views.py:753
msgid "Treatment request: administrative act deletion"
msgstr ""
+
+#: wizards.py:394
+msgid ""
+"The new basket: \"{}\" have been created with the resulting items. This "
+"search have been pinned."
+msgstr ""
diff --git a/archaeological_finds/migrations/0039_auto_20181115_1649.py b/archaeological_finds/migrations/0039_auto_20181115_1649.py
new file mode 100644
index 000000000..3752c173c
--- /dev/null
+++ b/archaeological_finds/migrations/0039_auto_20181115_1649.py
@@ -0,0 +1,36 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.10 on 2018-11-15 16:49
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import virtualtime
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('archaeological_finds', '0038_auto_20181112_1625'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='historicaltreatment',
+ name='creation_date',
+ field=models.DateTimeField(default=virtualtime.virtual_datetime.now),
+ ),
+ migrations.AddField(
+ model_name='treatment',
+ name='creation_date',
+ field=models.DateTimeField(default=virtualtime.virtual_datetime.now),
+ ),
+ migrations.AddField(
+ model_name='treatment',
+ name='finds',
+ field=models.ManyToManyField(blank=True, help_text='Related finds for non-destructive treatment', related_name='treatments', to='archaeological_finds.Find', verbose_name='Finds'),
+ ),
+ migrations.AddField(
+ model_name='treatmenttype',
+ name='destructive',
+ field=models.BooleanField(default=False, verbose_name='Destructive'),
+ ),
+ ]
diff --git a/archaeological_finds/migrations/0040_auto_20181120_1027.py b/archaeological_finds/migrations/0040_auto_20181120_1027.py
new file mode 100644
index 000000000..fd649dd8f
--- /dev/null
+++ b/archaeological_finds/migrations/0040_auto_20181120_1027.py
@@ -0,0 +1,33 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.10 on 2018-11-20 10:27
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+def init_create_new_find(apps, schema):
+ TreatmentType = apps.get_model('archaeological_finds', 'TreatmentType')
+ for tp in TreatmentType.objects.all():
+ if (tp.upstream_is_many or tp.downstream_is_many) and not tp.virtual:
+ tp.create_new_find = True
+ tp.save()
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('archaeological_finds', '0039_auto_20181115_1649'),
+ ]
+
+ operations = [
+ migrations.AlterModelOptions(
+ name='treatment',
+ options={'ordering': ('start_date',), 'permissions': (('view_treatment', 'Can view all Treatments'), ('view_own_treatment', 'Can view own Treatment'), ('add_own_treatment', 'Can add own Treatment'), ('change_own_treatment', 'Can change own Treatment'), ('delete_own_treatment', 'Can delete own Treatment')), 'verbose_name': 'Treatment', 'verbose_name_plural': 'Treatments'},
+ ),
+ migrations.AddField(
+ model_name='treatmenttype',
+ name='create_new_find',
+ field=models.BooleanField(default=False, help_text='If True when this treatment is applied a new version of the object will be created.', verbose_name='Create a new find'),
+ ),
+ migrations.RunPython(init_create_new_find)
+ ]
diff --git a/archaeological_finds/migrations/0041_auto_20181121_1225.py b/archaeological_finds/migrations/0041_auto_20181121_1225.py
new file mode 100644
index 000000000..248dc6499
--- /dev/null
+++ b/archaeological_finds/migrations/0041_auto_20181121_1225.py
@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.10 on 2018-11-21 12:25
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('archaeological_finds', '0040_auto_20181120_1027'),
+ ]
+
+ operations = [
+ migrations.RemoveField(
+ model_name='treatment',
+ name='finds',
+ ),
+ migrations.AddField(
+ model_name='find',
+ name='treatments',
+ field=models.ManyToManyField(blank=True, help_text='Related treatments when no new find is created', related_name='finds', to='archaeological_finds.Treatment', verbose_name='Treatments'),
+ ),
+ ]
diff --git a/archaeological_finds/migrations/0042_auto_20181129_1755.py b/archaeological_finds/migrations/0042_auto_20181129_1755.py
new file mode 100644
index 000000000..42d732cf2
--- /dev/null
+++ b/archaeological_finds/migrations/0042_auto_20181129_1755.py
@@ -0,0 +1,30 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.10 on 2018-11-29 17:55
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('ishtar_common', '0077_auto_20181129_1755'),
+ ('archaeological_finds', '0041_auto_20181121_1225'),
+ ]
+
+ operations = [
+ migrations.AlterModelOptions(
+ name='treatmentfile',
+ options={'ordering': ('cached_label',), 'permissions': (('view_treatmentfile', 'Can view all Treatment requests'), ('view_own_treatmentfile', 'Can view own Treatment request'), ('add_own_treatmentfile', 'Can add own Treatment request'), ('change_own_treatmentfile', 'Can change own Treatment request'), ('delete_own_treatmentfile', 'Can delete own Treatment request')), 'verbose_name': 'Treatment request', 'verbose_name_plural': 'Treatment requests'},
+ ),
+ migrations.AddField(
+ model_name='findbasket',
+ name='shared_write_with',
+ field=models.ManyToManyField(blank=True, related_name='shared_write_findbaskets', to='ishtar_common.IshtarUser', verbose_name='Shared (read/edit) with'),
+ ),
+ migrations.AlterField(
+ model_name='findbasket',
+ name='shared_with',
+ field=models.ManyToManyField(blank=True, related_name='shared_findbaskets', to='ishtar_common.IshtarUser', verbose_name='Shared (read) with'),
+ ),
+ ]
diff --git a/archaeological_finds/migrations/0043_auto_20181130_1310.py b/archaeological_finds/migrations/0043_auto_20181130_1310.py
new file mode 100644
index 000000000..e8881e45d
--- /dev/null
+++ b/archaeological_finds/migrations/0043_auto_20181130_1310.py
@@ -0,0 +1,34 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.10 on 2018-11-30 13:10
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('archaeological_finds', '0042_auto_20181129_1755'),
+ ]
+
+ operations = [
+ migrations.RemoveField(
+ model_name='historicaltreatment',
+ name='target_is_basket',
+ ),
+ migrations.RemoveField(
+ model_name='treatment',
+ name='target_is_basket',
+ ),
+ migrations.AddField(
+ model_name='historicaltreatmentfile',
+ name='associated_basket',
+ field=models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='archaeological_finds.FindBasket'),
+ ),
+ migrations.AddField(
+ model_name='treatmentfile',
+ name='associated_basket',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='archaeological_finds.FindBasket'),
+ ),
+ ]
diff --git a/archaeological_finds/migrations/0044_auto_20181201_1854.py b/archaeological_finds/migrations/0044_auto_20181201_1854.py
new file mode 100644
index 000000000..e11a9db81
--- /dev/null
+++ b/archaeological_finds/migrations/0044_auto_20181201_1854.py
@@ -0,0 +1,36 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.10 on 2018-12-01 18:54
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('archaeological_warehouse', '0025_auto_20181112_1842'),
+ ('archaeological_finds', '0043_auto_20181130_1310'),
+ ]
+
+ operations = [
+ migrations.AlterModelOptions(
+ name='findbasket',
+ options={'permissions': (('view_find', 'Can view all Finds'), ('view_own_find', 'Can view own Find')), 'verbose_name': 'Basket'},
+ ),
+ migrations.AddField(
+ model_name='find',
+ name='container_ref',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='finds_ref', to='archaeological_warehouse.Container', verbose_name='Reference container'),
+ ),
+ migrations.AddField(
+ model_name='historicalfind',
+ name='container_ref',
+ field=models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='archaeological_warehouse.Container'),
+ ),
+ migrations.AlterField(
+ model_name='treatmentfile',
+ name='associated_basket',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='treatment_files', to='archaeological_finds.FindBasket'),
+ ),
+ ]
diff --git a/archaeological_finds/migrations/0045_migrate_current_container_to_ref_container.py b/archaeological_finds/migrations/0045_migrate_current_container_to_ref_container.py
new file mode 100644
index 000000000..7639f95b7
--- /dev/null
+++ b/archaeological_finds/migrations/0045_migrate_current_container_to_ref_container.py
@@ -0,0 +1,40 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.10 on 2018-12-01 19:17
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+def migrate_containers(apps, schema):
+ Find = apps.get_model('archaeological_finds', 'find')
+ for f in Find.objects.filter(container__isnull=False).all():
+ f.skip_history_when_saving = True
+ f.container_ref = f.container
+ f.save()
+ TreatmentType = apps.get_model('archaeological_finds', 'TreatmentType')
+ TreatmentType.objects.get_or_create(
+ txt_idx="loan",
+ defaults={
+ "label": u"Prêt",
+ "virtual": False,
+ "comment": u"Un prêt est un changement temporaire de contenant "
+ u"pour du mobilier."}
+ )
+ TreatmentType.objects.get_or_create(
+ txt_idx="loan-return",
+ defaults={
+ "label": u"Retour de prêt",
+ "virtual": False,
+ "comment": u"Retour de mobilier dans son contenant de référence."}
+ )
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('archaeological_finds', '0044_auto_20181201_1854'),
+ ]
+
+ operations = [
+ migrations.RunPython(migrate_containers)
+ ]
diff --git a/archaeological_finds/migrations/0046_treatmentfiletype_treatment_type.py b/archaeological_finds/migrations/0046_treatmentfiletype_treatment_type.py
new file mode 100644
index 000000000..867cd4545
--- /dev/null
+++ b/archaeological_finds/migrations/0046_treatmentfiletype_treatment_type.py
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.10 on 2018-12-02 18:31
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('archaeological_finds', '0045_migrate_current_container_to_ref_container'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='treatmentfiletype',
+ name='treatment_type',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='archaeological_finds.TreatmentType'),
+ ),
+ ]
diff --git a/archaeological_finds/migrations/0047_auto_20181203_1442.py b/archaeological_finds/migrations/0047_auto_20181203_1442.py
new file mode 100644
index 000000000..90ed25028
--- /dev/null
+++ b/archaeological_finds/migrations/0047_auto_20181203_1442.py
@@ -0,0 +1,1523 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.10 on 2018-12-03 14:42
+from __future__ import unicode_literals
+
+import datetime
+from django.conf import settings
+import django.contrib.gis.db.models.fields
+import django.contrib.postgres.search
+import django.core.validators
+from django.db import migrations, models
+import django.db.models.deletion
+import ishtar_common.utils
+import re
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('archaeological_finds', '0046_treatmentfiletype_treatment_type'),
+ ]
+
+ operations = [
+ migrations.AlterModelOptions(
+ name='alterationcausetype',
+ options={'ordering': ('parent__label', 'label'), 'verbose_name': "Type de cause d'alt\xe9ration", 'verbose_name_plural': "Types de cause d'alt\xe9ration"},
+ ),
+ migrations.AlterModelOptions(
+ name='alterationtype',
+ options={'ordering': ('parent__label', 'label'), 'verbose_name': "Type d'alt\xe9ration", 'verbose_name_plural': "Types d'alt\xe9ration"},
+ ),
+ migrations.AlterModelOptions(
+ name='basefind',
+ options={'permissions': (('view_basefind', 'Can view all Base finds'), ('view_own_basefind', 'Can view own Base find'), ('add_own_basefind', 'Can add own Base find'), ('change_own_basefind', 'Can change own Base find'), ('delete_own_basefind', 'Can delete own Base find')), 'verbose_name': "Mobilier d'origine", 'verbose_name_plural': "Mobilier d'origine"},
+ ),
+ migrations.AlterModelOptions(
+ name='batchtype',
+ options={'ordering': ('order',), 'verbose_name': 'Type de lot', 'verbose_name_plural': 'Types de lot'},
+ ),
+ migrations.AlterModelOptions(
+ name='checkedtype',
+ options={'ordering': ('order',), 'verbose_name': 'Type de v\xe9rification', 'verbose_name_plural': 'Types de v\xe9rification'},
+ ),
+ migrations.AlterModelOptions(
+ name='communicabilitytype',
+ options={'ordering': ('parent__label', 'label'), 'verbose_name': 'Type de communicabilit\xe9', 'verbose_name_plural': 'Types de communicabilit\xe9'},
+ ),
+ migrations.AlterModelOptions(
+ name='find',
+ options={'ordering': ('cached_label',), 'permissions': (('view_find', 'Can view all Finds'), ('view_own_find', 'Can view own Find'), ('add_own_find', 'Can add own Find'), ('change_own_find', 'Can change own Find'), ('delete_own_find', 'Can delete own Find')), 'verbose_name': 'Mobilier', 'verbose_name_plural': 'Mobilier'},
+ ),
+ migrations.AlterModelOptions(
+ name='findbasket',
+ options={'permissions': (('view_find', 'Can view all Finds'), ('view_own_find', 'Can view own Find')), 'verbose_name': 'Panier'},
+ ),
+ migrations.AlterModelOptions(
+ name='historicalbasefind',
+ options={'get_latest_by': 'history_date', 'ordering': ('-history_date', '-history_id'), 'verbose_name': "historical Mobilier d'origine"},
+ ),
+ migrations.AlterModelOptions(
+ name='historicalfind',
+ options={'get_latest_by': 'history_date', 'ordering': ('-history_date', '-history_id'), 'verbose_name': 'historical Mobilier'},
+ ),
+ migrations.AlterModelOptions(
+ name='historicaltreatment',
+ options={'get_latest_by': 'history_date', 'ordering': ('-history_date', '-history_id'), 'verbose_name': 'historical Traitement'},
+ ),
+ migrations.AlterModelOptions(
+ name='historicaltreatmentfile',
+ options={'get_latest_by': 'history_date', 'ordering': ('-history_date', '-history_id'), 'verbose_name': 'historical Demande de traitement'},
+ ),
+ migrations.AlterModelOptions(
+ name='integritytype',
+ options={'ordering': ('label',), 'verbose_name': "Type d'int\xe9grit\xe9 / int\xe9r\xeat", 'verbose_name_plural': "Types d'int\xe9grit\xe9 / int\xe9r\xeat"},
+ ),
+ migrations.AlterModelOptions(
+ name='materialtype',
+ options={'ordering': ('label',), 'verbose_name': 'Type de mat\xe9riau', 'verbose_name_plural': 'Types de mat\xe9riau'},
+ ),
+ migrations.AlterModelOptions(
+ name='materialtypequalitytype',
+ options={'ordering': ('order',), 'verbose_name': 'Type de qualit\xe9 du type de mat\xe9riaux', 'verbose_name_plural': 'Types de qualit\xe9 du type de mat\xe9riaux'},
+ ),
+ migrations.AlterModelOptions(
+ name='objecttype',
+ options={'ordering': ('parent__label', 'label'), 'verbose_name': "Type d'objet", 'verbose_name_plural': "Types d'objet"},
+ ),
+ migrations.AlterModelOptions(
+ name='objecttypequalitytype',
+ options={'ordering': ('order',), 'verbose_name': "Type de qualit\xe9 du type d'objet", 'verbose_name_plural': "Types de qualit\xe9 du type d'objet"},
+ ),
+ migrations.AlterModelOptions(
+ name='property',
+ options={'verbose_name': 'Propri\xe9t\xe9', 'verbose_name_plural': 'Propri\xe9t\xe9s'},
+ ),
+ migrations.AlterModelOptions(
+ name='remarkabilitytype',
+ options={'ordering': ('label',), 'verbose_name': 'Type de remarquabilit\xe9', 'verbose_name_plural': 'Types de remarquabilit\xe9'},
+ ),
+ migrations.AlterModelOptions(
+ name='treatment',
+ options={'ordering': ('start_date',), 'permissions': (('view_treatment', 'Can view all Treatments'), ('view_own_treatment', 'Can view own Treatment'), ('add_own_treatment', 'Can add own Treatment'), ('change_own_treatment', 'Can change own Treatment'), ('delete_own_treatment', 'Can delete own Treatment')), 'verbose_name': 'Traitement', 'verbose_name_plural': 'Traitements'},
+ ),
+ migrations.AlterModelOptions(
+ name='treatmentemergencytype',
+ options={'ordering': ('label',), 'verbose_name': "Type d'urgence de traitement", 'verbose_name_plural': "Types d'urgence du traitement"},
+ ),
+ migrations.AlterModelOptions(
+ name='treatmentfile',
+ options={'ordering': ('cached_label',), 'permissions': (('view_treatmentfile', 'Can view all Treatment requests'), ('view_own_treatmentfile', 'Can view own Treatment request'), ('add_own_treatmentfile', 'Can add own Treatment request'), ('change_own_treatmentfile', 'Can change own Treatment request'), ('delete_own_treatmentfile', 'Can delete own Treatment request')), 'verbose_name': 'Demande de traitement', 'verbose_name_plural': 'Demandes de traitement'},
+ ),
+ migrations.AlterModelOptions(
+ name='treatmentfiletype',
+ options={'ordering': ('label',), 'verbose_name': 'Type de demande de traitement', 'verbose_name_plural': 'Types de demande de traitement'},
+ ),
+ migrations.AlterModelOptions(
+ name='treatmentstate',
+ options={'ordering': ('label',), 'verbose_name': "Type d'\xe9tat de traitement", 'verbose_name_plural': "Types d'\xe9tat de traitement"},
+ ),
+ migrations.AlterModelOptions(
+ name='treatmenttype',
+ options={'ordering': ('order', 'label'), 'verbose_name': 'Type de traitement', 'verbose_name_plural': 'Types de traitement'},
+ ),
+ migrations.AlterField(
+ model_name='alterationcausetype',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='alterationcausetype',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='alterationcausetype',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='alterationcausetype',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ migrations.AlterField(
+ model_name='alterationtype',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='alterationtype',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='alterationtype',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='alterationtype',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ migrations.AlterField(
+ model_name='basefind',
+ name='auto_external_id',
+ field=models.BooleanField(default=False, verbose_name="L'identifiant est attribu\xe9 automatiquement"),
+ ),
+ migrations.AlterField(
+ model_name='basefind',
+ name='batch',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='archaeological_finds.BatchType', verbose_name='Lot/objet'),
+ ),
+ migrations.AlterField(
+ model_name='basefind',
+ name='cache_complete_id',
+ field=models.TextField(blank=True, db_index=True, help_text='Valeur en cache - ne pas \xe9diter', null=True, verbose_name='Identifiant complet'),
+ ),
+ migrations.AlterField(
+ model_name='basefind',
+ name='cache_short_id',
+ field=models.TextField(blank=True, db_index=True, help_text='Valeur en cache - ne pas \xe9diter', null=True, verbose_name='Identifiant court'),
+ ),
+ migrations.AlterField(
+ model_name='basefind',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='basefind',
+ name='context_record',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='base_finds', to='archaeological_context_records.ContextRecord', verbose_name="Unit\xe9 d'Enregistrement"),
+ ),
+ migrations.AlterField(
+ model_name='basefind',
+ name='discovery_date',
+ field=models.DateField(blank=True, null=True, verbose_name='Date de d\xe9couverte (exacte ou TPQ)'),
+ ),
+ migrations.AlterField(
+ model_name='basefind',
+ name='discovery_date_taq',
+ field=models.DateField(blank=True, null=True, verbose_name='Date de d\xe9couverte (TAQ)'),
+ ),
+ migrations.AlterField(
+ model_name='basefind',
+ name='estimated_error_x',
+ field=models.FloatField(blank=True, null=True, verbose_name='Erreur estim\xe9e pour X'),
+ ),
+ migrations.AlterField(
+ model_name='basefind',
+ name='estimated_error_y',
+ field=models.FloatField(blank=True, null=True, verbose_name='Erreur estim\xe9e pour Y'),
+ ),
+ migrations.AlterField(
+ model_name='basefind',
+ name='estimated_error_z',
+ field=models.FloatField(blank=True, null=True, verbose_name='Erreur estim\xe9e pour Z'),
+ ),
+ migrations.AlterField(
+ model_name='basefind',
+ name='excavation_id',
+ field=models.TextField(blank=True, null=True, verbose_name='Identifiant fouille'),
+ ),
+ migrations.AlterField(
+ model_name='basefind',
+ name='external_id',
+ field=models.TextField(blank=True, null=True, verbose_name='Identifiant'),
+ ),
+ migrations.AlterField(
+ model_name='basefind',
+ name='history_creator',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Cr\xe9ateur'),
+ ),
+ migrations.AlterField(
+ model_name='basefind',
+ name='history_modifier',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Dernier \xe9diteur'),
+ ),
+ migrations.AlterField(
+ model_name='basefind',
+ name='label',
+ field=models.TextField(verbose_name='Identifiant libre'),
+ ),
+ migrations.AlterField(
+ model_name='basefind',
+ name='line',
+ field=django.contrib.gis.db.models.fields.LineStringField(blank=True, null=True, srid=4326, verbose_name='Ligne'),
+ ),
+ migrations.AlterField(
+ model_name='basefind',
+ name='material_index',
+ field=models.IntegerField(default=0, verbose_name='Index mat\xe9riel'),
+ ),
+ migrations.AlterField(
+ model_name='basefind',
+ name='multi_polygon',
+ field=django.contrib.gis.db.models.fields.MultiPolygonField(blank=True, null=True, srid=4326, verbose_name='Polygones multi-parties'),
+ ),
+ migrations.AlterField(
+ model_name='basefind',
+ name='search_vector',
+ field=django.contrib.postgres.search.SearchVectorField(blank=True, help_text='Auto-rempli \xe0 la sauvegarde', null=True, verbose_name='Vecteur de recherche'),
+ ),
+ migrations.AlterField(
+ model_name='basefind',
+ name='spatial_reference_system',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='ishtar_common.SpatialReferenceSystem', verbose_name='Syst\xe8me de r\xe9f\xe9rence spatiale'),
+ ),
+ migrations.AlterField(
+ model_name='basefind',
+ name='special_interest',
+ field=models.CharField(blank=True, max_length=120, null=True, verbose_name='Int\xe9r\xeat sp\xe9cifique'),
+ ),
+ migrations.AlterField(
+ model_name='basefind',
+ name='topographic_localisation',
+ field=models.CharField(blank=True, max_length=120, null=True, verbose_name='Point topographique'),
+ ),
+ migrations.AlterField(
+ model_name='batchtype',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='batchtype',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='batchtype',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='batchtype',
+ name='order',
+ field=models.IntegerField(default=10, verbose_name='Ordre'),
+ ),
+ migrations.AlterField(
+ model_name='batchtype',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ migrations.AlterField(
+ model_name='checkedtype',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='checkedtype',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='checkedtype',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='checkedtype',
+ name='order',
+ field=models.IntegerField(default=10, verbose_name='Ordre'),
+ ),
+ migrations.AlterField(
+ model_name='checkedtype',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ migrations.AlterField(
+ model_name='communicabilitytype',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='communicabilitytype',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='communicabilitytype',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='communicabilitytype',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ migrations.AlterField(
+ model_name='conservatorystate',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='conservatorystate',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='conservatorystate',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='conservatorystate',
+ name='order',
+ field=models.IntegerField(default=10, verbose_name='Ordre'),
+ ),
+ migrations.AlterField(
+ model_name='conservatorystate',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='alteration_causes',
+ field=models.ManyToManyField(blank=True, related_name='finds', to='archaeological_finds.AlterationCauseType', verbose_name="Cause d'alt\xe9ration"),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='alterations',
+ field=models.ManyToManyField(blank=True, related_name='finds', to='archaeological_finds.AlterationType', verbose_name='Alt\xe9ration'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='appraisal_date',
+ field=models.DateField(blank=True, null=True, verbose_name="Date d'\xe9valuation"),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='auto_external_id',
+ field=models.BooleanField(default=False, verbose_name="L'identifiant est attribu\xe9 automatiquement"),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='base_finds',
+ field=models.ManyToManyField(related_name='find', to='archaeological_finds.BaseFind', verbose_name="Mobilier d'origine"),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='cached_label',
+ field=models.TextField(blank=True, db_index=True, null=True, verbose_name='Nom en cache'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='check_date',
+ field=models.DateField(default=datetime.date.today, verbose_name='Date de v\xe9rification'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='checked_type',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='archaeological_finds.CheckedType', verbose_name='V\xe9rification'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='clutter_height',
+ field=models.FloatField(blank=True, null=True, verbose_name='Encombrement - hauteur (cm)'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='clutter_long_side',
+ field=models.FloatField(blank=True, null=True, verbose_name='Encombrement - grand c\xf4t\xe9 (cm)'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='clutter_short_side',
+ field=models.FloatField(blank=True, null=True, verbose_name='Encombrement - petit c\xf4t\xe9 (cm)'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='communicabilities',
+ field=models.ManyToManyField(blank=True, related_name='find', to='archaeological_finds.CommunicabilityType', verbose_name='Communicabilit\xe9'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='conservatory_comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire relatif \xe0 la conservation'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='conservatory_state',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='archaeological_finds.ConservatoryState', verbose_name='\xc9tat de conservation'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='container',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='finds', to='archaeological_warehouse.Container', verbose_name='Contenant'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='dating_comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire relatif aux datations'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='datings',
+ field=models.ManyToManyField(related_name='find', to='archaeological_context_records.Dating', verbose_name='Datation'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='decoration',
+ field=models.TextField(blank=True, null=True, verbose_name='D\xe9cor'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='denomination',
+ field=models.TextField(blank=True, null=True, verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='diameter',
+ field=models.FloatField(blank=True, null=True, verbose_name='Diam\xe8tre (cm)'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='dimensions_comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire relatif aux dimensions'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='downstream_treatment',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='upstream', to='archaeological_finds.Treatment', verbose_name='Traitement aval'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='estimated_value',
+ field=models.FloatField(blank=True, null=True, verbose_name='Valeur estim\xe9e'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='external_id',
+ field=models.TextField(blank=True, null=True, verbose_name='Identifiant'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='find_number',
+ field=models.IntegerField(blank=True, null=True, verbose_name='Mobilier (en nombre)'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='height',
+ field=models.FloatField(blank=True, null=True, verbose_name='Hauteur (cm)'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='history_creator',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Cr\xe9ateur'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='history_modifier',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Dernier \xe9diteur'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='insurance_value',
+ field=models.FloatField(blank=True, null=True, verbose_name="Valeur d'assurance"),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='integrities',
+ field=models.ManyToManyField(blank=True, related_name='find', to='archaeological_finds.IntegrityType', verbose_name='Int\xe9grit\xe9 / int\xe9r\xeat'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='is_complete',
+ field=models.NullBooleanField(verbose_name='Est complet ?'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='label',
+ field=models.TextField(verbose_name='Identifiant libre'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='length',
+ field=models.FloatField(blank=True, null=True, verbose_name='Longueur (cm)'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='manufacturing_place',
+ field=models.TextField(blank=True, null=True, verbose_name='Lieu de fabrication'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='mark',
+ field=models.TextField(blank=True, null=True, verbose_name='Marquage'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='material_type_quality',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='finds', to='archaeological_finds.MaterialTypeQualityType', verbose_name='Qualit\xe9 du type de mat\xe9riaux'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='material_types',
+ field=models.ManyToManyField(blank=True, related_name='finds', to='archaeological_finds.MaterialType', verbose_name='Types de mat\xe9riau'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='min_number_of_individuals',
+ field=models.IntegerField(blank=True, null=True, verbose_name="Nombre minimum d'individus (NMI)"),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='museum_id',
+ field=models.TextField(blank=True, null=True, verbose_name='Identifiant mus\xe9e'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='object_type_quality',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='finds', to='archaeological_finds.ObjectTypeQualityType', verbose_name="Qualit\xe9 du type d'objet"),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='object_types',
+ field=models.ManyToManyField(blank=True, related_name='find', to='archaeological_finds.ObjectType', verbose_name="Types d'objet"),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='order',
+ field=models.IntegerField(default=1, verbose_name='Ordre'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='preservation_to_considers',
+ field=models.ManyToManyField(blank=True, related_name='finds_recommended', to='archaeological_finds.TreatmentType', verbose_name='Traitements recommand\xe9s'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='previous_id',
+ field=models.TextField(blank=True, null=True, verbose_name='Identifiant pr\xe9c\xe9dent'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='remarkabilities',
+ field=models.ManyToManyField(blank=True, related_name='find', to='archaeological_finds.RemarkabilityType', verbose_name='Remarquabilit\xe9'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='seal_number',
+ field=models.TextField(blank=True, null=True, verbose_name='Num\xe9ro de scell\xe9'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='search_vector',
+ field=django.contrib.postgres.search.SearchVectorField(blank=True, help_text='Auto-rempli \xe0 la sauvegarde', null=True, verbose_name='Vecteur de recherche'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='thickness',
+ field=models.FloatField(blank=True, null=True, verbose_name='\xc9paisseur (cm)'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='treatment_emergency',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='archaeological_finds.TreatmentEmergencyType', verbose_name='Urgence du traitement'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='treatments',
+ field=models.ManyToManyField(blank=True, help_text='Related treatments when no new find is created', related_name='finds', to='archaeological_finds.Treatment', verbose_name='Traitements'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='upstream_treatment',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='downstream', to='archaeological_finds.Treatment', verbose_name='Traitement amont'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='weight',
+ field=models.FloatField(blank=True, null=True, verbose_name='Poids'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='weight_unit',
+ field=models.CharField(blank=True, choices=[(b'g', 'g'), (b'kg', 'kg')], max_length=4, null=True, verbose_name='Unit\xe9 de poids'),
+ ),
+ migrations.AlterField(
+ model_name='find',
+ name='width',
+ field=models.FloatField(blank=True, null=True, verbose_name='Largeur (cm)'),
+ ),
+ migrations.AlterField(
+ model_name='findbasket',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='findbasket',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='findbasket',
+ name='label',
+ field=models.CharField(max_length=1000, verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='findbasket',
+ name='search_vector',
+ field=django.contrib.postgres.search.SearchVectorField(blank=True, help_text='Auto-rempli \xe0 la sauvegarde', null=True, verbose_name='Vecteur de recherche'),
+ ),
+ migrations.AlterField(
+ model_name='findbasket',
+ name='user',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='findbaskets', to='ishtar_common.IshtarUser', verbose_name='Propri\xe9taire'),
+ ),
+ migrations.AlterField(
+ model_name='historicalbasefind',
+ name='auto_external_id',
+ field=models.BooleanField(default=False, verbose_name="L'identifiant est attribu\xe9 automatiquement"),
+ ),
+ migrations.AlterField(
+ model_name='historicalbasefind',
+ name='cache_complete_id',
+ field=models.TextField(blank=True, db_index=True, help_text='Valeur en cache - ne pas \xe9diter', null=True, verbose_name='Identifiant complet'),
+ ),
+ migrations.AlterField(
+ model_name='historicalbasefind',
+ name='cache_short_id',
+ field=models.TextField(blank=True, db_index=True, help_text='Valeur en cache - ne pas \xe9diter', null=True, verbose_name='Identifiant court'),
+ ),
+ migrations.AlterField(
+ model_name='historicalbasefind',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='historicalbasefind',
+ name='discovery_date',
+ field=models.DateField(blank=True, null=True, verbose_name='Date de d\xe9couverte (exacte ou TPQ)'),
+ ),
+ migrations.AlterField(
+ model_name='historicalbasefind',
+ name='discovery_date_taq',
+ field=models.DateField(blank=True, null=True, verbose_name='Date de d\xe9couverte (TAQ)'),
+ ),
+ migrations.AlterField(
+ model_name='historicalbasefind',
+ name='estimated_error_x',
+ field=models.FloatField(blank=True, null=True, verbose_name='Erreur estim\xe9e pour X'),
+ ),
+ migrations.AlterField(
+ model_name='historicalbasefind',
+ name='estimated_error_y',
+ field=models.FloatField(blank=True, null=True, verbose_name='Erreur estim\xe9e pour Y'),
+ ),
+ migrations.AlterField(
+ model_name='historicalbasefind',
+ name='estimated_error_z',
+ field=models.FloatField(blank=True, null=True, verbose_name='Erreur estim\xe9e pour Z'),
+ ),
+ migrations.AlterField(
+ model_name='historicalbasefind',
+ name='excavation_id',
+ field=models.TextField(blank=True, null=True, verbose_name='Identifiant fouille'),
+ ),
+ migrations.AlterField(
+ model_name='historicalbasefind',
+ name='external_id',
+ field=models.TextField(blank=True, null=True, verbose_name='Identifiant'),
+ ),
+ migrations.AlterField(
+ model_name='historicalbasefind',
+ name='label',
+ field=models.TextField(verbose_name='Identifiant libre'),
+ ),
+ migrations.AlterField(
+ model_name='historicalbasefind',
+ name='line',
+ field=django.contrib.gis.db.models.fields.LineStringField(blank=True, null=True, srid=4326, verbose_name='Ligne'),
+ ),
+ migrations.AlterField(
+ model_name='historicalbasefind',
+ name='material_index',
+ field=models.IntegerField(default=0, verbose_name='Index mat\xe9riel'),
+ ),
+ migrations.AlterField(
+ model_name='historicalbasefind',
+ name='multi_polygon',
+ field=django.contrib.gis.db.models.fields.MultiPolygonField(blank=True, null=True, srid=4326, verbose_name='Polygones multi-parties'),
+ ),
+ migrations.AlterField(
+ model_name='historicalbasefind',
+ name='search_vector',
+ field=django.contrib.postgres.search.SearchVectorField(blank=True, help_text='Auto-rempli \xe0 la sauvegarde', null=True, verbose_name='Vecteur de recherche'),
+ ),
+ migrations.AlterField(
+ model_name='historicalbasefind',
+ name='special_interest',
+ field=models.CharField(blank=True, max_length=120, null=True, verbose_name='Int\xe9r\xeat sp\xe9cifique'),
+ ),
+ migrations.AlterField(
+ model_name='historicalbasefind',
+ name='topographic_localisation',
+ field=models.CharField(blank=True, max_length=120, null=True, verbose_name='Point topographique'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfind',
+ name='appraisal_date',
+ field=models.DateField(blank=True, null=True, verbose_name="Date d'\xe9valuation"),
+ ),
+ migrations.AlterField(
+ model_name='historicalfind',
+ name='auto_external_id',
+ field=models.BooleanField(default=False, verbose_name="L'identifiant est attribu\xe9 automatiquement"),
+ ),
+ migrations.AlterField(
+ model_name='historicalfind',
+ name='cached_label',
+ field=models.TextField(blank=True, db_index=True, null=True, verbose_name='Nom en cache'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfind',
+ name='check_date',
+ field=models.DateField(default=datetime.date.today, verbose_name='Date de v\xe9rification'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfind',
+ name='clutter_height',
+ field=models.FloatField(blank=True, null=True, verbose_name='Encombrement - hauteur (cm)'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfind',
+ name='clutter_long_side',
+ field=models.FloatField(blank=True, null=True, verbose_name='Encombrement - grand c\xf4t\xe9 (cm)'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfind',
+ name='clutter_short_side',
+ field=models.FloatField(blank=True, null=True, verbose_name='Encombrement - petit c\xf4t\xe9 (cm)'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfind',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfind',
+ name='conservatory_comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire relatif \xe0 la conservation'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfind',
+ name='dating_comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire relatif aux datations'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfind',
+ name='decoration',
+ field=models.TextField(blank=True, null=True, verbose_name='D\xe9cor'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfind',
+ name='denomination',
+ field=models.TextField(blank=True, null=True, verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfind',
+ name='diameter',
+ field=models.FloatField(blank=True, null=True, verbose_name='Diam\xe8tre (cm)'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfind',
+ name='dimensions_comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire relatif aux dimensions'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfind',
+ name='estimated_value',
+ field=models.FloatField(blank=True, null=True, verbose_name='Valeur estim\xe9e'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfind',
+ name='external_id',
+ field=models.TextField(blank=True, null=True, verbose_name='Identifiant'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfind',
+ name='find_number',
+ field=models.IntegerField(blank=True, null=True, verbose_name='Mobilier (en nombre)'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfind',
+ name='height',
+ field=models.FloatField(blank=True, null=True, verbose_name='Hauteur (cm)'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfind',
+ name='insurance_value',
+ field=models.FloatField(blank=True, null=True, verbose_name="Valeur d'assurance"),
+ ),
+ migrations.AlterField(
+ model_name='historicalfind',
+ name='is_complete',
+ field=models.NullBooleanField(verbose_name='Est complet ?'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfind',
+ name='label',
+ field=models.TextField(verbose_name='Identifiant libre'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfind',
+ name='length',
+ field=models.FloatField(blank=True, null=True, verbose_name='Longueur (cm)'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfind',
+ name='manufacturing_place',
+ field=models.TextField(blank=True, null=True, verbose_name='Lieu de fabrication'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfind',
+ name='mark',
+ field=models.TextField(blank=True, null=True, verbose_name='Marquage'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfind',
+ name='min_number_of_individuals',
+ field=models.IntegerField(blank=True, null=True, verbose_name="Nombre minimum d'individus (NMI)"),
+ ),
+ migrations.AlterField(
+ model_name='historicalfind',
+ name='museum_id',
+ field=models.TextField(blank=True, null=True, verbose_name='Identifiant mus\xe9e'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfind',
+ name='order',
+ field=models.IntegerField(default=1, verbose_name='Ordre'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfind',
+ name='previous_id',
+ field=models.TextField(blank=True, null=True, verbose_name='Identifiant pr\xe9c\xe9dent'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfind',
+ name='seal_number',
+ field=models.TextField(blank=True, null=True, verbose_name='Num\xe9ro de scell\xe9'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfind',
+ name='search_vector',
+ field=django.contrib.postgres.search.SearchVectorField(blank=True, help_text='Auto-rempli \xe0 la sauvegarde', null=True, verbose_name='Vecteur de recherche'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfind',
+ name='thickness',
+ field=models.FloatField(blank=True, null=True, verbose_name='\xc9paisseur (cm)'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfind',
+ name='weight',
+ field=models.FloatField(blank=True, null=True, verbose_name='Poids'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfind',
+ name='weight_unit',
+ field=models.CharField(blank=True, choices=[(b'g', 'g'), (b'kg', 'kg')], max_length=4, null=True, verbose_name='Unit\xe9 de poids'),
+ ),
+ migrations.AlterField(
+ model_name='historicalfind',
+ name='width',
+ field=models.FloatField(blank=True, null=True, verbose_name='Largeur (cm)'),
+ ),
+ migrations.AlterField(
+ model_name='historicaltreatment',
+ name='cached_label',
+ field=models.TextField(blank=True, db_index=True, null=True, verbose_name='Nom en cache'),
+ ),
+ migrations.AlterField(
+ model_name='historicaltreatment',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='historicaltreatment',
+ name='end_date',
+ field=models.DateField(blank=True, null=True, verbose_name='Date de cl\xf4ture'),
+ ),
+ migrations.AlterField(
+ model_name='historicaltreatment',
+ name='estimated_cost',
+ field=models.FloatField(blank=True, null=True, verbose_name='Co\xfbt estim\xe9'),
+ ),
+ migrations.AlterField(
+ model_name='historicaltreatment',
+ name='external_id',
+ field=models.CharField(blank=True, max_length=200, null=True, verbose_name='Identifiant'),
+ ),
+ migrations.AlterField(
+ model_name='historicaltreatment',
+ name='goal',
+ field=models.TextField(blank=True, null=True, verbose_name='But'),
+ ),
+ migrations.AlterField(
+ model_name='historicaltreatment',
+ name='insurance_cost',
+ field=models.FloatField(blank=True, null=True, verbose_name="Co\xfbt d'assurance"),
+ ),
+ migrations.AlterField(
+ model_name='historicaltreatment',
+ name='label',
+ field=models.CharField(blank=True, max_length=200, null=True, verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='historicaltreatment',
+ name='other_reference',
+ field=models.CharField(blank=True, max_length=200, null=True, verbose_name='Autre r\xe9f.'),
+ ),
+ migrations.AlterField(
+ model_name='historicaltreatment',
+ name='quoted_cost',
+ field=models.FloatField(blank=True, null=True, verbose_name='Co\xfbt devis\xe9'),
+ ),
+ migrations.AlterField(
+ model_name='historicaltreatment',
+ name='realized_cost',
+ field=models.FloatField(blank=True, null=True, verbose_name='Co\xfbt r\xe9alis\xe9'),
+ ),
+ migrations.AlterField(
+ model_name='historicaltreatment',
+ name='search_vector',
+ field=django.contrib.postgres.search.SearchVectorField(blank=True, help_text='Auto-rempli \xe0 la sauvegarde', null=True, verbose_name='Vecteur de recherche'),
+ ),
+ migrations.AlterField(
+ model_name='historicaltreatment',
+ name='start_date',
+ field=models.DateField(blank=True, null=True, verbose_name='Date de d\xe9but'),
+ ),
+ migrations.AlterField(
+ model_name='historicaltreatment',
+ name='year',
+ field=models.IntegerField(default=ishtar_common.utils.get_current_year, verbose_name='Ann\xe9e'),
+ ),
+ migrations.AlterField(
+ model_name='historicaltreatmentfile',
+ name='cached_label',
+ field=models.TextField(blank=True, db_index=True, null=True, verbose_name='Nom en cache'),
+ ),
+ migrations.AlterField(
+ model_name='historicaltreatmentfile',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='historicaltreatmentfile',
+ name='creation_date',
+ field=models.DateField(blank=True, default=datetime.date.today, null=True, verbose_name='Date de cr\xe9ation'),
+ ),
+ migrations.AlterField(
+ model_name='historicaltreatmentfile',
+ name='end_date',
+ field=models.DateField(blank=True, null=True, verbose_name='Date de cl\xf4ture'),
+ ),
+ migrations.AlterField(
+ model_name='historicaltreatmentfile',
+ name='external_id',
+ field=models.CharField(blank=True, max_length=200, null=True, verbose_name='Identifiant'),
+ ),
+ migrations.AlterField(
+ model_name='historicaltreatmentfile',
+ name='internal_reference',
+ field=models.CharField(blank=True, max_length=200, null=True, verbose_name='R\xe9f\xe9rence interne'),
+ ),
+ migrations.AlterField(
+ model_name='historicaltreatmentfile',
+ name='name',
+ field=models.TextField(blank=True, null=True, verbose_name='Nom'),
+ ),
+ migrations.AlterField(
+ model_name='historicaltreatmentfile',
+ name='reception_date',
+ field=models.DateField(blank=True, null=True, verbose_name='Date de r\xe9ception'),
+ ),
+ migrations.AlterField(
+ model_name='historicaltreatmentfile',
+ name='search_vector',
+ field=django.contrib.postgres.search.SearchVectorField(blank=True, help_text='Auto-rempli \xe0 la sauvegarde', null=True, verbose_name='Vecteur de recherche'),
+ ),
+ migrations.AlterField(
+ model_name='historicaltreatmentfile',
+ name='year',
+ field=models.IntegerField(default=ishtar_common.utils.get_current_year, verbose_name='Ann\xe9e'),
+ ),
+ migrations.AlterField(
+ model_name='integritytype',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='integritytype',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='integritytype',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='integritytype',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ migrations.AlterField(
+ model_name='materialtype',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='materialtype',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='materialtype',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='materialtype',
+ name='recommendation',
+ field=models.TextField(blank=True, null=True, verbose_name='Recommandation'),
+ ),
+ migrations.AlterField(
+ model_name='materialtype',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ migrations.AlterField(
+ model_name='materialtypequalitytype',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='materialtypequalitytype',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='materialtypequalitytype',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='materialtypequalitytype',
+ name='order',
+ field=models.IntegerField(default=10, verbose_name='Ordre'),
+ ),
+ migrations.AlterField(
+ model_name='materialtypequalitytype',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ migrations.AlterField(
+ model_name='objecttype',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='objecttype',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='objecttype',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='objecttype',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ migrations.AlterField(
+ model_name='objecttypequalitytype',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='objecttypequalitytype',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='objecttypequalitytype',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='objecttypequalitytype',
+ name='order',
+ field=models.IntegerField(default=10, verbose_name='Ordre'),
+ ),
+ migrations.AlterField(
+ model_name='objecttypequalitytype',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ migrations.AlterField(
+ model_name='property',
+ name='administrative_act',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='archaeological_operations.AdministrativeAct', verbose_name='Acte administratif'),
+ ),
+ migrations.AlterField(
+ model_name='property',
+ name='end_date',
+ field=models.DateField(verbose_name='Date de fin'),
+ ),
+ migrations.AlterField(
+ model_name='property',
+ name='find',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='archaeological_finds.Find', verbose_name='Mobilier'),
+ ),
+ migrations.AlterField(
+ model_name='property',
+ name='history_creator',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Cr\xe9ateur'),
+ ),
+ migrations.AlterField(
+ model_name='property',
+ name='history_modifier',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Dernier \xe9diteur'),
+ ),
+ migrations.AlterField(
+ model_name='property',
+ name='person',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='properties', to='ishtar_common.Person', verbose_name='Personne'),
+ ),
+ migrations.AlterField(
+ model_name='property',
+ name='search_vector',
+ field=django.contrib.postgres.search.SearchVectorField(blank=True, help_text='Auto-rempli \xe0 la sauvegarde', null=True, verbose_name='Vecteur de recherche'),
+ ),
+ migrations.AlterField(
+ model_name='property',
+ name='start_date',
+ field=models.DateField(verbose_name='Date de d\xe9but'),
+ ),
+ migrations.AlterField(
+ model_name='remarkabilitytype',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='remarkabilitytype',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='remarkabilitytype',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='remarkabilitytype',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ migrations.AlterField(
+ model_name='treatment',
+ name='cached_label',
+ field=models.TextField(blank=True, db_index=True, null=True, verbose_name='Nom en cache'),
+ ),
+ migrations.AlterField(
+ model_name='treatment',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='treatment',
+ name='container',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='archaeological_warehouse.Container', verbose_name='Contenant'),
+ ),
+ migrations.AlterField(
+ model_name='treatment',
+ name='end_date',
+ field=models.DateField(blank=True, null=True, verbose_name='Date de cl\xf4ture'),
+ ),
+ migrations.AlterField(
+ model_name='treatment',
+ name='estimated_cost',
+ field=models.FloatField(blank=True, null=True, verbose_name='Co\xfbt estim\xe9'),
+ ),
+ migrations.AlterField(
+ model_name='treatment',
+ name='external_id',
+ field=models.CharField(blank=True, max_length=200, null=True, verbose_name='Identifiant'),
+ ),
+ migrations.AlterField(
+ model_name='treatment',
+ name='file',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='treatments', to='archaeological_finds.TreatmentFile', verbose_name='Demande associ\xe9e'),
+ ),
+ migrations.AlterField(
+ model_name='treatment',
+ name='goal',
+ field=models.TextField(blank=True, null=True, verbose_name='But'),
+ ),
+ migrations.AlterField(
+ model_name='treatment',
+ name='history_creator',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Cr\xe9ateur'),
+ ),
+ migrations.AlterField(
+ model_name='treatment',
+ name='history_modifier',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Dernier \xe9diteur'),
+ ),
+ migrations.AlterField(
+ model_name='treatment',
+ name='insurance_cost',
+ field=models.FloatField(blank=True, null=True, verbose_name="Co\xfbt d'assurance"),
+ ),
+ migrations.AlterField(
+ model_name='treatment',
+ name='label',
+ field=models.CharField(blank=True, max_length=200, null=True, verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='treatment',
+ name='location',
+ field=models.ForeignKey(blank=True, help_text='Endroit o\xf9 le traitement est r\xe9alis\xe9. Renseignez le lieu de conservation de destination pour un d\xe9placement.', null=True, on_delete=django.db.models.deletion.CASCADE, to='archaeological_warehouse.Warehouse', verbose_name='Localisation'),
+ ),
+ migrations.AlterField(
+ model_name='treatment',
+ name='organization',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='treatments', to='ishtar_common.Organization', verbose_name='Organisation'),
+ ),
+ migrations.AlterField(
+ model_name='treatment',
+ name='other_reference',
+ field=models.CharField(blank=True, max_length=200, null=True, verbose_name='Autre r\xe9f.'),
+ ),
+ migrations.AlterField(
+ model_name='treatment',
+ name='person',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='treatments', to='ishtar_common.Person', verbose_name='Responsable'),
+ ),
+ migrations.AlterField(
+ model_name='treatment',
+ name='quoted_cost',
+ field=models.FloatField(blank=True, null=True, verbose_name='Co\xfbt devis\xe9'),
+ ),
+ migrations.AlterField(
+ model_name='treatment',
+ name='realized_cost',
+ field=models.FloatField(blank=True, null=True, verbose_name='Co\xfbt r\xe9alis\xe9'),
+ ),
+ migrations.AlterField(
+ model_name='treatment',
+ name='search_vector',
+ field=django.contrib.postgres.search.SearchVectorField(blank=True, help_text='Auto-rempli \xe0 la sauvegarde', null=True, verbose_name='Vecteur de recherche'),
+ ),
+ migrations.AlterField(
+ model_name='treatment',
+ name='start_date',
+ field=models.DateField(blank=True, null=True, verbose_name='Date de d\xe9but'),
+ ),
+ migrations.AlterField(
+ model_name='treatment',
+ name='treatment_state',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='archaeological_finds.TreatmentState', verbose_name='\xc9tat'),
+ ),
+ migrations.AlterField(
+ model_name='treatment',
+ name='treatment_types',
+ field=models.ManyToManyField(to='archaeological_finds.TreatmentType', verbose_name='Type de traitement'),
+ ),
+ migrations.AlterField(
+ model_name='treatment',
+ name='year',
+ field=models.IntegerField(default=ishtar_common.utils.get_current_year, verbose_name='Ann\xe9e'),
+ ),
+ migrations.AlterField(
+ model_name='treatmentemergencytype',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='treatmentemergencytype',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='treatmentemergencytype',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='treatmentemergencytype',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ migrations.AlterField(
+ model_name='treatmentfile',
+ name='applicant',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='treatmentfile_applicant', to='ishtar_common.Person', verbose_name='Demandeur'),
+ ),
+ migrations.AlterField(
+ model_name='treatmentfile',
+ name='applicant_organisation',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='treatmentfile_applicant', to='ishtar_common.Organization', verbose_name='Organisation du demandeur'),
+ ),
+ migrations.AlterField(
+ model_name='treatmentfile',
+ name='cached_label',
+ field=models.TextField(blank=True, db_index=True, null=True, verbose_name='Nom en cache'),
+ ),
+ migrations.AlterField(
+ model_name='treatmentfile',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='treatmentfile',
+ name='creation_date',
+ field=models.DateField(blank=True, default=datetime.date.today, null=True, verbose_name='Date de cr\xe9ation'),
+ ),
+ migrations.AlterField(
+ model_name='treatmentfile',
+ name='end_date',
+ field=models.DateField(blank=True, null=True, verbose_name='Date de cl\xf4ture'),
+ ),
+ migrations.AlterField(
+ model_name='treatmentfile',
+ name='external_id',
+ field=models.CharField(blank=True, max_length=200, null=True, verbose_name='Identifiant'),
+ ),
+ migrations.AlterField(
+ model_name='treatmentfile',
+ name='history_creator',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Cr\xe9ateur'),
+ ),
+ migrations.AlterField(
+ model_name='treatmentfile',
+ name='history_modifier',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Dernier \xe9diteur'),
+ ),
+ migrations.AlterField(
+ model_name='treatmentfile',
+ name='in_charge',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='treatmentfile_responsability', to='ishtar_common.Person', verbose_name='Dossier suivi par'),
+ ),
+ migrations.AlterField(
+ model_name='treatmentfile',
+ name='internal_reference',
+ field=models.CharField(blank=True, max_length=200, null=True, verbose_name='R\xe9f\xe9rence interne'),
+ ),
+ migrations.AlterField(
+ model_name='treatmentfile',
+ name='name',
+ field=models.TextField(blank=True, null=True, verbose_name='Nom'),
+ ),
+ migrations.AlterField(
+ model_name='treatmentfile',
+ name='reception_date',
+ field=models.DateField(blank=True, null=True, verbose_name='Date de r\xe9ception'),
+ ),
+ migrations.AlterField(
+ model_name='treatmentfile',
+ name='search_vector',
+ field=django.contrib.postgres.search.SearchVectorField(blank=True, help_text='Auto-rempli \xe0 la sauvegarde', null=True, verbose_name='Vecteur de recherche'),
+ ),
+ migrations.AlterField(
+ model_name='treatmentfile',
+ name='type',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='archaeological_finds.TreatmentFileType', verbose_name='Type de demande de traitement'),
+ ),
+ migrations.AlterField(
+ model_name='treatmentfile',
+ name='year',
+ field=models.IntegerField(default=ishtar_common.utils.get_current_year, verbose_name='Ann\xe9e'),
+ ),
+ migrations.AlterField(
+ model_name='treatmentfiletype',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='treatmentfiletype',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='treatmentfiletype',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='treatmentfiletype',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ migrations.AlterField(
+ model_name='treatmentstate',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='treatmentstate',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='treatmentstate',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='treatmentstate',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ migrations.AlterField(
+ model_name='treatmenttype',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='treatmenttype',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='treatmenttype',
+ name='downstream_is_many',
+ field=models.BooleanField(default=False, help_text="Cochez cela si, pour ce traitement, \xe0 partir d'un seul \xe9l\xe9ment vous en obtenez plusieurs.", verbose_name='Les \xe9l\xe9ments aval sont multiples'),
+ ),
+ migrations.AlterField(
+ model_name='treatmenttype',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='treatmenttype',
+ name='order',
+ field=models.IntegerField(default=10, verbose_name='Ordre'),
+ ),
+ migrations.AlterField(
+ model_name='treatmenttype',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ migrations.AlterField(
+ model_name='treatmenttype',
+ name='upstream_is_many',
+ field=models.BooleanField(default=False, help_text='Cochez cela si, pour ce traitement, \xe0 partir de plusieurs \xe9l\xe9ments vous en obtenez un seul.', verbose_name='Les \xe9l\xe9ments amont sont multiples'),
+ ),
+ migrations.AlterField(
+ model_name='treatmenttype',
+ name='virtual',
+ field=models.BooleanField(verbose_name='Virtuel'),
+ ),
+ ]
diff --git a/archaeological_finds/migrations/0048_auto_20181203_1746.py b/archaeological_finds/migrations/0048_auto_20181203_1746.py
new file mode 100644
index 000000000..567832d72
--- /dev/null
+++ b/archaeological_finds/migrations/0048_auto_20181203_1746.py
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.10 on 2018-12-03 17:46
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('archaeological_finds', '0047_auto_20181203_1442'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='find',
+ name='circumference',
+ field=models.FloatField(blank=True, null=True, verbose_name='Circumference (cm)'),
+ ),
+ migrations.AddField(
+ model_name='historicalfind',
+ name='circumference',
+ field=models.FloatField(blank=True, null=True, verbose_name='Circumference (cm)'),
+ ),
+ ]
diff --git a/archaeological_finds/migrations/0049_auto_20181210_1518.py b/archaeological_finds/migrations/0049_auto_20181210_1518.py
new file mode 100644
index 000000000..28f790ab0
--- /dev/null
+++ b/archaeological_finds/migrations/0049_auto_20181210_1518.py
@@ -0,0 +1,64 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.10 on 2018-12-10 15:18
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+def migrate_treatment_types(apps, schema):
+ TreatmentType = apps.get_model('archaeological_finds', 'TreatmentType')
+ q = TreatmentType.objects.filter(txt_idx="loan")
+ if q.count():
+ loan = q.all()[0]
+ loan.change_current_location = True
+ loan.save()
+ q = TreatmentType.objects.filter(txt_idx="loan-return")
+ if q.count():
+ loan_r = q.all()[0]
+ loan_r.restore_reference_location = True
+ loan_r.save()
+ q = TreatmentType.objects.filter(txt_idx="packaging")
+ if q.count():
+ packaging = q.all()[0]
+ packaging.change_reference_location = True
+ packaging.change_current_location = True
+ packaging.save()
+ q = TreatmentType.objects.filter(txt_idx="virtual-reassembly")
+ if q.count():
+ v = q.all()[0]
+ v.upstream_is_many = False
+ v.save()
+ q = TreatmentType.objects.filter(txt_idx="virtual_group")
+ if q.count():
+ v = q.all()[0]
+ v.upstream_is_many = False
+ v.save()
+ for t in TreatmentType.objects.all():
+ t.txt_idx = t.txt_idx.replace("_", "-")
+ t.save()
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('archaeological_finds', '0048_auto_20181203_1746'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='treatmenttype',
+ name='change_current_location',
+ field=models.BooleanField(default=False, help_text='The treatment change the current location.', verbose_name='Change current location'),
+ ),
+ migrations.AddField(
+ model_name='treatmenttype',
+ name='change_reference_location',
+ field=models.BooleanField(default=False, help_text='The treatment change the reference location.', verbose_name='Change reference location'),
+ ),
+ migrations.AddField(
+ model_name='treatmenttype',
+ name='restore_reference_location',
+ field=models.BooleanField(default=False, help_text='The treatment change restore reference location to the current location.', verbose_name='Restore the reference location'),
+ ),
+ migrations.RunPython(migrate_treatment_types)
+ ]
diff --git a/archaeological_finds/migrations/0050_auto_20181211_1509.py b/archaeological_finds/migrations/0050_auto_20181211_1509.py
new file mode 100644
index 000000000..c9928d617
--- /dev/null
+++ b/archaeological_finds/migrations/0050_auto_20181211_1509.py
@@ -0,0 +1,51 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.10 on 2018-12-11 15:09
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+def migrate_treatment_states(apps, schema):
+ TreatmentState = apps.get_model('archaeological_finds', 'TreatmentState')
+ q = TreatmentState.objects.filter(txt_idx="completed")
+ if q.count():
+ t = q.all()[0]
+ t.executed = True
+ t.save()
+ for t in TreatmentState.objects.all():
+ t.txt_idx = t.txt_idx.replace("_", "-")
+ t.save()
+ orders = [(10, "planned"), (20, "to-be-confirmed"), (30, "in-progress"),
+ (40, "completed"), (50, "cancelled"), (60, "unknown"),]
+ for order, txt_idx in orders:
+ q = TreatmentState.objects.filter(txt_idx=txt_idx)
+ if not q.count():
+ continue
+ t = q.all()[0]
+ t.order = order
+ t.save()
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('archaeological_finds', '0049_auto_20181210_1518'),
+ ]
+
+ operations = [
+ migrations.AlterModelOptions(
+ name='treatmentstate',
+ options={'ordering': ('order', 'label'), 'verbose_name': "Type d'\xe9tat de traitement", 'verbose_name_plural': "Types d'\xe9tat de traitement"},
+ ),
+ migrations.AddField(
+ model_name='treatmentstate',
+ name='executed',
+ field=models.BooleanField(default=False, verbose_name='Treatment is executed'),
+ ),
+ migrations.AddField(
+ model_name='treatmentstate',
+ name='order',
+ field=models.IntegerField(default=10, verbose_name='Ordre'),
+ ),
+ migrations.RunPython(migrate_treatment_states)
+ ]
diff --git a/archaeological_finds/migrations/0051_auto_20181211_1530.py b/archaeological_finds/migrations/0051_auto_20181211_1530.py
new file mode 100644
index 000000000..9bcdb60a7
--- /dev/null
+++ b/archaeological_finds/migrations/0051_auto_20181211_1530.py
@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.10 on 2018-12-11 15:30
+from __future__ import unicode_literals
+
+import archaeological_finds.models_treatments
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('archaeological_finds', '0050_auto_20181211_1509'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='treatment',
+ name='treatment_state',
+ field=models.ForeignKey(default=archaeological_finds.models_treatments.TreatmentState.get_default, on_delete=django.db.models.deletion.CASCADE, to='archaeological_finds.TreatmentState', verbose_name='\xc9tat'),
+ ),
+ ]
diff --git a/archaeological_finds/migrations/0052_auto_20181211_1558.py b/archaeological_finds/migrations/0052_auto_20181211_1558.py
new file mode 100644
index 000000000..5c0f63d7c
--- /dev/null
+++ b/archaeological_finds/migrations/0052_auto_20181211_1558.py
@@ -0,0 +1,33 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.10 on 2018-12-11 15:58
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+def migrate_treatment_states(apps, schema):
+ Treatment = apps.get_model('archaeological_finds', 'Treatment')
+ for t in Treatment.objects.all():
+ t.executed = True
+ t.save()
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('archaeological_finds', '0051_auto_20181211_1530'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='historicaltreatment',
+ name='executed',
+ field=models.BooleanField(default=False, verbose_name='Treatment have been executed'),
+ ),
+ migrations.AddField(
+ model_name='treatment',
+ name='executed',
+ field=models.BooleanField(default=False, verbose_name='Treatment have been executed'),
+ ),
+ migrations.RunPython(migrate_treatment_states)
+ ]
diff --git a/archaeological_finds/models_finds.py b/archaeological_finds/models_finds.py
index e53ad6e6d..393583749 100644
--- a/archaeological_finds/models_finds.py
+++ b/archaeological_finds/models_finds.py
@@ -23,7 +23,7 @@ from django.conf import settings
from django.contrib.gis.db import models
from django.core.urlresolvers import reverse
from django.db import connection
-from django.db.models import Max, Q
+from django.db.models import Max, Q, F
from django.db.models.signals import m2m_changed, post_save, post_delete, \
pre_delete
from django.core.exceptions import ObjectDoesNotExist
@@ -91,6 +91,11 @@ post_delete.connect(post_save_cache, sender=ConservatoryState)
class TreatmentType(HierarchicalType):
order = models.IntegerField(_(u"Order"), default=10)
virtual = models.BooleanField(_(u"Virtual"))
+ destructive = models.BooleanField(_(u"Destructive"), default=False)
+ create_new_find = models.BooleanField(
+ _(u"Create a new find"), default=False,
+ help_text=_(u"If True when this treatment is applied a new version "
+ u"of the object will be created."))
upstream_is_many = models.BooleanField(
_(u"Upstream is many"), default=False,
help_text=_(
@@ -101,6 +106,16 @@ class TreatmentType(HierarchicalType):
help_text=_(
u"Check this if for this treatment from one find you'll get "
u"many."))
+ change_reference_location = models.BooleanField(
+ _(u"Change reference location"), default=False,
+ help_text=_(u"The treatment change the reference location."))
+ change_current_location = models.BooleanField(
+ _(u"Change current location"), default=False,
+ help_text=_(u"The treatment change the current location."))
+ restore_reference_location = models.BooleanField(
+ _(u"Restore the reference location"), default=False,
+ help_text=_(u"The treatment change restore reference location to the "
+ u"current location."))
class Meta:
verbose_name = _(u"Treatment type")
@@ -326,6 +341,15 @@ class BaseFind(BulkUpdatedItem, BaseHistorizedItem, OwnPerms):
finds = self.find.filter().order_by("-order").all()
return finds and finds[0]
+ def get_main_find(self):
+ """
+ Get the last find which is not related to many base_find
+ """
+ for find in self.find.order_by('-pk'):
+ if find.base_finds.count() == 1:
+ return find
+ return
+
def generate_index(self):
"""
Generate index based on operation or context record (based on
@@ -566,31 +590,54 @@ WEIGHT_UNIT = (('g', _(u"g")),
('kg', _(u"kg")),)
-class FindBasket(Basket, OwnPerms):
+class FindBasket(Basket, MainItem):
+ SHOW_URL = 'show-findbasket'
items = models.ManyToManyField('Find', blank=True, related_name='basket')
+ QUICK_ACTIONS = [
+ QuickAction(
+ url="findbasket-qa-duplicate", icon_class="fa fa-clone",
+ text=_(u"Duplicate"), target="one",
+ rights=['view_find', 'view_own_find']),
+ ]
+
class Meta:
+ verbose_name = _(u"Basket")
permissions = (
("view_find", u"Can view all Finds"),
("view_own_find", u"Can view own Find"),
)
- @classmethod
- def get_query_owns(cls, ishtaruser):
- return Q(user=ishtaruser)
-
def get_extra_actions(self, request):
"""
For sheet template: return "Manage basket" action
"""
# url, base_text, icon, extra_text, extra css class, is a quick action
- # no particular rights: if you can view an itm you can add it to your
- # own basket
- actions = [
- (reverse("select_itemsinbasket", args=[self.pk]),
- _(u"Manage basket"),
- "fa fa-shopping-basket", "", "", False),
+ if not request.user or not request.user.ishtaruser:
+ return []
+
+ ishtaruser = request.user.ishtaruser
+ actions = []
+ if self.user == ishtaruser or ishtaruser.pk in [
+ user.pk for user in self.shared_write_with.all()]:
+ actions = [
+ (reverse("select_itemsinbasket", args=[self.pk]),
+ _(u"Manage basket"),
+ "fa fa-shopping-basket", "", "", False),
+ ]
+ can_edit_find = self.can_do(request, 'change_find')
+ if can_edit_find:
+ actions += [
+ (reverse('findbasket-add-treatment', args=[self.pk]),
+ _(u"Add treatment"), "fa fa-exchange", "", "", False),
+ ]
+
+ duplicate = self.QUICK_ACTIONS[0]
+ actions += [
+ (reverse(duplicate.url, args=[self.pk]),
+ duplicate.text, duplicate.icon_class,
+ "", "", True),
]
return actions
@@ -631,6 +678,20 @@ class FBulkView(object):
"""
+def query_loan(is_true=True):
+ """
+ Query to get loan find
+
+ :return: (filter, exclude, extra)
+ """
+ if is_true:
+ return Q(container_ref__isnull=False, container__isnull=False), \
+ Q(container_ref=F('container')), None
+ else:
+ return Q(container_ref__isnull=False, container__isnull=False,
+ container_ref=F('container')), None, None
+
+
class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,
MainItem):
EXTERNAL_ID_KEY = 'find_external_id'
@@ -642,7 +703,8 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,
'base_finds__context_record__label',
'material_types__label', 'object_types__label',
'datings__period__label',
- 'container__cached_label', ]
+ 'container__cached_label',
+ 'container_ref__cached_label']
if settings.COUNTRY == 'fr':
TABLE_COLS.insert(
3, 'base_finds__context_record__operation__code_patriarche')
@@ -652,7 +714,7 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,
'previous_id', 'label', 'material_types__label',
'datings__period__label', 'find_number', 'object_types__label',
'container__cached_label',
- 'container__cached_location',
+ 'container_ref__cached_label',
'description',
'base_finds__context_record__town__name',
'base_finds__context_record__parcel', ]
@@ -670,7 +732,7 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,
'base_finds__context_record__archaeological_site__name':
IshtarSiteProfile.get_default_site_label,
'base_finds__context_record__parcel': _(u"Parcel"),
- 'base_finds__batch':_(u"Batch"),
+ 'base_finds__batch': _(u"Batch"),
'base_finds__comment': _(u"Base find - Comment"),
'base_finds__description': _(u"Base find - Description"),
'base_finds__topographic_localisation': _(u"Base find - "
@@ -680,7 +742,8 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,
u"Base find - Discovery date (exact or TPQ)"),
'base_finds__discovery_date_taq': _(
u"Base find - Discovery date (TAQ)"),
- 'container__cached_label': _(u"Container"),
+ 'container__cached_label': _(u"Current container"),
+ 'container_ref__cached_label': _(u"Reference container"),
'datings__period__label': _(u"Periods"),
'material_types__label': _(u"Material types"),
'object_types__label': _(u"Object types"),
@@ -706,7 +769,7 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,
'base_finds__context_record__',
}
- DATED_FIELDS = ['last_modified__gte']
+ DATED_FIELDS = ['last_modified__gte', 'treatments__file__end_date__lte']
BASE_REQUEST = {'downstream_treatment__isnull': True}
EXTRA_REQUEST_KEYS = {
'base_finds__context_record':
@@ -863,20 +926,36 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,
pgettext_lazy("key for text search", u"has-image"),
'documents__image__isnull',
),
- 'container__location': (
+ 'container_ref__location': (
pgettext_lazy("key for text search", u"location"),
+ 'container_ref__location__name__iexact',
+ ),
+ 'container_ref__responsible': (
+ pgettext_lazy("key for text search", u"warehouse"),
+ 'container_ref__responsible__name__iexact',
+ ),
+ 'container_ref__index': (
+ pgettext_lazy("key for text search", u"container-index"),
+ 'container_ref__index',
+ ),
+ 'container_ref__reference': (
+ pgettext_lazy("key for text search", u"container-ref"),
+ 'container_ref__reference__iexact',
+ ),
+ 'container__location': (
+ pgettext_lazy("key for text search", u"current-location"),
'container__location__name__iexact',
),
'container__responsible': (
- pgettext_lazy("key for text search", u"warehouse"),
+ pgettext_lazy("key for text search", u"current-warehouse"),
'container__responsible__name__iexact',
),
'container__index': (
- pgettext_lazy("key for text search", u"container-index"),
+ pgettext_lazy("key for text search", u"current-container-index"),
'container__index',
),
'container__reference': (
- pgettext_lazy("key for text search", u"container-ref"),
+ pgettext_lazy("key for text search", u"current-container-ref"),
'container__reference__iexact',
),
'basket': (
@@ -899,6 +978,14 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,
pgettext_lazy("key for text search", u"created-by"),
'history_creator__ishtaruser__person__cached_label__iexact'
),
+ 'loan': (
+ pgettext_lazy("key for text search", u"loan"),
+ query_loan
+ ),
+ 'treatments_file_end_date': (
+ pgettext_lazy("key for text search", u"treatment-end-date-before"),
+ 'treatments__file__end_date__lte'
+ )
}
for v in ALT_NAMES.values():
for language_code, language_lbl in settings.LANGUAGES:
@@ -906,6 +993,8 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,
EXTRA_REQUEST_KEYS[unicode(v[0])] = v[1]
deactivate()
+ EXTRA_REQUEST_FUNC = {""}
+
PARENT_SEARCH_VECTORS = ['base_finds']
BASE_SEARCH_VECTORS = [
"cached_label", "label", "description", "container__location__name",
@@ -1003,6 +1092,11 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,
"archaeological_warehouse.Container", verbose_name=_(u"Container"),
blank=True, null=True,
related_name='finds', on_delete=models.SET_NULL)
+ container_ref = models.ForeignKey(
+ "archaeological_warehouse.Container",
+ verbose_name=_(u"Reference container"),
+ blank=True, null=True,
+ related_name='finds_ref', on_delete=models.SET_NULL)
is_complete = models.NullBooleanField(_(u"Is complete?"), blank=True,
null=True)
object_types = models.ManyToManyField(
@@ -1029,6 +1123,8 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,
width = models.FloatField(_(u"Width (cm)"), blank=True, null=True)
height = models.FloatField(_(u"Height (cm)"), blank=True, null=True)
diameter = models.FloatField(_(u"Diameter (cm)"), blank=True, null=True)
+ circumference = models.FloatField(_(u"Circumference (cm)"), blank=True,
+ null=True)
thickness = models.FloatField(_(u"Thickness (cm)"), blank=True, null=True)
clutter_long_side = models.FloatField(
_(u"Clutter - long side (cm)"), blank=True, null=True)
@@ -1083,6 +1179,10 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,
documents = models.ManyToManyField(
Document, related_name='finds', verbose_name=_(u"Documents"),
blank=True)
+ treatments = models.ManyToManyField(
+ "Treatment", verbose_name=_(u"Treatments"),
+ related_name='finds', blank=True,
+ help_text=_(u"Related treatments when no new find is created"))
cached_label = models.TextField(_(u"Cached name"), null=True, blank=True,
db_index=True)
history = HistoricalRecords()
@@ -1156,6 +1256,22 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,
return
return self.base_finds.order_by('-pk').all()[0]
+ def get_values(self, prefix=''):
+ values = super(Find, self).get_values(prefix=prefix)
+ return values
+ # TODO
+ bf = self.get_first_base_find()
+ if not bf:
+ return values
+ operation = bf.context_record.operation
+ values[prefix + "operation"] = [
+ {
+ "common_name": operation.common_name,
+ "code_patriarche": operation.code_patriarche,
+ "address": operation.address
+ }
+ ]
+
@property
def reference(self):
bf = self.get_first_base_find()
@@ -1179,6 +1295,8 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,
(reverse("find-qa-basket", args=[self.pk]),
_(u"Add to basket"),
"fa fa-shopping-basket", "", "", True),
+ (reverse('find-add-treatment', args=[self.pk]),
+ _(u"Add treatment"), "fa fa-exchange", "", "", False),
]
if get_current_profile().warehouse:
actions.append(
@@ -1338,7 +1456,7 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,
q = q.filter(**fltr)
return q.filter(downstream_treatment__isnull=True).count()
- def duplicate(self, user):
+ def duplicate(self, user, copy_datings=True):
model = self.__class__
new = model.objects.get(pk=self.pk)
@@ -1356,12 +1474,22 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,
m2m = [field.name for field in model._meta.many_to_many
if field.name not in PRIVATE_FIELDS]
for field in m2m:
- if field == 'images':
- for doc in Document.objects.filter(finds__pk=self.pk).all():
- doc.finds.add(new.pk)
+ if field == 'datings' and copy_datings:
+ for dating in self.datings.all():
+ is_present = False
+ for current_dating in new.datings.all():
+ if Dating.is_identical(current_dating, dating):
+ is_present = True
+ break
+ if is_present:
+ continue
+ dating.pk = None
+ dating.save()
+ new.datings.add(dating)
else:
for val in getattr(self, field).all():
- getattr(new, field).add(val)
+ if val not in getattr(new, field).all():
+ getattr(new, field).add(val)
return new
@classmethod
@@ -1375,6 +1503,9 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,
) | cls._construct_query_own(
'base_finds__context_record__operation__',
Operation._get_query_owns_dicts(ishtaruser)
+ ) | cls._construct_query_own(
+ 'basket__',
+ [{"shared_with": ishtaruser, "shared_write_with": ishtaruser}]
) | cls._construct_query_own('', [
{'history_creator': ishtaruser.user_ptr},
{'base_finds__context_record__operation__end_date__isnull': True}
@@ -1493,21 +1624,62 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,
with connection.cursor() as c:
c.execute(sql, args)
- def get_localisation(self, place):
+ def get_localisation(self, place, is_ref=False):
"""
Get localisation reference in the warehouse
:param place: number of the localisation starting with 0
+ :param is_ref: if true - reference container else current container
:return: reference - empty string if not available
"""
- if not self.container:
+ if is_ref:
+ container = self.container_ref
+ else:
+ container = self.container
+ if not container:
return ""
- locas = self.container.get_localisations()
+ locas = container.get_localisations()
if len(locas) < (place + 1):
return ""
return locas[place]
@property
+ def reference_localisation_1(self):
+ return self.get_localisation(0, is_ref=True)
+
+ @property
+ def reference_localisation_2(self):
+ return self.get_localisation(1, is_ref=True)
+
+ @property
+ def reference_localisation_3(self):
+ return self.get_localisation(2, is_ref=True)
+
+ @property
+ def reference_localisation_4(self):
+ return self.get_localisation(3, is_ref=True)
+
+ @property
+ def reference_localisation_5(self):
+ return self.get_localisation(4, is_ref=True)
+
+ @property
+ def reference_localisation_6(self):
+ return self.get_localisation(5, is_ref=True)
+
+ @property
+ def reference_localisation_7(self):
+ return self.get_localisation(6, is_ref=True)
+
+ @property
+ def reference_localisation_8(self):
+ return self.get_localisation(7, is_ref=True)
+
+ @property
+ def reference_localisation_9(self):
+ return self.get_localisation(8, is_ref=True)
+
+ @property
def localisation_1(self):
return self.get_localisation(0)
@@ -1543,19 +1715,75 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,
def localisation_9(self):
return self.get_localisation(8)
- def set_localisation(self, place, context, value):
- if not self.container:
+ def set_localisation(self, place, context, value, is_ref=False):
+ """
+ Get localisation reference in the warehouse
+
+ :param place: number of the localisation starting with 0
+ :param context: context of the request - not used
+ :param value: localisation value
+ :param is_ref: if true - reference container else current container
+ :return: None
+ """
+ if is_ref:
+ container = self.container_ref
+ else:
+ container = self.container
+
+ if not container:
if not value:
return
- raise ImporterError(_(u"No container have been set - the "
- u"localisation cannot be set."))
+ if is_ref:
+ raise ImporterError(
+ _(u"No reference container have been set - the "
+ u"localisation cannot be set."))
+ else:
+ raise ImporterError(
+ _(u"No container have been set - the localisation cannot "
+ u"be set."))
- localisation = self.container.set_localisation(place, value)
+ localisation = container.set_localisation(place, value)
if value and value != '-' and not localisation:
raise ImporterError(
unicode(_(u"The division number {} have not been set "
u"for the warehouse {}.")).format(
- place + 1, self.container.location))
+ place + 1, container.location))
+
+ @post_importer_action
+ def set_reference_localisation_1(self, context, value):
+ return self.set_localisation(0, context, value, is_ref=True)
+
+ @post_importer_action
+ def set_reference_localisation_2(self, context, value):
+ return self.set_localisation(1, context, value, is_ref=True)
+
+ @post_importer_action
+ def set_reference_localisation_3(self, context, value):
+ return self.set_localisation(2, context, value, is_ref=True)
+
+ @post_importer_action
+ def set_reference_localisation_4(self, context, value):
+ return self.set_localisation(3, context, value, is_ref=True)
+
+ @post_importer_action
+ def set_reference_localisation_5(self, context, value):
+ return self.set_localisation(4, context, value, is_ref=True)
+
+ @post_importer_action
+ def set_reference_localisation_6(self, context, value):
+ return self.set_localisation(5, context, value, is_ref=True)
+
+ @post_importer_action
+ def set_reference_localisation_7(self, context, value):
+ return self.set_localisation(6, context, value, is_ref=True)
+
+ @post_importer_action
+ def set_reference_localisation_8(self, context, value):
+ return self.set_localisation(7, context, value, is_ref=True)
+
+ @post_importer_action
+ def set_reference_localisation_9(self, context, value):
+ return self.set_localisation(8, context, value, is_ref=True)
@post_importer_action
def set_localisation_1(self, context, value):
@@ -1634,6 +1862,9 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,
super(Find, self).save(*args, **kwargs)
self.skip_history_when_saving = True
+ if self.container_ref and not self.container:
+ self.container = self.container_ref
+
updated = self.update_external_id(save=False)
if updated:
self._cached_label_checked = False
@@ -1649,6 +1880,9 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,
for base_find in self.base_finds.filter(
context_record__operation__pk__isnull=False).all():
modified = False
+ if self.label and not base_find.label:
+ base_find.label = self.label
+ modified = True
if not base_find.index:
modified = base_find.generate_index()
short_id = base_find.short_id()
@@ -1659,6 +1893,8 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,
if base_find.cache_complete_id != complete_id:
base_find.cache_complete_id = complete_id
modified = True
+ if base_find.update_external_id():
+ modified = True
if modified:
base_find.skip_history_when_saving = True
base_find._cached_label_checked = False
diff --git a/archaeological_finds/models_treatments.py b/archaeological_finds/models_treatments.py
index 6a57a77f5..06f61068b 100644
--- a/archaeological_finds/models_treatments.py
+++ b/archaeological_finds/models_treatments.py
@@ -21,6 +21,7 @@ import datetime
from django.conf import settings
from django.contrib.gis.db import models
+from django.core.urlresolvers import reverse
from django.db.models import Max, Q
from django.db.models.signals import post_save, post_delete, pre_delete
from django.template.defaultfilters import slugify
@@ -29,19 +30,31 @@ from django.utils.translation import ugettext_lazy as _, pgettext_lazy, \
from archaeological_finds.models_finds import Find, FindBasket, TreatmentType
from archaeological_operations.models import ClosedItem, Operation
+from archaeological_context_records.models import Dating
from archaeological_warehouse.models import Warehouse, Container
from ishtar_common.models import Document, GeneralType, \
ImageModel, BaseHistorizedItem, OwnPerms, HistoricalRecords, Person, \
Organization, ValueGetter, post_save_cache, ShortMenuItem, \
DashboardFormItem, ExternalIdManager
-from ishtar_common.utils import cached_label_changed, get_current_year
+from ishtar_common.utils import cached_label_changed, get_current_year, \
+ update_data
class TreatmentState(GeneralType):
+ executed = models.BooleanField(_(u"Treatment is executed"), default=False)
+ order = models.IntegerField(verbose_name=_(u"Order"), default=10)
+
class Meta:
verbose_name = _(u"Treatment state type")
verbose_name_plural = _(u"Treatment state types")
- ordering = ('label',)
+ ordering = ('order', 'label',)
+
+ @classmethod
+ def get_default(cls):
+ q = cls.objects.filter(executed=True)
+ if not q.count():
+ return None
+ return q.all()[0].pk
post_save.connect(post_save_cache, sender=TreatmentState)
@@ -68,10 +81,12 @@ class Treatment(DashboardFormItem, ValueGetter, BaseHistorizedItem,
"upstream_cached_label": _(u"Upstream find"),
"treatment_types__label": _(u"Type"),
"treatment_state__label": _(u"State"),
- 'person__cached_label': _(u"Responsible"),
+ "person__cached_label": _(u"Responsible"),
}
# extra keys than can be passed to save method
- EXTRA_SAVED_KEYS = ('items', 'user')
+ EXTRA_SAVED_KEYS = ('items', 'user', 'resulting_find', 'upstream_items',
+ 'resulting_finds', 'upstream_item',
+ 'treatment_type_list')
# alternative names of fields for searches
ALT_NAMES = {
@@ -127,8 +142,11 @@ class Treatment(DashboardFormItem, ValueGetter, BaseHistorizedItem,
treatment_types = models.ManyToManyField(
TreatmentType, verbose_name=_(u"Treatment type"))
treatment_state = models.ForeignKey(
- TreatmentState, verbose_name=_(u"State"), blank=True, null=True,
+ TreatmentState, verbose_name=_(u"State"),
+ default=TreatmentState.get_default
)
+ executed = models.BooleanField(
+ _(u"Treatment have been executed"), default=False)
location = models.ForeignKey(
Warehouse, verbose_name=_(u"Location"), blank=True, null=True,
help_text=_(
@@ -147,6 +165,7 @@ class Treatment(DashboardFormItem, ValueGetter, BaseHistorizedItem,
goal = models.TextField(_(u"Goal"), blank=True, null=True)
start_date = models.DateField(_(u"Start date"), blank=True, null=True)
end_date = models.DateField(_(u"Closing date"), blank=True, null=True)
+ creation_date = models.DateTimeField(default=datetime.datetime.now)
container = models.ForeignKey(Container, verbose_name=_(u"Container"),
blank=True, null=True)
estimated_cost = models.FloatField(_(u"Estimated cost"),
@@ -157,8 +176,6 @@ class Treatment(DashboardFormItem, ValueGetter, BaseHistorizedItem,
blank=True, null=True)
insurance_cost = models.FloatField(_(u"Insurance cost"),
blank=True, null=True)
- target_is_basket = models.BooleanField(_(u"Target a basket"),
- default=False)
documents = models.ManyToManyField(
Document, related_name='treatments', verbose_name=_(u"Documents"),
blank=True)
@@ -177,6 +194,7 @@ class Treatment(DashboardFormItem, ValueGetter, BaseHistorizedItem,
("change_own_treatment", u"Can change own Treatment"),
("delete_own_treatment", u"Can delete own Treatment"),
)
+ ordering = ("start_date", )
def __unicode__(self):
if self.cached_label:
@@ -189,6 +207,10 @@ class Treatment(DashboardFormItem, ValueGetter, BaseHistorizedItem,
def short_class_name(self):
return _(u"TREATMENT")
+ @property
+ def limited_finds(self):
+ return self.finds.all()[:15]
+
def natural_key(self):
return (self.external_id, )
@@ -258,6 +280,17 @@ class Treatment(DashboardFormItem, ValueGetter, BaseHistorizedItem,
upstream_lbl.short_description = _(u"Upstream finds")
upstream_lbl.admin_order_field = 'upstream__cached_label'
+ def get_extra_actions(self, request):
+ # url, base_text, icon, extra_text, extra css class, is a quick action
+ actions = []
+ if self.can_do(request, 'add_administrativeact'):
+ actions += [
+ (reverse('treatment-add-adminact', args=[self.pk]),
+ _(u"Add associated administrative act"), "fa fa-plus",
+ _(u"admin. act"), "", False),
+ ]
+ return actions
+
def get_values(self, prefix=''):
values = super(Treatment, self).get_values(prefix=prefix)
values[prefix + "upstream_finds"] = u" ; ".join(
@@ -283,41 +316,243 @@ class Treatment(DashboardFormItem, ValueGetter, BaseHistorizedItem,
if q.count():
self.index = q.all().aggregate(Max('index'))['index__max'] + 1
+ def _create_n_1_resulting_find(self, resulting_find, upstream_items,
+ treatment_types):
+ """
+ Manage creation of n<->1 treatment
+ """
+ m2m = {}
+ base_fields = [f.name for f in Find._meta.get_fields()]
+ for k in resulting_find.keys():
+ # if not in base fields should be a m2m
+ if k not in base_fields:
+ values = resulting_find.pop(k)
+ if values:
+ m2m[k + "s"] = values
+
+ resulting_find['history_modifier'] = self.history_modifier
+ new_find = Find.objects.create(**resulting_find)
+
+ for k in m2m:
+ m2m_field = getattr(new_find, k)
+ try:
+ for value in m2m[k]:
+ m2m_field.add(value)
+ except TypeError:
+ m2m_field.add(m2m[k])
+
+ create_new_find = bool([tp for tp in treatment_types
+ if tp.create_new_find])
+
+ current_base_finds = []
+ current_documents = []
+ for upstream_item in upstream_items:
+ # datings are not explicitly part of the resulting_find
+ # need to reassociate with no duplicate
+ for dating in upstream_item.datings.all():
+ is_present = False
+ for current_dating in new_find.datings.all():
+ if Dating.is_identical(current_dating, dating):
+ is_present = True
+ break
+ if is_present:
+ continue
+ dating.pk = None # duplicate
+ dating.save()
+ new_find.datings.add(dating)
+
+ # associate base finds
+ for base_find in upstream_item.base_finds.all():
+ if base_find.pk in current_base_finds:
+ continue
+ current_base_finds.append(base_find.pk)
+ new_find.base_finds.add(base_find)
+
+ # documents
+ for document in upstream_item.documents.all():
+ if document.pk in current_documents:
+ continue
+ current_documents.append(document.pk)
+ new_find.documents.add(document)
+
+ # data
+ new_find.data = update_data(new_find.data, upstream_item.data,
+ merge=True)
+
+ if create_new_find:
+ upstream_item.downstream_treatment = self
+ upstream_item.history_modifier = self.history_modifier
+ upstream_item.save()
+ else:
+ self.finds.add(upstream_item)
+
+ new_find.upstream_treatment = self
+ new_find.skip_history_when_saving = True
+ new_find.save()
+
+ def _create_1_n_resulting_find(self, resulting_finds, upstream_item, user,
+ treatment_types):
+ """
+ Manage creation of 1<->n treatment
+ """
+ new_items = []
+ start_number = resulting_finds['start_number']
+ for idx in range(resulting_finds['number']):
+ label = resulting_finds['label'] + unicode(start_number + idx)
+ new_find = Find.objects.get(
+ pk=upstream_item.pk).duplicate(user)
+ new_find.upstream_treatment = self
+ new_find.label = label
+ new_find.skip_history_when_saving = True
+ new_find.save()
+ new_items.append(new_find)
+
+ create_new_find = bool([tp for tp in treatment_types
+ if tp.create_new_find])
+
+ if create_new_find:
+ upstream_item.downstream_treatment = self
+ upstream_item.skip_history_when_saving = True
+ upstream_item.save()
+ else:
+ self.finds.add(upstream_item)
+
+ if getattr(user, 'ishtaruser', None):
+ b = FindBasket.objects.create(
+ label=resulting_finds['basket_name'], user=user.ishtaruser)
+ for item in new_items:
+ b.items.add(item)
+
def save(self, *args, **kwargs):
- items, user, extra_args_for_new = [], None, []
+ items, user, extra_args_for_new, resulting_find = [], None, [], None
+ upstream_items, upstream_item, resulting_finds = [], None, None
+ treatment_types = []
if "items" in kwargs:
items = kwargs.pop('items')
+ if "resulting_find" in kwargs:
+ resulting_find = kwargs.pop('resulting_find')
+ if "resulting_finds" in kwargs:
+ resulting_finds = kwargs.pop('resulting_finds')
+ if "upstream_items" in kwargs:
+ upstream_items = kwargs.pop('upstream_items')
+ if "upstream_item" in kwargs:
+ upstream_item = kwargs.pop('upstream_item')
if "user" in kwargs:
user = kwargs.pop('user')
if "extra_args_for_new" in kwargs:
extra_args_for_new = kwargs.pop('extra_args_for_new')
+ if "treatment_type_list" in kwargs:
+ treatment_types = kwargs.pop('treatment_type_list')
self.pre_save()
super(Treatment, self).save(*args, **kwargs)
+ to_be_executed = not self.executed and self.treatment_state.executed
+
updated = []
+ # baskets
if hasattr(items, "items"):
items = items.items.all()
+ if hasattr(upstream_items, "items"):
+ upstream_items = upstream_items.items.all()
+ if not items and self.finds.count():
+ items = list(self.finds.all())
+ if not treatment_types and self.treatment_types.count():
+ treatment_types = list(self.treatment_types.all())
+
+ # execute the treatment
+ if upstream_items and resulting_find:
+ if not to_be_executed:
+ # should not happen but bad validation check...
+ return
+ self._create_n_1_resulting_find(resulting_find, upstream_items,
+ treatment_types)
+ self.executed = True
+ self.save()
+ return
+
+ if upstream_item and resulting_finds:
+ if not to_be_executed:
+ # should not happen but bad validation check...
+ return
+ self._create_1_n_resulting_find(
+ resulting_finds, upstream_item, self.history_modifier,
+ treatment_types)
+ self.executed = True
+ self.save()
+ return
+
+ create_new_find = bool([tp for tp in treatment_types
+ if tp.create_new_find])
+
for item in items:
- new = item.duplicate(user)
- item.downstream_treatment = self
- item.save()
- new.upstream_treatment = self
- for k in extra_args_for_new:
- setattr(new, k, extra_args_for_new[k])
- new.save()
- updated.append(new.pk)
- # update baskets
- for basket in \
- FindBasket.objects.filter(items__pk=item.pk).all():
- basket.items.remove(item)
- basket.items.add(new)
+ if not create_new_find or not to_be_executed:
+ self.finds.add(item)
+ else:
+ self.finds.clear()
+ new = item.duplicate(user)
+ item.downstream_treatment = self
+ item.save()
+ new.upstream_treatment = self
+ for k in extra_args_for_new:
+ setattr(new, k, extra_args_for_new[k])
+ new.save()
+ updated.append(new.pk)
+ # update baskets
+ for basket in \
+ FindBasket.objects.filter(items__pk=item.pk).all():
+ basket.items.remove(item)
+ basket.items.add(new)
+
+ if not to_be_executed:
+ return
+
+ if create_new_find:
+ q = Find.objects.filter(upstream_treatment=self)
+ else:
+ q = Find.objects.filter(treatments=self)
+
+ # manage loan return
+ for tp in treatment_types:
+ if tp.restore_reference_location:
+ for find in q.all():
+ if find.container_ref:
+ find.container = find.container_ref
+ if find.pk in updated:
+ # don't record twice history
+ find.skip_history_when_saving = True
+ find.save()
+ self.executed = True
+ self.save()
+ break
+
# manage containers
- for find in Find.objects.filter(upstream_treatment=self).all():
- if find.container != self.container:
- find.container = self.container
- if find.pk in updated:
- # don't record twice history
- find.skip_history_when_saving = True
- find.save()
+ if not self.container:
+ return
+
+ container_attrs = []
+ for tp in treatment_types:
+ if tp.change_current_location:
+ if 'container' in container_attrs:
+ continue
+ container_attrs.append('container')
+ if tp.change_reference_location:
+ if 'container_ref' in container_attrs:
+ continue
+ container_attrs.append('container_ref')
+
+ if not container_attrs:
+ # non consistent treatment
+ return
+
+ for find in q.all():
+ for container_attr in container_attrs:
+ if getattr(find, container_attr) != self.container:
+ setattr(find, container_attr, self.container)
+ if find.pk in updated:
+ # don't record twice history
+ find.skip_history_when_saving = True
+ find.save()
+ self.executed = True
+ self.save()
@property
def associated_filename(self):
@@ -515,6 +750,8 @@ class FindTreatments(AbsFindTreatments):
class TreatmentFileType(GeneralType):
+ treatment_type = models.ForeignKey(TreatmentType, blank=True, null=True)
+
class Meta:
verbose_name = _(u"Treatment request type")
verbose_name_plural = _(u"Treatment request types")
@@ -610,6 +847,10 @@ class TreatmentFile(DashboardFormItem, ClosedItem, BaseHistorizedItem,
documents = models.ManyToManyField(
Document, related_name='treatment_files', verbose_name=_(u"Documents"),
blank=True)
+ associated_basket = models.ForeignKey(
+ FindBasket, null=True, blank=True, on_delete=models.SET_NULL,
+ related_name='treatment_files'
+ )
cached_label = models.TextField(_(u"Cached name"), null=True, blank=True,
db_index=True)
history = HistoricalRecords()
@@ -619,21 +860,15 @@ class TreatmentFile(DashboardFormItem, ClosedItem, BaseHistorizedItem,
verbose_name_plural = _(u"Treatment requests")
unique_together = ('year', 'index')
permissions = (
- ("view_filetreatment",
+ ("view_treatmentfile",
u"Can view all Treatment requests"),
- ("add_filetreatment",
- u"Can add Treatment request"),
- ("change_filetreatment",
- u"Can change Treatment request"),
- ("delete_filetreatment",
- u"Can delete Treatment request"),
- ("view_own_filetreatment",
+ ("view_own_treatmentfile",
u"Can view own Treatment request"),
- ("add_own_filetreatment",
+ ("add_own_treatmentfile",
u"Can add own Treatment request"),
- ("change_own_filetreatment",
+ ("change_own_treatmentfile",
u"Can change own Treatment request"),
- ("delete_own_filetreatment",
+ ("delete_own_treatmentfile",
u"Can delete own Treatment request"),
)
ordering = ('cached_label',)
@@ -657,6 +892,39 @@ class TreatmentFile(DashboardFormItem, ClosedItem, BaseHistorizedItem,
for attr in ('year', 'index', 'internal_reference',
'name') if getattr(self, attr)])
+ def get_values(self, prefix=''):
+ values = super(TreatmentFile, self).get_values(prefix=prefix)
+ if not self.associated_basket:
+ return
+ values[prefix + "basket"] = [
+ find.get_values() for find in self.associated_basket.items.all()
+ ]
+ return values
+
+ def get_extra_actions(self, request):
+ # url, base_text, icon, extra_text, extra css class, is a quick action
+ actions = []
+ if self.can_do(request, 'add_administrativeact'):
+ actions += [
+ (reverse('treatmentfile-add-adminact', args=[self.pk]),
+ _(u"Add associated administrative act"), "fa fa-plus",
+ _(u"admin. act"), "", False),
+ ]
+ if not self.associated_basket:
+ return actions
+ if self.type.treatment_type and self.treatments.filter(
+ treatment_types__pk=self.type.treatment_type.pk).count():
+ # a treatment of this type already exists
+ return actions
+ can_edit_find = self.can_do(request, 'change_find')
+ if can_edit_find:
+ actions += [
+ (reverse('treatmentfile-add-treatment', args=[self.pk]),
+ _(u"Add associated treatment"), "fa fa-exchange", "", "",
+ False),
+ ]
+ return actions
+
@classmethod
def get_owns(cls, user, menu_filtr=None, limit=None, values=None,
get_short_menu_class=None):
diff --git a/archaeological_finds/templates/ishtar/blocks/window_find_nav.html b/archaeological_finds/templates/ishtar/blocks/window_find_nav.html
new file mode 100644
index 000000000..74c6858a1
--- /dev/null
+++ b/archaeological_finds/templates/ishtar/blocks/window_find_nav.html
@@ -0,0 +1,21 @@
+{% extends "ishtar/blocks/window_nav.html" %}
+{% load i18n link_to_window %}
+{% block post_pin %}{% if baskets %}
+<div class="dropdown btn-secondary">
+ <button class="btn btn-sm btn-secondary dropdown-toggle" type="button"
+ id="dropdown-post-pin-{{window_id}}"
+ data-toggle="dropdown"aria-haspopup="true"
+ aria-expanded="false">
+ <i class="fa fa-shopping-basket"></i> {% trans "Baskets" %}
+ </button>
+ <div class="dropdown-menu" aria-labelledby="dropdown-post-pin-{{window_id}}">
+ {% for basket_id, lbl in baskets %}
+ <a class="dropdown-item" href="#"
+ onclick="load_window('{% url 'show-findbasket' basket_id %}')">
+ <i class="fa fa-info-circle display_details" aria-hidden="true"></i>
+ {{lbl}}
+ </a>
+ {% endfor %}
+ </div>
+</div>
+{% endif %}{% endblock %}
diff --git a/archaeological_finds/templates/ishtar/forms/qa_find_treatment.html b/archaeological_finds/templates/ishtar/forms/qa_find_treatment.html
index ef3906735..f20f0cb65 100644
--- a/archaeological_finds/templates/ishtar/forms/qa_find_treatment.html
+++ b/archaeological_finds/templates/ishtar/forms/qa_find_treatment.html
@@ -27,20 +27,26 @@
</div>
<div class="form-row">
+ {{ form.reference_container }}&nbsp;<label for="{{form.reference_container.auto_id}}">
+ {% trans "Change the reference container" %}
+ </label>
+ </div>
+
+ <div class="form-row">
{{ form.create_treatment }}&nbsp;<label for="{{form.create_treatment.auto_id}}">
{% trans "Associate a treatment" %}
</label>
</div>
<div id="new-treatment">
- {% for field in form %}
- {% if field.name != 'container' and field.name != 'create_treatment' %}
- {% if forloop.counter0|divisibleby:2 %}
+ {% with force_large_col=True %}{% for field in form %}
+ {% if field.name != 'reference_container' and field.name != 'container' and field.name != 'create_treatment' %}
+ {% if forloop.counter|divisibleby:2 %}
<div class="form-row">{% endif %}
{% include "blocks/bs_field_snippet.html" %}
{% if not forloop.counter0|divisibleby:2 %}
</div>{% endif %}
{% endif %}
- {% endfor %}
+ {% endfor %}{% endwith %}
</div>
{% endblock %}
diff --git a/archaeological_finds/templates/ishtar/forms/qa_findbasket_duplicate.html b/archaeological_finds/templates/ishtar/forms/qa_findbasket_duplicate.html
new file mode 100644
index 000000000..b9ec50f22
--- /dev/null
+++ b/archaeological_finds/templates/ishtar/forms/qa_findbasket_duplicate.html
@@ -0,0 +1,22 @@
+{% extends "ishtar/forms/qa_base.html" %}
+{% load i18n inline_formset table_form %}
+
+{% block main_form %}
+<div class="alert alert-info">
+ {% trans "Items of the basket will be attached to the new basket but not the shares." %}
+</div>
+{% if form.non_field_errors %}
+<div class="alert alert-danger" role="alert">
+ {{form.non_field_errors}}
+</div>
+{% endif %}
+<div class="form-row">
+ <div class="form-group col-lg-6 required">
+ <label>{% trans "Label" %}</label>
+ </div>
+ {% with form.label as field %}
+ {% include "blocks/bs_field_snippet.html" %}
+ {% endwith %}
+</div>
+{% endblock %}
+
diff --git a/archaeological_finds/templates/ishtar/sheet_basefind.html b/archaeological_finds/templates/ishtar/sheet_basefind.html
index c20ca66ee..7ea16fecb 100644
--- a/archaeological_finds/templates/ishtar/sheet_basefind.html
+++ b/archaeological_finds/templates/ishtar/sheet_basefind.html
@@ -1,6 +1,10 @@
{% load i18n window_field from_dict link_to_window window_tables window_header humanize %}
- <p class='window-refs text-center'>{{base_find.complete_id }}</p>
- <p class='window-refs text-center'>{{base_find.short_id }}</p>
+<div id="{{window_id}}-base-find-{{forloop.counter}}" role="tabpanel"
+ class="tab-pane fade{% if forloop.first %} show active{% endif %}">
+ <p class='window-refs text-center'>{{ base_find.complete_id }}</p>
+ {% if base_find.complete_id != base_find.short_id %}
+ <p class='window-refs text-center'>{{ base_find.short_id }}</p>
+ {% endif %}
{% if base_find.external_id %}
<p class='window-refs text-center external-id'>
<small title="{% trans 'Internal ID' %}">
@@ -77,11 +81,5 @@
{% endwith %}{% endwith %}
{% endif %}
</div>
-
-{% if first %}
- </div>
</div>
-<div class="subsection">
-{% endif %}
-{% if forloop.counter0 %}<hr/>{% endif %}
diff --git a/archaeological_finds/templates/ishtar/sheet_find.html b/archaeological_finds/templates/ishtar/sheet_find.html
index 021ea5652..7171c3deb 100644
--- a/archaeological_finds/templates/ishtar/sheet_find.html
+++ b/archaeological_finds/templates/ishtar/sheet_find.html
@@ -1,10 +1,10 @@
{% extends "ishtar/sheet.html" %}
-{% load i18n window_field from_dict link_to_window window_tables window_header humanize %}
+{% load i18n ishtar_helpers window_field from_dict link_to_window window_tables window_header humanize %}
{% block head_title %}<strong>{% trans "Find" %}</strong>{% if item.denomination %} - {{item.denomination|default:""}}{% endif %} - {{item.label|default:""}}{% endblock %}
{% block toolbar %}
-{% window_nav item window_id 'show-find' 'find_modify' 'show-historized-find' 'revert-find' previous next 1 %}
+{% window_find_nav item window_id 'show-find' 'find_modify' 'show-historized-find' 'revert-find' previous next 1 baskets %}
{% endblock %}
{% block content %}
@@ -15,243 +15,387 @@
</div>
{% endif %}
+{# trick to set to null non existing variable #}
+{% with permission_view_document=permission_view_document %}
+{% with permission_view_own_document=permission_view_own_document %}
-{% with nb_image=item.images.count %}
-{% if nb_image %}
-<div class="clearfix">
- <div class="card float-left col-12 col-md-6 col-lg-4">
- {% include "ishtar/blocks/window_image.html" %}
- <div class="card-body">
- </div>
- </div>
-{% endif %}
+{% with display_identification=item.integrities.count|or_:item.remarkabilities.count|or_:item.conservatory_state|or_:item.conservatory_comment|or_:item.alterations.count|or_:item.alteration_causes.count|or_:item.preservation_to_considers.count|or_:item.appraisal_date|or_:item.treatment_emergency|or_:item.insurance_value|or_:item.estimated_value|or_:item.datings.count|or_:item.dating_comment %}
+{% with display_warehouse_treatments=item.container|or_:item.container_ref|or_:item.upstream_treatment|or_:item.downstream_treatment|or_:item.treatments.count %}
+{% with can_view_documents=permission_view_own_document|or_:permission_view_document %}
+{% with display_documents=can_view_documents|and_:item.documents.count %}
- <h2>{% trans "Associated base finds"%}</h2>
+<ul class="nav nav-tabs" id="{{window_id}}-tabs" role="tablist">
+ <li class="nav-item">
+ <a class="nav-link active" id="{{window_id}}-basefind-tab"
+ data-toggle="tab" href="#{{window_id}}-basefind" role="tab"
+ aria-controls="{{window_id}}-basefind" aria-selected="true">
+ {% trans "Image / Base find" %}
+ </a>
+ </li>
+ <li class="nav-item">
+ <a class="nav-link" id="{{window_id}}-identification-tab"
+ data-toggle="tab" href="#{{window_id}}-identification" role="tab"
+ aria-controls="{{window_id}}-identification" aria-selected="false">
+ {% trans "Identification / Description / Dimensions" %}
+ </a>
+ </li>
+ {% if display_identification %}
+ <li class="nav-item">
+ <a class="nav-link" id="{{window_id}}-preservation-tab"
+ data-toggle="tab" href="#{{window_id}}-preservation" role="tab"
+ aria-controls="{{window_id}}-preservation" aria-selected="false">
+ {% trans "Datings / Preservation" %}
+ </a>
+ </li>
+ {% endif %}
+ {% if display_warehouse_treatments %}
+ <li class="nav-item">
+ <a class="nav-link" id="{{window_id}}-warehouse-tab"
+ data-toggle="tab" href="#{{window_id}}-warehouse" role="tab"
+ aria-controls="{{window_id}}-warehouse" aria-selected="false">
+ {% trans "Warehouse / Treatments" %}
+ </a>
+ </li>
+ {% endif %}
+ {% if display_documents %}
+ <li class="nav-item">
+ <a class="nav-link" id="{{window_id}}-documents-tab"
+ data-toggle="tab" href="#{{window_id}}-documents" role="tab"
+ aria-controls="{{window_id}}-treatments" aria-selected="false">
+ {% trans "Documents" %}
+ </a>
+ </li>
+ {% endif %}
+ {% if item.data %}
+ <li class="nav-item">
+ <a class="nav-link" id="{{window_id}}-json-tab"
+ data-toggle="tab" href="#{{window_id}}-json" role="tab"
+ aria-controls="{{window_id}}-json" aria-selected="false">
+ {% trans "Custom fields" %}
+ </a>
+ </li>
+ {% endif %}
+</ul>
- <div class="subsection">
- {% for base_find in item.base_finds.all %}
- {% with first=forloop.first|add:nb_image %}
- {% include "ishtar/sheet_basefind.html" %}
- {% endwith %}
- {% endfor %}
- </div>
-{% endwith %}
+<div class="tab-content" id="{{window_id}}-tab-content">
-<h3>{% trans "Identification" %}</h3>
+ <div class="tab-pane fade show active" id="{{window_id}}-basefind"
+ role="tabpanel" aria-labelledby="{{window_id}}-basefind-tab">
+ {% with nb_image=item.images.count %}
+ {% if nb_image %}
+ <div class="clearfix">
+ <div class="card float-left col-12 col-md-6 col-lg-4">
+ {% include "ishtar/blocks/window_image.html" %}
+ <div class="card-body">
+ </div>
+ </div>
+ {% endif %}
-<div class='text-center'>
- {% include "ishtar/blocks/sheet_external_id.html" %}
-</div>
+ <ul class="nav nav-pills" role="tablist">
+ {% for base_find in item.base_finds.all %}
+ <li class="nav-item">
+ <a class="nav-link{% if forloop.first %} active{% endif %}"
+ data-toggle="tab" href="#{{window_id}}-base-find-{{forloop.counter}}"
+ role="tab">
+ {{base_find.short_id}}
+ </a>
+ </li>
+ {% endfor %}
+ </ul>
-<div class='row'>
- {% field_flex "Denomination" item.denomination %}
- {% field_flex "Free ID" item.label %}
- {% field_flex "Previous ID" item.previous_id %}
- {% field_flex "Excavation ID" item.excavation_ids %}
- {% field_flex "Museum ID" item.museum_id %}
- {% field_flex "Seal number" item.seal_number %}
- {% trans "Administrative index" as admin_index_label %}
- {% field_flex admin_index_label item.administrative_index %}
- {% field_flex_full "Mark" item.mark "<pre>" "</pre>" %}
-</div>
+ <div class="tab-content">
+ {% for base_find in item.base_finds.all %}
+ {% with first=forloop.first|add:nb_image %}
+ {% include "ishtar/sheet_basefind.html" %}
+ {% endwith %}
+ {% endfor %}
+ </div>
+ {% if nb_image %}
+ </div>
+ {% endif %}
+ {% endwith %}
+ </div>
-<h3>{% trans "Description" %}</h3>
-<div class='row'>
- {% field_flex_full "Description" item.description "<pre>" "</pre>" %}
- {% field_flex "Is complete?" item.is_complete %}
- {% field_flex_multiple "Material types" item.material_types %}
- {% field_flex "Material type quality" item.material_type_quality %}
- {% field_flex_multiple "Object types" item.object_types %}
- {% field_flex "Object type quality" item.object_type_quality %}
- {% field_flex "Find number" item.find_number %}
- {% field_flex "Minimum number of individuals (MNI)" item.min_number_of_individuals %}
- {% field_flex_full "Decoration" item.decoration "<pre>" "</pre>" %}
- {% field_flex_full "Inscription" item.inscription "<pre>" "</pre>" %}
- {% field_flex "Manufacturing place" item.manufacturing_place %}
- {% field_flex_multiple "Communicability" item.communicabilities %}
- {% field_flex_full "Comment" item.comment "<pre>" "</pre>" %}
-</div>
+ <div class="tab-pane fade" id="{{window_id}}-identification"
+ role="tabpanel" aria-labelledby="{{window_id}}-identification-tab">
+ <h3>{% trans "Identification" %}</h3>
-{% if item.length or item.width or item.height or item.diameter or item.thickness or item.volume or item.weight_string or item.dimensions_comment or item.clutter_long_side or item.clutter_short_side or item.clutter_height %}
-<h3>{% trans "Dimensions" %}</h3>
-<div class='row'>
- {% field_flex "Length (cm)" item.length %}
- {% field_flex "Width (cm)" item.width %}
- {% field_flex "Height (cm)" item.height %}
- {% field_flex "Diameter (cm)" item.diameter %}
- {% field_flex "Thickness (cm)" item.thickness %}
- {% field_flex "Volume (l)" item.volume %}
- {% trans "Weight (g)" as weight_label %}
- {% field_flex weight_label item.weight_string %}
- {% field_flex "Clutter long side (cm)" item.clutter_long_side %}
- {% field_flex "Clutter short side (cm)" item.clutter_short_side %}
- {% field_flex "Clutter height (cm)" item.clutter_height %}
- {% field_flex_full "Dimensions comment" item.dimensions_comment "<pre>" "</pre>" %}
-</div>
-{% endif %}
-
-<h3>{% trans "Sheet" %}</h3>
-<div class='row'>
- {% trans "Checked" as checked_label %}
- {% field_flex checked_label item.checked_type %}
- {% field_flex "Check date" item.check_date %}
- {% include "ishtar/blocks/sheet_creation_section.html" %}
-</div>
-
-{% if item.integrities.count or item.remarkabilities.count or item.conservatory_state or item.conservatory_comment or item.alterations.count or item.alteration_causes.count or item.preservation_to_considers.count or item.appraisal_date or item.treatment_emergency or item.insurance_value or item.estimated_value %}
-<h3>{% trans "Preservation" %}</h3>
-<div class='row'>
- {% field_flex_multiple "Integrity / interest" item.integrities %}
- {% field_flex_multiple "Remarkability" item.remarkabilities %}
- {% field_flex "Conservatory state" item.conservatory_state %}
- {% field_flex_multiple "Alteration" item.alterations %}
- {% field_flex_multiple "Alteration cause" item.alteration_causes %}
- {% field_flex_multiple "Recommended treatments" item.preservation_to_considers %}
- {% field_flex "Treatment emergency" item.treatment_emergency %}
- {% field_flex "Estimated value" item.estimated_value|default_if_none:''|intcomma '' ' '|add:CURRENCY %}
- {% field_flex "Insurance value" item.insurance_value|default_if_none:''|intcomma '' ' '|add:CURRENCY %}
- {% field_flex "Appraisal date" item.appraisal_date %}
- {% field_flex_full "Conservatory comment" item.conservatory_comment "<pre>" "</pre>" %}
-</div>
-{% endif %}
+ <div class='text-center'>
+ {% include "ishtar/blocks/sheet_external_id.html" %}
+ </div>
-{% if item.dating or item.dating_comment %}
-<h3>{% trans "Dating" %}</h3>
-{% if item.datings.count %}
-<table id='{{window_id}}-datings' class="table table-striped">
- <tr>
- <th>{% trans "Period" %}</th>
- <th>{% trans "Start date" %}</th>
- <th>{% trans "End date" %}</th>
- <th>{% trans "Dating type" %}</th>
- <th>{% trans "Quality" %}</th>
- <th>{% trans "Precise dating" %}</th>
- </tr>
-{% for dating in item.datings.all %}
- <tr>
- <td>
- {{dating.period}}
- </td>
- <td>
- {{dating.start_date|default_if_none:"-"}}
- </td>
- <td>
- {{dating.end_date|default_if_none:"-"}}
- </td>
- <td>
- {{dating.dating_type|default_if_none:"-"}}
- </td>
- <td>
- {{dating.quality|default_if_none:"-"}}
- </td>
- <td>
- {{dating.precise_dating|default_if_none:"-"}}
- </td>
- </tr>
-{% endfor %}
-</table>
-{% endif %}
- {% field_flex_full "Comment on dating" item.dating_comment "<pre>" "</pre>" %}
-{% endif %}
+ <div class='row'>
+ {% field_flex "Denomination" item.denomination %}
+ {% field_flex "Free ID" item.label %}
+ {% field_flex "Previous ID" item.previous_id %}
+ {% field_flex "Excavation ID" item.excavation_ids %}
+ {% field_flex "Museum ID" item.museum_id %}
+ {% field_flex "Seal number" item.seal_number %}
+ {% trans "Administrative index" as admin_index_label %}
+ {% field_flex admin_index_label item.administrative_index %}
+ {% field_flex_full "Mark" item.mark "<pre>" "</pre>" %}
+ </div>
-{% include "ishtar/blocks/sheet_json.html" %}
+ <h3>{% trans "Description" %}</h3>
+ <div class='row'>
+ {% field_flex_full "Description" item.description "<pre>" "</pre>" %}
+ {% field_flex "Is complete?" item.is_complete %}
+ {% field_flex_multiple "Material types" item.material_types %}
+ {% field_flex "Material type quality" item.material_type_quality %}
+ {% field_flex_multiple "Object types" item.object_types %}
+ {% field_flex "Object type quality" item.object_type_quality %}
+ {% field_flex "Find number" item.find_number %}
+ {% field_flex "Minimum number of individuals (MNI)" item.min_number_of_individuals %}
+ {% field_flex_full "Decoration" item.decoration "<pre>" "</pre>" %}
+ {% field_flex_full "Inscription" item.inscription "<pre>" "</pre>" %}
+ {% field_flex "Manufacturing place" item.manufacturing_place %}
+ {% field_flex_multiple "Communicability" item.communicabilities %}
+ {% field_flex_full "Comment" item.comment "<pre>" "</pre>" %}
+ </div>
-{% if item.container %}
-<h3>{% trans "Warehouse"%}</h3>
-<div class='row'>
- {% field_flex_detail "Container" item.container %}
- {% field_flex "Container ID" item.container.cached_location %}
- {% field_flex_detail "Responsible warehouse" item.container.responsible %}
- {% field_flex_detail "Location (warehouse)" item.container.location %}
- {% field_flex "Precise localisation" item.container.cached_division %}
-</div>
-{% endif %}
+ {% if item.length or item.width or item.height or item.diameter or item.thickness or item.volume or item.weight_string or item.dimensions_comment or item.clutter_long_side or item.clutter_short_side or item.clutter_height %}
+ <h3>{% trans "Dimensions" %}</h3>
+ <div class='row'>
+ {% field_flex "Length (cm)" item.length %}
+ {% field_flex "Width (cm)" item.width %}
+ {% field_flex "Height (cm)" item.height %}
+ {% field_flex "Thickness (cm)" item.thickness %}
+ {% field_flex "Diameter (cm)" item.diameter %}
+ {% field_flex "Circumference (cm)" item.circumference %}
+ {% field_flex "Volume (l)" item.volume %}
+ {% trans "Weight (g)" as weight_label %}
+ {% field_flex weight_label item.weight_string %}
+ {% field_flex "Clutter long side (cm)" item.clutter_long_side %}
+ {% field_flex "Clutter short side (cm)" item.clutter_short_side %}
+ {% field_flex "Clutter height (cm)" item.clutter_height %}
+ {% field_flex_full "Dimensions comment" item.dimensions_comment "<pre>" "</pre>" %}
+ </div>
+ {% endif %}
-{% if item.upstream_treatment or item.downstream_treatment %}
-<h3>{% trans "Treatments"%}</h3>
+ <h3>{% trans "Sheet" %}</h3>
+ <div class='row'>
+ {% trans "Checked" as checked_label %}
+ {% field_flex checked_label item.checked_type %}
+ {% field_flex "Check date" item.check_date %}
+ {% include "ishtar/blocks/sheet_creation_section.html" %}
+ </div>
+ </div>
+ {% if display_identification %}
+ <div class="tab-pane fade" id="{{window_id}}-preservation"
+ role="tabpanel" aria-labelledby="{{window_id}}-preservation-tab">
+ {% if item.integrities.count or item.remarkabilities.count or item.conservatory_state or item.conservatory_comment or item.alterations.count or item.alteration_causes.count or item.preservation_to_considers.count or item.appraisal_date or item.treatment_emergency or item.insurance_value or item.estimated_value %}
+ <h3>{% trans "Preservation" %}</h3>
+ <div class='row'>
+ {% field_flex_multiple "Integrity / interest" item.integrities %}
+ {% field_flex_multiple "Remarkability" item.remarkabilities %}
+ {% field_flex "Conservatory state" item.conservatory_state %}
+ {% field_flex_multiple "Alteration" item.alterations %}
+ {% field_flex_multiple "Alteration cause" item.alteration_causes %}
+ {% field_flex_multiple "Recommended treatments" item.preservation_to_considers %}
+ {% field_flex "Treatment emergency" item.treatment_emergency %}
+ {% field_flex "Estimated value" item.estimated_value|default_if_none:''|intcomma '' ' '|add:CURRENCY %}
+ {% field_flex "Insurance value" item.insurance_value|default_if_none:''|intcomma '' ' '|add:CURRENCY %}
+ {% field_flex "Appraisal date" item.appraisal_date %}
+ {% field_flex_full "Conservatory comment" item.conservatory_comment "<pre>" "</pre>" %}
+ </div>
+ {% endif %}
-{% if item.upstream_treatment %}
-<h3>{% trans "Upstream treatment" %}</h3>
-<table id='{{window_id}}-upstream' class="table table-striped">
- <tr>
- <th>&nbsp;</th>
- <th>{% trans "Year - index" %}</th>
- <th>{% trans "Label" %}</th>
- <th>{% trans "Type" %}</th>
- <th>{% trans "State" %}</th>
- <th>{% trans "Related finds (max. 15 displayed)" %}</th>
- <th>{% trans "Doer" %}</th>
- <th>{% trans "Container" %}</th>
- <th>{% trans "Start date" %}</th>
- <th>{% trans "End date" %}</th>
- </tr>
- {% for items, treatment in item.limited_upstream_treatments %}
- <tr>
- <td>
- <a class="display_details" href="#"
- onclick="load_window('{% url 'show-treatment' treatment.id %}/');">
- <i class="fa fa-info-circle" aria-hidden="true"></i>
- </a>
- </td>
- <td class='string'>{{ treatment.year }} - {{treatment.index}}</td>
- <td class='string'>{{ treatment.label|default_if_none:"-" }}</td>
- <td class='string'>{{ treatment.treatment_types_lbl }}</td>
- <td class='string'>{{ treatment.treatment_state|default_if_none:"-" }}</td>
- <td class='item-list'>{% for item in items %}<span>{{item}} {{ item|link_to_window}}</span>{% endfor %}</td>
- <td class='string'>{{ treatment.person|default_if_none:"-" }}</td>
- <td class='string'>{{ treatment.container|default_if_none:"-" }}</td>
- <td class='string'>{{ treatment.start_date|default_if_none:"-" }}</td>
- <td class='string'>{{ treatment.end_date|default_if_none:"-" }}</td>
- </tr>
- {% endfor %}
-</table>
-<p class='tool'><a class='badge' href="{% url 'get-upstreamtreatment' 'csv' %}?submited=1&amp;find_id={{item.pk}}" target="_blank" title='{% trans "Export as CSV"%}'>{% trans "CSV" %}</a> ({{ENCODING}})</p>
-{% endif %}
+ {% if item.datings.count or item.dating_comment %}
+ <h3>{% trans "Dating" %}</h3>
+ {% if item.datings.count %}
+ <table id='{{window_id}}-datings' class="table table-striped">
+ <tr>
+ <th>{% trans "Period" %}</th>
+ <th>{% trans "Start date" %}</th>
+ <th>{% trans "End date" %}</th>
+ <th>{% trans "Dating type" %}</th>
+ <th>{% trans "Quality" %}</th>
+ <th>{% trans "Precise dating" %}</th>
+ </tr>
+ {% for dating in item.datings.all %}
+ <tr>
+ <td>
+ {{dating.period}}
+ </td>
+ <td>
+ {{dating.start_date|default_if_none:"-"}}
+ </td>
+ <td>
+ {{dating.end_date|default_if_none:"-"}}
+ </td>
+ <td>
+ {{dating.dating_type|default_if_none:"-"}}
+ </td>
+ <td>
+ {{dating.quality|default_if_none:"-"}}
+ </td>
+ <td>
+ {{dating.precise_dating|default_if_none:"-"}}
+ </td>
+ </tr>
+ {% endfor %}
+ </table>
+ {% endif %}
+ {% field_flex_full "Comment on dating" item.dating_comment "<pre>" "</pre>" %}
+ {% endif %}
+ </div>
+ {% endif %}
+ {% if display_warehouse_treatments %}
+ <div class="tab-pane fade" id="{{window_id}}-warehouse"
+ role="tabpanel" aria-labelledby="{{window_id}}-warehouse-tab">
+ {% if item.container_ref %}
+ <h3>{% trans "Warehouse - reference container"%}</h3>
+ <div class='row'>
+ {% field_flex_detail "Container" item.container_ref %}
+ {% field_flex "Container ID" item.container_ref.cached_location %}
+ {% field_flex_detail "Responsible warehouse" item.container_ref.responsible %}
+ {% field_flex_detail "Location (warehouse)" item.container_ref.location %}
+ {% field_flex "Precise localisation" item.container_ref.cached_division %}
+ </div>
+ {% endif %}
+ {% if item.container and item.container_ref.pk != item.container.pk %}
+ <h3>{% trans "Warehouse - current container"%}</h3>
+ <div class='row'>
+ {% field_flex_detail "Container" item.container %}
+ {% field_flex "Container ID" item.container.cached_location %}
+ {% field_flex_detail "Responsible warehouse" item.container.responsible %}
+ {% field_flex_detail "Location (warehouse)" item.container.location %}
+ {% field_flex "Precise localisation" item.container.cached_division %}
+ </div>
+ {% endif %}
+ {% if item.upstream_treatment or item.downstream_treatment or item.treatments.count %}
+ {% if item.treatments.all %}
+ <h3>{% trans "Treatments"%}</h3>
+ <table id='{{window_id}}-treatments' class="table table-striped">
+ <tr>
+ <th>&nbsp;</th>
+ <th>{% trans "Year - index" %}</th>
+ <th>{% trans "Label" %}</th>
+ <th>{% trans "Type" %}</th>
+ <th>{% trans "State" %}</th>
+ <th>{% trans "Related finds (max. 15 displayed)" %}</th>
+ <th>{% trans "Doer" %}</th>
+ <th>{% trans "Container" %}</th>
+ <th>{% trans "Start date" %}</th>
+ <th>{% trans "End date" %}</th>
+ </tr>
+ {% for treatment in item.treatments.all %}
+ <tr>
+ <td>
+ <a class="display_details" href="#"
+ onclick="load_window('{% url 'show-treatment' treatment.id %}/');">
+ <i class="fa fa-info-circle" aria-hidden="true"></i>
+ </a>
+ </td>
+ <td class='string'>{{ treatment.year }} - {{treatment.index}}</td>
+ <td class='string'>{{ treatment.label|default_if_none:"-" }}</td>
+ <td class='string'>{{ treatment.treatment_types_lbl }}</td>
+ <td class='string'>{{ treatment.treatment_state|default_if_none:"-" }}</td>
+ <td class='item-list'>{% for it in treatment.limited_finds %}<span>{{it}} {{it|link_to_window}}</span>{% endfor %}</td>
+ <td class='string'>{{ treatment.person|default_if_none:"-" }}</td>
+ <td class='string'>{{ treatment.container|default_if_none:"-" }}</td>
+ <td class='string'>{{ treatment.start_date|default_if_none:"-" }}</td>
+ <td class='string'>{{ treatment.end_date|default_if_none:"-" }}</td>
+ </tr>
+ {% endfor %}
+ </table>
+ {% endif %}
-{% if item.downstream_treatment %}
-<h3>{% trans "Downstream treatment" %}</h3>
-<table id='{{window_id}}-downstream' class="table table-striped">
- <tr>
- <th>&nbsp;</th>
- <th>{% trans "Year - index" %}</th>
- <th>{% trans "Label" %}</th>
- <th>{% trans "Type" %}</th>
- <th>{% trans "State" %}</th>
- <th>{% trans "Related finds (max. 15 displayed)" %}</th>
- <th>{% trans "Doer" %}</th>
- <th>{% trans "Container" %}</th>
- <th>{% trans "Start date" %}</th>
- <th>{% trans "End date" %}</th>
- </tr>
- {% for items, treatment in item.limited_downstream_treatments %}
- <tr>
- <td>
- <a class="display_details" href="#"
- onclick="load_window('{% url 'show-treatment' treatment.id %}/');">
- <i class="fa fa-info-circle" aria-hidden="true"></i>
- </a>
- </td>
- <td class='string'>{{ treatment.year }} - {{treatment.index}}</td>
- <td class='string'>{{ treatment.label|default_if_none:"-" }}</td>
- <td class='string'>{{ treatment.treatment_types_lbl }}</td>
- <td class='string'>{{ treatment.treatment_state|default_if_none:"-" }}</td>
- <td class='item-list'>{% for item in items %}<span>{{item}} {{ item|link_to_window}}</span>{% endfor %}</td>
- <td class='string'>{{ treatment.person|default_if_none:"" }}</td>
- <td class='string'>{{ treatment.container|default_if_none:"-" }}</td>
- <td class='string'>{{ treatment.start_date|default_if_none:"" }}</td>
- <td class='string'>{{ treatment.end_date|default_if_none:"" }}</td>
- </tr>
- {% endfor %}
-</table>
+ {% if item.upstream_treatment %}
+ <h3>{% trans "Upstream treatment" %}</h3>
+ <table id='{{window_id}}-upstream' class="table table-striped">
+ <tr>
+ <th>&nbsp;</th>
+ <th>{% trans "Year - index" %}</th>
+ <th>{% trans "Label" %}</th>
+ <th>{% trans "Type" %}</th>
+ <th>{% trans "State" %}</th>
+ <th>{% trans "Related finds (max. 15 displayed)" %}</th>
+ <th>{% trans "Doer" %}</th>
+ <th>{% trans "Container" %}</th>
+ <th>{% trans "Start date" %}</th>
+ <th>{% trans "End date" %}</th>
+ </tr>
+ {% for items, treatment in item.limited_upstream_treatments %}
+ <tr>
+ <td>
+ <a class="display_details" href="#"
+ onclick="load_window('{% url 'show-treatment' treatment.id %}/');">
+ <i class="fa fa-info-circle" aria-hidden="true"></i>
+ </a>
+ </td>
+ <td class='string'>{{ treatment.year }} - {{treatment.index}}</td>
+ <td class='string'>{{ treatment.label|default_if_none:"-" }}</td>
+ <td class='string'>{{ treatment.treatment_types_lbl }}</td>
+ <td class='string'>{{ treatment.treatment_state|default_if_none:"-" }}</td>
+ <td class='item-list'>{% for it in items %}<span>{{it}} {{it|link_to_window}}</span>{% endfor %}</td>
+ <td class='string'>{{ treatment.person|default_if_none:"-" }}</td>
+ <td class='string'>{{ treatment.container|default_if_none:"-" }}</td>
+ <td class='string'>{{ treatment.start_date|default_if_none:"-" }}</td>
+ <td class='string'>{{ treatment.end_date|default_if_none:"-" }}</td>
+ </tr>
+ {% endfor %}
+ </table>
+ <p class='tool'><a class='badge' href="{% url 'get-upstreamtreatment' 'csv' %}?submited=1&amp;find_id={{item.pk}}" target="_blank" title='{% trans "Export as CSV"%}'>{% trans "CSV" %}</a> ({{ENCODING}})</p>
+ {% endif %}
-<p class='tool'><a class='badge' href="{% url 'get-downstreamtreatment' 'csv' %}?submited=1&amp;find_id={{item.pk}}" target="_blank">{% trans "CSV" %}</a> ({{ENCODING}})</p>
-{% endif %}
+ {% if item.downstream_treatment %}
+ <h3>{% trans "Downstream treatment" %}</h3>
+ <table id='{{window_id}}-downstream' class="table table-striped">
+ <tr>
+ <th>&nbsp;</th>
+ <th>{% trans "Year - index" %}</th>
+ <th>{% trans "Label" %}</th>
+ <th>{% trans "Type" %}</th>
+ <th>{% trans "State" %}</th>
+ <th>{% trans "Related finds (max. 15 displayed)" %}</th>
+ <th>{% trans "Doer" %}</th>
+ <th>{% trans "Container" %}</th>
+ <th>{% trans "Start date" %}</th>
+ <th>{% trans "End date" %}</th>
+ </tr>
+ {% for items, treatment in item.limited_downstream_treatments %}
+ <tr>
+ <td>
+ <a class="display_details" href="#"
+ onclick="load_window('{% url 'show-treatment' treatment.id %}/');">
+ <i class="fa fa-info-circle" aria-hidden="true"></i>
+ </a>
+ </td>
+ <td class='string'>{{ treatment.year }} - {{treatment.index}}</td>
+ <td class='string'>{{ treatment.label|default_if_none:"-" }}</td>
+ <td class='string'>{{ treatment.treatment_types_lbl }}</td>
+ <td class='string'>{{ treatment.treatment_state|default_if_none:"-" }}</td>
+ <td class='item-list'>{% for it in items %}<span>{{it}} {{ it|link_to_window}}</span>{% endfor %}</td>
+ <td class='string'>{{ treatment.person|default_if_none:"" }}</td>
+ <td class='string'>{{ treatment.container|default_if_none:"-" }}</td>
+ <td class='string'>{{ treatment.start_date|default_if_none:"" }}</td>
+ <td class='string'>{{ treatment.end_date|default_if_none:"" }}</td>
+ </tr>
+ {% endfor %}
+ </table>
-{% endif %}
+ <p class='tool'><a class='badge' href="{% url 'get-downstreamtreatment' 'csv' %}?submited=1&amp;find_id={{item.pk}}" target="_blank">{% trans "CSV" %}</a> ({{ENCODING}})</p>
+ {% endif %}
+ {% endif %}
+ </div>
+ {% endif %}
+ {% if display_documents %}
+ <div class="tab-pane fade" id="{{window_id}}-documents"
+ role="tabpanel" aria-labelledby="{{window_id}}-documents-tab">
+ {% trans "Associated documents" as finds_docs %}
+ {% dynamic_table_document finds_docs 'documents' 'finds' item.pk '' output %}
+ </div>
+ {% endif %}
+ {% if item.data %}
+ <div class="tab-pane fade" id="{{window_id}}-json"
+ role="tabpanel" aria-labelledby="{{window_id}}-json-tab">
+ {% include "ishtar/blocks/sheet_json.html" %}
+ </div>
+ {% endif %}
+</div>
-{% trans "Associated documents" as finds_docs %}
-{% if item.documents.count %}
-{% dynamic_table_document finds_docs 'documents' 'finds' item.pk '' output %}
-{% endif %}
+{% endwith %}{% endwith %}{% endwith %}{% endwith %}{% endwith %}{% endwith %}
{% endblock %}
+
diff --git a/archaeological_finds/templates/ishtar/sheet_findbasket.html b/archaeological_finds/templates/ishtar/sheet_findbasket.html
index 3c3ca1d3f..4a101d8f2 100644
--- a/archaeological_finds/templates/ishtar/sheet_findbasket.html
+++ b/archaeological_finds/templates/ishtar/sheet_findbasket.html
@@ -12,8 +12,9 @@
<div class='row'>
{% field_flex "Label" item.label %}
{% field_flex_detail "Owned by" item.user.person %}
- {% field_flex_multiple "Shared_with" item.shared_with %}
{% field_flex "Comment" item.comment %}
+ {% field_flex_multiple_full "Shared (read) with" item.shared_with %}
+ {% field_flex_multiple_full "Shared (read/edit) with" item.shared_write_with %}
</div>
<h3>{% trans "Content" %}</h3>
diff --git a/archaeological_finds/templates/ishtar/sheet_treatment.html b/archaeological_finds/templates/ishtar/sheet_treatment.html
index 1a3bb931f..78460d002 100644
--- a/archaeological_finds/templates/ishtar/sheet_treatment.html
+++ b/archaeological_finds/templates/ishtar/sheet_treatment.html
@@ -1,7 +1,7 @@
{% extends "ishtar/sheet.html" %}
{% load i18n window_field from_dict link_to_window window_tables window_ope_tables window_header humanize %}
-{% block head_title %}<strong>{% trans "Treatment" %}</strong> - {{ item.label|default:"" }}{% endblock %}
+{% block head_title %}<strong>{% trans "Treatment" %}</strong> - {{ item|default:"" }}{% endblock %}
{% block toolbar %}
{% window_nav item window_id 'show-treatment' 'treatment_modify' 'show-historized-treatment' 'revert-treatment' previous next 1 %}
@@ -9,73 +9,130 @@
{% block content %}
-<div class="row">
- <div class="offset-lg-4 col-lg-4 offset-md-3 col-md-6 offset-sm-1 col-sm-10 col-12">
- <div class="card">
- {% include "ishtar/blocks/window_image.html" %}
- <div class="card-body">
- <p class="card-text">
- <p class="window-refs">{{ item.label|default:"" }}</p>
- {% if item.other_reference %}
- <p class="window-refs">{{ item.other_reference }}</p>{% endif %}
- <p class="window-refs">{{ item.year }} - {{ item.index }}</p>
- {% if item.external_id %}
- <p class="window-refs">{{ item.external_id }}</p>{% endif %}
- {% if item.end_date %}
- <p class="window-refs">{% trans "Closed" context "Treatment" %} ({{item.end_date}})</p>
- {% else %}
- <p class="window-refs">{% trans "Active" context "Treatment" %}</p>
- {% endif %}
- </p>
+<ul class="nav nav-tabs" id="{{window_id}}-tabs" role="tablist">
+ <li class="nav-item">
+ <a class="nav-link active" id="{{window_id}}-treatment-tab"
+ data-toggle="tab" href="#{{window_id}}-treatment" role="tab"
+ aria-controls="{{window_id}}-treatment" aria-selected="true">
+ {% trans "Treatment" %}
+ </a>
+ </li>
+ <li class="nav-item">
+ <a class="nav-link" id="{{window_id}}-find-tab"
+ data-toggle="tab" href="#{{window_id}}-find" role="tab"
+ aria-controls="{{window_id}}-find" aria-selected="true">
+ {% trans "Finds" %}
+ </a>
+ </li>
+ {% if item.documents.count %}
+ <li class="nav-item">
+ <a class="nav-link" id="{{window_id}}-documents-tab"
+ data-toggle="tab" href="#{{window_id}}-documents" role="tab"
+ aria-controls="{{window_id}}-documents" aria-selected="true">
+ {% trans "Documents" %}
+ </a>
+ </li>
+ {% endif %}
+ {% if item.administrative_act.count %}
+ <li class="nav-item">
+ <a class="nav-link" id="{{window_id}}-admin-tab"
+ data-toggle="tab" href="#{{window_id}}-admin" role="tab"
+ aria-controls="{{window_id}}-admin" aria-selected="true">
+ {% trans "Administrative acts" %}
+ </a>
+ </li>
+ {% endif %}
+</ul>
+
+<div class="tab-content" id="{{window_id}}-tab-content">
+ <div class="tab-pane fade show active" id="{{window_id}}-treatment"
+ role="tabpanel" aria-labelledby="{{window_id}}-treatment-tab">
+ <div class="row">
+ <div class="offset-lg-4 col-lg-4 offset-md-3 col-md-6 offset-sm-1 col-sm-10 col-12">
+ <div class="card">
+ {% include "ishtar/blocks/window_image.html" %}
+ <div class="card-body">
+ <p class="card-text">
+ <p class="window-refs">{{ item.label|default:"" }}</p>
+ {% if item.other_reference %}
+ <p class="window-refs">{{ item.other_reference }}</p>{% endif %}
+ <p class="window-refs">{{ item.year }} - {{ item.index }}</p>
+ {% if item.external_id %}
+ <p class="window-refs">{{ item.external_id }}</p>{% endif %}
+ {% if item.end_date %}
+ <p class="window-refs">{% trans "Closed" context "Treatment" %} ({{item.end_date}})</p>
+ {% else %}
+ <p class="window-refs">{% trans "Active" context "Treatment" %}</p>
+ {% endif %}
+ </p>
+ </div>
+ </div>
</div>
</div>
+
+ <div class="row">
+ {% field_flex_multiple "Treatment type" item.treatment_types %}
+ {% field_flex "State" item.treatment_state %}
+ {% field_flex_detail "Associated request" item.file %}
+ {% field_flex "Location" item.location %}
+ {% field_flex "Container" item.container %}
+ {% field_flex "Responsible" item.person %}
+ {% field_flex "Organization" item.organization %}
+ {% field_flex "Start date" item.start_date %}
+ {% field_flex "Closing date" item.end_date %}
+ {% field_flex "Estimated cost" item.estimated_cost|intcomma '' " "|add:CURRENCY %}
+ {% field_flex "Quoted cost" item.quoted_cost|intcomma '' " "|add:CURRENCY %}
+ {% field_flex "Realized cost" item.realized_cost|intcomma '' " "|add:CURRENCY %}
+ {% field_flex "Insurance cost" item.insurance_cost|intcomma '' " "|add:CURRENCY %}
+ {% field_flex_full "Comment" item.comment "<pre>" "</pre>" %}
+ {% field_flex_full "Description" item.description "<pre>" "</pre>" %}
+ {% field_flex_full "Goal" item.goal "<pre>" "</pre>" %}
+
+ {% include "ishtar/blocks/sheet_json.html" %}
+ </div>
</div>
-</div>
-<div class="row">
- {% field_flex_multiple "Treatment type" item.treatment_types %}
- {% field_flex "State" item.treatment_state %}
- {% field_flex_detail "Associated request" item.file %}
- {% field_flex "Location" item.location %}
- {% field_flex "Container" item.container %}
- {% field_flex "Responsible" item.person %}
- {% field_flex "Organization" item.organization %}
- {% field_flex "Start date" item.start_date %}
- {% field_flex "Closing date" item.end_date %}
- {% field_flex "Estimated cost" item.estimated_cost|intcomma '' " "|add:CURRENCY %}
- {% field_flex "Quoted cost" item.quoted_cost|intcomma '' " "|add:CURRENCY %}
- {% field_flex "Realized cost" item.realized_cost|intcomma '' " "|add:CURRENCY %}
- {% field_flex "Insurance cost" item.insurance_cost|intcomma '' " "|add:CURRENCY %}
- {% field_flex_full "Comment" item.comment "<pre>" "</pre>" %}
- {% field_flex_full "Description" item.description "<pre>" "</pre>" %}
- {% field_flex_full "Goal" item.goal "<pre>" "</pre>" %}
-
- {% include "ishtar/blocks/sheet_json.html" %}
-</div>
+ <div class="tab-pane fade" id="{{window_id}}-find"
+ role="tabpanel" aria-labelledby="{{window_id}}-find-tab">
+ {% trans "Related finds" as finds %}
+ {% if item.finds.count %}
+ {% dynamic_table_document finds 'finds_for_treatment' 'treatments' item.pk 'TABLE_COLS_FOR_OPE' output %}
+ {% endif %}
-{% trans "Upstream finds" as finds %}
-{% if item.upstream.count %}
-{% dynamic_table_document finds 'finds_for_treatment' 'downstream_treatment' item.pk 'TABLE_COLS_FOR_OPE' output %}
-{% endif %}
+ {% trans "Upstream finds" as finds %}
+ {% if item.upstream.count %}
+ {% dynamic_table_document finds 'finds_for_treatment' 'downstream_treatment' item.pk 'TABLE_COLS_FOR_OPE' output %}
+ {% endif %}
-{% trans "Downstream finds" as finds %}
-{% if item.downstream.count %}
-{% dynamic_table_document finds 'finds_for_treatment' 'upstream_treatment' item.pk 'TABLE_COLS_FOR_OPE' output %}
-{% endif %}
+ {% trans "Downstream finds" as finds %}
+ {% if item.downstream.count %}
+ {% dynamic_table_document finds 'finds_for_treatment' 'upstream_treatment' item.pk 'TABLE_COLS_FOR_OPE' output %}
+ {% endif %}
-{% trans "Related operations" as related_operations %}
-{% dynamic_table_document related_operations 'operations' 'related_treatment' item.pk 'TABLE_COLS' output %}
+ {% comment %}
+ {% trans "Related operations" as related_operations %}
+ {% dynamic_table_document related_operations 'operations' 'related_treatment' item.pk 'TABLE_COLS' output %}
+ {% endcomment %}
-{% comment %}
-{% if item.source.count %}
-{% trans "Associated documents" as associated_docs %}
-{% dynamic_table_document associated_docs 'treatments_docs' 'treatment' item.pk '' output %}
-{% endif %}
-{% endcomment %}
-{% if item.administrative_act.count %}
-{% trans "Administrative acts" as admact_lbl %}
-{% table_administrativact admact_lbl item.administrative_act.all %}
-{% endif %}
+ </div>
+ {% if item.documents.count %}
+ <div class="tab-pane fade" id="{{window_id}}-documents"
+ role="tabpanel" aria-labelledby="{{window_id}}-documents-tab">
+ {% trans "Associated documents" as treat_docs %}
+ {% dynamic_table_document treat_docs 'documents' 'treatments' item.pk '' output %}
+ </div>
+ {% endif %}
+
+ {% if item.administrative_act.count %}
+ <div class="tab-pane fade" id="{{window_id}}-admin"
+ role="tabpanel" aria-labelledby="{{window_id}}-admin-tab">
+ {% trans "Administrative acts" as admact_lbl %}
+ {% table_administrativact admact_lbl item.administrative_act.all %}
+ </div>
+ {% endif %}
+
+
+</div>
{% endblock %}
diff --git a/archaeological_finds/templates/ishtar/sheet_treatmentfile.html b/archaeological_finds/templates/ishtar/sheet_treatmentfile.html
index 08398a6c2..072285262 100644
--- a/archaeological_finds/templates/ishtar/sheet_treatmentfile.html
+++ b/archaeological_finds/templates/ishtar/sheet_treatmentfile.html
@@ -34,6 +34,7 @@
<div class="row">
{% field_flex "Type" item.type %}
{% field_flex_detail "Responsible" item.in_charge %}
+ {% field_flex_detail "Associated basket" item.associated_basket %}
{% field_flex "Creation date" item.creation_date %}
{% field_flex "Reception date" item.reception_date %}
{% field_flex "Closing date" item.end_date %}
diff --git a/archaeological_finds/templates/ishtar/wizard/wizard_findbasket_deletion.html b/archaeological_finds/templates/ishtar/wizard/wizard_findbasket_deletion.html
new file mode 100644
index 000000000..ffd5f0398
--- /dev/null
+++ b/archaeological_finds/templates/ishtar/wizard/wizard_findbasket_deletion.html
@@ -0,0 +1,25 @@
+{% extends "ishtar/wizard/confirm_wizard.html" %}
+{% load i18n link_to_window %}
+
+{% block "warning_message" %}
+{% if current_object.treatment_files.count %}
+<div class="alert alert-{% if has_downstream %}danger{% else %}warning{% endif%}">
+ <i class="fa fa-exclamation-triangle" aria-hidden="true"></i>
+ {% trans "This basket is attached to treatments requests:" %}
+ <ul>{% for tf in current_object.treatment_files.all %}
+ <li>{{ tf }} {{tf|link_to_window}}</li>
+ {% endfor %}</ul>
+ {% trans "Are you sure you want to delete this basket?" %}
+</div>
+{% endif %}
+<div class="alert alert-info">
+ {% trans "Items inside the basket (these items will not be deleted):" %}
+</div>
+<ul>{% for item in current_object.items.all %}
+ <li>{{item}} {{item|link_to_window}}</li>
+{% endfor %}</ul>
+
+<div class="alert alert-info">
+ {% trans "Basket informations:" %}
+</div>
+{% endblock %}
diff --git a/archaeological_finds/templates/ishtar/wizard/wizard_simplefind.html b/archaeological_finds/templates/ishtar/wizard/wizard_simplefind.html
new file mode 100644
index 000000000..b1d77ba81
--- /dev/null
+++ b/archaeological_finds/templates/ishtar/wizard/wizard_simplefind.html
@@ -0,0 +1,13 @@
+{% extends "ishtar/wizard/default_wizard.html" %}
+{% load i18n %}
+{% block form_head %}
+<div class="alert alert-warning">
+ <i class="fa fa-exclamation-triangle"></i>
+ {% trans 'This find is related to many base finds. To edit field related to base finds edit the corresponding find between theses:' %}
+ <ul>{% for base_find in wizard.form.base_finds %}
+ {% with find=base_find.get_main_find %}<li>
+ {{find.short_label }}
+ <a href="{% url 'find_modify' find.pk %}"><i class="fa fa-pencil"></i></a>
+ </li>{% endwith %}{% endfor %}</ul>
+</div>
+{% endblock %}
diff --git a/archaeological_finds/templates/ishtar/wizard/wizard_treatement_deletion.html b/archaeological_finds/templates/ishtar/wizard/wizard_treatement_deletion.html
new file mode 100644
index 000000000..be46bfd05
--- /dev/null
+++ b/archaeological_finds/templates/ishtar/wizard/wizard_treatement_deletion.html
@@ -0,0 +1,27 @@
+{% extends "ishtar/wizard/confirm_wizard.html" %}
+{% load i18n link_to_window %}
+
+{% block "warning_message" %}
+{% with has_downstream=current_object.downstream.count %}
+<div class="alert alert-{% if has_downstream %}danger{% else %}warning{% endif%}">
+ <i class="fa fa-exclamation-triangle" aria-hidden="true"></i>
+ {% trans "Are you sure you want to delete this treatment?" %}
+{% if has_downstream %}
+ {% trans "The following finds will be deleted and restored to a previous version."%}
+ <ul>{% for item in current_object.downstream.all %}
+ <li>
+ {{item}} {{item|link_to_window}}
+ </li>
+ {% endfor %}</ul>
+ {% trans "All changes made to the associated finds since this treatment record will be lost!" %}
+{% endif %}
+</div>
+
+<div class="alert alert-info">
+ {% trans "Treatment informations:" %}
+</div>
+
+
+
+{% endwith %}
+{% endblock %}
diff --git a/archaeological_finds/tests.py b/archaeological_finds/tests.py
index a55e075b7..ae03b2ba4 100644
--- a/archaeological_finds/tests.py
+++ b/archaeological_finds/tests.py
@@ -215,8 +215,7 @@ class TreatmentWizardCreationTest(WizardTest, FindInit, TestCase):
'treatment_type': None,
'person': 1, # doer
'location': 1, # associated warehouse
- 'year': 2016,
- 'target_is_basket': False
+ 'year': 2016
},
'selecfind': {
'pk': 1,
@@ -243,6 +242,13 @@ class TreatmentWizardCreationTest(WizardTest, FindInit, TestCase):
trt_type = models.TreatmentType.objects.get(txt_idx='moving')
self.form_datas[0].set('basetreatment', 'treatment_type', trt_type.pk)
+ completed, created = models.TreatmentState.objects.get_or_create(
+ txt_idx='completed', defaults={"executed": True, "label": u"Done"}
+ )
+ completed.executed = True
+ completed.save()
+
+ self.form_datas[0].set('basetreatment', 'treatment_state', completed.pk)
self.find, base_find = self.get_default_find(force=True)
self.form_datas[0].form_datas['selecfind'][
@@ -258,9 +264,10 @@ class TreatmentWizardCreationTest(WizardTest, FindInit, TestCase):
treat = models.Treatment.objects.order_by('-pk').all()[0]
self.find = models.Find.objects.get(pk=self.find.pk)
self.assertEqual(models.Find.objects.filter(
- upstream_treatment=treat).count(), 1)
- self.assertEqual(self.find.downstream_treatment,
- treat)
+ treatments=treat).count(), 1)
+ # TODO: test treatment with new find creation
+ # self.assertEqual(self.find.downstream_treatment,
+ # treat)
class ImportFindTest(ImportTest, TestCase):
@@ -796,7 +803,8 @@ class FindQATest(FindInit, TestCase):
reverse('find-qa-bulk-update-confirm', args=[pks]),
{'qa_period': period, 'qa_description': extra_desc}
)
- self.assertRedirects(response, '/success/')
+ if response.status_code != 200:
+ self.assertRedirects(response, '/success/')
self.assertIn(period,
[dating.period.pk for dating in find_0.datings.all()])
self.assertIn(period,
@@ -807,7 +815,7 @@ class FindQATest(FindInit, TestCase):
base_desc_1 + u"\n" + extra_desc)
-class PackagingTest(FindInit, TestCase):
+class TreatmentTest(FindInit, TestCase):
fixtures = FIND_FIXTURES
model = models.Find
@@ -832,18 +840,33 @@ class PackagingTest(FindInit, TestCase):
self.basket.items.add(find)
self.other_basket.items.add(find)
- def testPackaging(self):
+ def test_packaging_with_new_find_creation(self):
treatment_type = models.TreatmentType.objects.get(txt_idx='packaging')
+ # make packaging a treatment with a new version of the find created
+ treatment_type.create_new_find = True
+ treatment_type.save()
+
treatment = models.Treatment()
items_nb = models.Find.objects.count()
first_find = self.finds[0]
- treatment.save(user=self.get_default_user(), items=self.basket)
+ completed, created = models.TreatmentState.objects.get_or_create(
+ txt_idx='completed', defaults={"executed": True, "label": u"Done"}
+ )
+ completed.executed = True
+ completed.save()
+
+ treatment.treatment_state = completed
+ treatment.save(
+ user=self.get_default_user(), items=self.basket,
+ treatment_type_list=[treatment_type],
+ )
+ treatment.treatment_types.add(treatment_type)
+
self.assertEqual(items_nb + self.basket.items.count(),
models.Find.objects.count(),
msg="Packaging doesn't generate enough new finds")
- treatment.treatment_types.add(treatment_type)
resulting_find = models.Find.objects.get(
upstream_treatment__upstream=first_find,
@@ -866,15 +889,69 @@ class PackagingTest(FindInit, TestCase):
item, self.finds,
msg="Other basket have not been upgraded after packaging")
- def test_delete(self):
- # manage treatment deletion
+ def test_simple_delete(self):
treatment_type = models.TreatmentType.objects.get(txt_idx='packaging')
+ treatment_type.create_new_find = False
+ treatment_type.save()
+
+ nb_find = models.Find.objects.count()
+
treatment = models.Treatment()
initial_find = self.finds[0]
- treatment.save(user=self.get_default_user(), items=self.basket)
+ completed, created = models.TreatmentState.objects.get_or_create(
+ txt_idx='completed', defaults={"executed": True, "label": u"Done"}
+ )
+ completed.executed = True
+ completed.save()
+
+ treatment.treatment_state = completed
+ treatment.save(
+ user=self.get_default_user(), items=self.basket,
+ treatment_type_list=[treatment_type],
+ )
treatment.treatment_types.add(treatment_type)
+ self.assertEqual(nb_find, models.Find.objects.count())
+
+ treatment.delete()
+ self.assertEqual(
+ models.Treatment.objects.filter(pk=treatment.pk).count(), 0)
+
+ q = models.Find.objects.filter(pk=initial_find.pk)
+ # initial find not deleted
+ self.assertEqual(q.count(), 1)
+ initial_find = q.all()[0]
+ self.assertEqual(initial_find.upstream_treatment, None)
+
+ def test_upstream_find_delete(self):
+ treatment_type = models.TreatmentType.objects.get(txt_idx='packaging')
+ # make packaging a treatment with a new version of the find created
+ treatment_type.create_new_find = True
+ treatment_type.save()
+
+ nb_find = models.Find.objects.count()
+
+ treatment = models.Treatment()
+
+ initial_find = self.finds[0]
+ completed, created = models.TreatmentState.objects.get_or_create(
+ txt_idx='completed', defaults={"executed": True, "label": u"Done"}
+ )
+ completed.executed = True
+ completed.save()
+
+ treatment.treatment_state = completed
+ treatment.save(
+ user=self.get_default_user(), items=self.basket,
+ treatment_type_list=[treatment_type],
+ )
+ treatment.treatment_types.add(treatment_type)
+
+ nb_b = self.basket.items.count()
+ self.assertEqual(
+ nb_find + nb_b, models.Find.objects.count())
+
resulting_find = models.Find.objects.get(
upstream_treatment__upstream=initial_find,
base_finds__pk=initial_find.base_finds.all()[0].pk
@@ -888,3 +965,42 @@ class PackagingTest(FindInit, TestCase):
self.assertEqual(q.count(), 1)
initial_find = q.all()[0]
self.assertEqual(initial_find.upstream_treatment, None)
+
+ def test_treatment_delete(self):
+ treatment_type = models.TreatmentType.objects.get(txt_idx='packaging')
+ treatment_type.create_new_find = True
+ treatment_type.save()
+
+ nb_find = models.Find.objects.count()
+
+ treatment = models.Treatment()
+
+ initial_find = self.finds[0]
+ completed, created = models.TreatmentState.objects.get_or_create(
+ txt_idx='completed', defaults={"executed": True, "label": u"Done"}
+ )
+ completed.executed = True
+ completed.save()
+
+ treatment.treatment_state = completed
+ treatment.save(
+ user=self.get_default_user(), items=self.basket,
+ treatment_type_list=[treatment_type],
+ )
+ treatment.treatment_types.add(treatment_type)
+
+ nb_b = self.basket.items.count()
+ self.assertEqual(
+ nb_find + nb_b, models.Find.objects.count())
+
+ treatment.delete()
+
+ self.assertEqual(nb_find, models.Find.objects.count())
+
+ self.assertEqual(
+ models.Treatment.objects.filter(pk=treatment.pk).count(), 0)
+ q = models.Find.objects.filter(pk=initial_find.pk)
+ # initial find not deleted
+ self.assertEqual(q.count(), 1)
+ initial_find = q.all()[0]
+ self.assertEqual(initial_find.upstream_treatment, None)
diff --git a/archaeological_finds/urls.py b/archaeological_finds/urls.py
index 588c8d520..fe7b2acd2 100644
--- a/archaeological_finds/urls.py
+++ b/archaeological_finds/urls.py
@@ -45,6 +45,8 @@ urlpatterns = [
views.find_modify, name='find_modify'),
url(r'get-findbasket/$', views.get_find_basket,
name='get-findbasket'),
+ url(r'get-findbasket-write/$', views.get_find_basket_for_write,
+ name='get-findbasket-write'),
url(r'find_basket_search/(?P<step>.+)?$',
check_rights(['view_find', 'view_own_find'])(
views.basket_search_wizard), name='find_basket_search'),
@@ -78,9 +80,36 @@ urlpatterns = [
check_rights(['view_find', 'view_own_find'])(
views.FindBasketListView.as_view()),
name='list_iteminbasket'),
- url(r'^find_basket_deletion/$',
+ url(r'^find_basket_deletion/(?P<step>.+)?$',
check_rights(['view_find', 'view_own_find'])(
- views.DeleteFindBasketView.as_view()), name='delete_findbasket'),
+ views.basket_delete_wizard),
+ name='find_basket_deletion'),
+ url(r'^findbasket-qa-duplicate/(?P<pks>[0-9-]+)?/$',
+ check_rights(['view_find', 'view_own_find'])(
+ views.QAFindbasketDuplicateFormView.as_view()),
+ name='findbasket-qa-duplicate'),
+
+ url(r'^findbasket-add-treatment/(?P<pk>[0-9-]+)/$',
+ check_rights(['change_find', 'change_own_find'])(
+ views.findbasket_treatment_add),
+ name='findbasket-add-treatment'),
+ url(r'^find-add-treatment/(?P<pk>[0-9-]+)/$',
+ check_rights(['change_find', 'change_own_find'])(
+ views.find_treatment_add),
+ name='find-add-treatment'),
+ url(r'^treatmentfile-add-treatment/(?P<pk>[0-9-]+)/$',
+ check_rights(['change_find', 'change_own_find'])(
+ views.treatmentfile_treatment_add),
+ name='treatmentfile-add-treatment'),
+ url(r'^treatment-add-adminact/(?P<pk>[0-9-]+)/$',
+ check_rights(['add_administrativeact'])(
+ views.treatment_adminact_add),
+ name='treatment-add-adminact'),
+
+ url(r'^treatmentfile-add-adminact/(?P<pk>[0-9-]+)/$',
+ check_rights(['add_administrativeact'])(
+ views.treatmentfile_adminact_add),
+ name='treatmentfile-add-adminact'),
url(r'^find-qa-bulk-update/(?P<pks>[0-9-]+)?/$',
check_rights(['change_find', 'change_own_find'])(
@@ -100,10 +129,16 @@ urlpatterns = [
views.QAFindTreatmentFormView.as_view()),
name='find-qa-packaging'),
-
url(r'^treatment_creation/(?P<step>.+)?$',
check_rights(['change_find', 'change_own_find'])(
views.treatment_creation_wizard), name='treatment_creation'),
+ url(r'^treatment_creation_n1/(?P<step>.+)?$',
+ check_rights(['change_find', 'change_own_find'])(
+ views.treatment_creation_n1_wizard), name='treatment_creation_n1'),
+ url(r'^treatment_creation_1n/(?P<step>.+)?$',
+ check_rights(['change_find', 'change_own_find'])(
+ views.treatment_creation_1n_wizard), name='treatment_creation_1n'),
+
url(r'^treatment_modification/(?P<step>.+)?$',
check_rights(['change_find', 'change_own_find'])(
views.treatment_modification_wizard),
@@ -248,6 +283,10 @@ urlpatterns = [
administrativeactfile_document,
name='treatmentfle-administrativeact-document',
kwargs={'treatment_file': True}),
+ url(r'autocomplete-findbasket/$',
+ check_rights(['change_find', 'change_own_find'])(
+ views.autocomplete_findbasket),
+ name='autocomplete-findbasket'),
]
urlpatterns += get_urls_for_model(models.Find, views, own=True,
diff --git a/archaeological_finds/views.py b/archaeological_finds/views.py
index c340639c5..fb5cdc11e 100644
--- a/archaeological_finds/views.py
+++ b/archaeological_finds/views.py
@@ -19,6 +19,7 @@
import json
+from django.core.exceptions import PermissionDenied
from django.core.urlresolvers import reverse
from django.db.models import Q
from django.http import HttpResponseRedirect, HttpResponse, Http404
@@ -27,18 +28,24 @@ from django.utils.translation import ugettext_lazy as _
from django.views.generic import TemplateView
from django.views.generic.edit import CreateView, FormView
+
+from ishtar_common.models import IshtarUser, get_current_profile
+from archaeological_operations.models import AdministrativeAct
+from archaeological_finds import models
+
+from ishtar_common.forms import FinalForm
from archaeological_context_records.forms \
import RecordFormSelection as RecordFormSelectionTable
from archaeological_operations.forms import FinalAdministrativeActDeleteForm
-from archaeological_operations.wizards import AdministrativeActDeletionWizard
-from forms import *
-from ishtar_common.forms import FinalForm
-from ishtar_common.models import IshtarUser, get_current_profile
+from archaeological_finds import forms
+
from ishtar_common.views import get_autocomplete_generic, IshtarMixin, \
LoginRequiredMixin, QAItemEditForm, QAItemForm
from ishtar_common.views_item import display_item, get_item, show_item, \
- revert_item, get_autocomplete_item
-from wizards import *
+ revert_item, get_autocomplete_item, get_autocomplete_query
+
+from archaeological_operations.wizards import AdministrativeActDeletionWizard
+from archaeological_finds import wizards
get_find = get_item(models.Find, 'get_find', 'find')
@@ -105,30 +112,66 @@ def autocomplete_treatmentfile(request):
return HttpResponse(data, content_type='text/plain')
-show_find = show_item(models.Find, 'find')
+def show_find_extra(request, find):
+ if not request.user or not request.user.ishtaruser:
+ return {}
+ user = request.user.ishtaruser
+ q = models.FindBasket.objects.filter(items__pk=find.pk).filter(
+ Q(user=user) | Q(shared_with__pk=user.pk) |
+ Q(shared_write_with__pk=user.pk)
+ )
+ return {"baskets": [(basket.pk, basket.full_label) for basket in q.all()]}
+
+
+show_find = show_item(models.Find, 'find', extra_dct=show_find_extra)
display_find = display_item(models.Find)
revert_find = revert_item(models.Find)
-show_findbasket = show_item(models.FindBasket, 'findbasket')
+show_findbasket = show_item(models.FindBasket, 'findbasket',
+ model_for_perms=models.Find)
display_findbasket = display_item(models.FindBasket,
show_url='show-find/basket-')
+
+def autocomplete_findbasket(request, current_right=None):
+ if not request.GET.get('term'):
+ return HttpResponse(content_type='text/plain')
+
+ query = get_autocomplete_query(request, ['label'])
+ limit = 20
+ query = query & models.FindBasket.get_write_query_owns(
+ request.user.ishtaruser)
+ items = models.FindBasket.objects.filter(query).order_by('label')[:limit]
+ data = json.dumps(
+ [{'id': item.pk,
+ 'value': u"{} - {}".format(item.label, item.user)[:60]}
+ for item in items]
+ )
+ return HttpResponse(data, content_type='text/plain')
+
get_find_basket = get_item(
models.FindBasket, 'get_findbasket', 'findbasket',
+ model_for_perms=models.Find
)
-basket_search_wizard = FindBasketSearch.as_view(
- [('selec-find_basket_search', FindBasketFormSelection)],
+get_find_basket_for_write = get_item(
+ models.FindBasket, 'get_findbasket', 'findbasket',
+ model_for_perms=models.Find, alt_query_own='get_write_query_owns'
+)
+
+basket_search_wizard = wizards.FindBasketSearch.as_view(
+ [('selec-find_basket_search', forms.FindBasketFormSelection)],
label=_(u"Basket search"),
url_name='find_basket_search',
)
-basket_modify_wizard = FindBasketEditWizard.as_view(
+basket_modify_wizard = wizards.FindBasketEditWizard.as_view(
[
- ('selec-find_basket_modification', FindBasketFormSelection),
- ('basket-find_basket_modification', FindBasketForm),
+ ('selec-find_basket_modification',
+ forms.FindBasketForWriteFormSelection),
+ ('basket-find_basket_modification', forms.FindBasketForm),
('final-find_basket_modification', FinalForm)
- ],
+ ],
label=_(u"Basket modify"),
url_name='find_basket_modification',
)
@@ -137,13 +180,26 @@ basket_modify_wizard = FindBasketEditWizard.as_view(
def find_basket_modify(request, pk):
basket_modify_wizard(request)
key = 'selec-find_basket_modification'
- FindBasketEditWizard.session_set_value(
+ wizards.FindBasketEditWizard.session_set_value(
request, key, 'pk', pk, reset=True)
return redirect(
reverse('find_basket_modification',
kwargs={'step': 'basket-find_basket_modification'}))
+findbasket_deletion_steps = [
+ ('selec-find_basket_deletion', forms.FindBasketForWriteFormSelection),
+ ('final-find_basket_deletion', FinalForm)
+]
+
+
+basket_delete_wizard = wizards.FindBasketDeletionWizard.as_view(
+ findbasket_deletion_steps,
+ label=_(u"Basket deletion"),
+ url_name='find_basket_deletion',
+)
+
+
def check_preservation_module(self):
return get_current_profile().preservation
@@ -158,9 +214,9 @@ def check_not_warehouse_module(self):
find_creation_steps = [
('selecrecord-find_creation', RecordFormSelectionTable),
- ('find-find_creation', FindForm),
- ('preservation-find_creation', PreservationForm),
- ('dating-find_creation', DatingFormSet),
+ ('find-find_creation', forms.FindForm),
+ ('preservation-find_creation', forms.PreservationForm),
+ ('dating-find_creation', forms.DatingFormSet),
('final-find_creation', FinalForm)
]
@@ -168,7 +224,7 @@ find_creation_condition_dict = {
'preservation-find_creation': check_preservation_module,
}
-find_creation_wizard = FindWizard.as_view(
+find_creation_wizard = wizards.FindWizard.as_view(
find_creation_steps,
label=_(u"New find"),
condition_dict=find_creation_condition_dict,
@@ -179,31 +235,47 @@ find_search_condition_dict = {
'generalwarehouse-find_search': check_warehouse_module,
}
-find_search_wizard = FindSearch.as_view([
- ('general-find_search', FindFormSelection),
- ('generalwarehouse-find_search', FindFormSelectionWarehouseModule)],
+find_search_wizard = wizards.FindSearch.as_view([
+ ('general-find_search', forms.FindFormSelection),
+ ('generalwarehouse-find_search', forms.FindFormSelectionWarehouseModule)],
label=_(u"Find search"),
url_name='find_search',
condition_dict=find_search_condition_dict
)
+
+def has_many_base_find(wizard):
+ find = wizard.get_current_object()
+ if not find:
+ return False
+ return find.base_finds.count() > 1
+
+
+def has_only_one_base_find(wizard):
+ return not has_many_base_find(wizard)
+
+
find_modification_condition_dict = {
'selec-find_modification': check_not_warehouse_module,
'selecw-find_modification': check_warehouse_module,
'preservation-find_modification': check_preservation_module,
+ 'selecrecord-find_modification': has_only_one_base_find,
+ 'find-find_modification': has_only_one_base_find,
+ 'simplefind-find_modification': has_many_base_find,
}
find_modification_steps = [
- ('selec-find_modification', FindFormSelection),
- ('selecw-find_modification', FindFormSelectionWarehouseModule),
- ('selecrecord-find_modification', RecordFormSelection),
- ('find-find_modification', FindForm),
- ('preservation-find_modification', PreservationForm),
- ('dating-find_modification', DatingFormSet),
+ ('selec-find_modification', forms.FindFormSelection),
+ ('selecw-find_modification', forms.FindFormSelectionWarehouseModule),
+ ('selecrecord-find_modification', forms.RecordFormSelection),
+ ('find-find_modification', forms.FindForm),
+ ('simplefind-find_modification', forms.SimpleFindForm),
+ ('preservation-find_modification', forms.PreservationForm),
+ ('dating-find_modification', forms.DatingFormSet),
('final-find_modification', FinalForm)
]
-find_modification_wizard = FindModificationWizard.as_view(
+find_modification_wizard = wizards.FindModificationWizard.as_view(
find_modification_steps,
condition_dict=find_modification_condition_dict,
label=_(u"Find modification"),
@@ -216,11 +288,18 @@ def find_modify(request, pk):
key = 'selec-find_modification'
if get_current_profile().warehouse:
key = 'selecw-find_modification'
- FindModificationWizard.session_set_value(
+ wizards.FindModificationWizard.session_set_value(
request, key, 'pk', pk, reset=True)
+ q = models.Find.objects.filter(pk=pk)
+ if not q.count():
+ raise Http404()
+ step = 'find-find_modification'
+ find = q.all()[0]
+ if find.base_finds.count() > 1:
+ step = 'simplefind-find_modification'
+
return redirect(
- reverse('find_modification',
- kwargs={'step': 'selecrecord-find_modification'}))
+ reverse('find_modification', kwargs={'step': step}))
find_deletion_condition_dict = {
'selec-find_deletion': check_not_warehouse_module,
@@ -228,11 +307,11 @@ find_deletion_condition_dict = {
}
find_deletion_steps = [
- ('selec-find_deletion', FindFormSelection),
- ('selecw-find_deletion', FindFormSelectionWarehouseModule),
- ('final-find_deletion', FindDeletionForm)]
+ ('selec-find_deletion', forms.FindFormSelection),
+ ('selecw-find_deletion', forms.FindFormSelectionWarehouseModule),
+ ('final-find_deletion', forms.FindDeletionForm)]
-find_deletion_wizard = FindDeletionWizard.as_view(
+find_deletion_wizard = wizards.FindDeletionWizard.as_view(
find_deletion_steps,
condition_dict=find_deletion_condition_dict,
label=_(u"Find deletion"),
@@ -247,7 +326,7 @@ autocomplete_integritytype = get_autocomplete_generic(models.IntegrityType)
class NewFindBasketView(IshtarMixin, LoginRequiredMixin, CreateView):
template_name = 'ishtar/form.html'
model = models.FindBasket
- form_class = NewFindBasketForm
+ form_class = forms.NewFindBasketForm
page_name = _(u"New basket")
def get_form_kwargs(self):
@@ -268,15 +347,15 @@ class OwnBasket(object):
def get_basket(self, user, pk):
try:
return models.FindBasket.objects.filter(
- Q(user=user) | Q(shared_with=user)
- ).get(pk=pk)
+ Q(user=user) | Q(shared_with=user) | Q(shared_write_with=user)
+ ).distinct().get(pk=pk)
except models.FindBasket.DoesNotExist:
raise PermissionDenied
class SelectBasketForManagement(IshtarMixin, LoginRequiredMixin, FormView):
template_name = 'ishtar/form.html'
- form_class = SelectFindBasketForm
+ form_class = forms.SelectFindBasketForm
page_name = _(u"Manage items in basket")
def get_form_kwargs(self):
@@ -309,9 +388,9 @@ class SelectItemsInBasket(OwnBasket, IshtarMixin, LoginRequiredMixin,
)
context['basket'] = self.basket
if get_current_profile().warehouse:
- context['form'] = MultipleFindFormSelectionWarehouseModule()
+ context['form'] = forms.MultipleFindFormSelectionWarehouseModule()
else:
- context['form'] = MultipleFindFormSelection()
+ context['form'] = forms.MultipleFindFormSelection()
context['add_url'] = reverse('add_iteminbasket')
context['list_url'] = reverse('list_iteminbasket',
kwargs={'pk': self.basket.pk})
@@ -323,7 +402,7 @@ class SelectItemsInBasket(OwnBasket, IshtarMixin, LoginRequiredMixin,
class FindBasketAddItemView(IshtarMixin, LoginRequiredMixin, FormView):
template_name = 'ishtar/simple_form.html'
- form_class = FindBasketAddItemForm
+ form_class = forms.FindBasketAddItemForm
def get_success_url(self, basket):
return reverse('list_iteminbasket', kwargs={'pk': basket.pk})
@@ -381,22 +460,6 @@ class FindBasketDeleteItemView(OwnBasket, IshtarMixin, LoginRequiredMixin,
basket.items.remove(find)
return HttpResponseRedirect(self.get_success_url(basket))
-
-class DeleteFindBasketView(IshtarMixin, LoginRequiredMixin, FormView):
- template_name = 'ishtar/form_delete.html'
- form_class = DeleteFindBasketForm
- success_url = '/'
- page_name = _(u"Delete basket")
-
- def get_form_kwargs(self):
- kwargs = super(DeleteFindBasketView, self).get_form_kwargs()
- kwargs['user'] = IshtarUser.objects.get(pk=self.request.user.pk)
- return kwargs
-
- def form_valid(self, form):
- form.save()
- return HttpResponseRedirect(self.get_success_url())
-
get_upstreamtreatment = get_item(
models.FindUpstreamTreatments, 'get_upstreamtreatment', 'uptreatment')
@@ -405,46 +468,53 @@ get_downstreamtreatment = get_item(
'downtreatment')
treatment_wizard_steps = [
- ('file-treatment_creation', TreatmentFormFileChoice),
- ('basetreatment-treatment_creation', BaseTreatmentForm),
- ('selecfind-treatment_creation', UpstreamFindFormSelection),
- ('selecbasket-treatment_creation', SelectFindBasketForm),
- # ('resultfind-treatment_creation', ResultFindForm),
- # ('resultfinds-treatment_creation', ResultFindFormSet),
+ ('selecfind-treatment_creation', forms.UpstreamFindFormSelection),
+ ('file-treatment_creation', forms.TreatmentFormFileChoice),
+ ('basetreatment-treatment_creation', forms.BaseTreatmentForm),
('final-treatment_creation', FinalForm)
]
-treatment_search_wizard = TreatmentSearch.as_view([
- ('general-treatment_search', TreatmentFormSelection)],
+treatment_search_wizard = wizards.TreatmentSearch.as_view([
+ ('general-treatment_search', forms.TreatmentFormSelection)],
label=_(u"Treatment search"),
url_name='treatment_search',)
-treatment_creation_wizard = TreatmentWizard.as_view(
+treatment_creation_wizard = wizards.TreatmentWizard.as_view(
treatment_wizard_steps,
- condition_dict={
- 'selecfind-treatment_creation':
- check_value('basetreatment-treatment_creation',
- 'target_is_basket', False),
- 'selecbasket-treatment_creation':
- check_value('basetreatment-treatment_creation',
- 'target_is_basket', True),
- # 'resultfinds-treatment_creation':
- # check_type_field('basetreatment-treatment_creation',
- # 'treatment_type', models.TreatmentType,
- # 'downstream_is_many'),
- # 'resultfind-treatment_creation':
- # check_type_field('basetreatment-treatment_creation',
- # 'treatment_type', models.TreatmentType,
- # 'upstream_is_many')
- },
label=_(u"New treatment"),
url_name='treatment_creation',)
-treatment_modification_wizard = TreatmentModificationWizard.as_view(
- [('selec-treatment_modification', TreatmentFormSelection),
- ('file-treatment_modification', TreatmentFormFileChoice),
- ('basetreatment-treatment_modification', TreatmentModifyForm),
+treatment_n1_wizard_steps = [
+ ('selecfind-treatment_creation_n1', forms.UpstreamFindFormSelection),
+ ('file-treatment_creation_n1', forms.TreatmentFormFileChoice),
+ ('basetreatment-treatment_creation_n1', forms.N1TreatmentForm),
+ ('resultingfind-treatment_creation_n1', forms.ResultingFindForm),
+ ('final-treatment_creation_n1', FinalForm)
+]
+
+treatment_creation_n1_wizard = wizards.TreatmentN1Wizard.as_view(
+ treatment_n1_wizard_steps,
+ label=_(u"New treatment"),
+ url_name='treatment_creation_n1',)
+
+treatment_1n_wizard_steps = [
+ ('selecfind-treatment_creation_1n', forms.SingleUpstreamFindFormSelection),
+ ('file-treatment_creation_1n', forms.TreatmentFormFileChoice),
+ ('basetreatment-treatment_creation_1n', forms.OneNTreatmentForm),
+ ('resultingfinds-treatment_creation_1n', forms.ResultingFindsForm),
+ ('final-treatment_creation_1n', FinalForm)
+]
+
+treatment_creation_1n_wizard = wizards.Treatment1NWizard.as_view(
+ treatment_1n_wizard_steps,
+ label=_(u"New treatment"),
+ url_name='treatment_creation_1n',)
+
+treatment_modification_wizard = wizards.TreatmentModificationWizard.as_view(
+ [('selec-treatment_modification', forms.TreatmentFormSelection),
+ ('file-treatment_modification', forms.TreatmentFormFileChoice),
+ ('basetreatment-treatment_modification', forms.TreatmentModifyForm),
('final-treatment_modification', FinalForm)],
label=_(u"Treatment modification"),
url_name='treatment_modification',
@@ -453,41 +523,116 @@ treatment_modification_wizard = TreatmentModificationWizard.as_view(
def treatment_modify(request, pk):
treatment_modification_wizard(request)
- TreatmentModificationWizard.session_set_value(
+ wizards.TreatmentModificationWizard.session_set_value(
request, 'selec-treatment_modification', 'pk', pk, reset=True)
return redirect(reverse(
'treatment_modification',
- kwargs={'step': 'basetreatment-treatment_modification'}))
-
-
-treatment_deletion_wizard = TreatmentDeletionWizard.as_view([
- ('selec-treatment_deletion', TreatmentFormSelection),
- ('final-treatment_deletion', TreatmentDeletionForm)],
+ kwargs={'step': 'file-treatment_modification'}))
+
+
+def treatment_add(request, pks, treatment_file=None):
+ treatment_creation_wizard(request)
+ wizards.TreatmentWizard.session_set_value(
+ request, 'selecfind-treatment_creation',
+ 'resulting_pk', pks, reset=True)
+ if treatment_file:
+ wizards.TreatmentWizard.session_set_value(
+ request, 'file-treatment_creation', 'file', treatment_file.pk)
+ else:
+ wizards.TreatmentWizard.session_set_value(
+ request, 'file-treatment_creation', 'file', '')
+ if treatment_file:
+ in_charge = treatment_file.in_charge
+ if not in_charge:
+ in_charge = request.user.ishtaruser.person
+ dct = {
+ "treatment_type": treatment_file.type.treatment_type.pk
+ if treatment_file.type and treatment_file.type.treatment_type
+ else "",
+ "year": treatment_file.year,
+ "person": in_charge.pk,
+ }
+ locas = list(
+ set([str(f.container.location.pk)
+ for f in treatment_file.associated_basket.items.all()
+ if f.container and f.container.location])
+ )
+ if len(locas) == 1: # one and only one location for all finds
+ dct["location"] = locas[0]
+ for k in dct:
+ wizards.TreatmentWizard.session_set_value(
+ request, 'basetreatment-treatment_creation', k, dct[k])
+ return redirect(reverse(
+ 'treatment_creation',
+ kwargs={'step': 'basetreatment-treatment_creation'}))
+
+
+def find_treatment_add(request, pk, current_right=None):
+ if not models.Find.objects.filter(pk=pk).count():
+ raise Http404()
+ return treatment_add(request, str(pk))
+
+
+def findbasket_treatment_add(request, pk, current_right=None):
+ try:
+ basket = models.FindBasket.objects.get(pk=pk)
+ except models.FindBasket.DoesNotExist:
+ raise Http404()
+ return treatment_add(
+ request, ",".join([str(f.pk) for f in basket.items.all()]))
+
+
+def container_treatment_add(request, pk, current_right=None):
+ try:
+ basket = models.FindBasket.objects.get(pk=pk)
+ except models.FindBasket.DoesNotExist:
+ raise Http404()
+ return treatment_add(request,
+ ",".join([str(f.pk) for f in basket.items.all()]))
+
+
+def treatmentfile_treatment_add(request, pk, current_right=None):
+ try:
+ tf = models.TreatmentFile.objects.get(pk=pk)
+ except models.TreatmentFile.DoesNotExist:
+ raise Http404()
+ if not tf.associated_basket:
+ raise Http404()
+ basket = tf.associated_basket
+ return treatment_add(
+ request, ",".join([str(f.pk) for f in basket.items.all()]),
+ treatment_file=tf
+ )
+
+
+treatment_deletion_wizard = wizards.TreatmentDeletionWizard.as_view([
+ ('selec-treatment_deletion', forms.TreatmentFormSelection),
+ ('final-treatment_deletion', forms.TreatmentDeletionForm)],
label=_(u"Treatment deletion"),
url_name='treatment_deletion',)
treatment_administrativeact_search_wizard = \
- SearchWizard.as_view([
+ wizards.SearchWizard.as_view([
('selec-treatment_admacttreatment_search',
- AdministrativeActTreatmentFormSelection)],
+ forms.AdministrativeActTreatmentFormSelection)],
label=_(u"Treatment: search administrative act"),
url_name='treatment_admacttreatment_search',)
treatment_administrativeact_wizard = \
- TreatmentAdministrativeActWizard.as_view([
- ('selec-treatment_admacttreatment', TreatmentFormSelection),
+ wizards.TreatmentAdministrativeActWizard.as_view([
+ ('selec-treatment_admacttreatment', forms.TreatmentFormSelection),
('administrativeact-treatment_admacttreatment',
- AdministrativeActTreatmentForm),
+ forms.AdministrativeActTreatmentForm),
('final-treatment_admacttreatment', FinalForm)],
label=_(u"Treatment: new administrative act"),
url_name='treatment_admacttreatment',)
treatment_administrativeact_modification_wizard = \
- TreatmentEditAdministrativeActWizard.as_view([
+ wizards.TreatmentEditAdministrativeActWizard.as_view([
('selec-treatment_admacttreatment_modification',
- AdministrativeActTreatmentFormSelection),
+ forms.AdministrativeActTreatmentFormSelection),
('administrativeact-treatment_admacttreatment_modification',
- AdministrativeActTreatmentModifForm),
+ forms.AdministrativeActTreatmentModifForm),
('final-treatment_admacttreatment_modification', FinalForm)],
label=_(u"Treatment: administrative act modification"),
url_name='treatment_admacttreatment_modification',)
@@ -495,7 +640,7 @@ treatment_administrativeact_modification_wizard = \
treatment_admacttreatment_deletion_wizard = \
AdministrativeActDeletionWizard.as_view([
('selec-treatment_admacttreatment_deletion',
- AdministrativeActTreatmentFormSelection),
+ forms.AdministrativeActTreatmentFormSelection),
('final-treatment_admacttreatment_deletion',
FinalAdministrativeActDeleteForm)],
label=_(u"Treatment: administrative act deletion"),
@@ -504,7 +649,7 @@ treatment_admacttreatment_deletion_wizard = \
def treatment_administrativeacttreatment_modify(request, pk):
treatment_administrativeact_modification_wizard(request)
- TreatmentEditAdministrativeActWizard.session_set_value(
+ wizards.TreatmentEditAdministrativeActWizard.session_set_value(
request,
'selec-treatment_admacttreatment_modification',
'pk', pk, reset=True)
@@ -517,69 +662,86 @@ def treatment_administrativeacttreatment_modify(request, pk):
}))
+def treatment_adminact_add(request, pk, current_right=None):
+ try:
+ models.Treatment.objects.get(pk=pk)
+ except models.Treatment.DoesNotExist:
+ raise Http404()
+ treatment_administrativeact_wizard(request)
+
+ wizards.TreatmentAdministrativeActWizard.session_set_value(
+ request, 'selec-treatment_admacttreatment', 'pk', pk, reset=True)
+ return redirect(reverse(
+ 'treatment_admacttreatment',
+ kwargs={'step': 'administrativeact-treatment_admacttreatment'}))
+
+
# treatment request
-treatmentfile_search_wizard = TreatmentFileSearch.as_view([
- ('general-treatmentfile_search', TreatmentFileFormSelection)],
+treatmentfile_search_wizard = wizards.TreatmentFileSearch.as_view([
+ ('general-treatmentfile_search', forms.TreatmentFileFormSelection)],
label=_(u"Treatment request search"),
url_name='treatmentfile_search',)
treatmentfile_wizard_steps = [
- ('treatmentfile-treatmentfile_creation', TreatmentFileForm),
+ ('treatmentfile-treatmentfile_creation', forms.TreatmentFileForm),
('final-treatmentfile_creation', FinalForm)]
-treatmentfile_creation_wizard = TreatmentFileWizard.as_view(
+treatmentfile_creation_wizard = wizards.TreatmentFileWizard.as_view(
treatmentfile_wizard_steps,
label=_(u"New treatment request"),
url_name='treatmentfile_creation',)
-treatmentfile_modification_wizard = TreatmentFileModificationWizard.as_view(
- [('selec-treatmentfile_modification', TreatmentFileFormSelection),
- ('treatmentfile-treatmentfile_modification', TreatmentFileModifyForm),
- ('final-treatmentfile_modification', FinalForm)],
- label=_(u"Treatment request modification"),
- url_name='treatmentfile_modification',
-)
+treatmentfile_modification_wizard = \
+ wizards.TreatmentFileModificationWizard.as_view(
+ [('selec-treatmentfile_modification', forms.TreatmentFileFormSelection),
+ ('treatmentfile-treatmentfile_modification',
+ forms.TreatmentFileModifyForm),
+ ('final-treatmentfile_modification', FinalForm)],
+ label=_(u"Treatment request modification"),
+ url_name='treatmentfile_modification',
+ )
def treatmentfile_modify(request, pk):
treatmentfile_modification_wizard(request)
- TreatmentFileModificationWizard.session_set_value(
+ wizards.TreatmentFileModificationWizard.session_set_value(
request, 'selec-treatmentfile_modification', 'pk', pk, reset=True)
return redirect(reverse(
'treatmentfile_modification',
kwargs={'step': 'treatmentfile-treatmentfile_modification'}))
-treatmentfile_deletion_wizard = TreatmentFileDeletionWizard.as_view([
- ('selec-treatmentfile_deletion', TreatmentFileFormSelection),
- ('final-treatmentfile_deletion', TreatmentFileDeletionForm)],
+treatmentfile_deletion_wizard = wizards.TreatmentFileDeletionWizard.as_view([
+ ('selec-treatmentfile_deletion', forms.TreatmentFileFormSelection),
+ ('final-treatmentfile_deletion', forms.TreatmentFileDeletionForm)],
label=_(u"Treatment request deletion"),
url_name='treatmentfile_deletion',)
treatmentfile_admacttreatmentfile_search_wizard = \
- SearchWizard.as_view([
+ wizards.SearchWizard.as_view([
('selec-treatmentfle_admacttreatmentfle_search',
- AdministrativeActTreatmentFileFormSelection)],
+ forms.AdministrativeActTreatmentFileFormSelection)],
label=_(u"Treatment request: search administrative act"),
url_name='treatmentfle_admacttreatmentfle_search',)
treatmentfile_admacttreatmentfile_wizard = \
- TreatmentFileAdministrativeActWizard.as_view([
- ('selec-treatmentfle_admacttreatmentfle', TreatmentFileFormSelection),
+ wizards.TreatmentFileAdministrativeActWizard.as_view([
+ ('selec-treatmentfle_admacttreatmentfle',
+ forms.TreatmentFileFormSelection),
('admact-treatmentfle_admacttreatmentfle',
- AdministrativeActTreatmentFileForm),
+ forms.AdministrativeActTreatmentFileForm),
('final-treatmentfle_admacttreatmentfle', FinalForm)],
label=_(u"Treatment request: new administrative act"),
url_name='treatmentfle_admacttreatmentfle',)
treatmentfile_admacttreatmentfile_modification_wizard = \
- TreatmentFileEditAdministrativeActWizard.as_view([
+ wizards.TreatmentFileEditAdministrativeActWizard.as_view([
('selec-treatmentfle_admacttreatmentfle_modification',
- AdministrativeActTreatmentFileFormSelection),
+ forms.AdministrativeActTreatmentFileFormSelection),
('admact-treatmentfle_admacttreatmentfle_modification',
- AdministrativeActTreatmentFileModifForm),
+ forms.AdministrativeActTreatmentFileModifForm),
('final-treatmentfle_admacttreatmentfle_modification', FinalForm)],
label=_(u"Treatment request: administrative act modification"),
url_name='treatmentfle_admacttreatmentfle_modification',)
@@ -587,7 +749,7 @@ treatmentfile_admacttreatmentfile_modification_wizard = \
treatmentfile_admacttreatmentfile_deletion_wizard = \
AdministrativeActDeletionWizard.as_view([
('selec-treatmentfle_admacttreatmentfle_deletion',
- AdministrativeActTreatmentFileFormSelection),
+ forms.AdministrativeActTreatmentFileFormSelection),
('final-treatmentfle_admacttreatmentfle_deletion',
FinalAdministrativeActDeleteForm)],
label=_(u"Treatment request: administrative act deletion"),
@@ -596,7 +758,7 @@ treatmentfile_admacttreatmentfile_deletion_wizard = \
def treatmentfile_administrativeacttreatmentfile_modify(request, pk):
treatmentfile_admacttreatmentfile_modification_wizard(request)
- TreatmentFileEditAdministrativeActWizard.session_set_value(
+ wizards.TreatmentFileEditAdministrativeActWizard.session_set_value(
request,
'selec-treatmentfle_admacttreatmentfle_modification',
'pk', pk, reset=True)
@@ -609,24 +771,42 @@ def treatmentfile_administrativeacttreatmentfile_modify(request, pk):
}))
+def treatmentfile_adminact_add(request, pk, current_right=None):
+ try:
+ models.TreatmentFile.objects.get(pk=pk)
+ except models.TreatmentFile.DoesNotExist:
+ raise Http404()
+ treatmentfile_admacttreatmentfile_wizard(request)
+
+ wizards.TreatmentFileAdministrativeActWizard.session_set_value(
+ request, 'selec-treatmentfle_admacttreatmentfle', 'pk', pk, reset=True)
+ return redirect(reverse(
+ 'treatmentfle_admacttreatmentfle',
+ kwargs={'step': 'admact-treatmentfle_admacttreatmentfle'}))
+
+
def reset_wizards(request):
for wizard_class, url_name in (
- (FindWizard, 'find_creation'),
- (FindModificationWizard, 'find_modification'),
- (FindDeletionWizard, 'find_deletion'),
- (TreatmentWizard, 'treatement_creation'),
- (TreatmentModificationWizard, 'treatment_modification'),
- (TreatmentDeletionWizard, 'treatment_deletion'),
- (TreatmentAdministrativeActWizard, 'treatment_admacttreatment'),
- (TreatmentEditAdministrativeActWizard,
+ (wizards.FindWizard, 'find_creation'),
+ (wizards.FindModificationWizard, 'find_modification'),
+ (wizards.FindDeletionWizard, 'find_deletion'),
+ (wizards.TreatmentWizard, 'treatement_creation'),
+ (wizards.TreatmentModificationWizard, 'treatment_modification'),
+ (wizards.TreatmentDeletionWizard, 'treatment_deletion'),
+ (wizards.TreatmentAdministrativeActWizard,
+ 'treatment_admacttreatment'),
+ (wizards.TreatmentEditAdministrativeActWizard,
'treatment_admacttreatment_modification'),
- (TreatmentDeletionWizard, 'treatment_admacttreatment_deletion'),
- (TreatmentFileWizard, 'treatmentfile_creation'),
- (TreatmentFileModificationWizard, 'treatmentfile_modification'),
- (TreatmentFileDeletionWizard, 'treatmentfile_deletion'),
- (TreatmentFileAdministrativeActWizard,
+ (wizards.TreatmentDeletionWizard,
+ 'treatment_admacttreatment_deletion'),
+ (wizards.TreatmentFileWizard,
+ 'treatmentfile_creation'),
+ (wizards.TreatmentFileModificationWizard,
+ 'treatmentfile_modification'),
+ (wizards.TreatmentFileDeletionWizard, 'treatmentfile_deletion'),
+ (wizards.TreatmentFileAdministrativeActWizard,
'treatmentfle_admacttreatmentfle'),
- (TreatmentFileEditAdministrativeActWizard,
+ (wizards.TreatmentFileEditAdministrativeActWizard,
'treatmentfle_admacttreatmentfle_modification'),
(AdministrativeActDeletionWizard,
'treatmentfle_admacttreatmentfle_deletion'),
@@ -636,13 +816,13 @@ def reset_wizards(request):
class QAFindForm(QAItemEditForm):
model = models.Find
- form_class = QAFindFormMulti
+ form_class = forms.QAFindFormMulti
class QAFindBasketFormView(QAItemForm):
template_name = 'ishtar/forms/qa_find_basket.html'
model = models.Find
- form_class = QAFindBasketForm
+ form_class = forms.QAFindBasketForm
page_name = _(u"Basket")
modal_size = "small"
@@ -662,7 +842,7 @@ class QAFindBasketFormView(QAItemForm):
class QAFindTreatmentFormView(QAItemForm):
template_name = 'ishtar/forms/qa_find_treatment.html'
model = models.Find
- form_class = QAFindTreatmentForm
+ form_class = forms.QAFindTreatmentForm
page_name = _(u"Packaging")
def get_quick_action(self):
@@ -677,3 +857,29 @@ class QAFindTreatmentFormView(QAItemForm):
def form_valid(self, form):
form.save(self.items, self.request.user)
return HttpResponseRedirect(reverse("success"))
+
+
+class QAFindbasketDuplicateFormView(QAItemForm):
+ template_name = 'ishtar/forms/qa_findbasket_duplicate.html'
+ model = models.FindBasket
+ page_name = _(u"Duplicate")
+ modal_size = "small"
+ form_class = forms.QAFindbasketDuplicateForm
+
+ def get_quick_action(self):
+ return models.FindBasket.QUICK_ACTIONS[0]
+
+ def get_form_kwargs(self):
+ kwargs = super(QAFindbasketDuplicateFormView, self).get_form_kwargs()
+ kwargs['user'] = self.request.user
+ return kwargs
+
+ def form_valid(self, form):
+ form.save()
+ return HttpResponseRedirect(reverse("success"))
+
+ def get_context_data(self, **kwargs):
+ data = super(QAFindbasketDuplicateFormView, self).get_context_data(
+ **kwargs)
+ data['action_name'] = _(u"Duplicate")
+ return data
diff --git a/archaeological_finds/wizards.py b/archaeological_finds/wizards.py
index 0e0fe80e1..7f4e1b498 100644
--- a/archaeological_finds/wizards.py
+++ b/archaeological_finds/wizards.py
@@ -17,8 +17,9 @@
# See the file COPYING for details.
+from django.contrib import messages
from django.core.exceptions import ObjectDoesNotExist, PermissionDenied
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import ugettext_lazy as _, pgettext
from ishtar_common.forms import reverse_lazy
from ishtar_common.wizards import Wizard, DeletionWizard, SearchWizard
@@ -55,11 +56,21 @@ class FindWizard(Wizard):
if base_finds:
return base_finds[0].context_record
+ def get_current_basefinds(self):
+ find = self.get_current_object()
+ if not find:
+ return []
+ return find.base_finds.all()
+
def get_form_kwargs(self, step=None):
kwargs = super(FindWizard, self).get_form_kwargs(step)
- if step not in ('find-find_creation', 'find-find_modification'):
+ if step not in (
+ 'find-find_creation', 'find-find_modification',
+ 'simplefind-find_modification',):
return kwargs
kwargs['context_record'] = self.get_current_contextrecord()
+ if step == 'simplefind-find_modification':
+ kwargs['base_finds'] = self.get_current_basefinds()
return kwargs
def get_context_data(self, form, **kwargs):
@@ -75,8 +86,8 @@ class FindWizard(Wizard):
(_(u"Context record"), unicode(current_cr)))
return context
- def get_extra_model(self, dct, form_list):
- dct = super(FindWizard, self).get_extra_model(dct, form_list)
+ def get_extra_model(self, dct, m2m, form_list):
+ dct = super(FindWizard, self).get_extra_model(dct, m2m, form_list)
dct['order'] = 1
if 'pk' in dct and type(dct['pk']) == ContextRecord:
dct['base_finds__context_record'] = dct.pop('pk')
@@ -90,6 +101,10 @@ class FindModificationWizard(FindWizard):
'selec-find_modification': ['pk'],
'selecw-find_modification': ['pk'],
}
+ wizard_templates = {
+ 'simplefind-find_modification':
+ 'ishtar/wizard/wizard_simplefind.html',
+ }
class FindDeletionWizard(DeletionWizard):
@@ -106,11 +121,59 @@ class TreatmentSearch(SearchWizard):
model = models.Treatment
-class TreatmentWizard(Wizard):
+class TreatmentBase(Wizard):
model = models.Treatment
wizard_done_window = reverse_lazy('show-treatment')
+ base_url = ""
+ saved_args = {"treatment_type_list": []}
+
+ def get_current_finds(self):
+ step = self.steps.current
+ if not step:
+ return
+ find_form_key = 'selecfind-' + self.base_url
+ find_ids = self.session_get_value(find_form_key, "resulting_pk")
+ try:
+ return [
+ models.Find.objects.get(pk=int(find_id.strip()))
+ for find_id in find_ids.split(u',')
+ ]
+ except(TypeError, ValueError, AttributeError, ObjectDoesNotExist):
+ pass
+
+ def get_form_initial(self, step, data=None):
+ initial = super(TreatmentBase, self).get_form_initial(step)
+ base_step = 'basetreatment-' + self.base_url
+ if step != base_step:
+ return initial
+ finds = self.get_current_finds()
+ if not finds:
+ return initial
+ locations = [find.container.location.pk for find in finds
+ if find.container]
+ # no location or multiple locations
+ if not locations or len(set(locations)) != 1:
+ return initial
+ if not initial:
+ initial = {}
+ initial['location'] = locations[0]
+ return initial
+
+ def get_extra_model(self, dct, m2m, form_list):
+ dct = super(TreatmentBase, self).get_extra_model(dct, m2m, form_list)
+ dct['treatment_type_list'] = []
+ for k, v in m2m:
+ if k == 'treatment_type':
+ if type(v) not in (list, tuple):
+ v = [v]
+ dct['treatment_type_list'] += v
+ return dct
+
+
+class TreatmentWizard(TreatmentBase):
basket_step = 'basetreatment-treatment_creation'
- saved_args = {"items": []}
+ saved_args = {"items": [], "treatment_type_list": []}
+ base_url = 'treatment_creation'
def get_form_kwargs(self, step, **kwargs):
kwargs = super(TreatmentWizard, self).get_form_kwargs(step, **kwargs)
@@ -119,25 +182,31 @@ class TreatmentWizard(Wizard):
kwargs['user'] = self.request.user
return kwargs
- def get_extra_model(self, dct, form_list):
+ def get_extra_model(self, dct, m2m, form_list):
"""
Get items concerned by the treatment
"""
- dct = super(TreatmentWizard, self).get_extra_model(dct, form_list)
+ dct = super(TreatmentWizard, self).get_extra_model(dct, m2m, form_list)
if 'resulting_pk' in dct:
- try:
- find = models.Find.objects.get(pk=dct.pop('resulting_pk'))
- if 'own' in self.current_right \
- and not find.is_own(dct['history_modifier']):
+ dct['items'] = []
+ pks = dct.pop('resulting_pk').split(u',')
+ for pk in pks:
+ try:
+ find = models.Find.objects.get(pk=pk)
+ dct['items'].append(find)
+ except models.Find.DoesNotExist:
raise PermissionDenied
- dct['items'] = [find]
- except models.Find.DoesNotExist:
- raise PermissionDenied
if 'basket' in dct:
basket = dct.pop('basket')
if basket.user.pk != dct['history_modifier'].pk:
raise PermissionDenied
dct['items'] = list(basket.items.all())
+
+ if 'items' in dct:
+ for find in dct['items']:
+ if 'own' in self.current_right \
+ and not find.is_own(dct['history_modifier']):
+ raise PermissionDenied
return dct
@@ -145,7 +214,196 @@ class TreatmentModificationWizard(TreatmentWizard):
modification = True
+class TreatmentN1Wizard(TreatmentBase):
+ saved_args = {"upstream_items": [], "resulting_find": None,
+ "treatment_type_list": []}
+ base_url = 'treatment_creation_n1'
+
+ def _update_simple_initial_from_finds(self, initial, find, k):
+ r_k = "resulting_" + k
+ if getattr(find, k) and r_k in initial:
+ # pop k when value is inconsistent between finds
+ if initial[r_k] and initial[r_k] != getattr(find, k).pk:
+ initial.pop(r_k)
+ else:
+ initial[r_k] = getattr(find, k).pk
+ return initial
+
+ def _update_multi_initial_from_finds(self, initial, find, k):
+ r_k = "resulting_" + k
+ for value in getattr(find, k + 's').all():
+ if value.pk not in initial[r_k]:
+ initial[r_k].append(value.pk)
+ return initial
+
+ def _update_num_initial_from_finds(self, initial, find, k):
+ r_k = "resulting_" + k
+ if not getattr(find, k):
+ return initial
+ if initial[r_k] is None:
+ initial[r_k] = 0
+ initial[r_k] += getattr(find, k)
+ return initial
+
+ def _update_char_initial_from_finds(self, initial, find, k, sep=' ; '):
+ r_k = "resulting_" + k
+ value = getattr(find, k)
+ if not value:
+ return initial
+ value = value.strip()
+ if not initial[r_k]:
+ initial[r_k] = value
+ else:
+ # new value is entirely inside the current value
+ if value == initial[r_k] or (value + sep) in initial[r_k] or \
+ (sep + value) in initial[r_k]:
+ return initial
+ initial[r_k] += sep + value
+ return initial
+
+ def get_form_initial(self, step, data=None):
+ initial = super(TreatmentN1Wizard, self).get_form_initial(step)
+ if step != 'resultingfind-treatment_creation_n1':
+ return initial
+ finds = self.get_current_finds()
+ if not finds:
+ return initial
+ simple_key = ['material_type_quality']
+ multi_key = ['material_type', 'object_type', 'communicabilitie']
+ numeric_key = ['find_number', 'min_number_of_individuals']
+ desc_key = ['decoration', 'inscription', 'comment', 'dating_comment']
+ char_key = ['manufacturing_place']
+
+ for k in simple_key + numeric_key + desc_key + char_key:
+ initial["resulting_" + k] = None
+ for k in multi_key:
+ initial["resulting_" + k] = []
+
+ for find in finds:
+ for k in simple_key:
+ initial = self._update_simple_initial_from_finds(
+ initial, find, k)
+ for k in multi_key:
+ initial = self._update_multi_initial_from_finds(
+ initial, find, k)
+ for k in numeric_key:
+ initial = self._update_num_initial_from_finds(
+ initial, find, k)
+ for k in char_key:
+ initial = self._update_char_initial_from_finds(
+ initial, find, k, sep=' ; ')
+ for k in desc_key:
+ initial = self._update_char_initial_from_finds(
+ initial, find, k, sep='\n')
+
+ for k in initial.keys():
+ if initial[k] is None:
+ initial.pop(k)
+ return initial
+
+ def get_extra_model(self, dct, m2m, form_list):
+ """
+ Get items concerned by the treatment
+ """
+ dct = super(TreatmentN1Wizard, self).get_extra_model(
+ dct, m2m, form_list)
+ if 'resulting_pk' not in dct:
+ return dct
+
+ dct['upstream_items'] = []
+ # manage upstream items
+ pks = dct.pop('resulting_pk')
+ if hasattr(pks, 'split'):
+ pks = pks.split(u',') # unicode or string
+ for pk in pks:
+ try:
+ find = models.Find.objects.get(pk=pk)
+ dct['upstream_items'].append(find)
+ except models.Find.DoesNotExist:
+ raise PermissionDenied
+
+ for find in dct['upstream_items']:
+ if 'own' in self.current_right \
+ and not find.is_own(dct['history_modifier']):
+ raise PermissionDenied
+
+ # extract data of the new find
+ dct['resulting_find'] = {}
+ for k in dct.keys():
+ if k.startswith('resulting_') and k != "resulting_find":
+ dct['resulting_find'][
+ k[len('resulting_'):]
+ ] = dct.pop(k)
+ return dct
+
+
+class Treatment1NWizard(TreatmentBase):
+ saved_args = {"upstream_item": None, "resulting_finds": None,
+ "treatment_type_list": []}
+ base_url = 'treatment_creation_1n'
+
+ def get_form_kwargs(self, step, **kwargs):
+ kwargs = super(Treatment1NWizard, self).get_form_kwargs(step, **kwargs)
+ if step != 'resultingfind-treatment_creation_1n':
+ return kwargs
+ kwargs['user'] = self.request.user
+ return kwargs
+
+ def get_form_initial(self, step, data=None):
+ initial = super(Treatment1NWizard, self).get_form_initial(step)
+ if step != 'resultingfinds-treatment_creation_1n':
+ return initial
+ finds = self.get_current_finds()
+ if not finds:
+ return initial
+ lbl = finds[0].label
+ initial['resultings_basket_name'] = unicode(_(u"Basket")) + u" - " + lbl
+ initial['resultings_label'] = lbl + u"-"
+ return initial
+
+ def get_extra_model(self, dct, m2m, form_list):
+ """
+ Get items concerned by the treatment
+ """
+ dct = super(Treatment1NWizard, self).get_extra_model(
+ dct, m2m, form_list)
+ if 'resulting_pk' not in dct:
+ return dct
+
+ # manage upstream item
+ pk = dct.pop('resulting_pk')
+ try:
+ find = models.Find.objects.get(pk=pk)
+ dct['upstream_item'] = find
+ except models.Find.DoesNotExist:
+ raise PermissionDenied
+
+ if 'own' in self.current_right \
+ and not find.is_own(dct['history_modifier']):
+ raise PermissionDenied
+
+ # extract attributes to generate the new find
+ dct['resulting_finds'] = {}
+ for k in dct.keys():
+ if k.startswith('resultings_'):
+ dct['resulting_finds'][
+ k[len('resultings_'):]
+ ] = dct.pop(k)
+ messages.add_message(
+ self.request, messages.INFO,
+ unicode(_(u"The new basket: \"{}\" have been created with the "
+ u"resulting items. This search have been pinned.")
+ ).format(dct["resulting_finds"]["basket_name"])
+ )
+ self.request.session["pin-search-find"] = u'{}="{}"'.format(
+ unicode(pgettext("key for text search", u"basket")),
+ dct["resulting_finds"]["basket_name"])
+ self.request.session['find'] = ''
+ return dct
+
+
class TreatmentDeletionWizard(DeletionWizard):
+ wizard_confirm = 'ishtar/wizard/wizard_treatement_deletion.html'
model = models.Treatment
fields = ['label', 'other_reference', 'year', 'index',
'treatment_types', 'location', 'person', 'organization',
@@ -243,3 +501,9 @@ class FindBasketWizard(Wizard):
class FindBasketEditWizard(FindBasketWizard):
edit = True
+ alt_is_own_method = 'get_write_query_owns'
+
+
+class FindBasketDeletionWizard(DeletionWizard):
+ wizard_confirm = 'ishtar/wizard/wizard_findbasket_deletion.html'
+ model = models.FindBasket
diff --git a/archaeological_operations/forms.py b/archaeological_operations/forms.py
index 4942d9f05..3103990c9 100644
--- a/archaeological_operations/forms.py
+++ b/archaeological_operations/forms.py
@@ -479,11 +479,12 @@ class OperationSelect(TableSelect):
'archaeological-operations', 'operation'))
year = forms.IntegerField(label=_("Year"))
operation_code = forms.IntegerField(label=_(u"Numeric reference"))
- if settings.COUNTRY == 'fr':
- code_patriarche = forms.CharField(
+ code_patriarche = forms.CharField(
max_length=500,
widget=OAWidget,
label="Code PATRIARCHE")
+ drassm_code = forms.CharField(
+ label=_(u"DRASSM code"), required=False, max_length=100)
towns = get_town_field()
parcel = forms.CharField(label=_(u"Parcel"))
if settings.ISHTAR_DPTS:
@@ -577,13 +578,16 @@ class OperationSelect(TableSelect):
def __init__(self, *args, **kwargs):
super(OperationSelect, self).__init__(*args, **kwargs)
- if not get_current_profile().warehouse:
+ profile = get_current_profile()
+ if not profile.warehouse:
self.fields.pop('documentation_deadline_before')
self.fields.pop('documentation_deadline_after')
self.fields.pop('documentation_received')
self.fields.pop('finds_deadline_before')
self.fields.pop('finds_deadline_after')
self.fields.pop('finds_received')
+ if not profile.underwater:
+ self.fields.pop('drassm_code')
if settings.ISHTAR_DPTS:
k = 'towns__numero_insee__startswith'
self.fields[k].choices = [
@@ -749,11 +753,12 @@ class OperationFormGeneral(CustomForm, ManageOldType):
'report_processing': models.ReportState
}
pk = forms.IntegerField(required=False, widget=forms.HiddenInput)
- if settings.COUNTRY == 'fr':
- code_patriarche = forms.CharField(label=u"Code PATRIARCHE",
- max_length=500,
- widget=OAWidget,
- required=False)
+ code_patriarche = forms.CharField(label=u"Code PATRIARCHE",
+ max_length=500,
+ widget=OAWidget,
+ required=False)
+ drassm_code = forms.CharField(
+ label=_(u"DRASSM code"), required=False, max_length=100)
operation_type = forms.ChoiceField(label=_(u"Operation type"),
choices=[])
common_name = forms.CharField(label=_(u"Generic name"), required=False,
@@ -873,9 +878,11 @@ class OperationFormGeneral(CustomForm, ManageOldType):
if not profile.files:
for key in self.FILE_FIELDS:
self.remove_field(key)
- if not profile.warehouse:
- for key in self.WAREHOUSE_FIELDS:
- self.remove_field(key)
+ if not profile.warehouse:
+ for key in self.WAREHOUSE_FIELDS:
+ self.remove_field(key)
+ if not profile.underwater:
+ self.fields.pop('drassm_code')
def clean(self):
cleaned_data = self.cleaned_data
@@ -1262,6 +1269,11 @@ class SiteSelect(TableSelect):
locality_cadastral = forms.CharField(
label=_(u"Cadastral locality"), max_length=200,
required=False)
+
+ affmar_number = forms.CharField(
+ label=_(u"AffMar number"), required=False, max_length=100)
+ drassm_number = forms.CharField(
+ label=_(u"DRASSM number"), required=False, max_length=100)
shipwreck_name = forms.CharField(
label=_(u"Shipwreck name"), max_length=200,
required=False)
@@ -1288,6 +1300,8 @@ class SiteSelect(TableSelect):
self.fields.pop('shipwreck_code')
self.fields.pop('sinking_date')
self.fields.pop('discovery_area')
+ self.fields.pop('affmar_number')
+ self.fields.pop('drassm_number')
class SiteFormSelection(IshtarForm):
@@ -1378,6 +1392,10 @@ class SiteUnderwaterForm(CustomForm, ManageOldType):
form_admin_name = _(u"Archaeological site - 030 - Underwater")
form_slug = u"archaeological_site-030-underwater"
+ affmar_number = forms.CharField(
+ label=_(u"AffMar number"), required=False, max_length=100)
+ drassm_number = forms.CharField(
+ label=_(u"DRASSM number"), required=False, max_length=100)
shipwreck_name = forms.CharField(
label=_(u"Shipwreck name"), required=False)
shipwreck_code = forms.CharField(
diff --git a/archaeological_operations/ishtar_menu.py b/archaeological_operations/ishtar_menu.py
index 4baf14295..bfc027573 100644
--- a/archaeological_operations/ishtar_menu.py
+++ b/archaeological_operations/ishtar_menu.py
@@ -82,11 +82,6 @@ MENU_SECTIONS = [
_(u"Deletion"),
model=models.AdministrativeAct,
access_controls=['change_administrativeact']),
- MenuItem(
- 'operation_administrativeact_document',
- _(u"Documents"),
- model=models.AdministrativeAct,
- access_controls=['change_administrativeact']),
],),
]),
),
diff --git a/archaeological_operations/locale/django.pot b/archaeological_operations/locale/django.pot
index 83373847b..2c2124db3 100644
--- a/archaeological_operations/locale/django.pot
+++ b/archaeological_operations/locale/django.pot
@@ -9,21 +9,21 @@
msgid ""
msgstr ""
-#: admin.py:91 models.py:244 models.py:836
+#: admin.py:91 models.py:263 models.py:880
msgid "Point"
msgstr ""
-#: admin.py:93 models.py:245 models.py:837
+#: admin.py:93 models.py:264 models.py:881
msgid "Multi polygon"
msgstr ""
-#: forms.py:64 forms.py:1061 forms.py:1077 forms.py:1083 models.py:1931
+#: forms.py:64 forms.py:1068 forms.py:1084 forms.py:1090 models.py:2014
#: templates/ishtar/blocks/window_tables/parcels.html:9
-#: templates/ishtar/sheet_operation.html:250
+#: templates/ishtar/sheet_operation.html:257
msgid "Parcels"
msgstr ""
-#: forms.py:67 forms.py:200 forms.py:1036 models.py:1915
+#: forms.py:67 forms.py:200 forms.py:1043 models.py:1998
#: templates/ishtar/blocks/window_tables/parcels.html:6
#: templates/ishtar/dashboards/dashboard_operation.html:432
#: templates/ishtar/dashboards/dashboard_operation.html:446
@@ -32,22 +32,22 @@ msgstr ""
msgid "Town"
msgstr ""
-#: forms.py:69 forms.py:480 forms.py:763 forms.py:1400 models.py:734
-#: models.py:1489 models.py:1696 models.py:1913
+#: forms.py:69 forms.py:480 forms.py:768 forms.py:1426 models.py:774
+#: models.py:1562 models.py:1769 models.py:1996
#: templates/ishtar/blocks/window_tables/parcels.html:7
msgid "Year"
msgstr ""
-#: forms.py:72 models.py:1916
+#: forms.py:72 models.py:1999
#: templates/ishtar/blocks/window_tables/parcels.html:8
msgid "Section"
msgstr ""
-#: forms.py:75 models.py:1918
+#: forms.py:75 models.py:2001
msgid "Parcel number"
msgstr ""
-#: forms.py:77 models.py:1920 models.py:1939 models.py:2000
+#: forms.py:77 models.py:2003 models.py:2022 models.py:2083
msgid "Public domain"
msgstr ""
@@ -83,8 +83,8 @@ msgstr ""
msgid "Relation type"
msgstr ""
-#: forms.py:373 forms.py:1254 ishtar_menu.py:32 models.py:842 models.py:1394
-#: models.py:1405 models.py:1491 models.py:1678 models.py:1912
+#: forms.py:373 forms.py:1261 ishtar_menu.py:32 models.py:886 models.py:1466
+#: models.py:1477 models.py:1564 models.py:1751 models.py:1995
#: templates/ishtar/sheet_operation.html:4 wizards.py:320 wizards.py:331
msgid "Operation"
msgstr ""
@@ -93,7 +93,7 @@ msgstr ""
msgid ":"
msgstr ""
-#: forms.py:404 forms.py:608
+#: forms.py:404 forms.py:612
msgid "You should select an operation."
msgstr ""
@@ -113,7 +113,7 @@ msgstr ""
msgid "Deleted relations"
msgstr ""
-#: forms.py:469 templates/ishtar/sheet_operation.html:169
+#: forms.py:469 templates/ishtar/sheet_operation.html:170
msgid "Relations"
msgstr ""
@@ -121,19 +121,23 @@ msgstr ""
msgid "Operation - 080 - Relations"
msgstr ""
-#: forms.py:478 forms.py:1237 forms.py:1396
+#: forms.py:478 forms.py:1244 forms.py:1422
msgid "Full text search"
msgstr ""
-#: forms.py:481 models.py:735
+#: forms.py:481 models.py:775
msgid "Numeric reference"
msgstr ""
-#: forms.py:488 forms.py:1064 forms.py:1412 models.py:1930 models.py:2142
+#: forms.py:487 forms.py:761 models.py:870
+msgid "DRASSM code"
+msgstr ""
+
+#: forms.py:489 forms.py:1071 forms.py:1438 models.py:2013 models.py:2225
msgid "Parcel"
msgstr ""
-#: forms.py:491 forms.py:1415 models.py:1395
+#: forms.py:492 forms.py:1441 models.py:1467
#: templates/ishtar/dashboards/dashboard_operation.html:390
#: templates/ishtar/dashboards/dashboard_operation.html:411
#: templates/ishtar/dashboards/dashboard_operation.html:643
@@ -142,558 +146,566 @@ msgstr ""
msgid "Department"
msgstr ""
-#: forms.py:492 forms.py:1148 forms.py:1241 forms.py:1325 models.py:213
+#: forms.py:493 forms.py:1155 forms.py:1248 forms.py:1340 models.py:224
#: templates/ishtar/blocks/window_tables/archaeologicalsites.html:7
#: templates/ishtar/sheet_operation.html:29
msgid "Name"
msgstr ""
-#: forms.py:493 forms.py:761 models.py:797
+#: forms.py:494 forms.py:766 models.py:838
msgid "Address / Locality"
msgstr ""
-#: forms.py:494 forms.py:678 forms.py:757 models.py:742
+#: forms.py:495 forms.py:682 forms.py:762 models.py:782
msgid "Operation type"
msgstr ""
-#: forms.py:495
+#: forms.py:496
msgid "Is open?"
msgstr ""
-#: forms.py:503 forms.py:793 models.py:727
+#: forms.py:504 forms.py:798 models.py:767
msgid "In charge"
msgstr ""
-#: forms.py:510 models.py:1672
+#: forms.py:511 models.py:1745
msgid "Scientist in charge"
msgstr ""
-#: forms.py:512 forms.py:680 forms.py:783 models.py:725
+#: forms.py:513 forms.py:684 forms.py:788 models.py:765
msgid "Operator"
msgstr ""
-#: forms.py:521 forms.py:1153 forms.py:1243 forms.py:1330 models.py:217
-#: models.py:744
+#: forms.py:522 forms.py:1160 forms.py:1250 forms.py:1345 models.py:228
+#: models.py:784
#: templates/ishtar/blocks/window_tables/archaeologicalsites.html:9
msgid "Remains"
msgstr ""
-#: forms.py:522 forms.py:1131 forms.py:1150 forms.py:1242 forms.py:1327
-#: models.py:215 models.py:750
+#: forms.py:523 forms.py:1138 forms.py:1157 forms.py:1249 forms.py:1342
+#: models.py:226 models.py:790
#: templates/ishtar/blocks/window_tables/archaeologicalsites.html:8
msgid "Periods"
msgstr ""
-#: forms.py:523
+#: forms.py:524
msgid "Started before"
msgstr ""
-#: forms.py:524
+#: forms.py:525
msgid "Started after"
msgstr ""
-#: forms.py:525
+#: forms.py:526
msgid "Ended before"
msgstr ""
-#: forms.py:526
+#: forms.py:527
msgid "Ended after"
msgstr ""
-#: forms.py:528
+#: forms.py:529
msgid "Search within relations"
msgstr ""
-#: forms.py:529 forms.py:841 forms.py:1245 forms.py:1340 models.py:221
-#: models.py:798
+#: forms.py:530 forms.py:846 forms.py:1252 forms.py:1357 models.py:232
+#: models.py:839
msgid "Comment"
msgstr ""
-#: forms.py:530
+#: forms.py:531
msgid "Abstract (full text search)"
msgstr ""
-#: forms.py:532 forms.py:844 models.py:800
+#: forms.py:533 forms.py:849 models.py:841
msgid "Comment about scientific documentation"
msgstr ""
-#: forms.py:533 forms.py:846 models.py:815
+#: forms.py:534 forms.py:851 models.py:856
msgid "Record quality"
msgstr ""
-#: forms.py:534 forms.py:812 models.py:762
+#: forms.py:535 forms.py:817 models.py:802
msgid "Report processing"
msgstr ""
-#: forms.py:536 forms.py:849 models.py:810
+#: forms.py:537 forms.py:854 models.py:851
msgid "Virtual operation"
msgstr ""
-#: forms.py:538 forms.py:1188 forms.py:1192 models.py:257
+#: forms.py:539 forms.py:1195 forms.py:1199 models.py:276
msgid "Archaeological site"
msgstr ""
-#: forms.py:544 forms.py:1419
+#: forms.py:545 forms.py:1445
msgid "Created by"
msgstr ""
-#: forms.py:550 forms.py:1425
+#: forms.py:551 forms.py:1451
msgid "Modified by"
msgstr ""
-#: forms.py:557 forms.py:834 models.py:822
+#: forms.py:558 forms.py:839 models.py:863
msgid "Documentation received"
msgstr ""
-#: forms.py:559
+#: forms.py:560
msgid "Documentation deadline before"
msgstr ""
-#: forms.py:561
+#: forms.py:562
msgid "Documentation deadline after"
msgstr ""
-#: forms.py:563 forms.py:839 models.py:826
+#: forms.py:564 forms.py:844 models.py:867
msgid "Finds received"
msgstr ""
-#: forms.py:565
+#: forms.py:566
msgid "Finds deadline before"
msgstr ""
-#: forms.py:567
+#: forms.py:568
msgid "Finds deadline after"
msgstr ""
-#: forms.py:595 views.py:182
+#: forms.py:599 views.py:183
msgid "Operation search"
msgstr ""
-#: forms.py:639
+#: forms.py:643
msgid "Associated file"
msgstr ""
-#: forms.py:643 forms.py:937 models.py:1023 models.py:1404 models.py:1490
-#: models.py:1683 wizards.py:83
+#: forms.py:647 forms.py:944 models.py:1083 models.py:1476 models.py:1563
+#: models.py:1756 wizards.py:83
msgid "Archaeological file"
msgstr ""
-#: forms.py:650 forms.py:654 models.py:817
+#: forms.py:654 forms.py:658 models.py:858
msgid "Abstract"
msgstr ""
-#: forms.py:651
+#: forms.py:655
msgid "Operation - 090 - Abstract"
msgstr ""
-#: forms.py:658
+#: forms.py:662
msgid "months"
msgstr ""
-#: forms.py:658
+#: forms.py:662
msgid "years"
msgstr ""
-#: forms.py:660 models.py:711
+#: forms.py:664 models.py:751
msgid "Creation date"
msgstr ""
-#: forms.py:661
+#: forms.py:665
msgid "Start of field work"
msgstr ""
-#: forms.py:663
+#: forms.py:667
msgid "All"
msgstr ""
-#: forms.py:664
+#: forms.py:668
msgid "Preventive"
msgstr ""
-#: forms.py:665
+#: forms.py:669
msgid "Research"
msgstr ""
-#: forms.py:669
+#: forms.py:673
msgid "Slicing"
msgstr ""
-#: forms.py:672
+#: forms.py:676
msgid "Department detail"
msgstr ""
-#: forms.py:674
+#: forms.py:678
msgid "Date get from"
msgstr ""
-#: forms.py:676
+#: forms.py:680
msgid "Preventive/Research"
msgstr ""
-#: forms.py:682
+#: forms.py:686
msgid "Date after"
msgstr ""
-#: forms.py:683
+#: forms.py:687
msgid "Date before"
msgstr ""
-#: forms.py:684
+#: forms.py:688
msgid "With reports"
msgstr ""
-#: forms.py:685
+#: forms.py:689
msgid "With finds"
msgstr ""
-#: forms.py:737 forms.py:1317 forms.py:1466
+#: forms.py:741 forms.py:1331 forms.py:1492
#: templates/ishtar/sheet_administrativeact.html:23
#: templates/ishtar/sheet_operation.html:12 templates/ishtar/sheet_site.html:33
msgid "General"
msgstr ""
-#: forms.py:738
+#: forms.py:742
msgid "Operation - 010 - General"
msgstr ""
-#: forms.py:759 models.py:796
+#: forms.py:764 models.py:837
msgid "Generic name"
msgstr ""
-#: forms.py:768 models.py:764
+#: forms.py:773 models.py:804
msgid "Old code"
msgstr ""
-#: forms.py:771
+#: forms.py:776
msgid "Head scientist"
msgstr ""
-#: forms.py:790 models.py:795
+#: forms.py:795 models.py:836
msgid "Operator reference"
msgstr ""
-#: forms.py:804
+#: forms.py:809
msgid "Total surface (m2)"
msgstr ""
-#: forms.py:807 models.py:57 models.py:714 models.py:2144
+#: forms.py:812 models.py:57 models.py:754 models.py:2227
msgid "Start date"
msgstr ""
-#: forms.py:808 models.py:716
+#: forms.py:813 models.py:756
msgid "Excavation end date"
msgstr ""
-#: forms.py:810 models.py:717
+#: forms.py:815 models.py:757
msgid "Report delivery date"
msgstr ""
-#: forms.py:831 models.py:819
+#: forms.py:836 models.py:860
msgid "Deadline for submission of the documentation"
msgstr ""
-#: forms.py:836 models.py:824
+#: forms.py:841 models.py:865
msgid "Deadline for submission of the finds"
msgstr ""
-#: forms.py:888
+#: forms.py:895
msgid ""
"If you want to set an excavation end date you have to provide a start date."
msgstr ""
-#: forms.py:893
+#: forms.py:900
msgid "The excavation end date cannot be before the start date."
msgstr ""
-#: forms.py:923
+#: forms.py:930
#, python-format
msgid ""
"Operation code already exists for year: %(year)d - use a value bigger than "
"%(last_val)d"
msgstr ""
-#: forms.py:927
+#: forms.py:934
msgid "Bad operation code"
msgstr ""
-#: forms.py:933 models.py:1038
+#: forms.py:940 models.py:1098
msgid "Operation code"
msgstr ""
-#: forms.py:968 templates/ishtar/sheet_operation.html:149
+#: forms.py:975 templates/ishtar/sheet_operation.html:150
msgid "Court-ordered seizure"
msgstr ""
-#: forms.py:969
+#: forms.py:976
msgid "Operation - 015 - Court-ordered seizure"
msgstr ""
-#: forms.py:973 models.py:829
+#: forms.py:980 models.py:873
msgid "Seizure name"
msgstr ""
-#: forms.py:976 models.py:830
+#: forms.py:983 models.py:874
msgid "Official report number"
msgstr ""
-#: forms.py:979 models.py:832
+#: forms.py:986 models.py:876
msgid "Name of the protagonist"
msgstr ""
-#: forms.py:984 forms.py:991 models.py:731
+#: forms.py:991 forms.py:998 forms.py:1356 models.py:243 models.py:771
msgid "Collaborators"
msgstr ""
-#: forms.py:985
+#: forms.py:992
msgid "Operation - 020 - Collaborators"
msgstr ""
-#: forms.py:1000
+#: forms.py:1007
msgid "Preventive informations - excavation"
msgstr ""
-#: forms.py:1001
+#: forms.py:1008
msgid "Operation - 033 - Preventive - Excavation"
msgstr ""
-#: forms.py:1004 models.py:748
+#: forms.py:1011 models.py:788
#: templates/ishtar/dashboards/dashboard_operation.html:701
msgid "Cost (euros)"
msgstr ""
-#: forms.py:1005 models.py:753
+#: forms.py:1012 models.py:793
msgid "Scheduled man-days"
msgstr ""
-#: forms.py:1007 models.py:756
+#: forms.py:1014 models.py:796
msgid "Optional man-days"
msgstr ""
-#: forms.py:1009 models.py:759
+#: forms.py:1016 models.py:799
msgid "Effective man-days"
msgstr ""
-#: forms.py:1019
+#: forms.py:1026
msgid "Preventive informations - diagnostic"
msgstr ""
-#: forms.py:1020
+#: forms.py:1027
msgid "Operation - 037 - Preventive - Diagnostic"
msgstr ""
-#: forms.py:1025 models.py:779
+#: forms.py:1032 models.py:819
msgid "Prescription on zoning"
msgstr ""
-#: forms.py:1027 models.py:782
+#: forms.py:1034 models.py:822
msgid "Prescription on large area"
msgstr ""
-#: forms.py:1030 models.py:784
+#: forms.py:1037 models.py:824
msgid "Prescription on geoarchaeological context"
msgstr ""
-#: forms.py:1034 forms.py:1050 forms.py:1055 forms.py:1359 models.py:128
-#: models.py:219 models.py:506 models.py:746 models.py:1706
+#: forms.py:1041 forms.py:1057 forms.py:1062 forms.py:1381 models.py:131
+#: models.py:230 models.py:541 models.py:786 models.py:1779
msgid "Towns"
msgstr ""
-#: forms.py:1051
+#: forms.py:1058
msgid "Operation - 040 - Towns"
msgstr ""
-#: forms.py:1056
+#: forms.py:1063
msgid "Operation - 040 - Towns (2)"
msgstr ""
-#: forms.py:1078
+#: forms.py:1085
msgid "Operation - 050 - Parcels"
msgstr ""
-#: forms.py:1085
+#: forms.py:1092
msgid "Operation - 050 - Parcels (2)"
msgstr ""
-#: forms.py:1115 models.py:47
+#: forms.py:1122 models.py:47
msgid "Remain types"
msgstr ""
-#: forms.py:1116
+#: forms.py:1123
msgid "Operation - 060 - Remains"
msgstr ""
-#: forms.py:1122 models.py:46
+#: forms.py:1129 models.py:46
msgid "Remain type"
msgstr ""
-#: forms.py:1132
+#: forms.py:1139
msgid "Operation - 070 - Periods"
msgstr ""
-#: forms.py:1138 templates/ishtar/sheet_operation.html:273
-#: templates/ishtar/sheet_operation.html:310
+#: forms.py:1145 templates/ishtar/sheet_operation.html:280
+#: templates/ishtar/sheet_operation.html:317
msgid "Period"
msgstr ""
-#: forms.py:1147 forms.py:1239 forms.py:1324 models.py:212
+#: forms.py:1154 forms.py:1246 forms.py:1339 models.py:223
msgid "Reference"
msgstr ""
-#: forms.py:1171 forms.py:1353
+#: forms.py:1178 forms.py:1375
msgid "This reference already exists."
msgstr ""
-#: forms.py:1203 models.py:258 models.py:807
-#: templates/ishtar/sheet_operation.html:194
+#: forms.py:1210 models.py:277 models.py:848
+#: templates/ishtar/sheet_operation.html:195
msgid "Archaeological sites"
msgstr ""
-#: forms.py:1205
+#: forms.py:1212
msgid "Operation - 030 - Archaeological sites"
msgstr ""
-#: forms.py:1210
+#: forms.py:1217
msgid "Associated archaeological sites"
msgstr ""
-#: forms.py:1216 ishtar_menu.py:36 ishtar_menu.py:66 ishtar_menu.py:113
+#: forms.py:1223 ishtar_menu.py:36 ishtar_menu.py:66 ishtar_menu.py:108
msgid "Search"
msgstr ""
-#: forms.py:1221
+#: forms.py:1228
msgid "Would you like to close this operation?"
msgstr ""
-#: forms.py:1226
+#: forms.py:1233
msgid "Would you like to delete this operation?"
msgstr ""
-#: forms.py:1248 models.py:223
+#: forms.py:1255 models.py:234
msgid "Top operation"
msgstr ""
-#: forms.py:1260 forms.py:1333 models.py:226
+#: forms.py:1267 forms.py:1348 models.py:237
msgid "National Geographic Institute locality"
msgstr ""
-#: forms.py:1263 forms.py:1337 models.py:229
+#: forms.py:1270 forms.py:1352 models.py:240
msgid "Cadastral locality"
msgstr ""
-#: forms.py:1266 forms.py:1374 models.py:233
+#: forms.py:1274 forms.py:1396 models.py:257
+msgid "AffMar number"
+msgstr ""
+
+#: forms.py:1276 forms.py:1398 models.py:259
+msgid "DRASSM number"
+msgstr ""
+
+#: forms.py:1278 forms.py:1400 models.py:248
msgid "Shipwreck name"
msgstr ""
-#: forms.py:1269 forms.py:1382 models.py:235
+#: forms.py:1281 forms.py:1408 models.py:250
msgid "Oceanographic service localisation"
msgstr ""
-#: forms.py:1272 forms.py:1376 models.py:237
+#: forms.py:1284 forms.py:1402 models.py:252
msgid "Shipwreck code"
msgstr ""
-#: forms.py:1274 forms.py:1378 models.py:239
+#: forms.py:1286 forms.py:1404 models.py:254
msgid "Sinking date"
msgstr ""
-#: forms.py:1276 forms.py:1380 models.py:241
+#: forms.py:1288 forms.py:1406 models.py:256
msgid "Discovery area"
msgstr ""
-#: forms.py:1312
+#: forms.py:1326
msgid "You should select an item."
msgstr ""
-#: forms.py:1318
+#: forms.py:1332
msgid "Archaeological site - 010 - General"
msgstr ""
-#: forms.py:1360
+#: forms.py:1382
msgid "Archaeological site - 020 - Towns"
msgstr ""
-#: forms.py:1369 templates/ishtar/sheet_site.html:52
+#: forms.py:1391 templates/ishtar/sheet_site.html:53
msgid "Underwater"
msgstr ""
-#: forms.py:1370
+#: forms.py:1392
msgid "Archaeological site - 030 - Underwater"
msgstr ""
-#: forms.py:1401 forms.py:1535 models.py:1663
+#: forms.py:1427 forms.py:1561 models.py:1736
msgid "Index"
msgstr ""
-#: forms.py:1409 forms.py:1469 models.py:1418 models.py:1657
+#: forms.py:1435 forms.py:1495 models.py:1490 models.py:1730
msgid "Act type"
msgstr ""
-#: forms.py:1410 forms.py:1605
+#: forms.py:1436 forms.py:1631
msgid "Indexed?"
msgstr ""
-#: forms.py:1416 forms.py:1474 models.py:1697
+#: forms.py:1442 forms.py:1500 models.py:1770
#: templates/ishtar/blocks/window_tables/administrativacts.html:9
msgid "Object"
msgstr ""
-#: forms.py:1446 views.py:412
+#: forms.py:1472 views.py:413
msgid "Administrative act search"
msgstr ""
-#: forms.py:1461 forms.py:1563 forms.py:1630
+#: forms.py:1487 forms.py:1589 forms.py:1656
msgid "You should select an administrative act."
msgstr ""
-#: forms.py:1477 models.py:1694
+#: forms.py:1503 models.py:1767
msgid "Signature date"
msgstr ""
-#: forms.py:1489
+#: forms.py:1515
msgid "Operation - Administrative act - General"
msgstr ""
-#: forms.py:1523
+#: forms.py:1549
#, python-format
msgid ""
"This index already exists for year: %(year)d - use a value bigger than "
"%(last_val)d"
msgstr ""
-#: forms.py:1527
+#: forms.py:1553
msgid "Bad index"
msgstr ""
-#: forms.py:1540
+#: forms.py:1566
msgid "Would you like to delete this administrative act?"
msgstr ""
-#: forms.py:1545
+#: forms.py:1571
msgid "Template"
msgstr ""
-#: forms.py:1569 forms.py:1573
+#: forms.py:1595 forms.py:1599
msgid "This document is not intended for this type of act."
msgstr ""
-#: forms.py:1591
+#: forms.py:1617
msgid "Doc generation"
msgstr ""
-#: forms.py:1593
+#: forms.py:1619
msgid "Generate the associated doc?"
msgstr ""
-#: forms.py:1614 ishtar_menu.py:101 views.py:465
+#: forms.py:1640 ishtar_menu.py:96 views.py:466
msgctxt "admin act register"
msgid "Register"
msgstr ""
-#: ishtar_menu.py:41 ishtar_menu.py:72 ishtar_menu.py:118
+#: ishtar_menu.py:41 ishtar_menu.py:72 ishtar_menu.py:113
msgid "Creation"
msgstr ""
-#: ishtar_menu.py:46 ishtar_menu.py:77 ishtar_menu.py:123
+#: ishtar_menu.py:46 ishtar_menu.py:77 ishtar_menu.py:118
msgid "Modification"
msgstr ""
@@ -701,42 +713,38 @@ msgstr ""
msgid "Closing"
msgstr ""
-#: ishtar_menu.py:55 ishtar_menu.py:82 ishtar_menu.py:128
+#: ishtar_menu.py:55 ishtar_menu.py:82 ishtar_menu.py:123
msgid "Deletion"
msgstr ""
-#: ishtar_menu.py:61 models.py:1713
+#: ishtar_menu.py:61 models.py:1786
#: templates/ishtar/sheet_administrativeact.html:4
msgid "Administrative act"
msgstr ""
-#: ishtar_menu.py:87 models.py:249 models.py:802
-msgid "Documents"
-msgstr ""
-
-#: ishtar_menu.py:95
+#: ishtar_menu.py:90
msgid "Administrative Act"
msgstr ""
-#: ishtar_menu.py:135
+#: ishtar_menu.py:130
msgid "Dashboard"
msgstr ""
-#: ishtar_menu.py:139
+#: ishtar_menu.py:134
msgid "General informations"
msgstr ""
-#: ishtar_menu.py:143 models.py:843
+#: ishtar_menu.py:138 models.py:887
#: templates/ishtar/dashboards/dashboard_operation.html:8
-#: templates/ishtar/sheet_site.html:65
+#: templates/ishtar/sheet_site.html:68
msgid "Operations"
msgstr ""
-#: models.py:56 models.py:76 models.py:94 models.py:2622
+#: models.py:56 models.py:76 models.py:94 models.py:2705
msgid "Order"
msgstr ""
-#: models.py:58 models.py:2145
+#: models.py:58 models.py:2228
msgid "End date"
msgstr ""
@@ -768,665 +776,692 @@ msgstr ""
msgid "Types of record quality"
msgstr ""
-#: models.py:135
+#: models.py:138
msgctxt "key for text search"
msgid "reference"
msgstr ""
-#: models.py:139 models.py:569
+#: models.py:142 models.py:605
msgctxt "key for text search"
msgid "name"
msgstr ""
-#: models.py:143 models.py:601 tests.py:1625
+#: models.py:146 models.py:637 tests.py:1625
msgctxt "key for text search"
msgid "period"
msgstr ""
-#: models.py:147 models.py:597 tests.py:1656
+#: models.py:150 models.py:633 tests.py:1656
msgctxt "key for text search"
msgid "remain"
msgstr ""
-#: models.py:151 models.py:557 tests.py:1633
+#: models.py:154 models.py:593 tests.py:1633
msgctxt "key for text search"
msgid "town"
msgstr ""
-#: models.py:155 models.py:625
+#: models.py:158 models.py:661
msgctxt "key for text search"
msgid "comment"
msgstr ""
-#: models.py:159
+#: models.py:162
msgctxt "key for text search"
msgid "locality-ngi"
msgstr ""
-#: models.py:163
+#: models.py:166
msgctxt "key for text search"
msgid "locality-cadastral"
msgstr ""
-#: models.py:167
+#: models.py:170
msgctxt "key for text search"
msgid "shipwreck-name"
msgstr ""
-#: models.py:172
+#: models.py:175
msgctxt "key for text search"
msgid "oceanographic-service-localisation"
msgstr ""
-#: models.py:176
+#: models.py:179
msgctxt "key for text search"
msgid "shipwreck-code"
msgstr ""
-#: models.py:180
+#: models.py:183
msgctxt "key for text search"
msgid "sinking-date"
msgstr ""
-#: models.py:184
+#: models.py:187
msgctxt "key for text search"
msgid "discovery-area"
msgstr ""
-#: models.py:188 models.py:203
+#: models.py:191 models.py:214
msgctxt "key for text search"
msgid "operation"
msgstr ""
-#: models.py:192
+#: models.py:195
msgctxt "key for text search"
msgid "top-operation"
msgstr ""
-#: models.py:251 models.py:804 models.py:1926
+#: models.py:199
+msgctxt "key for text search"
+msgid "numero-drassm"
+msgstr ""
+
+#: models.py:203
+msgctxt "key for text search"
+msgid "numero-affmar"
+msgstr ""
+
+#: models.py:268 models.py:843
+msgid "Documents"
+msgstr ""
+
+#: models.py:270 models.py:845 models.py:2009
msgid "Cached name"
msgstr ""
-#: models.py:280
+#: models.py:299
msgid "SITE"
msgstr ""
-#: models.py:345
+#: models.py:380
msgid "Unknown"
msgstr ""
-#: models.py:348
+#: models.py:383
msgid "Virtual operation of site: {}"
msgstr ""
-#: models.py:488
+#: models.py:523
msgid "Associated file (label)"
msgstr ""
-#: models.py:489
+#: models.py:524
msgid "Operator name"
msgstr ""
-#: models.py:490
+#: models.py:525
msgid "Scientist (full name)"
msgstr ""
-#: models.py:491
+#: models.py:526
msgid "Associated file (external ID)"
msgstr ""
-#: models.py:492
+#: models.py:527
msgid "Scientist (title)"
msgstr ""
-#: models.py:493
+#: models.py:528
msgid "Scientist (surname)"
msgstr ""
-#: models.py:494
+#: models.py:529
msgid "Scientist (name)"
msgstr ""
-#: models.py:495
+#: models.py:530
msgid "Scientist - Organization (name)"
msgstr ""
-#: models.py:496
+#: models.py:531
msgid "In charge (title)"
msgstr ""
-#: models.py:497
+#: models.py:532
msgid "In charge (surname)"
msgstr ""
-#: models.py:498
+#: models.py:533
msgid "In charge (name)"
msgstr ""
-#: models.py:499
+#: models.py:534
msgid "In charge - Organization (name)"
msgstr ""
-#: models.py:504
+#: models.py:539
msgid "Archaeological sites (reference)"
msgstr ""
-#: models.py:545 models.py:1502 tests.py:1628 tests.py:1673
+#: models.py:581 models.py:1575 tests.py:1628 tests.py:1673
msgctxt "key for text search"
msgid "year"
msgstr ""
-#: models.py:549
+#: models.py:585
msgctxt "key for text search"
msgid "operation-code"
msgstr ""
-#: models.py:553 models.py:1514
+#: models.py:589 models.py:1587
msgctxt "key for text search"
msgid "patriarche"
msgstr ""
-#: models.py:561 models.py:1534
+#: models.py:597 models.py:1607
msgctxt "key for text search"
msgid "parcel"
msgstr ""
-#: models.py:565
+#: models.py:601
msgctxt "key for text search"
msgid "department"
msgstr ""
-#: models.py:573
+#: models.py:609
msgctxt "key for text search"
msgid "address"
msgstr ""
-#: models.py:577 models.py:1518
+#: models.py:613 models.py:1591
msgctxt "key for text search"
msgid "type"
msgstr ""
-#: models.py:581 tests.py:1661
+#: models.py:617 tests.py:1661
msgctxt "key for text search"
msgid "is-open"
msgstr ""
-#: models.py:585
+#: models.py:621
msgctxt "key for text search"
msgid "in-charge"
msgstr ""
-#: models.py:589
+#: models.py:625
msgctxt "key for text search"
msgid "scientist"
msgstr ""
-#: models.py:593
+#: models.py:629
msgctxt "key for text search"
msgid "operator"
msgstr ""
-#: models.py:605
+#: models.py:641
msgctxt "key for text search"
msgid "start-before"
msgstr ""
-#: models.py:609
+#: models.py:645
msgctxt "key for text search"
msgid "start-after"
msgstr ""
-#: models.py:613
+#: models.py:649
msgctxt "key for text search"
msgid "end-before"
msgstr ""
-#: models.py:617
+#: models.py:653
msgctxt "key for text search"
msgid "end-after"
msgstr ""
-#: models.py:621
+#: models.py:657
msgctxt "key for text search"
msgid "relation-types"
msgstr ""
-#: models.py:629
+#: models.py:665
msgctxt "key for text search"
msgid "abstract"
msgstr ""
-#: models.py:634
+#: models.py:670
msgctxt "key for text search"
msgid "scientific-documentation-comment"
msgstr ""
-#: models.py:638
+#: models.py:674
msgctxt "key for text search"
msgid "record-quality"
msgstr ""
-#: models.py:643
+#: models.py:679
msgctxt "key for text search"
msgid "report-processing"
msgstr ""
-#: models.py:648
+#: models.py:684
msgctxt "key for text search"
msgid "virtual-operation"
msgstr ""
-#: models.py:653 models.py:696
+#: models.py:689 models.py:736
msgctxt "key for text search"
msgid "site"
msgstr ""
-#: models.py:657 models.py:1552
+#: models.py:693 models.py:1625
msgctxt "key for text search"
msgid "created-by"
msgstr ""
-#: models.py:661 models.py:1556
+#: models.py:697 models.py:1629
msgctxt "key for text search"
msgid "modified-by"
msgstr ""
-#: models.py:665
+#: models.py:701
msgctxt "key for text search"
msgid "documentation-received"
msgstr ""
-#: models.py:669
+#: models.py:705
msgctxt "key for text search"
msgid "documentation-deadline-before"
msgstr ""
-#: models.py:673
+#: models.py:709
msgctxt "key for text search"
msgid "documentation-deadline-after"
msgstr ""
-#: models.py:677
+#: models.py:713
msgctxt "key for text search"
msgid "finds-received"
msgstr ""
-#: models.py:681
+#: models.py:717
msgctxt "key for text search"
msgid "finds-deadline-before"
msgstr ""
-#: models.py:685
+#: models.py:721
msgctxt "key for text search"
msgid "finds-deadline-after"
msgstr ""
-#: models.py:698
+#: models.py:725
+msgctxt "key for text search"
+msgid "code-drassm"
+msgstr ""
+
+#: models.py:738
msgctxt "key for text search"
msgid "file"
msgstr ""
-#: models.py:713 templates/ishtar/sheet_operation.html:60
+#: models.py:753 templates/ishtar/sheet_operation.html:61
msgid "Closing date"
msgstr ""
-#: models.py:720
+#: models.py:760
msgid "In charge scientist"
msgstr ""
-#: models.py:739 models.py:1908
+#: models.py:779 models.py:1991
msgid "File"
msgstr ""
-#: models.py:743
+#: models.py:783
msgid "Surface (m2)"
msgstr ""
-#: models.py:812
+#: models.py:853
msgid ""
"If checked, it means that this operation have not been officialy registered."
msgstr ""
-#: models.py:891
+#: models.py:935
msgid "OPE"
msgstr ""
-#: models.py:988
+#: models.py:1032
msgid "Intercommunal"
msgstr ""
-#: models.py:1024
+#: models.py:1078
+msgid "Add context record"
+msgstr ""
+
+#: models.py:1079
+msgid "context record"
+msgstr ""
+
+#: models.py:1084
msgid "Code patriarche"
msgstr ""
-#: models.py:1066
+#: models.py:1126
msgid "This operation code already exists for this year"
msgstr ""
-#: models.py:1111
+#: models.py:1183
msgid "Number of parcels"
msgstr ""
-#: models.py:1121
+#: models.py:1193
msgid "Number of administrative acts"
msgstr ""
-#: models.py:1129
+#: models.py:1201
msgid "Number of indexed administrative acts"
msgstr ""
-#: models.py:1137
+#: models.py:1209
msgid "Number of context records"
msgstr ""
-#: models.py:1173
+#: models.py:1245
msgid "Number of finds"
msgstr ""
-#: models.py:1218
+#: models.py:1290
msgid "No type"
msgstr ""
-#: models.py:1249
+#: models.py:1321
msgid "Number of sources"
msgstr ""
-#: models.py:1287 templates/ishtar/dashboards/dashboard_operation.html:309
+#: models.py:1359 templates/ishtar/dashboards/dashboard_operation.html:309
#: templates/ishtar/dashboards/dashboard_operation.html:575
#: templates/ishtar/dashboards/dashboard_operation.html:611
msgid "Mean"
msgstr ""
-#: models.py:1349
+#: models.py:1421
msgid "Operation relation type"
msgstr ""
-#: models.py:1350
+#: models.py:1422
msgid "Operation relation types"
msgstr ""
-#: models.py:1363
+#: models.py:1435
msgid "Operation record relation"
msgstr ""
-#: models.py:1364
+#: models.py:1436
msgid "Operation record relations"
msgstr ""
-#: models.py:1406 models.py:1688
+#: models.py:1478 models.py:1761
msgid "Treatment request"
msgstr ""
-#: models.py:1407 models.py:1693
+#: models.py:1479 models.py:1766
msgid "Treatment"
msgstr ""
-#: models.py:1409
+#: models.py:1481
msgid "Intended to"
msgstr ""
-#: models.py:1411
+#: models.py:1483
msgid "Code"
msgstr ""
-#: models.py:1414
+#: models.py:1486
msgid "Associated template"
msgstr ""
-#: models.py:1415
+#: models.py:1487
msgid "Indexed"
msgstr ""
-#: models.py:1419
+#: models.py:1491
msgid "Act types"
msgstr ""
-#: models.py:1489 models.py:1734
+#: models.py:1562 models.py:1807
#: templates/ishtar/blocks/window_tables/administrativacts.html:6
#: templates/ishtar/blocks/window_tables/archaeologicalsites.html:6
msgid "Ref."
msgstr ""
-#: models.py:1506
+#: models.py:1579
msgctxt "key for text search"
msgid "index"
msgstr ""
-#: models.py:1510
+#: models.py:1583
msgctxt "key for text search"
msgid "other-ref"
msgstr ""
-#: models.py:1522
+#: models.py:1595
msgctxt "key for text search"
msgid "indexed"
msgstr ""
-#: models.py:1526
+#: models.py:1599
msgctxt "key for text search"
msgid "operation-town"
msgstr ""
-#: models.py:1530
+#: models.py:1603
msgctxt "key for text search"
msgid "file-town"
msgstr ""
-#: models.py:1540
+#: models.py:1613
msgctxt "key for text search"
msgid "operation-department"
msgstr ""
-#: models.py:1544
+#: models.py:1617
msgctxt "key for text search"
msgid "file-department"
msgstr ""
-#: models.py:1548
+#: models.py:1621
msgctxt "key for text search"
msgid "object"
msgstr ""
-#: models.py:1560
+#: models.py:1633
msgctxt "key for text search"
msgid "signature-before"
msgstr ""
-#: models.py:1564
+#: models.py:1637
msgctxt "key for text search"
msgid "signature-after"
msgstr ""
-#: models.py:1568
+#: models.py:1641
msgctxt "key for text search"
msgid "file-name"
msgstr ""
-#: models.py:1572
+#: models.py:1645
msgctxt "key for text search"
msgid "general-contractor"
msgstr ""
-#: models.py:1577
+#: models.py:1650
msgctxt "key for text search"
msgid "general-contractor-organization"
msgstr ""
-#: models.py:1582
+#: models.py:1655
msgctxt "key for text search"
msgid "file-reference"
msgstr ""
-#: models.py:1586
+#: models.py:1659
msgctxt "key for text search"
msgid "file-year"
msgstr ""
-#: models.py:1590
+#: models.py:1663
msgctxt "key for text search"
msgid "file-other-reference"
msgstr ""
-#: models.py:1594
+#: models.py:1667
msgctxt "key for text search"
msgid "file-in-charge"
msgstr ""
-#: models.py:1598
+#: models.py:1671
msgctxt "key for text search"
msgid "file-permit-reference"
msgstr ""
-#: models.py:1602
+#: models.py:1675
msgctxt "key for text search"
msgid "treatment-name"
msgstr ""
-#: models.py:1606
+#: models.py:1679
msgctxt "key for text search"
msgid "treatment-reference"
msgstr ""
-#: models.py:1610
+#: models.py:1683
msgctxt "key for text search"
msgid "treatment-year"
msgstr ""
-#: models.py:1614
+#: models.py:1687
msgctxt "key for text search"
msgid "treatment-index"
msgstr ""
-#: models.py:1618
+#: models.py:1691
msgctxt "key for text search"
msgid "treatment-type"
msgstr ""
-#: models.py:1622
+#: models.py:1695
msgctxt "key for text search"
msgid "treatment-file-name"
msgstr ""
-#: models.py:1626
+#: models.py:1699
msgctxt "key for text search"
msgid "treatment-file-reference"
msgstr ""
-#: models.py:1630
+#: models.py:1703
msgctxt "key for text search"
msgid "treatment-file-year"
msgstr ""
-#: models.py:1634
+#: models.py:1707
msgctxt "key for text search"
msgid "treatment-file-index"
msgstr ""
-#: models.py:1638
+#: models.py:1711
msgctxt "key for text search"
msgid "treatment-file-type"
msgstr ""
-#: models.py:1661
+#: models.py:1734
msgid "Person in charge of the operation"
msgstr ""
-#: models.py:1667
+#: models.py:1740
msgid "Archaeological preventive operator"
msgstr ""
-#: models.py:1675
+#: models.py:1748
msgid "Signatory"
msgstr ""
-#: models.py:1703
+#: models.py:1776
msgid "Departments"
msgstr ""
-#: models.py:1704
+#: models.py:1777
msgid "Cached values get from associated departments"
msgstr ""
-#: models.py:1707
+#: models.py:1780
msgid "Cached values get from associated towns"
msgstr ""
-#: models.py:1714 templates/ishtar/sheet_operation.html:202
-#: templates/ishtar/sheet_operation.html:244
+#: models.py:1787 templates/ishtar/sheet_operation.html:205
+#: templates/ishtar/sheet_operation.html:251
msgid "Administrative acts"
msgstr ""
-#: models.py:1837
+#: models.py:1920
msgid "This index already exists for this year"
msgstr ""
-#: models.py:1921
+#: models.py:2004
msgid "External ID"
msgstr ""
-#: models.py:1924
+#: models.py:2007
msgid "External ID is set automatically"
msgstr ""
-#: models.py:1925
+#: models.py:2008
msgid "Address - Locality"
msgstr ""
-#: models.py:2140
+#: models.py:2223
msgid "Owner"
msgstr ""
-#: models.py:2148
+#: models.py:2231
msgid "Parcel owner"
msgstr ""
-#: models.py:2149
+#: models.py:2232
msgid "Parcel owners"
msgstr ""
-#: models.py:2183
+#: models.py:2266
msgid "Recorded"
msgstr ""
-#: models.py:2184
+#: models.py:2267
msgid "Effective"
msgstr ""
-#: models.py:2185
+#: models.py:2268
msgid "Active"
msgstr ""
-#: models.py:2186
+#: models.py:2269
msgid "Field completed"
msgstr ""
-#: models.py:2187
+#: models.py:2270
msgid "Associated report"
msgstr ""
-#: models.py:2188
+#: models.py:2271
msgid "Closed"
msgstr ""
-#: models.py:2189
+#: models.py:2272
msgid "Documented and closed"
msgstr ""
-#: models.py:2623
+#: models.py:2706
msgid "Is preventive"
msgstr ""
-#: models.py:2626
+#: models.py:2709
msgid "Operation type old"
msgstr ""
-#: models.py:2627
+#: models.py:2710
msgid "Operation types old"
msgstr ""
#: templates/ishtar/blocks/window_tables/administrativacts.html:7
-#: templates/ishtar/sheet_operation.html:263
-#: templates/ishtar/sheet_operation.html:327
+#: templates/ishtar/sheet_operation.html:270
+#: templates/ishtar/sheet_operation.html:334
msgid "Type"
msgstr ""
@@ -1470,12 +1505,12 @@ msgstr ""
#: templates/ishtar/dashboards/dashboard_operation.html:432
#: templates/ishtar/dashboards/dashboard_operation.html:463
#: templates/ishtar/dashboards/dashboard_operation.html:687
-#: templates/ishtar/sheet_operation.html:263
-#: templates/ishtar/sheet_operation.html:273
-#: templates/ishtar/sheet_operation.html:290
-#: templates/ishtar/sheet_operation.html:300
-#: templates/ishtar/sheet_operation.html:310
-#: templates/ishtar/sheet_operation.html:327
+#: templates/ishtar/sheet_operation.html:270
+#: templates/ishtar/sheet_operation.html:280
+#: templates/ishtar/sheet_operation.html:297
+#: templates/ishtar/sheet_operation.html:307
+#: templates/ishtar/sheet_operation.html:317
+#: templates/ishtar/sheet_operation.html:334
msgid "Number"
msgstr ""
@@ -1501,7 +1536,7 @@ msgstr ""
#: templates/ishtar/dashboards/dashboard_operation.html:479
#: templates/ishtar/dashboards/dashboard_operation.html:499
#: templates/ishtar/dashboards/dashboard_operation.html:623
-#: templates/ishtar/sheet_operation.html:52
+#: templates/ishtar/sheet_operation.html:53
msgid "State"
msgstr ""
@@ -1664,7 +1699,7 @@ msgid "area by organization by realisation year"
msgstr ""
#: templates/ishtar/dashboards/dashboard_operation.html:670
-#: templates/ishtar/sheet_operation.html:77
+#: templates/ishtar/sheet_operation.html:78
msgid "Cost"
msgstr ""
@@ -1677,7 +1712,7 @@ msgid "main towns by cost"
msgstr ""
#: templates/ishtar/sheet_administrativeact.html:40
-#: templates/ishtar/sheet_operation.html:69
+#: templates/ishtar/sheet_operation.html:70
msgid "Surface"
msgstr ""
@@ -1685,103 +1720,103 @@ msgstr ""
msgid "Address"
msgstr ""
-#: templates/ishtar/sheet_operation.html:37
+#: templates/ishtar/sheet_operation.html:38
msgid "Begining date"
msgstr ""
-#: templates/ishtar/sheet_operation.html:54
+#: templates/ishtar/sheet_operation.html:55
msgid "Active file"
msgstr ""
-#: templates/ishtar/sheet_operation.html:55
+#: templates/ishtar/sheet_operation.html:56
msgid "Closed operation"
msgstr ""
-#: templates/ishtar/sheet_operation.html:62
+#: templates/ishtar/sheet_operation.html:63
msgid "by"
msgstr ""
-#: templates/ishtar/sheet_operation.html:85
+#: templates/ishtar/sheet_operation.html:86
msgid "Duration"
msgstr ""
-#: templates/ishtar/sheet_operation.html:87
+#: templates/ishtar/sheet_operation.html:88
msgid "days"
msgstr ""
-#: templates/ishtar/sheet_operation.html:129
+#: templates/ishtar/sheet_operation.html:130
msgid "Sheet"
msgstr ""
-#: templates/ishtar/sheet_operation.html:138
+#: templates/ishtar/sheet_operation.html:139
msgid "This operation is virtual."
msgstr ""
-#: templates/ishtar/sheet_operation.html:144
+#: templates/ishtar/sheet_operation.html:145
msgid "Patriarche OA code not yet recorded!"
msgstr ""
-#: templates/ishtar/sheet_operation.html:159
-#: templates/ishtar/sheet_site.html:43
+#: templates/ishtar/sheet_operation.html:160
+#: templates/ishtar/sheet_site.html:44
msgid "Localisation"
msgstr ""
-#: templates/ishtar/sheet_operation.html:198
+#: templates/ishtar/sheet_operation.html:200
msgid "Associated parcels"
msgstr ""
-#: templates/ishtar/sheet_operation.html:206
+#: templates/ishtar/sheet_operation.html:209
msgid "Document from this operation"
msgstr ""
-#: templates/ishtar/sheet_operation.html:212
-#: templates/ishtar/sheet_operation.html:255
+#: templates/ishtar/sheet_operation.html:216
+#: templates/ishtar/sheet_operation.html:262
msgid "Context records"
msgstr ""
-#: templates/ishtar/sheet_operation.html:217
+#: templates/ishtar/sheet_operation.html:221
msgid "Context record relations"
msgstr ""
-#: templates/ishtar/sheet_operation.html:222
+#: templates/ishtar/sheet_operation.html:226
msgid "Documents from associated context records"
msgstr ""
-#: templates/ishtar/sheet_operation.html:227
-#: templates/ishtar/sheet_operation.html:282
-#: templates/ishtar/sheet_site.html:70
+#: templates/ishtar/sheet_operation.html:232
+#: templates/ishtar/sheet_operation.html:289
+#: templates/ishtar/sheet_site.html:73
msgid "Finds"
msgstr ""
-#: templates/ishtar/sheet_operation.html:232
+#: templates/ishtar/sheet_operation.html:237
msgid "Documents from associated finds"
msgstr ""
-#: templates/ishtar/sheet_operation.html:237
+#: templates/ishtar/sheet_operation.html:243
msgid "Associated containers"
msgstr ""
-#: templates/ishtar/sheet_operation.html:241
+#: templates/ishtar/sheet_operation.html:248
msgid "Statistics"
msgstr ""
-#: templates/ishtar/sheet_operation.html:242
+#: templates/ishtar/sheet_operation.html:249
msgid "These numbers are updated hourly"
msgstr ""
-#: templates/ishtar/sheet_operation.html:290
+#: templates/ishtar/sheet_operation.html:297
msgid "Material type"
msgstr ""
-#: templates/ishtar/sheet_operation.html:300
+#: templates/ishtar/sheet_operation.html:307
msgid "Object type"
msgstr ""
-#: templates/ishtar/sheet_operation.html:319
+#: templates/ishtar/sheet_operation.html:326
msgid "Sources"
msgstr ""
-#: templates/ishtar/sheet_operation.html:337
+#: templates/ishtar/sheet_operation.html:344
msgid "Finds by context records"
msgstr ""
@@ -1802,43 +1837,43 @@ msgid ""
"The following error(s) has been encountered while parsing the source file:"
msgstr ""
-#: views.py:244
+#: views.py:245
msgid "New operation"
msgstr ""
-#: views.py:293
+#: views.py:294
msgid "Operation modification"
msgstr ""
-#: views.py:304
+#: views.py:305
msgid "You don't have sufficient permissions to do this action."
msgstr ""
-#: views.py:329
+#: views.py:330
msgid "Operation closing"
msgstr ""
-#: views.py:340
+#: views.py:341
msgid "Operation deletion"
msgstr ""
-#: views.py:406
+#: views.py:407
msgid "Site deletion"
msgstr ""
-#: views.py:425
+#: views.py:426
msgid "Operation: new administrative act"
msgstr ""
-#: views.py:435
+#: views.py:436
msgid "Operation: administrative act modification"
msgstr ""
-#: views.py:459
+#: views.py:460
msgid "Operation: administrative act deletion"
msgstr ""
-#: views.py:552
+#: views.py:530
msgid ""
"Syntax error on the source template \"{}\" - contact your administrator and "
"ask him to check the syntax of this document."
diff --git a/archaeological_operations/migrations/0041_auto_20181203_1442.py b/archaeological_operations/migrations/0041_auto_20181203_1442.py
new file mode 100644
index 000000000..5b6b9f7db
--- /dev/null
+++ b/archaeological_operations/migrations/0041_auto_20181203_1442.py
@@ -0,0 +1,1117 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.10 on 2018-12-03 14:42
+from __future__ import unicode_literals
+
+import datetime
+from django.conf import settings
+import django.contrib.gis.db.models.fields
+import django.contrib.postgres.search
+import django.core.validators
+from django.db import migrations, models
+import django.db.models.deletion
+import ishtar_common.models
+import re
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('archaeological_operations', '0040_archaeologicalsite_collaborators'),
+ ]
+
+ operations = [
+ migrations.AlterModelOptions(
+ name='acttype',
+ options={'ordering': ('label',), 'verbose_name': "Type d'acte", 'verbose_name_plural': "Types d'acte"},
+ ),
+ migrations.AlterModelOptions(
+ name='administrativeact',
+ options={'ordering': ('year', 'signature_date', 'index', 'act_type'), 'permissions': (('view_administrativeact', 'Can view all Administrative acts'), ('view_own_administrativeact', 'Can view own Administrative act'), ('add_own_administrativeact', 'Can add own Administrative act'), ('change_own_administrativeact', 'Can change own Administrative act'), ('delete_own_administrativeact', 'Can delete own Administrative act')), 'verbose_name': 'Acte administratif', 'verbose_name_plural': 'Actes administratifs'},
+ ),
+ migrations.AlterModelOptions(
+ name='archaeologicalsite',
+ options={'permissions': (('view_archaeologicalsite', 'Can view all Archaeological sites'), ('view_own_archaeologicalsite', 'Can view own Archaeological site'), ('add_own_archaeologicalsite', 'Can add own Archaeological site'), ('change_own_archaeologicalsite', 'Can change own Archaeological site'), ('delete_own_archaeologicalsite', 'Can delete own Archaeological site')), 'verbose_name': 'Entit\xe9 (EA)', 'verbose_name_plural': 'Entit\xe9s arch\xe9ologiques'},
+ ),
+ migrations.AlterModelOptions(
+ name='historicaladministrativeact',
+ options={'get_latest_by': 'history_date', 'ordering': ('-history_date', '-history_id'), 'verbose_name': 'historical Acte administratif'},
+ ),
+ migrations.AlterModelOptions(
+ name='historicalarchaeologicalsite',
+ options={'get_latest_by': 'history_date', 'ordering': ('-history_date', '-history_id'), 'verbose_name': 'historical Entit\xe9 (EA)'},
+ ),
+ migrations.AlterModelOptions(
+ name='historicaloperation',
+ options={'get_latest_by': 'history_date', 'ordering': ('-history_date', '-history_id'), 'verbose_name': 'historical Op\xe9ration'},
+ ),
+ migrations.AlterModelOptions(
+ name='operation',
+ options={'ordering': ('cached_label',), 'permissions': (('view_operation', 'Can view all Operations'), ('view_own_operation', 'Can view own Operation'), ('add_own_operation', 'Can add own Operation'), ('change_own_operation', 'Can change own Operation'), ('delete_own_operation', 'Can delete own Operation'), ('close_operation', 'Can close Operation')), 'verbose_name': 'Op\xe9ration', 'verbose_name_plural': 'Op\xe9rations'},
+ ),
+ migrations.AlterModelOptions(
+ name='operationtypeold',
+ options={'ordering': ['-preventive', 'order', 'label'], 'verbose_name': "Type d'op\xe9ration - ancien", 'verbose_name_plural': "Types d'op\xe9ration - ancien"},
+ ),
+ migrations.AlterModelOptions(
+ name='parcel',
+ options={'ordering': ('year', 'section', 'parcel_number'), 'verbose_name': 'Parcelle', 'verbose_name_plural': 'Parcelles'},
+ ),
+ migrations.AlterModelOptions(
+ name='parcelowner',
+ options={'verbose_name': 'Propri\xe9taire de parcelle', 'verbose_name_plural': 'Propri\xe9taires de parcelle'},
+ ),
+ migrations.AlterModelOptions(
+ name='period',
+ options={'ordering': ('order',), 'verbose_name': 'Type de p\xe9riode', 'verbose_name_plural': 'Types de p\xe9riode'},
+ ),
+ migrations.AlterModelOptions(
+ name='recordqualitytype',
+ options={'ordering': ('order',), 'verbose_name': "Type de qualit\xe9 d'enregistrement", 'verbose_name_plural': "Types de qualit\xe9 d'enregistrement"},
+ ),
+ migrations.AlterModelOptions(
+ name='recordrelations',
+ options={'ordering': ('left_record', 'relation_type'), 'permissions': [('view_operationrelation', 'Can view all Operation relations')], 'verbose_name': 'Relation entre op\xe9rations', 'verbose_name_plural': 'Relations entre op\xe9rations'},
+ ),
+ migrations.AlterModelOptions(
+ name='relationtype',
+ options={'ordering': ('order', 'label'), 'verbose_name': 'Type de relation entre op\xe9rations', 'verbose_name_plural': 'Types de relation entre op\xe9rations'},
+ ),
+ migrations.AlterModelOptions(
+ name='remaintype',
+ options={'ordering': ('label',), 'verbose_name': 'Type de vestige', 'verbose_name_plural': 'Types de vestige'},
+ ),
+ migrations.AlterModelOptions(
+ name='reportstate',
+ options={'ordering': ('order',), 'verbose_name': "Type d'\xe9tat de rapport", 'verbose_name_plural': "Types d'\xe9tat de rapport"},
+ ),
+ migrations.AddField(
+ model_name='archaeologicalsite',
+ name='affmar_number',
+ field=models.CharField(blank=True, max_length=100, null=True, verbose_name='Num\xe9ro AffMar'),
+ ),
+ migrations.AddField(
+ model_name='archaeologicalsite',
+ name='drassm_number',
+ field=models.CharField(blank=True, max_length=100, null=True, verbose_name='Num\xe9ro DRASSM'),
+ ),
+ migrations.AddField(
+ model_name='historicalarchaeologicalsite',
+ name='affmar_number',
+ field=models.CharField(blank=True, max_length=100, null=True, verbose_name='Num\xe9ro AffMar'),
+ ),
+ migrations.AddField(
+ model_name='historicalarchaeologicalsite',
+ name='drassm_number',
+ field=models.CharField(blank=True, max_length=100, null=True, verbose_name='Num\xe9ro DRASSM'),
+ ),
+ migrations.AddField(
+ model_name='historicaloperation',
+ name='drassm_code',
+ field=models.CharField(blank=True, max_length=100, null=True, verbose_name='Code DRASSM'),
+ ),
+ migrations.AddField(
+ model_name='operation',
+ name='drassm_code',
+ field=models.CharField(blank=True, max_length=100, null=True, verbose_name='Code DRASSM'),
+ ),
+ migrations.AlterField(
+ model_name='acttype',
+ name='associated_template',
+ field=models.ManyToManyField(blank=True, related_name='acttypes', to='ishtar_common.DocumentTemplate', verbose_name='Patron associ\xe9'),
+ ),
+ migrations.AlterField(
+ model_name='acttype',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='acttype',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='acttype',
+ name='indexed',
+ field=models.BooleanField(default=False, verbose_name='Index\xe9'),
+ ),
+ migrations.AlterField(
+ model_name='acttype',
+ name='intented_to',
+ field=models.CharField(choices=[(b'F', 'Dossier'), (b'O', 'Op\xe9ration'), (b'TF', 'Demande de traitement'), (b'T', 'Traitement')], max_length=2, verbose_name='Destin\xe9 \xe0'),
+ ),
+ migrations.AlterField(
+ model_name='acttype',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='acttype',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ migrations.AlterField(
+ model_name='administrativeact',
+ name='act_object',
+ field=models.TextField(blank=True, max_length=300, null=True, verbose_name='Objet'),
+ ),
+ migrations.AlterField(
+ model_name='administrativeact',
+ name='act_type',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='archaeological_operations.ActType', verbose_name="Type d'acte"),
+ ),
+ migrations.AlterField(
+ model_name='administrativeact',
+ name='associated_file',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='administrative_act', to='archaeological_files.File', verbose_name='Dossier'),
+ ),
+ migrations.AlterField(
+ model_name='administrativeact',
+ name='departments_label',
+ field=models.TextField(blank=True, help_text='Valeur en cache des d\xe9partements associ\xe9s', null=True, verbose_name='D\xe9partements'),
+ ),
+ migrations.AlterField(
+ model_name='administrativeact',
+ name='history_creator',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Cr\xe9ateur'),
+ ),
+ migrations.AlterField(
+ model_name='administrativeact',
+ name='history_modifier',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Dernier \xe9diteur'),
+ ),
+ migrations.AlterField(
+ model_name='administrativeact',
+ name='in_charge',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='adminact_operation_in_charge', to='ishtar_common.Person', verbose_name="Responsable d'op\xe9ration"),
+ ),
+ migrations.AlterField(
+ model_name='administrativeact',
+ name='operation',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='administrative_act', to='archaeological_operations.Operation', verbose_name='Op\xe9ration'),
+ ),
+ migrations.AlterField(
+ model_name='administrativeact',
+ name='operator',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='adminact_operator', to='ishtar_common.Organization', verbose_name="Op\xe9rateur d'arch\xe9ologie pr\xe9ventive"),
+ ),
+ migrations.AlterField(
+ model_name='administrativeact',
+ name='scientist',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='adminact_scientist', to='ishtar_common.Person', verbose_name='Responsable scientifique'),
+ ),
+ migrations.AlterField(
+ model_name='administrativeact',
+ name='search_vector',
+ field=django.contrib.postgres.search.SearchVectorField(blank=True, help_text='Auto-rempli \xe0 la sauvegarde', null=True, verbose_name='Vecteur de recherche'),
+ ),
+ migrations.AlterField(
+ model_name='administrativeact',
+ name='signatory',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='signatory', to='ishtar_common.Person', verbose_name='Signataire'),
+ ),
+ migrations.AlterField(
+ model_name='administrativeact',
+ name='signature_date',
+ field=models.DateField(blank=True, null=True, verbose_name='Date de signature'),
+ ),
+ migrations.AlterField(
+ model_name='administrativeact',
+ name='towns_label',
+ field=models.TextField(blank=True, help_text='Valeur en cache des communes associ\xe9es', null=True, verbose_name='Communes'),
+ ),
+ migrations.AlterField(
+ model_name='administrativeact',
+ name='treatment',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='administrative_act', to='archaeological_finds.Treatment', verbose_name='Traitement'),
+ ),
+ migrations.AlterField(
+ model_name='administrativeact',
+ name='treatment_file',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='administrative_act', to='archaeological_finds.TreatmentFile', verbose_name='Demande de traitement'),
+ ),
+ migrations.AlterField(
+ model_name='administrativeact',
+ name='year',
+ field=models.IntegerField(blank=True, null=True, verbose_name='Ann\xe9e'),
+ ),
+ migrations.AlterField(
+ model_name='archaeologicalsite',
+ name='cached_label',
+ field=models.TextField(blank=True, db_index=True, null=True, verbose_name='Nom en cache'),
+ ),
+ migrations.AlterField(
+ model_name='archaeologicalsite',
+ name='collaborators',
+ field=models.ManyToManyField(blank=True, related_name='site_collaborator', to='ishtar_common.Person', verbose_name='Collaborateurs'),
+ ),
+ migrations.AlterField(
+ model_name='archaeologicalsite',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='archaeologicalsite',
+ name='discovery_area',
+ field=models.TextField(blank=True, null=True, verbose_name='Zone de d\xe9couverte'),
+ ),
+ migrations.AlterField(
+ model_name='archaeologicalsite',
+ name='history_creator',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Cr\xe9ateur'),
+ ),
+ migrations.AlterField(
+ model_name='archaeologicalsite',
+ name='history_modifier',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Dernier \xe9diteur'),
+ ),
+ migrations.AlterField(
+ model_name='archaeologicalsite',
+ name='locality_cadastral',
+ field=models.TextField(blank=True, null=True, verbose_name='Lieu-dit cadastre'),
+ ),
+ migrations.AlterField(
+ model_name='archaeologicalsite',
+ name='locality_ngi',
+ field=models.TextField(blank=True, null=True, verbose_name='Lieu-dit IGN'),
+ ),
+ migrations.AlterField(
+ model_name='archaeologicalsite',
+ name='multi_polygon',
+ field=django.contrib.gis.db.models.fields.MultiPolygonField(blank=True, null=True, srid=4326, verbose_name='Polygones multi-parties'),
+ ),
+ migrations.AlterField(
+ model_name='archaeologicalsite',
+ name='name',
+ field=models.CharField(blank=True, max_length=200, null=True, verbose_name='Nom'),
+ ),
+ migrations.AlterField(
+ model_name='archaeologicalsite',
+ name='oceanographic_service_localisation',
+ field=models.TextField(blank=True, null=True, verbose_name='Localisation SHOM'),
+ ),
+ migrations.AlterField(
+ model_name='archaeologicalsite',
+ name='periods',
+ field=models.ManyToManyField(blank=True, to='archaeological_operations.Period', verbose_name='P\xe9riodes'),
+ ),
+ migrations.AlterField(
+ model_name='archaeologicalsite',
+ name='reference',
+ field=models.CharField(max_length=200, unique=True, verbose_name='R\xe9f\xe9rence'),
+ ),
+ migrations.AlterField(
+ model_name='archaeologicalsite',
+ name='remains',
+ field=models.ManyToManyField(blank=True, to='archaeological_operations.RemainType', verbose_name='Vestiges'),
+ ),
+ migrations.AlterField(
+ model_name='archaeologicalsite',
+ name='search_vector',
+ field=django.contrib.postgres.search.SearchVectorField(blank=True, help_text='Auto-rempli \xe0 la sauvegarde', null=True, verbose_name='Vecteur de recherche'),
+ ),
+ migrations.AlterField(
+ model_name='archaeologicalsite',
+ name='shipwreck_code',
+ field=models.TextField(blank=True, null=True, verbose_name='Code \xe9pave'),
+ ),
+ migrations.AlterField(
+ model_name='archaeologicalsite',
+ name='shipwreck_name',
+ field=models.TextField(blank=True, null=True, verbose_name="Nom de l'\xe9pave"),
+ ),
+ migrations.AlterField(
+ model_name='archaeologicalsite',
+ name='sinking_date',
+ field=models.DateField(blank=True, null=True, verbose_name='Date de naufrage'),
+ ),
+ migrations.AlterField(
+ model_name='archaeologicalsite',
+ name='top_operation',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='archaeological_operations.Operation', verbose_name='Op\xe9ration chapeau'),
+ ),
+ migrations.AlterField(
+ model_name='archaeologicalsite',
+ name='towns',
+ field=models.ManyToManyField(blank=True, related_name='sites', to='ishtar_common.Town', verbose_name='Communes'),
+ ),
+ migrations.AlterField(
+ model_name='historicaladministrativeact',
+ name='act_object',
+ field=models.TextField(blank=True, max_length=300, null=True, verbose_name='Objet'),
+ ),
+ migrations.AlterField(
+ model_name='historicaladministrativeact',
+ name='departments_label',
+ field=models.TextField(blank=True, help_text='Valeur en cache des d\xe9partements associ\xe9s', null=True, verbose_name='D\xe9partements'),
+ ),
+ migrations.AlterField(
+ model_name='historicaladministrativeact',
+ name='search_vector',
+ field=django.contrib.postgres.search.SearchVectorField(blank=True, help_text='Auto-rempli \xe0 la sauvegarde', null=True, verbose_name='Vecteur de recherche'),
+ ),
+ migrations.AlterField(
+ model_name='historicaladministrativeact',
+ name='signature_date',
+ field=models.DateField(blank=True, null=True, verbose_name='Date de signature'),
+ ),
+ migrations.AlterField(
+ model_name='historicaladministrativeact',
+ name='towns_label',
+ field=models.TextField(blank=True, help_text='Valeur en cache des communes associ\xe9es', null=True, verbose_name='Communes'),
+ ),
+ migrations.AlterField(
+ model_name='historicaladministrativeact',
+ name='year',
+ field=models.IntegerField(blank=True, null=True, verbose_name='Ann\xe9e'),
+ ),
+ migrations.AlterField(
+ model_name='historicalarchaeologicalsite',
+ name='cached_label',
+ field=models.TextField(blank=True, db_index=True, null=True, verbose_name='Nom en cache'),
+ ),
+ migrations.AlterField(
+ model_name='historicalarchaeologicalsite',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='historicalarchaeologicalsite',
+ name='discovery_area',
+ field=models.TextField(blank=True, null=True, verbose_name='Zone de d\xe9couverte'),
+ ),
+ migrations.AlterField(
+ model_name='historicalarchaeologicalsite',
+ name='locality_cadastral',
+ field=models.TextField(blank=True, null=True, verbose_name='Lieu-dit cadastre'),
+ ),
+ migrations.AlterField(
+ model_name='historicalarchaeologicalsite',
+ name='locality_ngi',
+ field=models.TextField(blank=True, null=True, verbose_name='Lieu-dit IGN'),
+ ),
+ migrations.AlterField(
+ model_name='historicalarchaeologicalsite',
+ name='multi_polygon',
+ field=django.contrib.gis.db.models.fields.MultiPolygonField(blank=True, null=True, srid=4326, verbose_name='Polygones multi-parties'),
+ ),
+ migrations.AlterField(
+ model_name='historicalarchaeologicalsite',
+ name='name',
+ field=models.CharField(blank=True, max_length=200, null=True, verbose_name='Nom'),
+ ),
+ migrations.AlterField(
+ model_name='historicalarchaeologicalsite',
+ name='oceanographic_service_localisation',
+ field=models.TextField(blank=True, null=True, verbose_name='Localisation SHOM'),
+ ),
+ migrations.AlterField(
+ model_name='historicalarchaeologicalsite',
+ name='reference',
+ field=models.CharField(db_index=True, max_length=200, verbose_name='R\xe9f\xe9rence'),
+ ),
+ migrations.AlterField(
+ model_name='historicalarchaeologicalsite',
+ name='search_vector',
+ field=django.contrib.postgres.search.SearchVectorField(blank=True, help_text='Auto-rempli \xe0 la sauvegarde', null=True, verbose_name='Vecteur de recherche'),
+ ),
+ migrations.AlterField(
+ model_name='historicalarchaeologicalsite',
+ name='shipwreck_code',
+ field=models.TextField(blank=True, null=True, verbose_name='Code \xe9pave'),
+ ),
+ migrations.AlterField(
+ model_name='historicalarchaeologicalsite',
+ name='shipwreck_name',
+ field=models.TextField(blank=True, null=True, verbose_name="Nom de l'\xe9pave"),
+ ),
+ migrations.AlterField(
+ model_name='historicalarchaeologicalsite',
+ name='sinking_date',
+ field=models.DateField(blank=True, null=True, verbose_name='Date de naufrage'),
+ ),
+ migrations.AlterField(
+ model_name='historicaloperation',
+ name='abstract',
+ field=models.TextField(blank=True, null=True, verbose_name='R\xe9sum\xe9'),
+ ),
+ migrations.AlterField(
+ model_name='historicaloperation',
+ name='address',
+ field=models.TextField(blank=True, null=True, verbose_name='Adresse / Lieu-dit'),
+ ),
+ migrations.AlterField(
+ model_name='historicaloperation',
+ name='cached_label',
+ field=models.CharField(blank=True, db_index=True, max_length=500, null=True, verbose_name='Nom en cache'),
+ ),
+ migrations.AlterField(
+ model_name='historicaloperation',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='historicaloperation',
+ name='common_name',
+ field=models.TextField(blank=True, null=True, verbose_name='Nom g\xe9n\xe9rique'),
+ ),
+ migrations.AlterField(
+ model_name='historicaloperation',
+ name='cost',
+ field=models.IntegerField(blank=True, null=True, verbose_name='Co\xfbt (euros)'),
+ ),
+ migrations.AlterField(
+ model_name='historicaloperation',
+ name='creation_date',
+ field=models.DateField(default=datetime.date.today, verbose_name='Date de cr\xe9ation'),
+ ),
+ migrations.AlterField(
+ model_name='historicaloperation',
+ name='documentation_deadline',
+ field=models.DateField(blank=True, null=True, verbose_name='Date limite de versement de la documentation'),
+ ),
+ migrations.AlterField(
+ model_name='historicaloperation',
+ name='documentation_received',
+ field=models.NullBooleanField(verbose_name='Documentation re\xe7ue'),
+ ),
+ migrations.AlterField(
+ model_name='historicaloperation',
+ name='effective_man_days',
+ field=models.IntegerField(blank=True, null=True, verbose_name='Jours-hommes effectifs'),
+ ),
+ migrations.AlterField(
+ model_name='historicaloperation',
+ name='end_date',
+ field=models.DateField(blank=True, null=True, verbose_name='Date de cl\xf4ture'),
+ ),
+ migrations.AlterField(
+ model_name='historicaloperation',
+ name='excavation_end_date',
+ field=models.DateField(blank=True, null=True, verbose_name='Date de fin de chantier'),
+ ),
+ migrations.AlterField(
+ model_name='historicaloperation',
+ name='finds_deadline',
+ field=models.DateField(blank=True, null=True, verbose_name='Date limite de versement du mobilier'),
+ ),
+ migrations.AlterField(
+ model_name='historicaloperation',
+ name='finds_received',
+ field=models.NullBooleanField(verbose_name='Mobilier re\xe7u'),
+ ),
+ migrations.AlterField(
+ model_name='historicaloperation',
+ name='geoarchaeological_context_prescription',
+ field=models.NullBooleanField(verbose_name='Prescription sur un contexte g\xe9oarch\xe9ologique'),
+ ),
+ migrations.AlterField(
+ model_name='historicaloperation',
+ name='large_area_prescription',
+ field=models.NullBooleanField(verbose_name='Prescription sur une vaste surface'),
+ ),
+ migrations.AlterField(
+ model_name='historicaloperation',
+ name='multi_polygon',
+ field=django.contrib.gis.db.models.fields.MultiPolygonField(blank=True, null=True, srid=4326, verbose_name='Polygones multi-parties'),
+ ),
+ migrations.AlterField(
+ model_name='historicaloperation',
+ name='name_of_the_protagonist',
+ field=models.TextField(blank=True, null=True, verbose_name='Nom du protagoniste'),
+ ),
+ migrations.AlterField(
+ model_name='historicaloperation',
+ name='official_report_number',
+ field=models.TextField(blank=True, null=True, verbose_name='Num\xe9ro de proc\xe8s-verbal'),
+ ),
+ migrations.AlterField(
+ model_name='historicaloperation',
+ name='old_code',
+ field=models.CharField(blank=True, max_length=200, null=True, verbose_name='Ancien code'),
+ ),
+ migrations.AlterField(
+ model_name='historicaloperation',
+ name='operation_code',
+ field=models.IntegerField(blank=True, null=True, verbose_name='R\xe9f\xe9rence num\xe9rique'),
+ ),
+ migrations.AlterField(
+ model_name='historicaloperation',
+ name='operator_reference',
+ field=models.CharField(blank=True, max_length=20, null=True, verbose_name="R\xe9f\xe9rence de l'op\xe9rateur"),
+ ),
+ migrations.AlterField(
+ model_name='historicaloperation',
+ name='optional_man_days',
+ field=models.IntegerField(blank=True, null=True, verbose_name='Jours-hommes optionnels'),
+ ),
+ migrations.AlterField(
+ model_name='historicaloperation',
+ name='relation_image',
+ field=models.TextField(blank=True, max_length=100, null=True, verbose_name='Image des relations (SVG g\xe9n\xe9r\xe9)'),
+ ),
+ migrations.AlterField(
+ model_name='historicaloperation',
+ name='report_delivery_date',
+ field=models.DateField(blank=True, null=True, verbose_name='Date de livraison du rapport'),
+ ),
+ migrations.AlterField(
+ model_name='historicaloperation',
+ name='scheduled_man_days',
+ field=models.IntegerField(blank=True, null=True, verbose_name='Jours-hommes pr\xe9vus'),
+ ),
+ migrations.AlterField(
+ model_name='historicaloperation',
+ name='scientific_documentation_comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire relatif \xe0 la documentation scientifique'),
+ ),
+ migrations.AlterField(
+ model_name='historicaloperation',
+ name='search_vector',
+ field=django.contrib.postgres.search.SearchVectorField(blank=True, help_text='Auto-rempli \xe0 la sauvegarde', null=True, verbose_name='Vecteur de recherche'),
+ ),
+ migrations.AlterField(
+ model_name='historicaloperation',
+ name='seizure_name',
+ field=models.TextField(blank=True, null=True, verbose_name='Nom de la saisie'),
+ ),
+ migrations.AlterField(
+ model_name='historicaloperation',
+ name='start_date',
+ field=models.DateField(blank=True, null=True, verbose_name='Date de d\xe9but'),
+ ),
+ migrations.AlterField(
+ model_name='historicaloperation',
+ name='virtual_operation',
+ field=models.BooleanField(default=False, help_text="Si coch\xe9, cela signifie que cette op\xe9ration n'a pas \xe9t\xe9 officiellement enregistr\xe9e.", verbose_name='Op\xe9ration virtuelle'),
+ ),
+ migrations.AlterField(
+ model_name='historicaloperation',
+ name='year',
+ field=models.IntegerField(blank=True, null=True, verbose_name='Ann\xe9e'),
+ ),
+ migrations.AlterField(
+ model_name='historicaloperation',
+ name='zoning_prescription',
+ field=models.NullBooleanField(verbose_name='Prescription sur zonage'),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='abstract',
+ field=models.TextField(blank=True, null=True, verbose_name='R\xe9sum\xe9'),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='address',
+ field=models.TextField(blank=True, null=True, verbose_name='Adresse / Lieu-dit'),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='archaeological_sites',
+ field=models.ManyToManyField(blank=True, related_name='operations', to='archaeological_operations.ArchaeologicalSite', verbose_name='Entit\xe9s arch\xe9ologiques'),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='associated_file',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='operations', to='archaeological_files.File', verbose_name='Dossier'),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='cached_label',
+ field=models.CharField(blank=True, db_index=True, max_length=500, null=True, verbose_name='Nom en cache'),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='collaborators',
+ field=models.ManyToManyField(blank=True, related_name='operation_collaborator', to='ishtar_common.Person', verbose_name='Collaborateurs'),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='common_name',
+ field=models.TextField(blank=True, null=True, verbose_name='Nom g\xe9n\xe9rique'),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='cost',
+ field=models.IntegerField(blank=True, null=True, verbose_name='Co\xfbt (euros)'),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='creation_date',
+ field=models.DateField(default=datetime.date.today, verbose_name='Date de cr\xe9ation'),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='documentation_deadline',
+ field=models.DateField(blank=True, null=True, verbose_name='Date limite de versement de la documentation'),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='documentation_received',
+ field=models.NullBooleanField(verbose_name='Documentation re\xe7ue'),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='effective_man_days',
+ field=models.IntegerField(blank=True, null=True, verbose_name='Jours-hommes effectifs'),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='end_date',
+ field=models.DateField(blank=True, null=True, verbose_name='Date de cl\xf4ture'),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='excavation_end_date',
+ field=models.DateField(blank=True, null=True, verbose_name='Date de fin de chantier'),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='finds_deadline',
+ field=models.DateField(blank=True, null=True, verbose_name='Date limite de versement du mobilier'),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='finds_received',
+ field=models.NullBooleanField(verbose_name='Mobilier re\xe7u'),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='geoarchaeological_context_prescription',
+ field=models.NullBooleanField(verbose_name='Prescription sur un contexte g\xe9oarch\xe9ologique'),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='history_creator',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Cr\xe9ateur'),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='history_modifier',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Dernier \xe9diteur'),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='in_charge',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='operation_responsability', to='ishtar_common.Person', verbose_name='Responsable'),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='large_area_prescription',
+ field=models.NullBooleanField(verbose_name='Prescription sur une vaste surface'),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='multi_polygon',
+ field=django.contrib.gis.db.models.fields.MultiPolygonField(blank=True, null=True, srid=4326, verbose_name='Polygones multi-parties'),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='name_of_the_protagonist',
+ field=models.TextField(blank=True, null=True, verbose_name='Nom du protagoniste'),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='official_report_number',
+ field=models.TextField(blank=True, null=True, verbose_name='Num\xe9ro de proc\xe8s-verbal'),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='old_code',
+ field=models.CharField(blank=True, max_length=200, null=True, verbose_name='Ancien code'),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='operation_code',
+ field=models.IntegerField(blank=True, null=True, verbose_name='R\xe9f\xe9rence num\xe9rique'),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='operation_type',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='ishtar_common.OperationType', verbose_name="Type d'op\xe9ration"),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='operator',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='operator', to='ishtar_common.Organization', verbose_name='Op\xe9rateur'),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='operator_reference',
+ field=models.CharField(blank=True, max_length=20, null=True, verbose_name="R\xe9f\xe9rence de l'op\xe9rateur"),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='optional_man_days',
+ field=models.IntegerField(blank=True, null=True, verbose_name='Jours-hommes optionnels'),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='periods',
+ field=models.ManyToManyField(blank=True, to='archaeological_operations.Period', verbose_name='P\xe9riodes'),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='record_quality_type',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='archaeological_operations.RecordQualityType', verbose_name="Qualit\xe9 d'enregistrement"),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='relation_image',
+ field=models.FileField(blank=True, null=True, upload_to=ishtar_common.models.get_image_path, verbose_name='Image des relations (SVG g\xe9n\xe9r\xe9)'),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='remains',
+ field=models.ManyToManyField(blank=True, to='archaeological_operations.RemainType', verbose_name='Vestiges'),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='report_delivery_date',
+ field=models.DateField(blank=True, null=True, verbose_name='Date de livraison du rapport'),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='report_processing',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='archaeological_operations.ReportState', verbose_name='Traitement du rapport'),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='scheduled_man_days',
+ field=models.IntegerField(blank=True, null=True, verbose_name='Jours-hommes pr\xe9vus'),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='scientific_documentation_comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire relatif \xe0 la documentation scientifique'),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='scientist',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='operation_scientist_responsability', to='ishtar_common.Person', verbose_name='Responsable du suivi scientifique'),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='search_vector',
+ field=django.contrib.postgres.search.SearchVectorField(blank=True, help_text='Auto-rempli \xe0 la sauvegarde', null=True, verbose_name='Vecteur de recherche'),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='seizure_name',
+ field=models.TextField(blank=True, null=True, verbose_name='Nom de la saisie'),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='start_date',
+ field=models.DateField(blank=True, null=True, verbose_name='Date de d\xe9but'),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='towns',
+ field=models.ManyToManyField(related_name='operations', to='ishtar_common.Town', verbose_name='Communes'),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='virtual_operation',
+ field=models.BooleanField(default=False, help_text="Si coch\xe9, cela signifie que cette op\xe9ration n'a pas \xe9t\xe9 officiellement enregistr\xe9e.", verbose_name='Op\xe9ration virtuelle'),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='year',
+ field=models.IntegerField(blank=True, null=True, verbose_name='Ann\xe9e'),
+ ),
+ migrations.AlterField(
+ model_name='operation',
+ name='zoning_prescription',
+ field=models.NullBooleanField(verbose_name='Prescription sur zonage'),
+ ),
+ migrations.AlterField(
+ model_name='operationtypeold',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='operationtypeold',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='operationtypeold',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='operationtypeold',
+ name='order',
+ field=models.IntegerField(default=1, verbose_name='Ordre'),
+ ),
+ migrations.AlterField(
+ model_name='operationtypeold',
+ name='preventive',
+ field=models.BooleanField(default=True, verbose_name='Est du pr\xe9ventif'),
+ ),
+ migrations.AlterField(
+ model_name='operationtypeold',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ migrations.AlterField(
+ model_name='parcel',
+ name='address',
+ field=models.TextField(blank=True, null=True, verbose_name='Adresse - Lieu-dit'),
+ ),
+ migrations.AlterField(
+ model_name='parcel',
+ name='associated_file',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='parcels', to='archaeological_files.File', verbose_name='Dossier'),
+ ),
+ migrations.AlterField(
+ model_name='parcel',
+ name='auto_external_id',
+ field=models.BooleanField(default=False, verbose_name="L'identifiant est attribu\xe9 automatiquement"),
+ ),
+ migrations.AlterField(
+ model_name='parcel',
+ name='cached_label',
+ field=models.TextField(blank=True, db_index=True, null=True, verbose_name='Nom en cache'),
+ ),
+ migrations.AlterField(
+ model_name='parcel',
+ name='external_id',
+ field=models.CharField(blank=True, max_length=100, null=True, verbose_name='Identifiant'),
+ ),
+ migrations.AlterField(
+ model_name='parcel',
+ name='history_creator',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Cr\xe9ateur'),
+ ),
+ migrations.AlterField(
+ model_name='parcel',
+ name='history_modifier',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Dernier \xe9diteur'),
+ ),
+ migrations.AlterField(
+ model_name='parcel',
+ name='operation',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='parcels', to='archaeological_operations.Operation', verbose_name='Op\xe9ration'),
+ ),
+ migrations.AlterField(
+ model_name='parcel',
+ name='parcel_number',
+ field=models.CharField(blank=True, max_length=6, null=True, verbose_name='Num\xe9ro de parcelle'),
+ ),
+ migrations.AlterField(
+ model_name='parcel',
+ name='public_domain',
+ field=models.BooleanField(default=False, verbose_name='Domaine public'),
+ ),
+ migrations.AlterField(
+ model_name='parcel',
+ name='search_vector',
+ field=django.contrib.postgres.search.SearchVectorField(blank=True, help_text='Auto-rempli \xe0 la sauvegarde', null=True, verbose_name='Vecteur de recherche'),
+ ),
+ migrations.AlterField(
+ model_name='parcel',
+ name='town',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='parcels', to='ishtar_common.Town', verbose_name='Commune'),
+ ),
+ migrations.AlterField(
+ model_name='parcel',
+ name='year',
+ field=models.IntegerField(blank=True, null=True, verbose_name='Ann\xe9e'),
+ ),
+ migrations.AlterField(
+ model_name='parcelowner',
+ name='end_date',
+ field=models.DateField(verbose_name='Date de fin'),
+ ),
+ migrations.AlterField(
+ model_name='parcelowner',
+ name='history_creator',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Cr\xe9ateur'),
+ ),
+ migrations.AlterField(
+ model_name='parcelowner',
+ name='history_modifier',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Dernier \xe9diteur'),
+ ),
+ migrations.AlterField(
+ model_name='parcelowner',
+ name='owner',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='parcel_owner', to='ishtar_common.Person', verbose_name='Propri\xe9taire'),
+ ),
+ migrations.AlterField(
+ model_name='parcelowner',
+ name='parcel',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='owners', to='archaeological_operations.Parcel', verbose_name='Parcelle'),
+ ),
+ migrations.AlterField(
+ model_name='parcelowner',
+ name='search_vector',
+ field=django.contrib.postgres.search.SearchVectorField(blank=True, help_text='Auto-rempli \xe0 la sauvegarde', null=True, verbose_name='Vecteur de recherche'),
+ ),
+ migrations.AlterField(
+ model_name='parcelowner',
+ name='start_date',
+ field=models.DateField(verbose_name='Date de d\xe9but'),
+ ),
+ migrations.AlterField(
+ model_name='period',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='period',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='period',
+ name='end_date',
+ field=models.IntegerField(blank=True, null=True, verbose_name='Date de fin'),
+ ),
+ migrations.AlterField(
+ model_name='period',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='period',
+ name='order',
+ field=models.IntegerField(verbose_name='Ordre'),
+ ),
+ migrations.AlterField(
+ model_name='period',
+ name='parent',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='archaeological_operations.Period', verbose_name='P\xe9riode parente'),
+ ),
+ migrations.AlterField(
+ model_name='period',
+ name='start_date',
+ field=models.IntegerField(blank=True, null=True, verbose_name='Date de d\xe9but'),
+ ),
+ migrations.AlterField(
+ model_name='period',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ migrations.AlterField(
+ model_name='recordqualitytype',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='recordqualitytype',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='recordqualitytype',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='recordqualitytype',
+ name='order',
+ field=models.IntegerField(verbose_name='Ordre'),
+ ),
+ migrations.AlterField(
+ model_name='recordqualitytype',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ migrations.AlterField(
+ model_name='relationtype',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='relationtype',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='relationtype',
+ name='inverse_relation',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='archaeological_operations.RelationType', verbose_name='Relation inverse'),
+ ),
+ migrations.AlterField(
+ model_name='relationtype',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='relationtype',
+ name='logical_relation',
+ field=models.CharField(blank=True, choices=[(b'above', 'Au-dessus'), (b'bellow', 'En dessous'), (b'equal', '\xc9gal')], max_length=10, null=True, verbose_name='Relation logique'),
+ ),
+ migrations.AlterField(
+ model_name='relationtype',
+ name='order',
+ field=models.IntegerField(default=1, verbose_name='Ordre'),
+ ),
+ migrations.AlterField(
+ model_name='relationtype',
+ name='symmetrical',
+ field=models.BooleanField(verbose_name='Sym\xe9trique'),
+ ),
+ migrations.AlterField(
+ model_name='relationtype',
+ name='tiny_label',
+ field=models.CharField(blank=True, max_length=50, null=True, verbose_name='D\xe9nomination courte'),
+ ),
+ migrations.AlterField(
+ model_name='relationtype',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ migrations.AlterField(
+ model_name='remaintype',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='remaintype',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='remaintype',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='remaintype',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ migrations.AlterField(
+ model_name='reportstate',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='reportstate',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='reportstate',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='reportstate',
+ name='order',
+ field=models.IntegerField(verbose_name='Ordre'),
+ ),
+ migrations.AlterField(
+ model_name='reportstate',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ ]
diff --git a/archaeological_operations/models.py b/archaeological_operations/models.py
index 872d2bf4e..d8233ba0f 100644
--- a/archaeological_operations/models.py
+++ b/archaeological_operations/models.py
@@ -108,6 +108,7 @@ class ArchaeologicalSite(BaseHistorizedItem, OwnPerms, ValueGetter,
SHOW_URL = 'show-site'
TABLE_COLS = ['reference', 'name', 'towns_label', 'periods', 'remains']
SLUG = 'site'
+ LONG_SLUG = 'archaeologicalsite'
BASE_SEARCH_VECTORS = [
"comment",
@@ -119,6 +120,8 @@ class ArchaeologicalSite(BaseHistorizedItem, OwnPerms, ValueGetter,
"reference",
"shipwreck_code",
"shipwreck_name",
+ "drassm_number",
+ "affmar_number",
]
M2M_SEARCH_VECTORS = ["periods__label", "remains__label", "towns__name"]
PARENT_SEARCH_VECTORS = ['operations']
@@ -192,6 +195,14 @@ class ArchaeologicalSite(BaseHistorizedItem, OwnPerms, ValueGetter,
pgettext_lazy("key for text search", u"top-operation"),
'top_operation__cached_label__icontains'
),
+ 'drassm_number': (
+ pgettext_lazy("key for text search", u"numero-drassm"),
+ 'drassm_number__iexact'
+ ),
+ 'affmar_number': (
+ pgettext_lazy("key for text search", u"numero-affmar"),
+ 'affmar_number__iexact'
+ ),
}
for v in ALT_NAMES.values():
for language_code, language_lbl in settings.LANGUAGES:
@@ -243,6 +254,10 @@ class ArchaeologicalSite(BaseHistorizedItem, OwnPerms, ValueGetter,
_(u"Sinking date"), null=True, blank=True)
discovery_area = models.TextField(
_(u"Discovery area"), null=True, blank=True)
+ affmar_number = models.CharField(_(u"AffMar number"), max_length=100,
+ null=True, blank=True)
+ drassm_number = models.CharField(_(u"DRASSM number"), max_length=100,
+ null=True, blank=True)
# gis
point = models.PointField(_(u"Point"), blank=True, null=True)
@@ -290,6 +305,9 @@ class ArchaeologicalSite(BaseHistorizedItem, OwnPerms, ValueGetter,
'operations__context_record__base_finds__find__container__responsible__',
Warehouse._get_query_owns_dicts(ishtaruser)
) | cls._construct_query_own(
+ 'operations__context_record__base_finds__find__basket__',
+ [{"shared_with": ishtaruser, "shared_write_with": ishtaruser}]
+ ) | cls._construct_query_own(
'operations__context_record__base_finds__find__container__location__',
Warehouse._get_query_owns_dicts(ishtaruser)
) | cls._construct_query_own(
@@ -541,6 +559,7 @@ class Operation(ClosedItem, BaseHistorizedItem, OwnPerms, ValueGetter,
"scientist__cached_label",
"scientific_documentation_comment",
"seizure_name",
+ "drassm_code",
]
PROPERTY_SEARCH_VECTORS = [
"full_reference", "short_code_patriarche"
@@ -705,6 +724,10 @@ class Operation(ClosedItem, BaseHistorizedItem, OwnPerms, ValueGetter,
pgettext_lazy("key for text search", u"finds-deadline-after"),
'finds_deadline__gte'
),
+ 'drassm_code': (
+ pgettext_lazy("key for text search", u"code-drassm"),
+ 'drassm_code__iexact'
+ ),
}
for v in ALT_NAMES.values():
for language_code, language_lbl in settings.LANGUAGES:
@@ -783,34 +806,35 @@ class Operation(ClosedItem, BaseHistorizedItem, OwnPerms, ValueGetter,
blank=True, null=True)
old_code = models.CharField(_(u"Old code"), max_length=200, null=True,
blank=True)
- if settings.COUNTRY == 'fr':
- code_patriarche = models.TextField(u"Code PATRIARCHE", null=True,
- blank=True, unique=True)
- TABLE_COLS = ['code_patriarche'] + TABLE_COLS
- BASE_SEARCH_VECTORS = ['code_patriarche'] + BASE_SEARCH_VECTORS
- # preventive
- fnap_financing = models.FloatField(u"Financement FNAP (%)",
- blank=True, null=True)
- # preventive
- fnap_cost = models.IntegerField(u"Financement FNAP (€)",
- blank=True, null=True)
- # preventive diag
- zoning_prescription = models.NullBooleanField(
- _(u"Prescription on zoning"), blank=True, null=True)
- # preventive diag
- large_area_prescription = models.NullBooleanField(
- _(u"Prescription on large area"), blank=True, null=True)
- geoarchaeological_context_prescription = models.NullBooleanField(
- _(u"Prescription on geoarchaeological context"), blank=True,
- null=True) # preventive diag
- cira_rapporteur = models.ForeignKey(
- Person, related_name='cira_rapporteur', null=True, blank=True,
- on_delete=models.SET_NULL, verbose_name=u"Rapporteur CIRA")
- negative_result = models.NullBooleanField(
- u"Résultat considéré comme négatif", blank=True, null=True)
- cira_date = models.DateField(u"Date avis CIRA", null=True, blank=True)
- eas_number = models.CharField(u"Numéro de l'EA", max_length=20,
- null=True, blank=True)
+ ## fr
+ code_patriarche = models.TextField(u"Code PATRIARCHE", null=True,
+ blank=True, unique=True)
+ TABLE_COLS = ['code_patriarche'] + TABLE_COLS
+ BASE_SEARCH_VECTORS = ['code_patriarche'] + BASE_SEARCH_VECTORS
+ # preventive
+ fnap_financing = models.FloatField(u"Financement FNAP (%)",
+ blank=True, null=True)
+ # preventive
+ fnap_cost = models.IntegerField(u"Financement FNAP (€)",
+ blank=True, null=True)
+ # preventive diag
+ zoning_prescription = models.NullBooleanField(
+ _(u"Prescription on zoning"), blank=True, null=True)
+ # preventive diag
+ large_area_prescription = models.NullBooleanField(
+ _(u"Prescription on large area"), blank=True, null=True)
+ geoarchaeological_context_prescription = models.NullBooleanField(
+ _(u"Prescription on geoarchaeological context"), blank=True,
+ null=True) # preventive diag
+ cira_rapporteur = models.ForeignKey(
+ Person, related_name='cira_rapporteur', null=True, blank=True,
+ on_delete=models.SET_NULL, verbose_name=u"Rapporteur CIRA")
+ negative_result = models.NullBooleanField(
+ u"Résultat considéré comme négatif", blank=True, null=True)
+ cira_date = models.DateField(u"Date avis CIRA", null=True, blank=True)
+ eas_number = models.CharField(u"Numéro de l'EA", max_length=20,
+ null=True, blank=True)
+ ## end fr
operator_reference = models.CharField(
_(u"Operator reference"), max_length=20, null=True, blank=True)
common_name = models.TextField(_(u"Generic name"), null=True, blank=True)
@@ -845,6 +869,9 @@ class Operation(ClosedItem, BaseHistorizedItem, OwnPerms, ValueGetter,
finds_received = models.NullBooleanField(
_(u"Finds received"), blank=True, null=True)
+ # underwater
+ drassm_code = models.CharField(_(u"DRASSM code"), max_length=100,
+ null=True, blank=True)
# judiciary
seizure_name = models.TextField(_(u"Seizure name"), blank=True, null=True)
official_report_number = models.TextField(_(u"Official report number"),
@@ -1040,6 +1067,22 @@ class Operation(ClosedItem, BaseHistorizedItem, OwnPerms, ValueGetter,
finds__base_finds__context_record__operation=self
)
+ def get_extra_actions(self, request):
+ """
+ For sheet template
+ """
+ # url, base_text, icon, extra_text, extra css class, is a quick action
+ actions = super(Operation, self).get_extra_actions(request)
+
+ can_add_cr = self.can_do(request, 'add_contextrecord')
+ if can_add_cr:
+ actions += [
+ (reverse('operation-qa-contextrecord', args=[self.pk]),
+ _(u"Add context record"), "fa fa-plus",
+ _(u"context record"), "", True),
+ ]
+ return actions
+
associated_file_short_label_lbl = _(u"Archaeological file")
full_code_patriarche_lbl = _(u"Code patriarche")
@@ -1131,6 +1174,9 @@ class Operation(ClosedItem, BaseHistorizedItem, OwnPerms, ValueGetter,
'context_record__base_finds__find__container__location__',
Warehouse._get_query_owns_dicts(ishtaruser)
) | cls._construct_query_own(
+ 'context_record__base_finds__find__basket__',
+ [{"shared_with": ishtaruser, "shared_write_with": ishtaruser}]
+ ) | cls._construct_query_own(
'', cls._get_query_owns_dicts(ishtaruser)
)
return q
@@ -1461,6 +1507,7 @@ class AdministrativeAct(BaseHistorizedItem, OwnPerms, ValueGetter):
'act_object', 'signature_date',
'associated_file__cached_label',
'operation__cached_label', 'towns_label']
+ SLUG = "administrativeact"
TABLE_COLS_FILE = [
'full_ref', 'year', 'index', 'act_type',
'act_object', 'associated_file', 'towns_label',
@@ -1826,6 +1873,16 @@ class AdministrativeAct(BaseHistorizedItem, OwnPerms, ValueGetter):
if self.treatment_file:
return self.treatment_file
+ def get_extra_templates(self, request):
+ templates = []
+ for template in self.act_type.associated_template.all():
+ urlname = "generatedoc-administrativeactop"
+ templates.append(
+ (template.name, reverse(
+ urlname, args=[self.pk, template.pk]))
+ )
+ return templates
+
def get_filename(self):
filename = self.related_item.associated_filename
filename = u"-".join(filename.split('-')[:-1]) # remove date
diff --git a/archaeological_operations/templates/ishtar/sheet_operation.html b/archaeological_operations/templates/ishtar/sheet_operation.html
index 6d8d475e4..8801855cd 100644
--- a/archaeological_operations/templates/ishtar/sheet_operation.html
+++ b/archaeological_operations/templates/ishtar/sheet_operation.html
@@ -33,6 +33,7 @@
</div>
<div class="row">
+ {% field_flex_2 "Code DRASSM" item.drassm_code %}
{% field_flex_2 "Old code" item.old_code %}
{% trans "Begining date" as begining_date_label %}
{% field_flex_2 begining_date_label item.start_date|date:"DATE_FORMAT" %}
@@ -195,20 +196,24 @@
{% dynamic_table_document archaeologicalsites_label 'sites' 'operations' item.pk '' output %}
{% endif %}
+{% if item.grouped_parcels %}
{% trans "Associated parcels" as parcels_label %}
{% include "ishtar/blocks/window_tables/parcels.html" %}
+{% endif %}
-{% if item.administrative_act %}
+{% if item.administrative_act.count %}
<h3>{% trans "Administrative acts" %}</h3>
{% table_administrativact "" item.administrative_act.all %}
{% endif %}
{% trans "Document from this operation" as operation_docs %}
+{% if permission_view_own_document or permission_view_document %}
{% if item.documents.count %}
{% dynamic_table_document operation_docs 'documents' 'operations' item.pk '' output %}
{% endif %}
+{% endif %}
-{% if view_own_contextrecord or view_contextrecord %}
+{% if permission_view_own_contextrecord or permission_view_contextrecord %}
{% if item.context_record.count %}
{% trans "Context records" as cr_lab %}
{% dynamic_table_document cr_lab 'context_records_for_ope' 'operation_id' item.pk 'TABLE_COLS_FOR_OPE' output %}
@@ -219,23 +224,28 @@
{% dynamic_table_document cr_rels 'context_records_relations_detail' 'left_record__operation' item.pk '' output %}
{% endif %}
+{% if permission_view_own_document or permission_view_document %}
{% if item.context_record_docs_q.count %}
{% trans "Documents from associated context records" as cr_docs %}
{% dynamic_table_document cr_docs 'documents' 'context_records__operation' item.pk '' output %}
{% endif %}
{% endif %}
+{% endif %}
+
{% if item.finds %}
{% trans "Finds" as finds %}
{% dynamic_table_document finds 'finds_for_ope' 'base_finds__context_record__operation' item.pk 'TABLE_COLS_FOR_OPE' output %}
{% endif %}
+{% if permission_view_own_document or permission_view_document %}
{% if item.find_docs_q.count %}
{% trans "Documents from associated finds" as finds_docs %}
{% dynamic_table_document finds_docs 'documents' 'finds__base_finds__context_record__operation' item.pk '' output %}
{% endif %}
+{% endif %}
-{% if view_own_container or view_container %}
+{% if permission_view_own_container or permission_view_container %}
{% if item.containers_q.count %}
{% trans "Associated containers" as containers_lbl %}
{% dynamic_table_document containers_lbl 'containers' 'finds__base_finds__context_record__operation' item.pk '' output %}
diff --git a/archaeological_operations/templates/ishtar/sheet_site.html b/archaeological_operations/templates/ishtar/sheet_site.html
index 8f8d018f6..0108d3db6 100644
--- a/archaeological_operations/templates/ishtar/sheet_site.html
+++ b/archaeological_operations/templates/ishtar/sheet_site.html
@@ -49,10 +49,12 @@
</div>
{% endif %}
-{% if item.oceanographic_service_localisation or item.shipwreck_code or item.sinking_date or item.discovery_area or item.shipwreck_name %}
+{% if item.affmar_number or item.drassm_number or item.oceanographic_service_localisation or item.shipwreck_code or item.sinking_date or item.discovery_area or item.shipwreck_name %}
<h3>{% trans "Underwater"%}</h3>
<div class="row">
+ {% field_flex "Numéro AffMar" item.affmar_number %}
+ {% field_flex "Numéro DRASSM" item.drassm_number %}
{% field_flex "Shipwreck name" item.shipwreck_name %}
{% field_flex "Shipwreck code" item.shipwreck_code %}
{% field_flex "Sinking date" item.sinking_date %}
diff --git a/archaeological_operations/views.py b/archaeological_operations/views.py
index 48d7c4a4f..06b8b6ce9 100644
--- a/archaeological_operations/views.py
+++ b/archaeological_operations/views.py
@@ -52,6 +52,7 @@ from ishtar_common.forms import ClosingDateFormSelection, FinalForm, \
from ishtar_common.models import get_current_profile, IshtarSiteProfile, \
DocumentTemplate
from ishtar_common.utils import put_session_message, check_rights_condition
+from ishtar_common.views import gen_generate_doc
from ishtar_common.views_item import get_item, show_item, revert_item, new_item
from ishtar_common.wizards import SearchWizard
@@ -466,30 +467,7 @@ administrativact_register_wizard = SearchWizard.as_view([
url_name='administrativact_register',)
-def generatedoc_administrativeactop(request, pk, template_pk=None):
- if (not request.user.has_perm(
- 'ishtar_common.view_operation', models.Operation)
- and not request.user.has_perm(
- 'ishtar_common.view_own_operation', models.Operation)):
- return HttpResponse(content_type='text/plain')
- try:
- act_file = models.AdministrativeAct.objects.get(pk=pk)
- doc = act_file.publish(template_pk)
- except models.AdministrativeAct.DoesNotExist:
- doc = None
- if doc:
- MIMES = {'odt': 'application/vnd.oasis.opendocument.text',
- 'ods': 'application/vnd.oasis.opendocument.spreadsheet'}
- ext = doc.split('.')[-1]
- doc_name = act_file.get_filename() + "." + ext
- mimetype = 'text/csv'
- if ext in MIMES:
- mimetype = MIMES[ext]
- response = HttpResponse(open(doc), content_type=mimetype)
- response['Content-Disposition'] = 'attachment; filename=%s' % \
- doc_name
- return response
- return HttpResponse(content_type='text/plain')
+generatedoc_administrativeactop = gen_generate_doc(models.AdministrativeAct)
def administrativeactfile_document(
diff --git a/archaeological_operations/wizards.py b/archaeological_operations/wizards.py
index de38beb95..798e622b4 100644
--- a/archaeological_operations/wizards.py
+++ b/archaeological_operations/wizards.py
@@ -332,7 +332,7 @@ class OperationAdministrativeActWizard(OperationWizard):
except models.AdministrativeAct.DoesNotExist:
return
- def get_extra_model(self, dct, form_list):
+ def get_extra_model(self, dct, m2m, form_list):
dct['history_modifier'] = self.request.user
return dct
diff --git a/archaeological_warehouse/forms.py b/archaeological_warehouse/forms.py
index 954c01918..2dc963ca0 100644
--- a/archaeological_warehouse/forms.py
+++ b/archaeological_warehouse/forms.py
@@ -18,6 +18,7 @@
# See the file COPYING for details.
from collections import OrderedDict
+import datetime
from django import forms
from django.conf import settings
@@ -294,7 +295,9 @@ class BasePackagingForm(SelectFindBasketForm):
associated_model=Person, new=True),
validators=[valid_id(Person)])
start_date = forms.DateField(
- label=_(u"Date"), required=False, widget=DatePicker)
+ label=_(u"Date"), required=False, widget=DatePicker,
+ initial=datetime.date.today
+ )
class FindPackagingFormSelection(FindMultipleFormSelection):
diff --git a/archaeological_warehouse/ishtar_menu.py b/archaeological_warehouse/ishtar_menu.py
index b697c4dd3..414b0431d 100644
--- a/archaeological_warehouse/ishtar_menu.py
+++ b/archaeological_warehouse/ishtar_menu.py
@@ -29,14 +29,6 @@ import models
MENU_SECTIONS = [
- (70, SectionItem('treatment_management', _(u"Treatment"),
- profile_restriction='warehouse',
- css='menu-warehouse',
- childs=[
- MenuItem('warehouse_packaging', _(u"Packaging"),
- model=Treatment,
- access_controls=['add_treatment', 'add_own_treatment']),
- ])),
(80, SectionItem('warehouse', _(u"Warehouse"),
profile_restriction='warehouse',
css='menu-warehouse',
diff --git a/archaeological_warehouse/locale/django.pot b/archaeological_warehouse/locale/django.pot
index 139895395..ac527e894 100644
--- a/archaeological_warehouse/locale/django.pot
+++ b/archaeological_warehouse/locale/django.pot
@@ -9,315 +9,315 @@
msgid ""
msgstr ""
-#: forms.py:41 forms.py:113 ishtar_menu.py:40 models.py:94 models.py:258
+#: forms.py:42 forms.py:114 ishtar_menu.py:32 models.py:95 models.py:259
#: templates/ishtar/sheet_warehouse.html:4
msgid "Warehouse"
msgstr ""
-#: forms.py:50 forms.py:55 models.py:622
+#: forms.py:51 forms.py:56 models.py:638
msgid "Division"
msgstr ""
-#: forms.py:57 models.py:286
+#: forms.py:58 models.py:287
msgid "Order"
msgstr ""
-#: forms.py:71
+#: forms.py:72
msgid "There are identical divisions."
msgstr ""
-#: forms.py:76 models.py:83
+#: forms.py:77 models.py:84
msgid "Divisions"
msgstr ""
-#: forms.py:77
+#: forms.py:78
msgid "Warehouse - 020 - Divisions"
msgstr ""
-#: forms.py:85 forms.py:254
+#: forms.py:86 forms.py:255
msgid "Full text search"
msgstr ""
-#: forms.py:88 forms.py:119 models.py:75 models.py:255
+#: forms.py:89 forms.py:120 models.py:76 models.py:256
msgid "Name"
msgstr ""
-#: forms.py:89 forms.py:121 models.py:39 models.py:77
+#: forms.py:90 forms.py:122 models.py:40 models.py:78
msgid "Warehouse type"
msgstr ""
-#: forms.py:101 views.py:108
+#: forms.py:102 views.py:120
msgid "Warehouse search"
msgstr ""
-#: forms.py:114
+#: forms.py:115
msgid "Warehouse - 010 - General"
msgstr ""
-#: forms.py:124 models.py:80
+#: forms.py:125 models.py:81
msgid "Person in charge"
msgstr ""
-#: forms.py:130 forms.py:198 models.py:81 models.py:381
+#: forms.py:131 forms.py:199 models.py:82 models.py:383
msgid "Comment"
msgstr ""
-#: forms.py:132
+#: forms.py:133
msgid "Address"
msgstr ""
-#: forms.py:134
+#: forms.py:135
msgid "Address complement"
msgstr ""
-#: forms.py:136
+#: forms.py:137
msgid "Postal code"
msgstr ""
-#: forms.py:138
+#: forms.py:139
msgid "Town"
msgstr ""
-#: forms.py:139
+#: forms.py:140
msgid "Country"
msgstr ""
-#: forms.py:141
+#: forms.py:142
msgid "Phone"
msgstr ""
-#: forms.py:142
+#: forms.py:143
msgid "Mobile phone"
msgstr ""
-#: forms.py:167 forms.py:168
+#: forms.py:168 forms.py:169
msgid "Would you like to delete this warehouse?"
msgstr ""
-#: forms.py:172 models.py:395 models.py:619
+#: forms.py:173 models.py:397 models.py:635
#: templates/ishtar/sheet_container.html:4
msgid "Container"
msgstr ""
-#: forms.py:173
+#: forms.py:174
msgid "Container - 010 - General"
msgstr ""
-#: forms.py:179 forms.py:261 models.py:301
+#: forms.py:180 forms.py:262 models.py:302
msgid "Ref."
msgstr ""
-#: forms.py:180 models.py:389
+#: forms.py:181 models.py:391
msgid "Old reference"
msgstr ""
-#: forms.py:182 forms.py:260 models.py:304 models.py:379
+#: forms.py:183 forms.py:261 models.py:306 models.py:381
msgid "Container type"
msgstr ""
-#: forms.py:184 forms.py:258
+#: forms.py:185 forms.py:259
msgid "Current location (warehouse)"
msgstr ""
-#: forms.py:190 forms.py:259 models.py:376
+#: forms.py:191 forms.py:260 models.py:378
msgid "Responsible warehouse"
msgstr ""
-#: forms.py:196
+#: forms.py:197
msgid "Image"
msgstr ""
-#: forms.py:223
+#: forms.py:224
msgid "ID"
msgstr ""
-#: forms.py:245
+#: forms.py:246
msgid "This ID already exists for this warehouse."
msgstr ""
-#: forms.py:272 forms.py:278 views.py:150
+#: forms.py:273 forms.py:279 views.py:162
msgid "Container search"
msgstr ""
-#: forms.py:274 forms.py:280
+#: forms.py:275 forms.py:281
msgid "You should select a container."
msgstr ""
-#: forms.py:275
+#: forms.py:276
msgid "Add a new container"
msgstr ""
-#: forms.py:285 ishtar_menu.py:36 views.py:103
+#: forms.py:286 views.py:115
msgid "Packaging"
msgstr ""
-#: forms.py:291
+#: forms.py:292
msgid "Packager"
msgstr ""
-#: forms.py:297
+#: forms.py:298
msgid "Date"
msgstr ""
-#: forms.py:301
+#: forms.py:304
msgid "Packaged finds"
msgstr ""
-#: forms.py:305
+#: forms.py:308
msgid "Container - 020 - Localisation"
msgstr ""
-#: forms.py:307 models.py:382
+#: forms.py:310 models.py:384
msgid "Localisation"
msgstr ""
-#: forms.py:331 forms.py:332
+#: forms.py:334 forms.py:335
msgid "Would you like to delete this container?"
msgstr ""
-#: ishtar_menu.py:32
-msgid "Treatment"
-msgstr ""
-
-#: ishtar_menu.py:44 ishtar_menu.py:59
+#: ishtar_menu.py:36 ishtar_menu.py:51
msgid "Search"
msgstr ""
-#: ishtar_menu.py:47 ishtar_menu.py:63
+#: ishtar_menu.py:39 ishtar_menu.py:55
msgid "Creation"
msgstr ""
-#: ishtar_menu.py:50 ishtar_menu.py:67
+#: ishtar_menu.py:42 ishtar_menu.py:59
msgid "Modification"
msgstr ""
-#: ishtar_menu.py:53 ishtar_menu.py:71
+#: ishtar_menu.py:45 ishtar_menu.py:63
msgid "Deletion"
msgstr ""
-#: ishtar_menu.py:57 models.py:396 templates/ishtar/sheet_warehouse.html:42
+#: ishtar_menu.py:49 models.py:398 templates/ishtar/sheet_warehouse.html:42
#: templates/ishtar/sheet_warehouse.html:87
msgid "Containers"
msgstr ""
-#: models.py:40
+#: models.py:41
msgid "Warehouse types"
msgstr ""
-#: models.py:60
+#: models.py:61
msgctxt "key for text search"
msgid "name"
msgstr ""
-#: models.py:64 models.py:356
+#: models.py:65 models.py:358
msgctxt "key for text search"
msgid "type"
msgstr ""
-#: models.py:87
+#: models.py:88
msgid "Documents"
msgstr ""
-#: models.py:89 models.py:390
+#: models.py:90 models.py:392
msgid "External ID"
msgstr ""
-#: models.py:91 models.py:392
+#: models.py:92 models.py:394
msgid "External ID is set automatically"
msgstr ""
-#: models.py:95
+#: models.py:96
msgid "Warehouses"
msgstr ""
-#: models.py:257
+#: models.py:258
msgid "Description"
msgstr ""
-#: models.py:262 models.py:263
+#: models.py:263 models.py:264
msgid "Collection"
msgstr ""
-#: models.py:272
+#: models.py:273
msgid "Warehouse division type"
msgstr ""
-#: models.py:273
+#: models.py:274
msgid "Warehouse division types"
msgstr ""
-#: models.py:297
+#: models.py:298
msgid "Length (mm)"
msgstr ""
-#: models.py:298
+#: models.py:299
msgid "Width (mm)"
msgstr ""
-#: models.py:299
+#: models.py:300
msgid "Height (mm)"
msgstr ""
-#: models.py:300
+#: models.py:301
msgid "Volume (l)"
msgstr ""
-#: models.py:305
+#: models.py:307
msgid "Container types"
msgstr ""
-#: models.py:339
+#: models.py:341
msgid "Location - index"
msgstr ""
-#: models.py:340
+#: models.py:342
msgid "Precise localisation"
msgstr ""
-#: models.py:341
+#: models.py:343
msgid "Type"
msgstr ""
-#: models.py:348
+#: models.py:350
msgctxt "key for text search"
msgid "location"
msgstr ""
-#: models.py:352
+#: models.py:354
msgctxt "key for text search"
msgid "responsible-warehouse"
msgstr ""
-#: models.py:360
+#: models.py:362
msgctxt "key for text search"
msgid "reference"
msgstr ""
-#: models.py:373
+#: models.py:375
msgid "Location (warehouse)"
msgstr ""
-#: models.py:380
+#: models.py:382
msgid "Container ref."
msgstr ""
-#: models.py:384
+#: models.py:386
msgid "Cached location"
msgstr ""
-#: models.py:386
+#: models.py:388
msgid "Cached division"
msgstr ""
-#: models.py:623
+#: models.py:584
+msgid "Add treatment"
+msgstr ""
+
+#: models.py:639
msgid "Reference"
msgstr ""
-#: models.py:626
+#: models.py:642
msgid "Container localisation"
msgstr ""
-#: models.py:627
+#: models.py:643
msgid "Container localisations"
msgstr ""
@@ -378,26 +378,26 @@ msgid ""
"change divisions."
msgstr ""
-#: views.py:120
+#: views.py:132
msgid "Warehouse creation"
msgstr ""
-#: views.py:129
+#: views.py:141
msgid "Warehouse modification"
msgstr ""
-#: views.py:145
+#: views.py:157
msgid "Warehouse deletion"
msgstr ""
-#: views.py:161
+#: views.py:173
msgid "Container creation"
msgstr ""
-#: views.py:170
+#: views.py:182
msgid "Container modification"
msgstr ""
-#: views.py:185
+#: views.py:197
msgid "Container deletion"
msgstr ""
diff --git a/archaeological_warehouse/migrations/0026_auto_20181203_1442.py b/archaeological_warehouse/migrations/0026_auto_20181203_1442.py
new file mode 100644
index 000000000..141ac8d2d
--- /dev/null
+++ b/archaeological_warehouse/migrations/0026_auto_20181203_1442.py
@@ -0,0 +1,374 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.10 on 2018-12-03 14:42
+from __future__ import unicode_literals
+
+from django.conf import settings
+import django.contrib.postgres.search
+import django.core.validators
+from django.db import migrations, models
+import django.db.models.deletion
+import re
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('archaeological_warehouse', '0025_auto_20181112_1842'),
+ ]
+
+ operations = [
+ migrations.AlterModelOptions(
+ name='container',
+ options={'ordering': ('cached_label',), 'permissions': (('view_container', 'Can view all Containers'), ('view_own_container', 'Can view own Container'), ('add_own_container', 'Can add own Container'), ('change_own_container', 'Can change own Container'), ('delete_own_container', 'Can delete own Container')), 'verbose_name': 'Contenant', 'verbose_name_plural': 'Contenants'},
+ ),
+ migrations.AlterModelOptions(
+ name='containerlocalisation',
+ options={'ordering': ('container', 'division__order'), 'verbose_name': 'Localisation de contenant', 'verbose_name_plural': 'Localisations de contenant'},
+ ),
+ migrations.AlterModelOptions(
+ name='containertype',
+ options={'ordering': ('label',), 'verbose_name': 'Type de contenant', 'verbose_name_plural': 'Types de contenant'},
+ ),
+ migrations.AlterModelOptions(
+ name='warehouse',
+ options={'permissions': (('view_warehouse', 'Can view all Warehouses'), ('view_own_warehouse', 'Can view own Warehouse'), ('add_own_warehouse', 'Can add own Warehouse'), ('change_own_warehouse', 'Can change own Warehouse'), ('delete_own_warehouse', 'Can delete own Warehouse')), 'verbose_name': 'Lieu de conservation', 'verbose_name_plural': 'Lieux de conservation'},
+ ),
+ migrations.AlterModelOptions(
+ name='warehousedivision',
+ options={'verbose_name': 'Type de division de lieu de conservation', 'verbose_name_plural': 'Types de division de lieu de conservation'},
+ ),
+ migrations.AlterModelOptions(
+ name='warehousetype',
+ options={'ordering': ('label',), 'verbose_name': 'Type de lieu de conservation', 'verbose_name_plural': 'Types de lieu de conservation'},
+ ),
+ migrations.AlterField(
+ model_name='collection',
+ name='history_creator',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Cr\xe9ateur'),
+ ),
+ migrations.AlterField(
+ model_name='collection',
+ name='history_modifier',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Dernier \xe9diteur'),
+ ),
+ migrations.AlterField(
+ model_name='collection',
+ name='name',
+ field=models.CharField(blank=True, max_length=200, null=True, verbose_name='Nom'),
+ ),
+ migrations.AlterField(
+ model_name='collection',
+ name='search_vector',
+ field=django.contrib.postgres.search.SearchVectorField(blank=True, help_text='Auto-rempli \xe0 la sauvegarde', null=True, verbose_name='Vecteur de recherche'),
+ ),
+ migrations.AlterField(
+ model_name='collection',
+ name='warehouse',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='collections', to='archaeological_warehouse.Warehouse', verbose_name='Lieu de conservation'),
+ ),
+ migrations.AlterField(
+ model_name='container',
+ name='auto_external_id',
+ field=models.BooleanField(default=False, verbose_name="L'identifiant est attribu\xe9 automatiquement"),
+ ),
+ migrations.AlterField(
+ model_name='container',
+ name='cached_division',
+ field=models.TextField(blank=True, db_index=True, null=True, verbose_name='Division mise en cache'),
+ ),
+ migrations.AlterField(
+ model_name='container',
+ name='cached_location',
+ field=models.TextField(blank=True, db_index=True, null=True, verbose_name='Localisation - en cache'),
+ ),
+ migrations.AlterField(
+ model_name='container',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='container',
+ name='container_type',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='archaeological_warehouse.ContainerType', verbose_name='Type de contenant'),
+ ),
+ migrations.AlterField(
+ model_name='container',
+ name='external_id',
+ field=models.TextField(blank=True, null=True, verbose_name='Identifiant'),
+ ),
+ migrations.AlterField(
+ model_name='container',
+ name='history_creator',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Cr\xe9ateur'),
+ ),
+ migrations.AlterField(
+ model_name='container',
+ name='history_modifier',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Dernier \xe9diteur'),
+ ),
+ migrations.AlterField(
+ model_name='container',
+ name='location',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='containers', to='archaeological_warehouse.Warehouse', verbose_name='Localisation (lieu de conservation)'),
+ ),
+ migrations.AlterField(
+ model_name='container',
+ name='old_reference',
+ field=models.TextField(blank=True, null=True, verbose_name='Ancienne r\xe9f\xe9rence'),
+ ),
+ migrations.AlterField(
+ model_name='container',
+ name='reference',
+ field=models.TextField(verbose_name='R\xe9f. du contenant'),
+ ),
+ migrations.AlterField(
+ model_name='container',
+ name='responsible',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='owned_containers', to='archaeological_warehouse.Warehouse', verbose_name='Lieu de conservation responsable'),
+ ),
+ migrations.AlterField(
+ model_name='container',
+ name='search_vector',
+ field=django.contrib.postgres.search.SearchVectorField(blank=True, help_text='Auto-rempli \xe0 la sauvegarde', null=True, verbose_name='Vecteur de recherche'),
+ ),
+ migrations.AlterField(
+ model_name='containerlocalisation',
+ name='container',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='division', to='archaeological_warehouse.Container', verbose_name='Contenant'),
+ ),
+ migrations.AlterField(
+ model_name='containerlocalisation',
+ name='reference',
+ field=models.CharField(default=b'', max_length=200, verbose_name='R\xe9f\xe9rence'),
+ ),
+ migrations.AlterField(
+ model_name='containertype',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='containertype',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='containertype',
+ name='height',
+ field=models.IntegerField(blank=True, null=True, verbose_name='Hauteur (mm)'),
+ ),
+ migrations.AlterField(
+ model_name='containertype',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='containertype',
+ name='length',
+ field=models.IntegerField(blank=True, null=True, verbose_name='Longueur (mm)'),
+ ),
+ migrations.AlterField(
+ model_name='containertype',
+ name='reference',
+ field=models.CharField(blank=True, max_length=300, null=True, verbose_name='R\xe9f.'),
+ ),
+ migrations.AlterField(
+ model_name='containertype',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ migrations.AlterField(
+ model_name='containertype',
+ name='width',
+ field=models.IntegerField(blank=True, null=True, verbose_name='Largeur (mm)'),
+ ),
+ migrations.AlterField(
+ model_name='warehouse',
+ name='address',
+ field=models.TextField(blank=True, null=True, verbose_name='Adresse'),
+ ),
+ migrations.AlterField(
+ model_name='warehouse',
+ name='address_complement',
+ field=models.TextField(blank=True, null=True, verbose_name="Compl\xe9ment d'adresse"),
+ ),
+ migrations.AlterField(
+ model_name='warehouse',
+ name='alt_address',
+ field=models.TextField(blank=True, null=True, verbose_name='Autre adresse : adresse'),
+ ),
+ migrations.AlterField(
+ model_name='warehouse',
+ name='alt_address_complement',
+ field=models.TextField(blank=True, null=True, verbose_name="Autre adresse : compl\xe9ment d'adresse"),
+ ),
+ migrations.AlterField(
+ model_name='warehouse',
+ name='alt_address_is_prefered',
+ field=models.BooleanField(default=False, verbose_name="L'adresse alternative est pr\xe9f\xe9r\xe9e"),
+ ),
+ migrations.AlterField(
+ model_name='warehouse',
+ name='alt_country',
+ field=models.CharField(blank=True, max_length=30, null=True, verbose_name='Autre adresse : pays'),
+ ),
+ migrations.AlterField(
+ model_name='warehouse',
+ name='alt_postal_code',
+ field=models.CharField(blank=True, max_length=10, null=True, verbose_name='Autre adresse : code postal'),
+ ),
+ migrations.AlterField(
+ model_name='warehouse',
+ name='alt_town',
+ field=models.CharField(blank=True, max_length=70, null=True, verbose_name='Autre adresse : ville'),
+ ),
+ migrations.AlterField(
+ model_name='warehouse',
+ name='auto_external_id',
+ field=models.BooleanField(default=False, verbose_name="L'identifiant est attribu\xe9 automatiquement"),
+ ),
+ migrations.AlterField(
+ model_name='warehouse',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='warehouse',
+ name='country',
+ field=models.CharField(blank=True, max_length=30, null=True, verbose_name='Pays'),
+ ),
+ migrations.AlterField(
+ model_name='warehouse',
+ name='email',
+ field=models.EmailField(blank=True, max_length=300, null=True, verbose_name='Courriel'),
+ ),
+ migrations.AlterField(
+ model_name='warehouse',
+ name='external_id',
+ field=models.TextField(blank=True, null=True, verbose_name='Identifiant'),
+ ),
+ migrations.AlterField(
+ model_name='warehouse',
+ name='history_creator',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Cr\xe9ateur'),
+ ),
+ migrations.AlterField(
+ model_name='warehouse',
+ name='history_modifier',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Dernier \xe9diteur'),
+ ),
+ migrations.AlterField(
+ model_name='warehouse',
+ name='mobile_phone',
+ field=models.CharField(blank=True, max_length=18, null=True, verbose_name='T\xe9l\xe9phone portable'),
+ ),
+ migrations.AlterField(
+ model_name='warehouse',
+ name='name',
+ field=models.CharField(max_length=200, verbose_name='Nom'),
+ ),
+ migrations.AlterField(
+ model_name='warehouse',
+ name='person_in_charge',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='warehouse_in_charge', to='ishtar_common.Person', verbose_name='Dossier suivi par'),
+ ),
+ migrations.AlterField(
+ model_name='warehouse',
+ name='phone',
+ field=models.CharField(blank=True, max_length=18, null=True, verbose_name='T\xe9l\xe9phone'),
+ ),
+ migrations.AlterField(
+ model_name='warehouse',
+ name='phone2',
+ field=models.CharField(blank=True, max_length=18, null=True, verbose_name='Type de t\xe9l\xe9phone 2'),
+ ),
+ migrations.AlterField(
+ model_name='warehouse',
+ name='phone3',
+ field=models.CharField(blank=True, max_length=18, null=True, verbose_name='T\xe9l\xe9phone 3'),
+ ),
+ migrations.AlterField(
+ model_name='warehouse',
+ name='phone_desc',
+ field=models.CharField(blank=True, max_length=300, null=True, verbose_name='Type de t\xe9l\xe9phone'),
+ ),
+ migrations.AlterField(
+ model_name='warehouse',
+ name='phone_desc2',
+ field=models.CharField(blank=True, max_length=300, null=True, verbose_name='Type de t\xe9l\xe9phone 2'),
+ ),
+ migrations.AlterField(
+ model_name='warehouse',
+ name='phone_desc3',
+ field=models.CharField(blank=True, max_length=300, null=True, verbose_name='Type de t\xe9l\xe9phone 3'),
+ ),
+ migrations.AlterField(
+ model_name='warehouse',
+ name='postal_code',
+ field=models.CharField(blank=True, max_length=10, null=True, verbose_name='Code postal'),
+ ),
+ migrations.AlterField(
+ model_name='warehouse',
+ name='raw_phone',
+ field=models.TextField(blank=True, null=True, verbose_name='T\xe9l\xe9phone brut'),
+ ),
+ migrations.AlterField(
+ model_name='warehouse',
+ name='search_vector',
+ field=django.contrib.postgres.search.SearchVectorField(blank=True, help_text='Auto-rempli \xe0 la sauvegarde', null=True, verbose_name='Vecteur de recherche'),
+ ),
+ migrations.AlterField(
+ model_name='warehouse',
+ name='town',
+ field=models.CharField(blank=True, max_length=70, null=True, verbose_name='Commune'),
+ ),
+ migrations.AlterField(
+ model_name='warehouse',
+ name='warehouse_type',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='archaeological_warehouse.WarehouseType', verbose_name='Type de lieu de conservation'),
+ ),
+ migrations.AlterField(
+ model_name='warehousedivision',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='warehousedivision',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='warehousedivision',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='warehousedivision',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ migrations.AlterField(
+ model_name='warehousedivisionlink',
+ name='order',
+ field=models.IntegerField(default=10, verbose_name='Ordre'),
+ ),
+ migrations.AlterField(
+ model_name='warehousetype',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='warehousetype',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='warehousetype',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='warehousetype',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ ]
diff --git a/archaeological_warehouse/models.py b/archaeological_warehouse/models.py
index 5565bc504..92eaf5d2f 100644
--- a/archaeological_warehouse/models.py
+++ b/archaeological_warehouse/models.py
@@ -21,6 +21,7 @@ import datetime
from django.conf import settings
from django.contrib.gis.db import models
+from django.core.urlresolvers import reverse
from django.db.models import Q
from django.db.models.signals import post_save, post_delete
from django.template.defaultfilters import slugify
@@ -311,7 +312,7 @@ post_save.connect(post_save_cache, sender=ContainerType)
post_delete.connect(post_save_cache, sender=ContainerType)
-class Container(LightHistorizedItem, ImageModel):
+class Container(LightHistorizedItem, ImageModel, OwnPerms):
TABLE_COLS = ['reference', 'container_type__label', 'cached_location',
'cached_division', 'old_reference']
IMAGE_PREFIX = 'containers/'
@@ -570,6 +571,20 @@ class Container(LightHistorizedItem, ImageModel):
def set_localisation_9(self, context, value):
return self.set_localisation(8, value)
+ def get_extra_actions(self, request):
+ """
+ extra actions for the sheet template
+ """
+ # url, base_text, icon, extra_text, extra css class, is a quick action
+ actions = []
+ can_edit_find = self.can_do(request, 'change_find')
+ if can_edit_find:
+ actions += [
+ (reverse('container-add-treatment', args=[self.pk]),
+ _(u"Add treatment"), "fa fa-exchange", "", "", False),
+ ]
+ return actions
+
def pre_save(self):
if not self.index:
q = Container.objects.filter(responsible=self.responsible).order_by(
diff --git a/archaeological_warehouse/urls.py b/archaeological_warehouse/urls.py
index fa895b7c4..47058a352 100644
--- a/archaeological_warehouse/urls.py
+++ b/archaeological_warehouse/urls.py
@@ -28,8 +28,9 @@ from archaeological_warehouse import models
# forms
urlpatterns = [
- url(r'warehouse_packaging/(?P<step>.+)?$',
- views.warehouse_packaging_wizard, name='warehouse_packaging'),
+ url(r'warehouse_packaging/(?P<step>.+)?$', # AFAC
+ check_rights(['change_find', 'change_own_find'])(
+ views.warehouse_packaging_wizard), name='warehouse_packaging'),
url(r'new-warehouse/(?P<parent_name>.+)?/$',
views.new_warehouse, name='new-warehouse'),
@@ -67,6 +68,11 @@ urlpatterns = [
url(r'warehouse-modify/(?P<pk>.+)/$',
views.warehouse_modify, name='warehouse_modify'),
+ url(r'^container-add-treatment/(?P<pk>[0-9-]+)/$',
+ check_rights(['change_find', 'change_own_find'])(
+ views.container_treatment_add),
+ name='container-add-treatment'),
+
url(r'^container_search/(?P<step>.+)?$',
check_rights(['view_container', 'view_own_container'])(
views.container_search_wizard),
diff --git a/archaeological_warehouse/views.py b/archaeological_warehouse/views.py
index 9b83fd829..83fd7f4e1 100644
--- a/archaeological_warehouse/views.py
+++ b/archaeological_warehouse/views.py
@@ -21,13 +21,26 @@ import json
from django.core.urlresolvers import reverse
from django.db.models import Q
-from django.http import HttpResponse
+from django.http import HttpResponse, Http404
from django.shortcuts import redirect
from django.utils.translation import ugettext_lazy as _
-from forms import *
+from archaeological_warehouse import models
+
+from archaeological_warehouse.forms import WarehouseForm, ContainerForm, \
+ ContainerFormSelection, BasePackagingForm, WarehouseFormSelection, \
+ SelectedDivisionFormset, WarehouseDeletionForm, \
+ MainContainerFormSelection, ContainerModifyForm, LocalisationForm, \
+ ContainerDeletionForm
+from ishtar_common.forms import FinalForm
+
from ishtar_common.views_item import get_item, show_item, new_item
-from wizards import *
+from archaeological_finds.views import treatment_add
+
+from archaeological_warehouse.wizards import PackagingWizard, WarehouseSearch, \
+ WarehouseWizard, WarehouseModificationWizard, WarehouseDeletionWizard, \
+ ContainerSearch, ContainerWizard, ContainerModificationWizard, \
+ ContainerDeletionWizard
get_container = get_item(models.Container, 'get_container', 'container')
show_container = show_item(models.Container, 'container')
@@ -95,10 +108,9 @@ def autocomplete_container(request):
for container in containers])
return HttpResponse(data, content_type='text/plain')
-warehouse_packaging_wizard = PackagingWizard.as_view([
+warehouse_packaging_wizard = PackagingWizard.as_view([ # AFAC
('seleccontainer-packaging', ContainerFormSelection),
('base-packaging', BasePackagingForm),
- # ('multiselecitems-packaging', FindPackagingFormSelection),
('final-packaging', FinalForm)],
label=_(u"Packaging"),
url_name='warehouse_packaging',)
@@ -185,6 +197,15 @@ container_deletion_wizard = ContainerDeletionWizard.as_view([
label=_(u"Container deletion"),
url_name='container_deletion',)
+
+def container_treatment_add(request, pk, current_right=None):
+ try:
+ container = models.Container.objects.get(pk=pk)
+ except models.Container.DoesNotExist:
+ raise Http404()
+ return treatment_add(
+ request, ",".join([str(f.pk) for f in container.finds.all()]))
+
"""
warehouse_packaging_wizard = ItemSourceWizard.as_view([
('selec-warehouse_packaging', ItemsSelection),
diff --git a/archaeological_warehouse/wizards.py b/archaeological_warehouse/wizards.py
index 41c5c5945..03258f1e2 100644
--- a/archaeological_warehouse/wizards.py
+++ b/archaeological_warehouse/wizards.py
@@ -38,9 +38,18 @@ class ContainerSearch(SearchWizard):
class PackagingWizard(TreatmentWizard):
basket_step = 'base-packaging'
+ def get_form_initial(self, step, data=None):
+ initial = super(PackagingWizard, self).get_form_initial(step)
+ user = self.request.user
+ if step != 'base-packaging' or not getattr(user, 'ishtaruser', None) \
+ or not user.ishtaruser.person:
+ return initial
+ initial['person'] = user.ishtaruser.person.pk
+ return initial
+
def save_model(self, dct, m2m, whole_associated_models, form_list,
return_object):
- dct = self.get_extra_model(dct, form_list)
+ dct = self.get_extra_model(dct, m2m, form_list)
obj = self.get_current_saved_object()
dct['location'] = dct['container'].location
items = None
@@ -51,6 +60,8 @@ class PackagingWizard(TreatmentWizard):
items = dct.pop('basket')
else:
dct.pop('basket')
+ if 'treatment_type_list' in dct:
+ dct.pop('treatment_type_list')
treatment = Treatment(**dct)
extra_args_for_new = {"container": dct['container']}
treatment.save(items=items, user=self.request.user,
diff --git a/docs/fr/source/_static/interface-generale.png b/docs/fr/source/_static/interface-generale.png
index f9c9bac22..fb054a075 100644
--- a/docs/fr/source/_static/interface-generale.png
+++ b/docs/fr/source/_static/interface-generale.png
Binary files differ
diff --git a/docs/fr/source/annexe-1-rattachement.rst b/docs/fr/source/annexe-1-rattachement.rst
new file mode 100644
index 000000000..2a8f041b4
--- /dev/null
+++ b/docs/fr/source/annexe-1-rattachement.rst
@@ -0,0 +1,23 @@
+.. -*- coding: utf-8 -*-
+
+.. _annexe-1-rattachement:
+
+==============================================
+Annexe 1 - Règles de rattachement aux éléments
+==============================================
+
+:Auteur: Étienne Loks
+:Date: 2018-12-04
+:Copyright: CC-BY 3.0
+
+----------------------------------
+
+
+
+ - Opération
+
+
+
+..
+ TODO: Penser aux zones...
+
diff --git a/docs/fr/source/annexe-2-permission-action.rst b/docs/fr/source/annexe-2-permission-action.rst
new file mode 100644
index 000000000..134237b81
--- /dev/null
+++ b/docs/fr/source/annexe-2-permission-action.rst
@@ -0,0 +1,17 @@
+.. -*- coding: utf-8 -*-
+
+.. _annexe-2-permission-action:
+
+===================================================
+Annexe 2 - Permissions nécessaires pour les actions
+===================================================
+
+:Auteur: Étienne Loks
+:Date: 2018-12-04
+:Copyright: CC-BY 3.0
+
+----------------------------------
+
+
+ - Action1....
+
diff --git a/docs/fr/source/annexe-3-ex-flux-ope.rst b/docs/fr/source/annexe-3-ex-flux-ope.rst
new file mode 100644
index 000000000..462b961c1
--- /dev/null
+++ b/docs/fr/source/annexe-3-ex-flux-ope.rst
@@ -0,0 +1,92 @@
+.. -*- coding: utf-8 -*-
+
+==============================================================
+Annexe 3 - Exemple de flux opérationnel : prêt pour exposition
+==============================================================
+
+:Auteur: Étienne Loks
+:Date: 2018-12-04
+:Copyright: CC-BY 3.0
+
+----------------------------------
+
+Description
+===========
+
+Le flux opérationnel « Prêt pour exposition » pourrait par exemple se décomposer suivant ces différentes étapes :
+
+ - pré-sélection du mobilier pour l'exposition par les gestionnaires de mobilier ;
+ - sélection du mobilier depuis cette pré-selection par la structure emprunteuse ;
+ - édition des documents administratifs : convention de prêt, assurance ;
+ - départ effectif du mobilier concerné ;
+ - gestion du retour du mobilier.
+
+Pré-requis :
+
+ - les patrons des actes administratifs associés à la demande de prêt ont été créés,
+ - la personne en charge du prêt a un compte Ishtar qui dispose au minimum :
+
+ - de droits de lecture et modification sur le mobilier éventuellement concerné par la sélection,
+ - d'un droit de création de demande de traitement,
+ - d'un droit de création d'acte administratif.
+ - les gestionnaires de mobilier concernés ont un compte sur Ishtar qui disposent au minimum de droits de lecture sur le mobilier éventuellement concerné par la sélection.
+ - la structure emprunteuse dispose d'un compte Ishtar avec droit de lecture sur le mobilier rattaché.
+
+
+Pré-sélection du mobilier pour l'exposition par les gestionnaires de mobilier
+-----------------------------------------------------------------------------
+
+1. Un des responsables de mobilier créé un panier depuis l'action rapide « Panier » sur les listes de mobilier (par exemple sur *Mobilier › Recherche*) ou depuis *Mobilier › Panier › Ajout*.
+2. Il ajoute quelques éléments à ce panier via l'action rapide « Panier » ou *Mobilier › Panier › Gestion des éléments*.
+3. Ce responsable partage ce panier en lecture/édition avec les autres gestionnaires de mobilier via *Mobilier › Panier › Modification*.
+4. Les autres gestionnaires peuvent de la même manière ajouter, enlever des éléments à ce panier via l'action rapide « Panier » ou *Mobilier › Panier › Gestion des éléments*.
+5. Fin d'étape : tous les gestionnaires ont signifié (oralement, par courriel, etc.) que la pré-sélection actuelle convenait.
+
+
+Sélection du mobilier depuis cette pré-selection par la structure emprunteuse
+-----------------------------------------------------------------------------
+
+1. Si l'on souhaite conserver cette pré-sélection avant partage et modification, elle peut être dupliquée depuis la fiche associée au panier (ouverte par exemple depuis : *Mobilier › Panier › Recherche* ou depuis l'icône « Paniers » sur une des fiches mobilier concernée par ce panier) avec l'icône « Dupliquer ».
+2. Le responsable du prêt partage le panier en lecture/édition avec la structure emprunteuse via *Mobilier › Panier › Modification* et l'informe que la pré-selection est disponible (via courriel, téléphone).
+
+.. note:: Un lien direct peut être donné à la structure emprunteuse pour quelle gère son panier, il suffit d'aller sur le panneau de gestion des éléments du panier concerné (*Mobilier › Panier › Gestion des éléments*) et de recopier l'adresse dans la barre d'adresse. La structure emprunteuse devra préalablement s'identifier avant d'accéder à ce lien.
+
+.. warning:: Si le droit de lecture de mobilier de la structure emprunteuse est basé sur le mobilier rattaché via ce panier, enlever un élément du panier lui retire le droit de consulter cet élément. Une astuce peut être de partager le panier dupliqué : une fois en lecture seule, une fois en lecture/édition, ainsi même si un élément est retiré du panier en lecture/édition, il reste « rattaché » à la structure emprunteuse par le panier en lecture seule. Le panier en lecture simple peut aussi recevoir des éléments disponibles pour prêt mais pas forcément retenu dans la sélection proposée.
+
+3. La structure emprunteuse retire du panier les éléments qui ne l'intéresse pas.
+4. Fin d'étape : la structure emprunteuse a fini sa sélection et confirme son intérêt pour un prêt (par courriel, ...).
+
+
+Édition des documents administratifs
+------------------------------------
+
+1. Le responsable du prêt enleve le partage en modification du panier (*Mobilier › Panier › Modification*).
+2. Le responsable du prêt crée une demande de traitement « Demande de prêt pour exposition » depuis *Demande de traitement › Ajout*. Il est important de bien renseigner les différents champs pour que la génération des documents se passe bien. Le panier concerné doit être associé à cette demande de traitement.
+3. Le responsable du prêt crée les actes administratifs correspondant aux documents administratifs attendus, via l'icône « + acte admin. » de la fiche de demande de traitement ou via *Demande de traitement › Acte administratif › Ajout*.
+4. Un document est généré pour chaque acte administratif depuis *Demande de traitement › Acte administratif › Documents*. Ceux-ci peuvent alors être transmis à la structure demandeuse.
+5. Fin d'étape : les documents ont été retournés signés. Ils sont éventuellement numérisés et ajoutés en tant que documents à la demande de traitement.
+
+
+Départ effectif du mobilier concerné
+------------------------------------
+
+1. Le responsable du prêt crée un traitement « Prêt » depuis la fiche de demande de traitement correspondante avec le bouton « Ajouter le traitement associé ». Un contenant correspondant au lieu d'emprunt doit être spécifié.
+
+.. note:: Le traitement peut être ajouté depuis la fiche panier ou via *Traitement › Traitement simple - Création* mais cela demande de re-sélectionner des éléments du panier ou de la demande de traitement associée. Passer par la fiche de demande de traitement correspondante est moins source d'erreur.
+
+2. Une alerte spécique est créée depuis le listing mobilier pour surveiller le retour du mobilier avec une chaîne de ce type : ::
+
+ panier="Exposition Sein 2018" pret="Oui" fin-de-traitement-avant="aujourdhui+30"
+
+3. Avec cette requête, 30 jours avant la date de retour attendue, l'alerte sera affichée.
+4. Fin d'étape : le mobilier a été retourné.
+
+
+Gestion du retour du mobilier
+-----------------------------
+
+1. Sur la fiche panier correspondante, sur les fiches contenants correspondants ou sur chaque fiche mobilier par mobilier, un traitement « Retour de prêt » est fait.
+
+.. note:: Il sera possible d'accéder rapidement aux fiches mobilier ou contenant via le QR-code.
+
+2. Depuis ces fiches, une demande de traitement « Constat d'état » pourra être ajoutée depuis le bouton « Ajouter une demande de traitement ».
diff --git a/docs/fr/source/index.rst b/docs/fr/source/index.rst
index 91ef3e740..a22a62ce0 100644
--- a/docs/fr/source/index.rst
+++ b/docs/fr/source/index.rst
@@ -15,3 +15,6 @@ Contents:
interface-utilisateur
interface-administrateur
installation
+ annexe-1-rattachement
+ annexe-2-permission-action
+ annexe-3-ex-flux-ope
diff --git a/docs/fr/source/interface-administrateur.rst b/docs/fr/source/interface-administrateur.rst
index 8e8506b6d..651111826 100644
--- a/docs/fr/source/interface-administrateur.rst
+++ b/docs/fr/source/interface-administrateur.rst
@@ -1,17 +1,251 @@
.. -*- coding: utf-8 -*-
-========================
-Interface administrateur
-========================
+==================================
+Configuration de l'instance Ishtar
+==================================
:Auteur: Étienne Loks
-:Date: 2018-10-02
+:Date: 2018-12-04
:Copyright: CC-BY 3.0
+----------------------------------
+
+La configuration d'Ishtar se fait essentiellement par le biais de « l'interface d'administration ». Cette interface propose une vue brute des tables en base de données. Même si cette interface propose une ergonomie simple et pratique, utiliser cette interface peut nécessiter d'avoir connaissance de notions de base d'une base de données pour pouvoir opérer des choix pertinents.
+
+L'interface d'administration nécessite d'avoir un compte administrateur pour y accéder. Les utilisateurs disposant de ce droit ont une icône « roue dentée » sur la barre de menu à l'extrémité droite. Sauf configuration spécifique, cette interface est aussi disponible via l'adresse « https://monsite-ishtar.net/admin/ » (ajouter `/admin/` à l'adresse de base).
+
+L'interface d'administration présente la liste des différentes tables par ordre alphabétique regroupées par application.
+
+.. warning:: Pour des questions de performance, Ishtar utilise intensément un système de cache. Il arrive parfois que celui-ci tarde à se mettre à jour. Il peut arriver que des modifications en administration prennent plusieurs minutes à être prises en compte.
+
+Listes de types
+---------------
+
+Ishtar fournit par défaut des données pour chaque liste de choix. Chacune de ces listes est paramétrable en administration.
+
+Dans les pages d'administration, les listes de types se retrouvent sous les dénominations « Types de ... », rangées par application :
+
+- **Ishtar - Commun** : contient les listes de types transversales utilisées par plusieurs types d'éléments ;
+- **Ishtar - Opération** : contient les listes de types concernant les opérations et les entités archéologiques/sites ;
+- **Ishtar - Unités d'enregistrement** : contient les listes de types relatives aux Unités d'enregistrement et aux datations ;
+- **Ishtar - Mobilier** : contient les listes de types relatives au mobilier et aux traitements ;
+- **Ishtar - Lieu de conservation** : contient les listes de types relatives aux lieux de conservation et aux contenants ;
+- **Ishtar - Dossier** : contient les listes de types relatives aux dossiers administratifs.
+
+Dans Ishtar, chaque type est défini au minimum par les champs suivants :
+
+- **Dénomination**
+- **Identifiant textuel** : L'identifiant textuel est une version standardisée du nom. Il ne contient que des lettres en minuscule non accentuées, des nombres et des tirets (-). Chaque identifiant textuel doit être unique dans la liste de types. Ces identifiants sont des clés permettant les échanges entre bases de données et pour des traductions. Ces identifiants peuvent être utilisés dans le code source de l'application. Une fois créés il ne faut a priori pas changer ces identifiants textuels.
+- **Commentaire** : Le contenu du commentaire est affiché dans l'aide en ligne sur les formulaires.
+- **Disponibilité** : Décocher ce champ rend indisponible ce type dans les formulaires, sans détruire l'information pour ce qui est déjà présent en base ; l'information est toujours visible dans les fiches.
+- **Ordre** : Dans les listes les champs sont ordonnés par ce numéro d'ordre et en cas d'égalité par ordre alphabétique.
+
+Certains types permettent de mettre en place une hiérarchie. Pour cela le champ **parent** est disponible. Pour chaque type enfant, ce champ est renseigné avec le type parent adéquat.
+
+Certains types disposent aussi d'autres champs spécifiques ; ceux-ci sont explicites ou disposent d'une aide en ligne.
+
+.. note:: Pour travailler sur ces listes de types ou les transmettre à des tiers, la possibilité est offerte d'exporter ces listes de types via l'interface d'administration. On sélectionne les éléments à exporter (ou tous les éléments) puis on utilise l'action « Exporter les éléments sélectionnés en fichier CSV ». Le fichier peut alors être édité dans un tableur. Pour une mise à jour, il est important de ne pas modifier les identifiants textuels qui sont la clé de rapprochement pour le ré-import. L'action d'import est disponible en haut à droite : « Import depuis un CSV ».
+
+
+Champs personnalisés
+--------------------
+
+Ishtar propose un certain nombre de champs standards et génériques permettant de disposer dès le départ d'une base solide et aussi pour assurer un certain degré d'inter-opérabilité entre les différentes installations d'Ishtar. Néanmoins nul ne peut prétendre à l'exhaustivité et, notamment dans le cadre d'une utilisation d'Ishtar axée recherche, le besoin se fera probablement sentir d'ajouter des champs.
+
+Dans Ishtar ces champs sont appelés : **Champs personnalisés**. Le format JSON étant utilisé pour stocker ces données, le nom **Données JSON** est aussi utilisé.
+
+Ajouter un champ personnalisé se fait via l'interface d'administration au niveau de la rubrique : *Ishtar - Commun › Données JSON - Champs*.
+
+Les différentes données à rentrer sont :
+
+* **Nom** : Ce nom sera repris dans les formulaires et la fiche.
+* **Type de contenu** : Le type d'objet auquel sera rattaché le champ - Opération, Site, Unité d'Enregistrement, Mobilier, ...
+* **Clé** : Valeur de la clé dans le format JSON. Cette clé ne doit impérativement comporter que des lettres minuscules, sans accent et des tirets bas « _ » (ne pas commencer la clé par le tiret bas et ne pas mettre plusieurs tirets bas d'affilée dans la clé de base). On peut structurer les données personnalisée de manière hiérarchique. Pour les clés hiérarchiques on utilise « __ » entre les sections. Par exemple pour la clé « ma_sousclef » dans la catégorie « ma_categorie », la clé sera notée : *ma_categorie__ma_sousclef*.
+* **Type** : Les types de données disponibles sont les suivants :
+
+ * Texte,
+ * Texte long : le composant de saisie sera une zone de texte,
+ * Entier : nombre entier positif ou négatif,
+ * Nombre à virgule,
+ * Booléen : case à cocher - Vrai ou Faux,
+ * Date : un composant permettant le choix de date depuis un calendrier est proposé,
+ * Choix : un composant en autocomplétion sur les valeurs existantes est proposé. L'utilisateur a la possibilité de rentrer librement de nouvelles valeurs.
+
+* **Ordre** : Le numéro saisie permet d'ordonner par défaut ce champ par rapport aux autres champs.
+* **Section** : La section correspond à un titre de section pour présenter ce champ sur la fiche et permettre des regroupements.
+* **Utiliser dans les index de recherche** : Si cette case est cochée, la recherche libre indexera le contenu de ce champ.
+* **Afficher** : Si cette case n'est pas cochée, ce champ ne sera pas affiché sur la fiche.
+
+Sauf si un champ personnalisé est uniquement destiné à des données importées et à un affichage sur la fiche, un champ personnalisé sera dans la plupart des cas intégré à un :ref:`formulaire personnalisé <formulaire-personnalise>`.
+
+.. _formulaire-personnalise:
+
+Formulaires personnalisés
+-------------------------
+
+La plupart des formulaires peuvent être personnalisés dans Ishtar, notamment tous les formulaires de création/modification ainsi que les formulaires de recherche. À ce jour, il n'est pas encore possible d'ajouter de nouveaux formulaires.
+
+Les formulaires personnalisés permettent deux choses : soustraire de l'affichage du formulaire les champs disponibles par défaut et ajouter des champs JSON dans le formulaire. Chaque formulaire personnalisé peut être mis à disposition pour tous ou seulement certains utilisateurs.
+
+La configuration de ces champs se fait en administration via : *Ishtar - Commun › Formulaires personnalisés*.
+
+La création se fait en deux temps, d'abord un paramétrage des champs de base puis une définition des champs à exclure et des champs JSON à ajouter.
+
+Le paramétrage de base demande les champs suivants :
+
+ * **Nom** : le nom correspondant au formulaire personnalisé. Ce nom ne sera visible qu'en administration mais pour s'y retrouver, il doit à la fois reprendre le nom du formulaire ainsi que le contexte pour lequel il a été défini. Par exemple : « Mobilier - 020 - Général - Tout utilisateur » ou « Mobilier - 030 - Conservation - Saisie terrain ».
+* **Formulaire** : le formulaire à personnaliser. Le nom utilisé permet d'identifier assez simplement le formulaire correspondant car il correspond dans l'ordre (séparé par des tirets) au :
+
+ * type d'objet concerné (par exemple : « Mobilier »),
+ * éventuellement, le numéro d'ordre dans les formulaires successifs,
+ * nom du formulaire.
+* **À qui s'applique ce formulaire**, cela peut être au choix :
+
+ * à tous les utilisateurs,
+ * à certains utilisateurs en particulier,
+ * à certains types d'utilisateurs.
+
+Une fois ce paramétrage de base enregistré, la configuration précise du formulaire peut se faire :
+
+* **champs à exclure** : chaque champ de base présent dans le formulaire actuel peut être sélectionné dans la liste pour être écarté de la saisie.
+* **champs JSON** : tous les champs JSON préalablement paramétrés concernant l'élément courant (mobilier, OA, ...) peuvent être sélectionnés. La dénomination permet éventuellement de surcharger le nom par défaut du champ JSON. L'ordre permet de placer le champ dans le formulaire. L'aide permet éventuellement d'ajouter un texte pour aider à la saisie.
+
+.. warning:: Sur les formulaires de création, il est impératif de ne pas exclure des champs obligatoires sans quoi la création devient impossible.
+
+.. note:: En tant qu'administrateur, en modifiant son profil depuis les pages d'administration (*Ishtar - Commun › Profils d'utilisateurs*) et en cochant « Afficher les numéros des champs », les numéros des champs actuels des formulaires s'affichent sur l'interface, cela permet ainsi de placer plus aisément les champs personnalisés.
+
+
+Gestion des permissions
+-----------------------
+
+Gestion des comptes
+*******************
+
+Dans Ishtar, un compte doit être associé à une personne. Si la personne n'existe pas dans la base, il faut l'ajouter via l'interface principale d'Ishtar : *Annuaire › Personne › Ajout*.
+
+Ensuite on crée un compte associé à cette personne, toujours via l'interface d'Ishtar : *Administration › Compte › Ajout/modification*. Dans les différents panneaux, il est demandé : l'identifiant du compte, le courriel rattaché, le mot de passe puis le type de profil.
+
+Les types de profil définiront les types de permissions auxquelles aura accès l'utilisateur. Sur ces types de profil, des zones peuvent être définies afin de permettre des règles de rattachement spécifique (cf. :ref:`permissions dans Ishtar<permissions-ishtar>`).
+
+Cette interface de création de compte permet aussi de modifier le mot de passe de comptes existants.
+
+Permissions dans Ishtar
+***********************
+
+Les permissions dans Ishtar sont essentiellement gérées par « Type de profil ». Chaque compte a un ou plusieurs « types de profil » associés à son compte. Chaque type de profil donne accès à des actions et des accès sur des types d'objets.
+
+La création/configuration d'un type de profil se fait via : *Ishtar - Commun › Types de profil* :
+
+- **dénomination** : ce champ doit être explicite car il va être retrouvé au niveau de l'interface utilisateur.
+- **identifiant textuel** : rempli selon les règles habituelles des identifiants textuels.
+- **groupes** : listes des groupes auxquels le profil est rattaché.
+
+Chaque groupe correspond à un type de permission pour un élément précis de la base de données :
+
+- droit de lecture ;
+- droit d'ajout ;
+- droit de modification/suppression.
+
+Chacun de ces droit est décliné en deux modalités :
+
+- droits sur tous les éléments ;
+- droit sur les éléments rattachés.
+
+Un élément est dit « rattaché » à une personne en fonction de règles précises spécifiées dans l':ref:`annexe 1 - règles de rattachement à un élément <annexe-1-rattachement>`. La notion de rattachement permet de spécifier finement les permissions pour des personnes qui sont directement associées à l'élément. Par exemple cela permet donner les droits de modification du mobilier d'une opération au responsable scientifique de cette opération.
+
+En pratique, globalement, les groupes de droits permettent d'accéder à certaines actions :
+
+- le droit de lecture permet une ouverture de la fiche correspondant à l'élément ;
+- le droit d'ajout permet d'accéder aux actions d'ajout d'un nouvel élément ;
+- le droit de modification/suppression permet d'accéder aux actions concernant la modification/suppression des éléments.
+
+Dans le détail, il y a certaines actions qui sont ouvertes en fonction d'appartenance à des groupes en particulier. Tout cela est détaillé dans l':ref:`annexe 2 - permissions nécessaires pour les actions <annexe-2-permission-action>`.
+
+.. note:: La page *Ishtar - Commun › Résumés des types de profil* permet d'accéder à un tableau qui reprend et rend explicites toutes les permissions associées aux types de profil.
+
+Permissions dans les pages d'administration
+*******************************************
+
+Les permissions des pages d'administration sont gérées différemment. Elles utilisent le système de permission du framework Django, framework (cadre de développement logiciel) utilisé par Ishtar.
+Une fois le compte créé, les droits se spécifient dans les pages d'administration : *Authentification et autorisation › Utilisateurs*.
+
+L'ouverture de l'accès aux pages d'administration se fait en cochant le « Statut équipe ». Si l'on souhaite n'ouvrir l'accès qu'à certaines pages spécifiques, on ajoute les « Permissions de l'utilisateur » correspondant aux tables que l'on souhaite ouvrir, si l'on souhaite ouvrir l'accès à toutes les tables, il suffit de cocher le « Statut super-utilisateur ».
+
+
+Patrons de documents
+--------------------
+
+Principes de base
+*****************
+
+Ishtar propose une génération automatisée de document. Depuis un patron au format LibreOffice (ODT), les données relatives à un élément (acte administratif, mobilier, ...) remplacent les variables du patron pour obtenir le document désiré.
+
+On créé le patron au format ODT avec un contenu adapté, puis depuis l'interface d'administration, sous l'entrée *Ishtar - Commun › Patrons de document › Document de référence*, on créé un patron de document avec ce fichier ODT associé au type d'élément pour lequel il est destiné.
+
+Le document peut alors être généré depuis n'importe quelle fiche de l'élément concerné (en haut à droite sous « Documents »).
+
+Un premier patron
+*****************
+
+Pour créer un patron, la première étape est de récupérer toutes les variables disponibles pour l'élément à partir duquel on veut générer un document. Il existe pour cela un `document de référence`_ que l'on peut attacher à l'élément pour lequel on souhaite éditer un nouveau document.
+
+.. _document de référence: https://gitlab.com/iggdrasil/ishtar/raw/master/archaeological_operations/tests/document_reference.odt
+
+.. note:: En cas d'indisponibilité du lien pour ce document, ce document est très simple et peut être recréé facilement, il suffit d'insérer : ``{{VALUES}}`` dans un document ODT vide et de sauvegarder le document.
+
+Depuis *Ishtar - Commun › Patrons de document › Document de référence*, on ajoute un nouveau patron de document : « Document de référence » auquel on associe le document de référence téléchargé et le type d'élément pour lequel on souhaite créer un patron de document.
+
+Ensuite, il faut récupérer un document de référence généré depuis la fiche d'un élément contenant tous les champs que l'on souhaite exploiter.
+
+On ouvre ce document sous LibreOffice. Le document produit contient une liste de clé avec la valeur associée concernant l'élément que l'on a choisi.
+
+Les différentes clés vont permettre de constituer un patron répondant à ce qui est attendu. Pour cela reprendre un exemple du document que l'on souhaite générer (toujours au format ODT) et remplacer chaque occurence d'une valeur par la clé entourée de deux acccolades, exemple : ::
+
+ Je, sousigné, {{nom_de_ma_clef_1}}, vous accorde un prêt de {{nom_ma_clef_2}}.
+
+Une fois quelques substitutions faites, on peut l'enregistrer et créer le patron dans l'interface d'administration Ishtar. Ce premier patron est alors disponible depuis la fiche des éléments.
+
+Notions avancées
+****************
+
+Conditions
+++++++++++
+
+Des structures conditionnelles peuvent être mise en place. Cela permet notamment de tester si une valeur a été renseignée et de permettre de contextualiser l'affichage en fonction de cela. Exemple : ::
+
+ Ce traitement sous
+ {% if responsable %}la responsabilité de {{responsable}}
+ {% else %}une responsabilité à définir
+ {% endif %} se tiendra...
+
+Les structures conditionnelles se structurent autour des mots clés ``if``, ``else`` et ``endif``. On utilise ``{%`` et ``%}`` autour de ces mots clés. La section ``else`` est facultative.
+
+Attributs
++++++++++
+
+Les valeurs utilisées dans les patrons peuvent avoir des attributs correspondant aux noms des colonnes des tables d'éléments utilisés en base de données. Ces attributs sont accédés avec la notation ``.`` . Par exemple, si l'élément a un attribut ``nom``, on accède à la valeur de cet élément avec ``{{element.nom}}``.
+
+
+Parcours de liste
++++++++++++++++++
+
+Certaines clés peuvent parfois renvoyer à des listes d'éléments, chacun ayant des attributs. On peut alors parcourir cette liste d'élément de cette manière : ::
+
+ {% for element in liste_elements %}
+ {{element.nom}} - {{element.prenom}}
+ {% endfor %}
+
+Cela se structure autour des mots clés ``for``, ``in`` et ``endfor``. Au lieu de doubles accolades, ``{%`` et ``%}`` encadrent ces mots clés.
+
+..
+ Images
+ ++++++
+
+ Il est possible d'utiliser des images dans les patrons. Pour cela il faut placer une image dans le document du patron et modifier son attribut nom sous LibreOffice (clic droit sur l'image, « Propriétés... » et l'onglet « Options ») par une chaîne sous la forme ``{{ mon_image|image }}``. ``mon_image`` correspond au champ image
+
+
-.. _configuration-instance-ishtar:
-Configuration de l'instance Ishtar
-----------------------------------
-WIP
+..
+ TODO: Profil d'instance Ishtar
diff --git a/docs/fr/source/interface-utilisateur.rst b/docs/fr/source/interface-utilisateur.rst
index ce8b5b82f..a7ab19a8c 100644
--- a/docs/fr/source/interface-utilisateur.rst
+++ b/docs/fr/source/interface-utilisateur.rst
@@ -9,6 +9,9 @@ Interface utilisateur
:Copyright: CC-BY 3.0
+----------------------------
+
+
Interface générale
==================
@@ -55,7 +58,7 @@ La zone centrale est totalement contextuelle. Néanmoins si certaines pages d'ac
Zone d'alerte et de sélection épinglée
--------------------------------------
-Cette zone reprend les éventuelles alertes (cf. :ref:`Page de recherche > Marques-pages et alertes <bookmarks>`), mise en place par l'utilisateur ainsi que les éléments actuellement épinglés (cf. :ref:`Utilisation avancée > Éléments épinglés <pinned>`).
+Cette zone reprend les éventuelles alertes (cf. :ref:`Page de recherche > Marques-pages et alertes <bookmarks>`), mise en place par l'utilisateur ainsi que (si l'affichage de ceux-ci est activé) les éléments actuellement épinglés (cf. :ref:`Utilisation avancée > Éléments épinglés <pinned>`).
.. _page-de-recherche:
@@ -73,6 +76,7 @@ La barre de recherche est composée d'une zone de saisie et d'une série d'icôn
- icône « loupe » : lancer la recherche,
- icône « engrenage » : accéder à la recherche par facette,
- icône « croix » : vider la zone de recherche,
+- icône « épingle » : épingler la recherche actuelle pour qu'elle devienne la recherche par défaut pour cette session,
- icône « étoile » : enregistrer une alerte, un marque-page,
- icône « marque-page » : accéder aux marques-pages (les supprimer).
@@ -179,7 +183,7 @@ Ensuite sur la droite, différentes actions sont disponibles. Ces actions dépen
- une icône « épingle » : elle permet d'épingler l'élément de la fiche (cf. :ref:`épinglage <pinned>`).
- une icône « crayon » : si l'on dispose des droits adéquats, elle permet d'éditer cette fiche. On accède au premier volet des pages d'assistants dédié à l'édition de ce type d'élément.
- des icônes « + » : ces icônes permettent d'associer facilement un type particulier d'élément à l'élément de la fiche courante. Par exemple « + doc./image » permet d'associer un document/une image à l'élément de la fiche.
-- les icônes « ODT », « PDF » : ces icônes permettent un export ODT ou PDF de la fiche actuelle.
+- un menu « exporter » : les éléments de ce menu permettent un export dans différement format de la fiche actuelle.
Contenu de la fiche
+++++++++++++++++++
@@ -259,8 +263,9 @@ L'épinglage d'élément est un outil de travail permettant de travailler dans u
**Exemple** : je souhaite travailler sur le mobilier d'une opération précise. En épinglant cette opération, par défaut, toutes les recherches de mobilier se feront sur cette opération.
L'épinglage est disponible directement dans la barre d'outil des fiches.
-L'épinglage est aussi disponible dans le menu de gestion des sélections épinglées (à droite de la zone 4 sur l'image de l'interface générale).
-Un élément créé ou modifié est automatiquement épinglé.
+L'épinglage est aussi disponible au niveau de la barre de recherche (cette recherche épinglée ne concerne que le tableau d'éléments en cours sans gestion hiérarchique).
+Si celui-ci est activé dans son profil, l'épinglage est aussi disponible dans le menu de gestion des sélections épinglées (à droite de la zone 4 sur l'image de l'interface générale).
+Si on a activé cette option dans son profil, un élément créé ou modifié est automatiquement épinglé.
Une gestion hiérarchique des épingles est faites : le fait d'épingler un élément épingle automatiquement ses parents directs.
@@ -269,7 +274,7 @@ Une gestion hiérarchique des épingles est faites : le fait d'épingler un élÃ
Menu de gestion des sélections épinglées
++++++++++++++++++++++++++++++++++++++++
-Ce menu propose de sélectionner les éléments que l'on souhaite épingler. Différentes versions de ce menu sont disponible :
+Ce menu n'est visible que s'il est activé dans son profil. Il propose de sélectionner les éléments que l'on souhaite épingler. Différentes versions de ce menu sont disponible :
- « simple » : des menus déroulants permettent d'épingler les éléments qui sont directement rattachés à notre compte utilisateur (en particulier les éléments que l'on a créé) ;
- « avancé - mes éléments » : on épingle ici seulement les éléments rattachés à notre compte utilisateur mais avec des champs fonctionnant en autocompletion ;
diff --git a/docs/fr/source/media-src/interface-generale.xcf b/docs/fr/source/media-src/interface-generale.xcf
index bb585bd09..f3158a233 100644
--- a/docs/fr/source/media-src/interface-generale.xcf
+++ b/docs/fr/source/media-src/interface-generale.xcf
Binary files differ
diff --git a/docs/fr/source/principes.rst b/docs/fr/source/principes.rst
index 5cfd6de3f..32313f990 100644
--- a/docs/fr/source/principes.rst
+++ b/docs/fr/source/principes.rst
@@ -107,20 +107,20 @@ Opération archéologique
L'opération archéologique est le cœur du modèle de données d'Ishtar.
Au sein d'Ishtar, l'opération archéologique est définie comme une action (ou un projet d'action) permettant d'acquérir des données archéologiques, sous la responsabilité d'une personne (exemples : découverte fortuite, diagnostic, fouille programmée, prospection, etc.) et dans un lieu si possible défini.
+Si l'opération est au centre du modèle de données d'Ishtar plutôt que le site ou l'entité archéologique, c'est parce que ce dernier est une interprétation (comme toute interprétation, sujette à évolution dans le temps) des données, alors que l'opération est l'information qui permet au mieux de regrouper un corpus documentaire cohérent mettant en lien des documents (plans, rapports, photos, etc.) et du mobilier.
+
Il est possible de créer des liens entre des opérations, soit en les associant à un même dossier source (avec le module « administratif », ex. : un permis de construire qui est associé à un diagnostic et une fouille préventive), soit en définissant une relation entre des opérations globales (ex. : PCR, suivi d'autoroutes, etc.) et d'autres plus ponctuelles (phases, tranches, secteurs, etc.). Le regroupement d'opérations est également pratique en contexte de fouilles programmées, où il peut être utile d'avoir des inventaires pour chaque opération par année, mais également une vision globale de la succession des fouilles (opération globale). En contexte de grande opération préventive, ce système peut servir à individualiser des secteurs de fouilles disposant de modes d’enregistrements spécifiques. L'utilisateur a toute latitude pour organiser les opérations entres elles selon ses besoins, du moment que ces éléments clefs représentent bien des lots documentaires et mobilier a priori cohérents.
Site/entité archéologique
-------------------------
-L'opération archéologique a été préférée au site ou l'entité archéologique comme centre des données dans Ishtar parce que les sites/entités sont une interprétation (comme toute interprétation, sujette à évolution dans le temps) des données, alors que l'opération est l'information qui permet au mieux de regrouper un corpus documentaire cohérent mettant en lien des documents (plans, rapports, photos, etc.) et du mobilier.
-
-Malgré cela, Ishtar gère pleinement les sites (ou entité - notion paramétrable en administration) archéologiques et la migration depuis une base orientée site est tout à fait envisageable.
+Malgré le choix de l'opération comme rôle central de son modèle de données, Ishtar gère pleinement les sites (ou entité - notion paramétrable en administration) archéologiques et la migration depuis une base orientée site est tout à fait envisageable.
Parcelle
--------
-Les parcelles sont gérées précisément au sein d'Ishtar en étant directement rattachées aux UE. Cela permet de faciliter la gestion des questions légales concernant le mobilier (réalisation du « partage » ou responsabilité en cas de restauration). Si la parcelle de l'UE n'est pas connue ou si elle n'est pas sujette a contrainte légale il est possible d'associer une parcelle virtuelle ou de ne pas renseigner ce champ.
+Les parcelles sont gérées précisément au sein d'Ishtar en étant directement rattachées aux UE. Cela permet de faciliter la gestion des questions légales concernant le mobilier (réalisation du « partage » ou responsabilité en cas de restauration). Si la parcelle de l'UE n'est pas connue ou si elle n'est pas sujette a contrainte légale, il est possible d'associer une parcelle virtuelle ou de ne pas renseigner ce champ.
Unité d'enregistrement
----------------------
diff --git a/drassm_app b/drassm_app
-Subproject afd2824264664d7bfecaa3702f495b0fe176fa4
+Subproject db4ff79c01fb71527bac6c00fd1d6831bb90d27
diff --git a/fixtures/initial_data-auth-fr.json b/fixtures/initial_data-auth-fr.json
index feecf1e8a..64fbd8051 100644
--- a/fixtures/initial_data-auth-fr.json
+++ b/fixtures/initial_data-auth-fr.json
@@ -3852,39 +3852,6 @@
{
"model": "auth.permission",
"fields": {
- "name": "Can add Treatment file",
- "content_type": [
- "archaeological_finds",
- "treatmentfile"
- ],
- "codename": "add_treatmentfile"
- }
-},
-{
- "model": "auth.permission",
- "fields": {
- "name": "Can change Treatment file",
- "content_type": [
- "archaeological_finds",
- "treatmentfile"
- ],
- "codename": "change_treatmentfile"
- }
-},
-{
- "model": "auth.permission",
- "fields": {
- "name": "Can delete Treatment file",
- "content_type": [
- "archaeological_finds",
- "treatmentfile"
- ],
- "codename": "delete_treatmentfile"
- }
-},
-{
- "model": "auth.permission",
- "fields": {
"name": "Can add Warehouse division",
"content_type": [
"archaeological_warehouse",
@@ -4121,7 +4088,7 @@
"archaeological_finds",
"treatmentfile"
],
- "codename": "view_filetreatment"
+ "codename": "view_treatmentfile"
}
},
{
@@ -4132,7 +4099,7 @@
"archaeological_finds",
"treatmentfile"
],
- "codename": "view_own_filetreatment"
+ "codename": "view_own_treatmentfile"
}
},
{
@@ -4143,7 +4110,7 @@
"archaeological_finds",
"treatmentfile"
],
- "codename": "add_own_filetreatment"
+ "codename": "add_own_treatmentfile"
}
},
{
@@ -4154,7 +4121,7 @@
"archaeological_finds",
"treatmentfile"
],
- "codename": "change_own_filetreatment"
+ "codename": "change_own_treatmentfile"
}
},
{
@@ -4165,7 +4132,7 @@
"archaeological_finds",
"treatmentfile"
],
- "codename": "delete_own_filetreatment"
+ "codename": "delete_own_treatmentfile"
}
},
{
@@ -4308,7 +4275,7 @@
"archaeological_finds",
"treatmentfile"
],
- "codename": "add_filetreatment"
+ "codename": "add_treatmentfile"
}
},
{
@@ -4319,7 +4286,7 @@
"archaeological_finds",
"treatmentfile"
],
- "codename": "change_filetreatment"
+ "codename": "change_treatmentfile"
}
},
{
@@ -4330,7 +4297,7 @@
"archaeological_finds",
"treatmentfile"
],
- "codename": "delete_filetreatment"
+ "codename": "delete_treatmentfile"
}
},
{
@@ -5935,7 +5902,7 @@
"name": "Demandes de traitement : ajout",
"permissions": [
[
- "add_filetreatment",
+ "add_treatmentfile",
"archaeological_finds",
"treatmentfile"
]
@@ -5948,12 +5915,12 @@
"name": "Demandes de traitement : modification/suppression",
"permissions": [
[
- "change_filetreatment",
+ "change_treatmentfile",
"archaeological_finds",
"treatmentfile"
],
[
- "delete_filetreatment",
+ "delete_treatmentfile",
"archaeological_finds",
"treatmentfile"
]
@@ -5966,7 +5933,7 @@
"name": "Demandes de traitement : lecture",
"permissions": [
[
- "view_filetreatment",
+ "view_treatmentfile",
"archaeological_finds",
"treatmentfile"
]
@@ -5979,7 +5946,7 @@
"name": "Demandes de traitement rattach\u00e9es : ajout",
"permissions": [
[
- "add_own_filetreatment",
+ "add_own_treatmentfile",
"archaeological_finds",
"treatmentfile"
]
@@ -5992,7 +5959,7 @@
"name": "Demandes de traitement rattach\u00e9es : lecture",
"permissions": [
[
- "view_own_filetreatment",
+ "view_own_treatmentfile",
"archaeological_finds",
"treatmentfile"
]
@@ -6005,12 +5972,12 @@
"name": "Demandes de traitement rattach\u00e9es : modification/suppression",
"permissions": [
[
- "change_own_filetreatment",
+ "change_own_treatmentfile",
"archaeological_finds",
"treatmentfile"
],
[
- "delete_own_filetreatment",
+ "delete_own_treatmentfile",
"archaeological_finds",
"treatmentfile"
]
diff --git a/ishtar_common/forms.py b/ishtar_common/forms.py
index 20c65971e..91e9fb3e9 100644
--- a/ishtar_common/forms.py
+++ b/ishtar_common/forms.py
@@ -341,6 +341,37 @@ class CustomForm(BSForm):
return sorted(customs, key=lambda x: x[1])
+class PkWizardSearch(object):
+ current_model = None
+ pk_key = None
+
+ @classmethod
+ def get_formated_datas(cls, cleaned_datas):
+ if not cls.current_model or not cls.pk_key:
+ return []
+ items = []
+ for data in cleaned_datas:
+ if not data or cls.pk_key not in data or not data[cls.pk_key]:
+ continue
+ pks = data[cls.pk_key]
+ for pk in unicode(pks).split(u','):
+ if not pk:
+ continue
+ try:
+ items.append(
+ unicode(cls.current_model.objects.get(pk=int(pk)))
+ )
+ except (cls.current_model.DoesNotExist, ValueError):
+ continue
+ return [
+ (u"",
+ mark_safe(
+ u"<ul class='compact'><li>" + u"</li><li>".join(items) +
+ u"</li></ul>"
+ ))
+ ]
+
+
class CustomFormSearch(forms.Form):
need_user_for_initialization = True
@@ -405,6 +436,22 @@ class FormSet(CustomForm, BaseFormSet):
form.fields[DELETION_FIELD_NAME].label = ''
form.fields[DELETION_FIELD_NAME].widget = self.delete_widget()
+ def _should_delete_form(self, form):
+ """
+ Returns whether or not the form was marked for deletion.
+ If no data, set deletion to True
+ """
+ if form.cleaned_data.get(DELETION_FIELD_NAME, False):
+ return True
+ if not form.cleaned_data or not [
+ __ for __ in form.cleaned_data
+ if __ != DELETION_FIELD_NAME and
+ form.cleaned_data[__] is not None and
+ form.cleaned_data[__] != '']:
+ form.cleaned_data[DELETION_FIELD_NAME] = True
+ return True
+ return False
+
class FormSetWithDeleteSwitches(FormSet):
delete_widget = widgets.DeleteSwitchWidget
@@ -714,16 +761,19 @@ class QAForm(CustomForm, ManageOldType):
elif hasattr(self.fields[k], "choices"):
values = []
for v in kwargs['data'].getlist(k):
- values.append(
- dict(self.fields[k].choices)[int(v)])
+ dct_choices = dict(self.fields[k].choices)
+ if v in dct_choices:
+ values.append(unicode(dct_choices[v]))
+ elif int(v) in dct_choices:
+ values.append(unicode(dct_choices[int(v)]))
self.fields[k].rendered_value = mark_safe(
u" ; ".join(values))
if k not in self.REPLACE_FIELDS:
self.fields[k].label = unicode(self.fields[k].label) + \
- unicode(u" - append to existing")
+ unicode(_(u" - append to existing"))
else:
self.fields[k].label = unicode(self.fields[k].label) + \
- unicode(u" - replace")
+ unicode(_(u" - replace"))
def _set_value(self, item, base_key):
value = self.cleaned_data[base_key]
diff --git a/ishtar_common/forms_common.py b/ishtar_common/forms_common.py
index 4cc0ca024..e5246d9bb 100644
--- a/ishtar_common/forms_common.py
+++ b/ishtar_common/forms_common.py
@@ -1176,7 +1176,7 @@ class DocumentForm(forms.ModelForm, CustomForm, ManageOldType):
for rel in models.Document.RELATED_MODELS:
if cleaned_data.get(rel, None):
return cleaned_data
- raise forms.ValidationError(_(u"A document have to attached at least "
+ raise forms.ValidationError(_(u"A document has to be attached at least "
u"to one item"))
def save(self, commit=True):
diff --git a/ishtar_common/locale/django.pot b/ishtar_common/locale/django.pot
index 638f29f22..371b21909 100644
--- a/ishtar_common/locale/django.pot
+++ b/ishtar_common/locale/django.pot
@@ -34,12 +34,12 @@ msgstr ""
msgid "Export selected as CSV file"
msgstr ""
-#: admin.py:207 models.py:1686 templates/navbar.html:31
+#: admin.py:207 models.py:1703 templates/navbar.html:31
msgid "Profile"
msgstr ""
#: admin.py:208 forms_common.py:782 forms_common.py:801 forms_common.py:802
-#: models.py:3039
+#: models.py:3063
msgid "Profiles"
msgstr ""
@@ -61,7 +61,7 @@ msgstr ""
msgid "These parents are missing: {}"
msgstr ""
-#: admin.py:386 admin.py:405 models.py:883 models.py:4141
+#: admin.py:386 admin.py:405 models.py:905 models.py:4214
msgid "Parent"
msgstr ""
@@ -69,11 +69,11 @@ msgstr ""
msgid "Center"
msgstr ""
-#: admin.py:395 models.py:4003
+#: admin.py:395 models.py:4076
msgid "Limit"
msgstr ""
-#: admin.py:398 models.py:4013
+#: admin.py:398 models.py:4086
msgid "Town children"
msgstr ""
@@ -121,16 +121,16 @@ msgstr ""
msgid "Hide selected"
msgstr ""
-#: admin.py:931 models.py:2080
+#: admin.py:931 models.py:2098
msgid "Form"
msgstr ""
-#: admin.py:933 models.py:2105 models_imports.py:127
+#: admin.py:933 models.py:2123 models_imports.py:127
#: templates/ishtar/dashboards/dashboard_main.html:39
msgid "Users"
msgstr ""
-#: admin.py:953 models.py:2180
+#: admin.py:953 models.py:2202
msgid "Field"
msgstr ""
@@ -224,7 +224,7 @@ msgstr ""
msgid "Too many cols (%(user_col)d) when maximum is %(ref_col)d"
msgstr ""
-#: data_importer.py:730 views.py:1177
+#: data_importer.py:730 views.py:1200
msgid "No data provided"
msgstr ""
@@ -253,7 +253,7 @@ msgid ""
"source file."
msgstr ""
-#: data_importer.py:1236 views.py:1255 views.py:1265
+#: data_importer.py:1236 views.py:1278 views.py:1288
msgid "Not imported"
msgstr ""
@@ -318,7 +318,7 @@ msgstr ""
msgid "Enter a valid name consisting of letters, spaces and hyphens."
msgstr ""
-#: forms.py:96 forms_common.py:808 views.py:1968
+#: forms.py:96 forms_common.py:808 views.py:2017
msgid "Confirm"
msgstr ""
@@ -326,36 +326,44 @@ msgstr ""
msgid "Are you sure you want to delete?"
msgstr ""
-#: forms.py:379
+#: forms.py:410
msgid "There are identical items."
msgstr ""
-#: forms.py:535
+#: forms.py:566
msgid "Last modified by"
msgstr ""
-#: forms.py:541
+#: forms.py:572
msgid "Modified since"
msgstr ""
-#: forms.py:565 forms.py:566
+#: forms.py:596 forms.py:597
msgid "Closing date"
msgstr ""
-#: forms.py:578 forms_common.py:1272
+#: forms.py:609 forms_common.py:1272
msgid "You should select an item."
msgstr ""
-#: forms.py:579
+#: forms.py:610
msgid "Add a new item"
msgstr ""
-#: forms.py:769 models.py:2434
+#: forms.py:757
+msgid " - append to existing"
+msgstr ""
+
+#: forms.py:760
+msgid " - replace"
+msgstr ""
+
+#: forms.py:803 models.py:2457
msgid "Template"
msgstr ""
#: forms_common.py:54 forms_common.py:72 forms_common.py:317
-#: forms_common.py:556 models.py:2568 models.py:4020
+#: forms_common.py:556 models.py:2591 models.py:4093
#: templates/blocks/JQueryAdvancedTown.html:19
msgid "Town"
msgstr ""
@@ -370,8 +378,8 @@ msgid ""
"french town Saint-Denis in the Seine-Saint-Denis department.</p>"
msgstr ""
-#: forms_common.py:81 forms_common.py:1293 ishtar_menu.py:48 models.py:2952
-#: models.py:3204 models.py:3332 models.py:3495
+#: forms_common.py:81 forms_common.py:1293 ishtar_menu.py:48 models.py:2976
+#: models.py:3228 models.py:3357 models.py:3561
#: templates/ishtar/sheet_person.html:4
msgid "Person"
msgstr ""
@@ -423,17 +431,17 @@ msgid "all users"
msgstr ""
#: forms_common.py:305 forms_common.py:475 forms_common.py:609
-#: ishtar_menu.py:76 models.py:2773 models.py:2890 models.py:3292
+#: ishtar_menu.py:76 models.py:2796 models.py:2914 models.py:3317
#: templates/ishtar/sheet_organization.html:4
msgid "Organization"
msgstr ""
#: forms_common.py:308 forms_common.py:351 forms_common.py:470
#: forms_common.py:526 forms_common.py:604 forms_common.py:790
-#: forms_common.py:823 models.py:1056 models.py:1080 models.py:1879
-#: models.py:2079 models.py:2430 models.py:2765 models.py:2936 models.py:3192
-#: models.py:3999 models.py:4262 models_imports.py:98 models_imports.py:123
-#: models_imports.py:445 models_imports.py:537 models_imports.py:827
+#: forms_common.py:823 models.py:1078 models.py:1102 models.py:1897
+#: models.py:2097 models.py:2453 models.py:2788 models.py:2960 models.py:3216
+#: models.py:4072 models.py:4337 models_imports.py:98 models_imports.py:123
+#: models_imports.py:445 models_imports.py:537 models_imports.py:828
#: templates/ishtar/import_step_by_step.html:102
#: templates/ishtar/import_step_by_step.html:270
#: templates/ishtar/import_table.html:27
@@ -441,40 +449,40 @@ msgstr ""
msgid "Name"
msgstr ""
-#: forms_common.py:309 models.py:2721 models_imports.py:630
+#: forms_common.py:309 models.py:2744 models_imports.py:630
#: models_imports.py:631
msgid "Organization type"
msgstr ""
-#: forms_common.py:311 forms_common.py:550 models.py:2563
+#: forms_common.py:311 forms_common.py:550 models.py:2586
#: templates/ishtar/blocks/sheet_address_section.html:4
msgid "Address"
msgstr ""
-#: forms_common.py:313 forms_common.py:553 models.py:2564
+#: forms_common.py:313 forms_common.py:553 models.py:2587
msgid "Address complement"
msgstr ""
-#: forms_common.py:315 forms_common.py:554 models.py:2566
+#: forms_common.py:315 forms_common.py:554 models.py:2589
msgid "Postal code"
msgstr ""
-#: forms_common.py:318 forms_common.py:557 models.py:2569
+#: forms_common.py:318 forms_common.py:557 models.py:2592
msgid "Country"
msgstr ""
#: forms_common.py:320 forms_common.py:472 forms_common.py:530
-#: forms_common.py:606 forms_common.py:731 models.py:2596
+#: forms_common.py:606 forms_common.py:731 models.py:2619
msgid "Email"
msgstr ""
-#: forms_common.py:321 forms_common.py:533 models.py:2581
+#: forms_common.py:321 forms_common.py:533 models.py:2604
#: templates/ishtar/sheet_person.html:27
#: templates/ishtar/wizard/wizard_person.html:33
msgid "Phone"
msgstr ""
-#: forms_common.py:322 forms_common.py:542 models.py:2593
+#: forms_common.py:322 forms_common.py:542 models.py:2616
#: templates/ishtar/sheet_person.html:45
#: templates/ishtar/wizard/wizard_person.html:54
msgid "Mobile phone"
@@ -486,8 +494,8 @@ msgid "Full text search"
msgstr ""
#: forms_common.py:352 forms_common.py:473 forms_common.py:607
-#: forms_common.py:788 models.py:1089 models.py:2767 models.py:3738
-#: models_imports.py:680 templates/ishtar/blocks/window_image_detail.html:24
+#: forms_common.py:788 models.py:1111 models.py:2790 models.py:3804
+#: models_imports.py:681 templates/ishtar/blocks/window_image_detail.html:24
#: templates/ishtar/blocks/window_tables/documents.html:8
#: templates/ishtar/import_table.html:28
#: templates/ishtar/sheet_organization.html:25
@@ -510,7 +518,7 @@ msgstr ""
msgid "Organization to merge"
msgstr ""
-#: forms_common.py:471 forms_common.py:524 forms_common.py:605 models.py:2934
+#: forms_common.py:471 forms_common.py:524 forms_common.py:605 models.py:2958
#: templates/ishtar/sheet_organization.html:24
msgid "Surname"
msgstr ""
@@ -527,25 +535,25 @@ msgstr ""
msgid "Identity"
msgstr ""
-#: forms_common.py:521 forms_common.py:1095 forms_common.py:1217 models.py:2928
-#: models.py:2930 models.py:3729 models_imports.py:632
+#: forms_common.py:521 forms_common.py:1095 forms_common.py:1217 models.py:2952
+#: models.py:2954 models.py:3795 models_imports.py:633
#: templates/ishtar/blocks/window_tables/documents.html:7
msgid "Title"
msgstr ""
-#: forms_common.py:522 models.py:2932
+#: forms_common.py:522 models.py:2956
msgid "Salutation"
msgstr ""
-#: forms_common.py:528 models.py:2938
+#: forms_common.py:528 models.py:2962
msgid "Raw name"
msgstr ""
-#: forms_common.py:531 models.py:2582
+#: forms_common.py:531 models.py:2605
msgid "Phone description"
msgstr ""
-#: forms_common.py:534 models.py:2584 models.py:2586
+#: forms_common.py:534 models.py:2607 models.py:2609
msgid "Phone description 2"
msgstr ""
@@ -553,11 +561,11 @@ msgstr ""
msgid "Phone 2"
msgstr ""
-#: forms_common.py:538 models.py:2590
+#: forms_common.py:538 models.py:2613
msgid "Phone description 3"
msgstr ""
-#: forms_common.py:540 models.py:2588
+#: forms_common.py:540 models.py:2611
msgid "Phone 3"
msgstr ""
@@ -565,23 +573,23 @@ msgstr ""
msgid "Current organization"
msgstr ""
-#: forms_common.py:559 models.py:2571
+#: forms_common.py:559 models.py:2594
msgid "Other address: address"
msgstr ""
-#: forms_common.py:562 models.py:2574
+#: forms_common.py:562 models.py:2597
msgid "Other address: address complement"
msgstr ""
-#: forms_common.py:564 models.py:2575
+#: forms_common.py:564 models.py:2598
msgid "Other address: postal code"
msgstr ""
-#: forms_common.py:566 models.py:2577
+#: forms_common.py:566 models.py:2600
msgid "Other address: town"
msgstr ""
-#: forms_common.py:568 models.py:2579
+#: forms_common.py:568 models.py:2602
msgid "Other address: country"
msgstr ""
@@ -589,7 +597,7 @@ msgstr ""
msgid "Already has an account"
msgstr ""
-#: forms_common.py:603 models.py:3293
+#: forms_common.py:603 models.py:3318
msgid "Username"
msgstr ""
@@ -597,7 +605,8 @@ msgstr ""
msgid "Account search"
msgstr ""
-#: forms_common.py:669 forms_common.py:709 forms_common.py:713 models.py:2829
+#: forms_common.py:669 forms_common.py:709 forms_common.py:713 models.py:2853
+#: models_imports.py:632
msgid "Person type"
msgstr ""
@@ -605,7 +614,7 @@ msgstr ""
msgid "Account"
msgstr ""
-#: forms_common.py:734 wizards.py:1639
+#: forms_common.py:734 wizards.py:1651
msgid "New password"
msgstr ""
@@ -625,7 +634,7 @@ msgstr ""
msgid "This username already exists."
msgstr ""
-#: forms_common.py:789 models.py:3195 models.py:4148
+#: forms_common.py:789 models.py:3219 models.py:4221
msgid "Areas"
msgstr ""
@@ -633,11 +642,11 @@ msgstr ""
msgid "Send the new password by email?"
msgstr ""
-#: forms_common.py:821 models.py:3197 views.py:968
+#: forms_common.py:821 models.py:3221 views.py:991
msgid "Current profile"
msgstr ""
-#: forms_common.py:824 models.py:3175 models.py:3194
+#: forms_common.py:824 models.py:3199 models.py:3218
msgid "Profile type"
msgstr ""
@@ -665,8 +674,8 @@ msgstr ""
msgid " (duplicate)"
msgstr ""
-#: forms_common.py:932 forms_common.py:946 forms_common.py:947 models.py:4021
-#: models.py:4136
+#: forms_common.py:932 forms_common.py:946 forms_common.py:947 models.py:4094
+#: models.py:4209
msgid "Towns"
msgstr ""
@@ -693,19 +702,19 @@ msgstr ""
msgid "Document - General"
msgstr ""
-#: forms_common.py:1098 forms_common.py:1218 models.py:3543
-#: models_imports.py:633
+#: forms_common.py:1098 forms_common.py:1218 models.py:3609
+#: models_imports.py:634
msgid "Source type"
msgstr ""
#: forms_common.py:1101 forms_common.py:1152 forms_common.py:1333
-#: forms_common.py:1334 models.py:3504 models.py:3612 models.py:3748
+#: forms_common.py:1334 models.py:3570 models.py:3678 models.py:3814
#: templates/ishtar/blocks/window_image_detail.html:9
#: templates/ishtar/blocks/window_tables/documents.html:9
msgid "Authors"
msgstr ""
-#: forms_common.py:1105 models.py:3754
+#: forms_common.py:1105 models.py:3820
msgid "Numerical ressource (web address)"
msgstr ""
@@ -718,7 +727,7 @@ msgctxt "Not directory"
msgid "File"
msgstr ""
-#: forms_common.py:1113 forms_common.py:1219 models.py:4138
+#: forms_common.py:1113 forms_common.py:1219 models.py:4211
msgid "Reference"
msgstr ""
@@ -726,38 +735,38 @@ msgstr ""
msgid "Internal reference"
msgstr ""
-#: forms_common.py:1118 models.py:3756
+#: forms_common.py:1118 models.py:3822
#: templates/ishtar/blocks/window_image_detail.html:150
msgid "Receipt date"
msgstr ""
-#: forms_common.py:1120 models.py:3758 models_imports.py:859
+#: forms_common.py:1120 models.py:3824 models_imports.py:860
#: templates/ishtar/blocks/window_image_detail.html:54
msgid "Creation date"
msgstr ""
-#: forms_common.py:1123 models.py:3761
+#: forms_common.py:1123 models.py:3827
#: templates/ishtar/blocks/window_image_detail.html:160
msgid "Receipt date in documentation"
msgstr ""
-#: forms_common.py:1125 forms_common.py:1222 models.py:473 models.py:2942
-#: models.py:3421 models.py:3764 models_imports.py:483
+#: forms_common.py:1125 forms_common.py:1222 models.py:496 models.py:2966
+#: models.py:3446 models.py:3830 models_imports.py:483
#: templates/ishtar/blocks/window_image_detail.html:170
msgid "Comment"
msgstr ""
-#: forms_common.py:1127 forms_common.py:1221 models.py:1884 models.py:3763
+#: forms_common.py:1127 forms_common.py:1221 models.py:1902 models.py:3829
#: models_imports.py:125 models_imports.py:372 models_imports.py:446
msgid "Description"
msgstr ""
-#: forms_common.py:1130 models.py:3765
+#: forms_common.py:1130 models.py:3831
#: templates/ishtar/blocks/window_image_detail.html:182
msgid "Additional information"
msgstr ""
-#: forms_common.py:1132 forms_common.py:1225 models.py:3767
+#: forms_common.py:1132 forms_common.py:1225 models.py:3833
#: templates/ishtar/blocks/window_image_detail.html:108
msgid "Has a duplicate"
msgstr ""
@@ -788,11 +797,11 @@ msgid "You should at least fill one of this field: title, url, image or file."
msgstr ""
#: forms_common.py:1179
-msgid "A document have to attached at least to one item"
+msgid "A document has to be attached at least to one item"
msgstr ""
#: forms_common.py:1214 forms_common.py:1286 forms_common.py:1321
-#: models.py:3503 templates/ishtar/wizard/wizard_person_deletion.html:139
+#: models.py:3569 templates/ishtar/wizard/wizard_person_deletion.html:139
msgid "Author"
msgstr ""
@@ -820,7 +829,7 @@ msgstr ""
msgid "Would you like to delete this documentation?"
msgstr ""
-#: forms_common.py:1294 models.py:3468 models.py:3497 models_imports.py:634
+#: forms_common.py:1294 models.py:3534 models.py:3563 models_imports.py:635
msgid "Author type"
msgstr ""
@@ -832,11 +841,11 @@ msgstr ""
msgid "There are identical authors."
msgstr ""
-#: forms_common.py:1339 models.py:1683
+#: forms_common.py:1339 models.py:1700
msgid "Query"
msgstr ""
-#: forms_common.py:1344 models.py:1687
+#: forms_common.py:1344 models.py:1704
msgid "Is an alert"
msgstr ""
@@ -876,7 +885,7 @@ msgstr ""
msgid "Deletion"
msgstr ""
-#: ishtar_menu.py:40 models.py:2209 views.py:992
+#: ishtar_menu.py:40 models.py:2231 views.py:1015
msgid "Global variables"
msgstr ""
@@ -896,7 +905,7 @@ msgid "Creation"
msgstr ""
#: ishtar_menu.py:59 ishtar_menu.py:89 ishtar_menu.py:139
-#: templates/ishtar/forms/qa_base.html:29
+#: templates/ishtar/forms/qa_base.html:28
#: templates/ishtar/forms/qa_form.html:16
msgid "Modification"
msgstr ""
@@ -909,19 +918,19 @@ msgstr ""
msgid "Manual merge"
msgstr ""
-#: ishtar_menu.py:110 models_imports.py:882
+#: ishtar_menu.py:110 models_imports.py:883
msgid "Imports"
msgstr ""
-#: ishtar_menu.py:113 views.py:1000
+#: ishtar_menu.py:113 views.py:1023
msgid "New import"
msgstr ""
-#: ishtar_menu.py:117 views.py:1019
+#: ishtar_menu.py:117 views.py:1042
msgid "Current imports"
msgstr ""
-#: ishtar_menu.py:121 views.py:1468
+#: ishtar_menu.py:121 views.py:1491
msgid "Old imports"
msgstr ""
@@ -933,35 +942,35 @@ msgstr ""
msgid "Not a valid item."
msgstr ""
-#: models.py:211
+#: models.py:212
msgid "A selected item is not a valid item."
msgstr ""
-#: models.py:222
+#: models.py:224
msgid "This item already exists."
msgstr ""
-#: models.py:465 models.py:1682 models.py:2191 models.py:2528 models.py:2544
-#: models.py:3420 models_imports.py:368
+#: models.py:488 models.py:1699 models.py:2213 models.py:2551 models.py:2567
+#: models.py:3445 models_imports.py:368
msgid "Label"
msgstr ""
-#: models.py:467
+#: models.py:490
msgid "Textual ID"
msgstr ""
-#: models.py:470
+#: models.py:493
msgid ""
"The slug is the standardized version of the name. It contains only lowercase "
"letters, numbers and hyphens. Each slug must be unique."
msgstr ""
-#: models.py:474 models.py:2081 models.py:2437 models.py:3425
+#: models.py:497 models.py:2099 models.py:2460 models.py:3450
#: models_imports.py:139 models_imports.py:542
msgid "Available"
msgstr ""
-#: models.py:898 models.py:1083 models_imports.py:563
+#: models.py:920 models.py:1105 models_imports.py:563
#: templates/ishtar/formset_import_match.html:21
#: templates/ishtar/import_step_by_step.html:171
#: templates/ishtar/import_step_by_step.html:199
@@ -970,56 +979,56 @@ msgstr ""
msgid "Key"
msgstr ""
-#: models.py:904
+#: models.py:926
msgid "Specific key to an import"
msgstr ""
-#: models.py:1043
+#: models.py:1065
msgid "Generated relation image (SVG)"
msgstr ""
-#: models.py:1057 models.py:1091 models.py:1604 models.py:2193 models.py:3465
-#: models.py:4165 models.py:4247
+#: models.py:1079 models.py:1113 models.py:1621 models.py:2215 models.py:3531
+#: models.py:4238 models.py:4320
msgid "Order"
msgstr ""
-#: models.py:1060
+#: models.py:1082
msgid "Json data - Menu"
msgstr ""
-#: models.py:1061
+#: models.py:1083
msgid "Json data - Menus"
msgstr ""
-#: models.py:1069
+#: models.py:1091
msgid "Text"
msgstr ""
-#: models.py:1070
+#: models.py:1092
msgid "Long text"
msgstr ""
-#: models.py:1071 models_imports.py:676
+#: models.py:1093 models_imports.py:677
msgid "Integer"
msgstr ""
-#: models.py:1072
+#: models.py:1094
msgid "Boolean"
msgstr ""
-#: models.py:1073 models_imports.py:677
+#: models.py:1095 models_imports.py:678
msgid "Float"
msgstr ""
-#: models.py:1074 models_imports.py:679
+#: models.py:1096 models_imports.py:680
msgid "Date"
msgstr ""
-#: models.py:1075
+#: models.py:1097
msgid "Choices"
msgstr ""
-#: models.py:1084
+#: models.py:1106
msgid ""
"Value of the key in the JSON schema. For hierarchical key use \"__\" to "
"explain it. For instance for the key 'my_subkey' with data such as "
@@ -1027,417 +1036,417 @@ msgid ""
"my_key__my_subkey."
msgstr ""
-#: models.py:1088
+#: models.py:1110
msgid "Display"
msgstr ""
-#: models.py:1092
+#: models.py:1114
msgid "Use in search indexes"
msgstr ""
-#: models.py:1099
+#: models.py:1121
msgid "Json data - Field"
msgstr ""
-#: models.py:1100
+#: models.py:1122
msgid "Json data - Fields"
msgstr ""
-#: models.py:1111
+#: models.py:1133
msgid "Content types of the field and of the menu do not match"
msgstr ""
-#: models.py:1171
+#: models.py:1193
msgid "Search vector"
msgstr ""
-#: models.py:1172
+#: models.py:1194
msgid "Auto filled at save"
msgstr ""
-#: models.py:1392
+#: models.py:1409
msgid "Add document/image"
msgstr ""
-#: models.py:1394
+#: models.py:1411
msgid "doc./image"
msgstr ""
-#: models.py:1413
+#: models.py:1430
msgid "Last editor"
msgstr ""
-#: models.py:1416
+#: models.py:1433
msgid "Creator"
msgstr ""
-#: models.py:1597
+#: models.py:1614
msgid "Above"
msgstr ""
-#: models.py:1598
+#: models.py:1615
msgid "Bellow"
msgstr ""
-#: models.py:1599
+#: models.py:1616
msgid "Equal"
msgstr ""
-#: models.py:1605
+#: models.py:1622
msgid "Symmetrical"
msgstr ""
-#: models.py:1606
+#: models.py:1623
msgid "Tiny label"
msgstr ""
-#: models.py:1609
+#: models.py:1626
msgid "Inverse relation"
msgstr ""
-#: models.py:1612
+#: models.py:1629
msgid "Logical relation"
msgstr ""
-#: models.py:1622
+#: models.py:1639
msgid "Cannot have symmetrical and an inverse_relation"
msgstr ""
-#: models.py:1685
+#: models.py:1702
msgid "Content type"
msgstr ""
-#: models.py:1690
+#: models.py:1707
msgid "Search query"
msgstr ""
-#: models.py:1691
+#: models.py:1708
msgid "Search queries"
msgstr ""
-#: models.py:1855
+#: models.py:1873
msgid "Euro"
msgstr ""
-#: models.py:1856
+#: models.py:1874
msgid "US dollar"
msgstr ""
-#: models.py:1857 views.py:742 views.py:803
+#: models.py:1875 views.py:765 views.py:826
msgid "Operations"
msgstr ""
-#: models.py:1858 views.py:744 views.py:807
+#: models.py:1876 views.py:767 views.py:830
msgid "Context records"
msgstr ""
-#: models.py:1859
+#: models.py:1877
msgid "Site"
msgstr ""
-#: models.py:1859
+#: models.py:1877
msgid "Archaeological entity"
msgstr ""
-#: models.py:1863
+#: models.py:1881
msgid "Site search"
msgstr ""
-#: models.py:1864
+#: models.py:1882
msgid "New site"
msgstr ""
-#: models.py:1865
+#: models.py:1883
msgid "Site modification"
msgstr ""
-#: models.py:1866
+#: models.py:1884
msgid "Site deletion"
msgstr ""
-#: models.py:1869
+#: models.py:1887
msgid "Archaeological entity search"
msgstr ""
-#: models.py:1870
+#: models.py:1888
msgid "New archaeological entity"
msgstr ""
-#: models.py:1871
+#: models.py:1889
msgid "Archaeological entity modification"
msgstr ""
-#: models.py:1872
+#: models.py:1890
msgid "Archaeological entity deletion"
msgstr ""
-#: models.py:1880 models.py:2431 models_imports.py:124
+#: models.py:1898 models.py:2454 models_imports.py:124
msgid "Slug"
msgstr ""
-#: models.py:1881
+#: models.py:1899
msgid "Current active"
msgstr ""
-#: models.py:1883
+#: models.py:1901
msgid "Activate experimental feature"
msgstr ""
-#: models.py:1886
+#: models.py:1904
msgid "Alternate configuration"
msgstr ""
-#: models.py:1888
+#: models.py:1906
msgid "Choose an alternate configuration for label, index management"
msgstr ""
-#: models.py:1892
+#: models.py:1910
msgid "Files module"
msgstr ""
-#: models.py:1894
+#: models.py:1912
msgid "Archaeological site module"
msgstr ""
-#: models.py:1896
+#: models.py:1914
msgid "Archaeological site type"
msgstr ""
-#: models.py:1900
+#: models.py:1918
msgid "Context records module"
msgstr ""
-#: models.py:1902
+#: models.py:1920
msgid "Finds module"
msgstr ""
-#: models.py:1903
+#: models.py:1921
msgid "Need context records module"
msgstr ""
-#: models.py:1905
+#: models.py:1923
msgid "Find index is based on"
msgstr ""
-#: models.py:1907
+#: models.py:1925
msgid ""
"To prevent irrelevant indexes, change this parameter only if there is no "
"find in the database"
msgstr ""
-#: models.py:1910
+#: models.py:1928
msgid "Warehouses module"
msgstr ""
-#: models.py:1911
+#: models.py:1929
msgid "Need finds module"
msgstr ""
-#: models.py:1912
+#: models.py:1930
msgid "Preservation module"
msgstr ""
-#: models.py:1914
+#: models.py:1932
msgid "Mapping module"
msgstr ""
-#: models.py:1915
+#: models.py:1933
msgid "Underwater module"
msgstr ""
-#: models.py:1917
+#: models.py:1935
msgid "Parcel are mandatory for context records"
msgstr ""
-#: models.py:1919
+#: models.py:1937
msgid "Home page"
msgstr ""
-#: models.py:1920
+#: models.py:1938
#, python-brace-format
msgid ""
"Homepage of Ishtar - if not defined a default homepage will appear. Use the "
"markdown syntax. {random_image} can be used to display a random image."
msgstr ""
-#: models.py:1924
+#: models.py:1942
msgid "Main operation code prefix"
msgstr ""
-#: models.py:1928
+#: models.py:1946
msgid "Default operation code prefix"
msgstr ""
-#: models.py:1932
+#: models.py:1950
msgid "Operation region code"
msgstr ""
-#: models.py:1936
+#: models.py:1954
msgid "File external id"
msgstr ""
-#: models.py:1938
+#: models.py:1956
msgid ""
"Formula to manage file external ID. Change this with care. With incorrect "
"formula, the application might be unusable and import of external data can "
"be destructive."
msgstr ""
-#: models.py:1943
+#: models.py:1961
msgid "Parcel external id"
msgstr ""
-#: models.py:1946
+#: models.py:1964
msgid ""
"Formula to manage parcel external ID. Change this with care. With incorrect "
"formula, the application might be unusable and import of external data can "
"be destructive."
msgstr ""
-#: models.py:1951
+#: models.py:1969
msgid "Context record external id"
msgstr ""
-#: models.py:1953
+#: models.py:1971
msgid ""
"Formula to manage context record external ID. Change this with care. With "
"incorrect formula, the application might be unusable and import of external "
"data can be destructive."
msgstr ""
-#: models.py:1958
+#: models.py:1976
msgid "Base find external id"
msgstr ""
-#: models.py:1960
+#: models.py:1978
msgid ""
"Formula to manage base find external ID. Change this with care. With "
"incorrect formula, the application might be unusable and import of external "
"data can be destructive."
msgstr ""
-#: models.py:1965
+#: models.py:1983
msgid "Find external id"
msgstr ""
-#: models.py:1967
+#: models.py:1985
msgid ""
"Formula to manage find external ID. Change this with care. With incorrect "
"formula, the application might be unusable and import of external data can "
"be destructive."
msgstr ""
-#: models.py:1972
+#: models.py:1990
msgid "Container external id"
msgstr ""
-#: models.py:1974
+#: models.py:1992
msgid ""
"Formula to manage container external ID. Change this with care. With "
"incorrect formula, the application might be unusable and import of external "
"data can be destructive."
msgstr ""
-#: models.py:1979
+#: models.py:1997
msgid "Warehouse external id"
msgstr ""
-#: models.py:1981
+#: models.py:1999
msgid ""
"Formula to manage warehouse external ID. Change this with care. With "
"incorrect formula, the application might be unusable and import of external "
"data can be destructive."
msgstr ""
-#: models.py:1986
+#: models.py:2004
msgid "Raw name for person"
msgstr ""
-#: models.py:1988
+#: models.py:2006
msgid ""
"Formula to manage person raw_name. Change this with care. With incorrect "
"formula, the application might be unusable and import of external data can "
"be destructive."
msgstr ""
-#: models.py:1992
+#: models.py:2010
msgid "Use auto index for finds"
msgstr ""
-#: models.py:1994
+#: models.py:2012
msgid "Currency"
msgstr ""
-#: models.py:1998
+#: models.py:2016
msgid "Ishtar site profile"
msgstr ""
-#: models.py:1999
+#: models.py:2017
msgid "Ishtar site profiles"
msgstr ""
-#: models.py:2083
+#: models.py:2101
msgid "Enable this form"
msgstr ""
-#: models.py:2084
+#: models.py:2102
msgid ""
"Disable with caution: disabling a form with mandatory fields may lead to "
"database errors."
msgstr ""
-#: models.py:2087
+#: models.py:2105
msgid "Apply to all"
msgstr ""
-#: models.py:2088
+#: models.py:2106
msgid ""
"Apply this form to all users. If set to True, selecting user and user type "
"is useless."
msgstr ""
-#: models.py:2094
+#: models.py:2112
msgid "Custom form"
msgstr ""
-#: models.py:2095
+#: models.py:2113
msgid "Custom forms"
msgstr ""
-#: models.py:2111
+#: models.py:2129
msgid "User types"
msgstr ""
-#: models.py:2183
+#: models.py:2205
msgid "Excluded field"
msgstr ""
-#: models.py:2184
+#: models.py:2206
msgid "Excluded fields"
msgstr ""
-#: models.py:2194 templates/blocks/form_flex_snippet.html:18
+#: models.py:2216 templates/blocks/form_flex_snippet.html:18
#: templates/blocks/table_form_snippet.html:9
msgid "Help"
msgstr ""
-#: models.py:2197
+#: models.py:2219
msgid "Custom form - Json data field"
msgstr ""
-#: models.py:2198
+#: models.py:2220
msgid "Custom form - Json data fields"
msgstr ""
-#: models.py:2202
+#: models.py:2224
msgid "Variable name"
msgstr ""
-#: models.py:2203
+#: models.py:2225
msgid "Description of the variable"
msgstr ""
-#: models.py:2205 models_imports.py:564
+#: models.py:2227 models_imports.py:564
#: templates/ishtar/formset_import_match.html:22
#: templates/ishtar/import_step_by_step.html:172
#: templates/ishtar/import_step_by_step.html:200
@@ -1445,559 +1454,563 @@ msgstr ""
msgid "Value"
msgstr ""
-#: models.py:2208
+#: models.py:2230
msgid "Global variable"
msgstr ""
-#: models.py:2335 models.py:2365
+#: models.py:2358 models.py:2388
msgid "Total"
msgstr ""
-#: models.py:2342 models.py:2529 models.py:2545
+#: models.py:2365 models.py:2552 models.py:2568
#: templates/ishtar/dashboards/dashboard_main_detail.html:211
#: templates/ishtar/dashboards/dashboard_main_detail_users.html:5
#: templates/ishtar/sheet_person.html:30
msgid "Number"
msgstr ""
-#: models.py:2429
+#: models.py:2452
msgid "Administrative Act"
msgstr ""
-#: models.py:2436
+#: models.py:2459
msgid "Associated object"
msgstr ""
-#: models.py:2441
+#: models.py:2464
msgid "Document template"
msgstr ""
-#: models.py:2442
+#: models.py:2465
msgid "Document templates"
msgstr ""
-#: models.py:2533 models.py:2546 models.py:4285 models_imports.py:853
+#: models.py:2556 models.py:2569 models.py:4360 models_imports.py:854
msgid "State"
msgstr ""
-#: models.py:2551 models.py:4007 templates/blocks/JQueryAdvancedTown.html:12
+#: models.py:2574 models.py:4080 templates/blocks/JQueryAdvancedTown.html:12
msgid "Department"
msgstr ""
-#: models.py:2552
+#: models.py:2575
msgid "Departments"
msgstr ""
-#: models.py:2592
+#: models.py:2615
msgid "Raw phone"
msgstr ""
-#: models.py:2598
+#: models.py:2621
msgid "Alternative address is prefered"
msgstr ""
-#: models.py:2637
+#: models.py:2660
msgid "Tel: "
msgstr ""
-#: models.py:2641
+#: models.py:2664
msgid "Mobile: "
msgstr ""
-#: models.py:2645
+#: models.py:2668
msgid "Email: "
msgstr ""
-#: models.py:2650
+#: models.py:2673
msgid "Merge key"
msgstr ""
-#: models.py:2722
+#: models.py:2745
msgid "Organization types"
msgstr ""
-#: models.py:2749 models.py:2896 models.py:3303
+#: models.py:2772 models.py:2920 models.py:3328
msgctxt "key for text search"
msgid "name"
msgstr ""
-#: models.py:2753 models.py:2908 models.py:3315 models.py:3639
+#: models.py:2776 models.py:2932 models.py:3340 models.py:3705
msgctxt "key for text search"
msgid "type"
msgstr ""
-#: models.py:2768 models.py:2947 models.py:3498 models.py:4015
+#: models.py:2791 models.py:2971 models.py:3564 models.py:4088
msgid "Cached name"
msgstr ""
-#: models.py:2774
+#: models.py:2797
msgid "Organizations"
msgstr ""
-#: models.py:2804
+#: models.py:2828
msgid "unknown organization"
msgstr ""
-#: models.py:2830
+#: models.py:2854
msgid "Person types"
msgstr ""
-#: models.py:2843 models_imports.py:670
+#: models.py:2867 models_imports.py:671
msgid "Title type"
msgstr ""
-#: models.py:2844
+#: models.py:2868
msgid "Title types"
msgstr ""
-#: models.py:2868
+#: models.py:2892
msgid "Mr"
msgstr ""
-#: models.py:2869
+#: models.py:2893
msgid "Miss"
msgstr ""
-#: models.py:2870
+#: models.py:2894
msgid "Mr and Mrs"
msgstr ""
-#: models.py:2871
+#: models.py:2895
msgid "Mrs"
msgstr ""
-#: models.py:2872
+#: models.py:2896
msgid "Doctor"
msgstr ""
-#: models.py:2900 models.py:3307
+#: models.py:2924 models.py:3332
msgctxt "key for text search"
msgid "surname"
msgstr ""
-#: models.py:2904 models.py:3311
+#: models.py:2928 models.py:3336
msgctxt "key for text search"
msgid "email"
msgstr ""
-#: models.py:2912 models.py:3319
+#: models.py:2936 models.py:3344
msgctxt "key for text search"
msgid "organization"
msgstr ""
-#: models.py:2916
+#: models.py:2940
msgctxt "key for text search"
msgid "has-account"
msgstr ""
-#: models.py:2940
+#: models.py:2964
msgid "Contact type"
msgstr ""
-#: models.py:2943 models.py:3033
+#: models.py:2967 models.py:3057
msgid "Types"
msgstr ""
-#: models.py:2946
+#: models.py:2970
msgid "Is attached to"
msgstr ""
-#: models.py:2953
+#: models.py:2977
msgid "Persons"
msgstr ""
-#: models.py:3171
+#: models.py:3195
msgid "Groups"
msgstr ""
-#: models.py:3176
+#: models.py:3200
msgid "Profile types"
msgstr ""
-#: models.py:3187
+#: models.py:3211
msgid "Profile type summary"
msgstr ""
-#: models.py:3188
+#: models.py:3212
msgid "Profile types summary"
msgstr ""
-#: models.py:3199
+#: models.py:3223
msgid "Show field number"
msgstr ""
-#: models.py:3200
+#: models.py:3224
msgid "Automatically pin"
msgstr ""
-#: models.py:3201
+#: models.py:3225
msgid "Display pin menu"
msgstr ""
-#: models.py:3207
+#: models.py:3231
msgid "User profile"
msgstr ""
-#: models.py:3208
+#: models.py:3232
msgid "User profiles"
msgstr ""
-#: models.py:3243
+#: models.py:3267 models.py:3522
msgid " - duplicate"
msgstr ""
-#: models.py:3299
+#: models.py:3324
msgctxt "key for text search"
msgid "username"
msgstr ""
-#: models.py:3335
+#: models.py:3360
msgid "Advanced shortcut menu"
msgstr ""
-#: models.py:3338
+#: models.py:3363
msgid "Ishtar user"
msgstr ""
-#: models.py:3339
+#: models.py:3364
msgid "Ishtar users"
msgstr ""
-#: models.py:3424
+#: models.py:3449
msgid "Owner"
msgstr ""
-#: models.py:3427
-msgid "Shared with"
+#: models.py:3452
+msgid "Shared (read) with"
+msgstr ""
+
+#: models.py:3456
+msgid "Shared (read/edit) with"
msgstr ""
-#: models.py:3469
+#: models.py:3535
msgid "Author types"
msgstr ""
-#: models.py:3544
+#: models.py:3610
msgid "Source types"
msgstr ""
-#: models.py:3554 models_imports.py:669
+#: models.py:3620 models_imports.py:670
msgid "Support type"
msgstr ""
-#: models.py:3555
+#: models.py:3621
msgid "Support types"
msgstr ""
-#: models.py:3564
+#: models.py:3630
msgid "Format type"
msgstr ""
-#: models.py:3565
+#: models.py:3631
msgid "Format types"
msgstr ""
-#: models.py:3574
+#: models.py:3640
msgid "URL"
msgstr ""
-#: models.py:3577
+#: models.py:3643
msgid "License type"
msgstr ""
-#: models.py:3578
+#: models.py:3644
msgid "License types"
msgstr ""
-#: models.py:3631
+#: models.py:3697
msgctxt "key for text search"
msgid "author"
msgstr ""
-#: models.py:3635
+#: models.py:3701
msgctxt "key for text search"
msgid "title"
msgstr ""
-#: models.py:3643
+#: models.py:3709
msgctxt "key for text search"
msgid "reference"
msgstr ""
-#: models.py:3647
+#: models.py:3713
msgctxt "key for text search"
msgid "internal-reference"
msgstr ""
-#: models.py:3651
+#: models.py:3717
msgctxt "key for text search"
msgid "description"
msgstr ""
-#: models.py:3655
+#: models.py:3721
msgctxt "key for text search"
msgid "comment"
msgstr ""
-#: models.py:3659
+#: models.py:3725
msgctxt "key for text search"
msgid "additional-information"
msgstr ""
-#: models.py:3663
+#: models.py:3729
msgctxt "key for text search"
msgid "has-duplicate"
msgstr ""
-#: models.py:3667 models.py:3714
+#: models.py:3733 models.py:3780
msgctxt "key for text search"
msgid "operation"
msgstr ""
-#: models.py:3671 models.py:3717
+#: models.py:3737 models.py:3783
msgctxt "key for text search"
msgid "context-record"
msgstr ""
-#: models.py:3675 models.py:3719
+#: models.py:3741 models.py:3785
msgctxt "key for text search"
msgid "find"
msgstr ""
-#: models.py:3679 models.py:3718
+#: models.py:3745 models.py:3784
msgctxt "key for text search"
msgid "file"
msgstr ""
-#: models.py:3683 models.py:3720
+#: models.py:3749 models.py:3786
msgctxt "key for text search"
msgid "site"
msgstr ""
-#: models.py:3687 models.py:3721
+#: models.py:3753 models.py:3787
msgctxt "key for text search"
msgid "warehouse"
msgstr ""
-#: models.py:3723
+#: models.py:3789
msgctxt "key for text search"
msgid "treatment"
msgstr ""
-#: models.py:3726
+#: models.py:3792
msgctxt "key for text search"
msgid "treatment-file"
msgstr ""
-#: models.py:3732
+#: models.py:3798
msgid "Index"
msgstr ""
-#: models.py:3734
+#: models.py:3800
msgid "External ID"
msgstr ""
-#: models.py:3735 templates/ishtar/blocks/window_image_detail.html:34
+#: models.py:3801 templates/ishtar/blocks/window_image_detail.html:34
msgid "Ref."
msgstr ""
-#: models.py:3736 templates/ishtar/blocks/window_image_detail.html:44
+#: models.py:3802 templates/ishtar/blocks/window_image_detail.html:44
msgid "Internal ref."
msgstr ""
-#: models.py:3740
+#: models.py:3806
msgid "License"
msgstr ""
-#: models.py:3742 templates/ishtar/blocks/window_image_detail.html:78
+#: models.py:3808 templates/ishtar/blocks/window_image_detail.html:78
msgid "Support"
msgstr ""
-#: models.py:3744 models_imports.py:635
+#: models.py:3810 models_imports.py:636
#: templates/ishtar/blocks/window_image_detail.html:88
msgid "Format"
msgstr ""
-#: models.py:3746 templates/ishtar/blocks/window_image_detail.html:98
+#: models.py:3812 templates/ishtar/blocks/window_image_detail.html:98
msgid "Scale"
msgstr ""
-#: models.py:3750
+#: models.py:3816
msgid "Authors (raw)"
msgstr ""
-#: models.py:3762 templates/ishtar/blocks/window_image_detail.html:118
+#: models.py:3828 templates/ishtar/blocks/window_image_detail.html:118
msgid "Number of items"
msgstr ""
-#: models.py:3769
+#: models.py:3835
msgid "Symbolic links"
msgstr ""
-#: models.py:3772
+#: models.py:3838
msgid "Related"
msgstr ""
-#: models.py:3773
+#: models.py:3839
msgid "Cached value - do not edit"
msgstr ""
-#: models.py:3776 templates/ishtar/sheet_document.html:4
+#: models.py:3842 templates/ishtar/sheet_document.html:4
msgid "Document"
msgstr ""
-#: models.py:3777 templates/ishtar/sheet_person.html:113
+#: models.py:3843 templates/ishtar/sheet_person.html:113
msgid "Documents"
msgstr ""
-#: models.py:3781
+#: models.py:3847
msgid "Can view all Documents"
msgstr ""
-#: models.py:3783
+#: models.py:3849
msgid "Can view own Document"
msgstr ""
-#: models.py:3785
+#: models.py:3851
msgid "Can add own Document"
msgstr ""
-#: models.py:3787
+#: models.py:3853
msgid "Can change own Document"
msgstr ""
-#: models.py:3789
+#: models.py:3855
msgid "Can delete own Document"
msgstr ""
-#: models.py:4000
+#: models.py:4073
msgid "Surface (m2)"
msgstr ""
-#: models.py:4001
+#: models.py:4074
msgid "Localisation"
msgstr ""
-#: models.py:4009
+#: models.py:4082
msgid "Year of creation"
msgstr ""
-#: models.py:4010
+#: models.py:4083
msgid "Filling this field is relevant to distinguish old towns from new towns."
msgstr ""
-#: models.py:4142
+#: models.py:4215
msgid "Only four level of parent are managed."
msgstr ""
-#: models.py:4147
+#: models.py:4220
msgid "Area"
msgstr ""
-#: models.py:4166
+#: models.py:4239
msgid "Is preventive"
msgstr ""
-#: models.py:4167
+#: models.py:4240
msgid "Is judiciary"
msgstr ""
-#: models.py:4170 models_imports.py:636
+#: models.py:4243 models_imports.py:637
msgid "Operation type"
msgstr ""
-#: models.py:4171
+#: models.py:4244
msgid "Operation types"
msgstr ""
-#: models.py:4210
+#: models.py:4283
msgid "Judiciary"
msgstr ""
-#: models.py:4212
+#: models.py:4285
msgid "Preventive"
msgstr ""
-#: models.py:4214
+#: models.py:4287
msgid "Research"
msgstr ""
-#: models.py:4249
+#: models.py:4322
msgid "Authority name"
msgstr ""
-#: models.py:4250
+#: models.py:4323
msgid "Authority SRID"
msgstr ""
-#: models.py:4253 models_imports.py:668
+#: models.py:4326 models_imports.py:669
msgid "Spatial reference system"
msgstr ""
-#: models.py:4254
+#: models.py:4327
msgid "Spatial reference systems"
msgstr ""
-#: models.py:4261
+#: models.py:4336
msgid "Filename"
msgstr ""
-#: models.py:4266
+#: models.py:4341
msgid "Administration script"
msgstr ""
-#: models.py:4267
+#: models.py:4342
msgid "Administration scripts"
msgstr ""
-#: models.py:4274
+#: models.py:4349
msgid "Scheduled"
msgstr ""
-#: models.py:4275
+#: models.py:4350
msgid "In progress"
msgstr ""
-#: models.py:4276 models_imports.py:792
+#: models.py:4351 models_imports.py:793
msgid "Finished with errors"
msgstr ""
-#: models.py:4277 models_imports.py:793
+#: models.py:4352 models_imports.py:794
msgid "Finished"
msgstr ""
-#: models.py:4290
+#: models.py:4365
msgid "Result"
msgstr ""
-#: models.py:4293
+#: models.py:4368
msgid "Administration task"
msgstr ""
-#: models.py:4294
+#: models.py:4369
msgid "Administration tasks"
msgstr ""
-#: models.py:4298
+#: models.py:4373
msgid "Unknown"
msgstr ""
-#: models.py:4313
+#: models.py:4388
msgid ""
"ISHTAR_SCRIPT_DIR is not set in your local_settings. Contact your "
"administrator."
msgstr ""
-#: models.py:4322
+#: models.py:4397
msgid ""
"Your ISHTAR_SCRIPT_DIR is containing dots \"..\". As it can refer to "
"relative paths, it can be a security issue and this is not allowed. Only put "
"a full path."
msgstr ""
-#: models.py:4333
+#: models.py:4408
msgid "Your ISHTAR_SCRIPT_DIR: \"{}\" is not a valid directory."
msgstr ""
-#: models.py:4349
+#: models.py:4424
msgid ""
"Script \"{}\" is not available in your script directory. Check your "
"configuration."
@@ -2028,7 +2041,7 @@ msgid "Leave blank for no restrictions"
msgstr ""
#: models_imports.py:136
-msgid "Is template"
+msgid "Can be exported"
msgstr ""
#: models_imports.py:137
@@ -2136,11 +2149,11 @@ msgstr ""
msgid "Importer - Targets"
msgstr ""
-#: models_imports.py:525 views_item.py:847
+#: models_imports.py:525 views_item.py:346 views_item.py:950
msgid "True"
msgstr ""
-#: models_imports.py:526 views_item.py:849
+#: models_imports.py:526 views_item.py:952
msgid "False"
msgstr ""
@@ -2172,327 +2185,327 @@ msgstr ""
msgid "Importer - Targets keys"
msgstr ""
-#: models_imports.py:637
+#: models_imports.py:638
msgid "Period"
msgstr ""
-#: models_imports.py:638
+#: models_imports.py:639
msgid "Report state"
msgstr ""
-#: models_imports.py:639
+#: models_imports.py:640
msgid "Remain type"
msgstr ""
-#: models_imports.py:640
+#: models_imports.py:641
msgid "Unit"
msgstr ""
-#: models_imports.py:642
+#: models_imports.py:643
msgid "Activity type"
msgstr ""
-#: models_imports.py:644
+#: models_imports.py:645
msgid "Documentation type"
msgstr ""
-#: models_imports.py:645
+#: models_imports.py:646
msgid "Material"
msgstr ""
-#: models_imports.py:647
+#: models_imports.py:648
msgid "Conservatory state"
msgstr ""
-#: models_imports.py:648
+#: models_imports.py:649
msgid "Container type"
msgstr ""
-#: models_imports.py:650
+#: models_imports.py:651
msgid "Warehouse division"
msgstr ""
-#: models_imports.py:651
+#: models_imports.py:652
msgid "Warehouse type"
msgstr ""
-#: models_imports.py:652
+#: models_imports.py:653
msgid "Treatment type"
msgstr ""
-#: models_imports.py:654
+#: models_imports.py:655
msgid "Treatment emergency type"
msgstr ""
-#: models_imports.py:655
+#: models_imports.py:656
msgid "Object type"
msgstr ""
-#: models_imports.py:656
+#: models_imports.py:657
msgid "Integrity type"
msgstr ""
-#: models_imports.py:658
+#: models_imports.py:659
msgid "Remarkability type"
msgstr ""
-#: models_imports.py:659
+#: models_imports.py:660
msgid "Alteration type"
msgstr ""
-#: models_imports.py:661
+#: models_imports.py:662
msgid "Alteration cause type"
msgstr ""
-#: models_imports.py:662
+#: models_imports.py:663
msgid "Batch type"
msgstr ""
-#: models_imports.py:663
+#: models_imports.py:664
msgid "Checked type"
msgstr ""
-#: models_imports.py:665
+#: models_imports.py:666
msgid "Identification type"
msgstr ""
-#: models_imports.py:667
+#: models_imports.py:668
msgid "Context record relation type"
msgstr ""
-#: models_imports.py:678
+#: models_imports.py:679
msgid "String"
msgstr ""
-#: models_imports.py:681
+#: models_imports.py:682
#: templates/ishtar/dashboards/dashboard_main_detail.html:196
msgid "Year"
msgstr ""
-#: models_imports.py:682
+#: models_imports.py:683
msgid "INSEE code"
msgstr ""
-#: models_imports.py:683
+#: models_imports.py:684
msgid "String to boolean"
msgstr ""
-#: models_imports.py:684
+#: models_imports.py:685
msgctxt "filesystem"
msgid "File"
msgstr ""
-#: models_imports.py:685
+#: models_imports.py:686
msgid "Unknow type"
msgstr ""
-#: models_imports.py:702
+#: models_imports.py:703
msgid "4 digit year. e.g.: \"2015\""
msgstr ""
-#: models_imports.py:703
+#: models_imports.py:704
msgid "4 digit year/month/day. e.g.: \"2015/02/04\""
msgstr ""
-#: models_imports.py:704
+#: models_imports.py:705
msgid "Day/month/4 digit year. e.g.: \"04/02/2015\""
msgstr ""
-#: models_imports.py:720
+#: models_imports.py:721
msgid "Options"
msgstr ""
-#: models_imports.py:722
+#: models_imports.py:723
msgid "Split character(s)"
msgstr ""
-#: models_imports.py:727
+#: models_imports.py:728
msgid "Importer - Formater type"
msgstr ""
-#: models_imports.py:728
+#: models_imports.py:729
msgid "Importer - Formater types"
msgstr ""
-#: models_imports.py:784
+#: models_imports.py:785
#: templates/ishtar/dashboards/dashboard_main_detail.html:132
msgid "Created"
msgstr ""
-#: models_imports.py:785
+#: models_imports.py:786
msgid "Analyse in progress"
msgstr ""
-#: models_imports.py:786
+#: models_imports.py:787
msgid "Analysed"
msgstr ""
-#: models_imports.py:787
+#: models_imports.py:788
msgid "Check modified in queue"
msgstr ""
-#: models_imports.py:788
+#: models_imports.py:789
msgid "Import in queue"
msgstr ""
-#: models_imports.py:789
+#: models_imports.py:790
msgid "Check modified in progress"
msgstr ""
-#: models_imports.py:790
+#: models_imports.py:791
msgid "Import in progress"
msgstr ""
-#: models_imports.py:791
+#: models_imports.py:792
msgid "Partially imported"
msgstr ""
-#: models_imports.py:794
+#: models_imports.py:795
msgid "Archived"
msgstr ""
-#: models_imports.py:830
+#: models_imports.py:831
msgid "Imported file"
msgstr ""
-#: models_imports.py:832
+#: models_imports.py:833
msgid "Associated images (zip file)"
msgstr ""
-#: models_imports.py:836
+#: models_imports.py:837
msgid "If a group is selected, target key saved in this group will be used."
msgstr ""
-#: models_imports.py:839
+#: models_imports.py:840
msgid "Encoding"
msgstr ""
-#: models_imports.py:842
+#: models_imports.py:843
msgid "Skip lines"
msgstr ""
-#: models_imports.py:843
+#: models_imports.py:844
msgid "Number of header lines in your file (can be 0)."
msgstr ""
-#: models_imports.py:844
+#: models_imports.py:845
msgid "Error file"
msgstr ""
-#: models_imports.py:847
+#: models_imports.py:848
msgid "Result file"
msgstr ""
-#: models_imports.py:850
+#: models_imports.py:851
msgid "Match file"
msgstr ""
-#: models_imports.py:856
+#: models_imports.py:857
msgid "Conservative import"
msgstr ""
-#: models_imports.py:857
+#: models_imports.py:858
msgid "If set to true, do not overload existing values."
msgstr ""
-#: models_imports.py:860
+#: models_imports.py:861
msgid "End date"
msgstr ""
-#: models_imports.py:863
+#: models_imports.py:864
msgid "Remaining seconds"
msgstr ""
-#: models_imports.py:865
+#: models_imports.py:866
msgid "Current line"
msgstr ""
-#: models_imports.py:867
+#: models_imports.py:868
msgid "Number of line"
msgstr ""
-#: models_imports.py:870
+#: models_imports.py:871
msgid "Imported line numbers"
msgstr ""
-#: models_imports.py:873
+#: models_imports.py:874
msgid "Changed have been checked"
msgstr ""
-#: models_imports.py:876
+#: models_imports.py:877
msgid "Changed line numbers"
msgstr ""
-#: models_imports.py:881
+#: models_imports.py:882
msgid "Import"
msgstr ""
-#: models_imports.py:970
+#: models_imports.py:971
msgid "Analyse"
msgstr ""
-#: models_imports.py:972 models_imports.py:981
+#: models_imports.py:973 models_imports.py:982
msgid "Re-analyse"
msgstr ""
-#: models_imports.py:973
+#: models_imports.py:974
msgid "Launch import"
msgstr ""
-#: models_imports.py:976
+#: models_imports.py:977
msgid "Step by step import"
msgstr ""
-#: models_imports.py:977 models_imports.py:986
+#: models_imports.py:978 models_imports.py:987
msgid "Re-check for changes"
msgstr ""
-#: models_imports.py:979 models_imports.py:988
+#: models_imports.py:980 models_imports.py:989
msgid "Check for changes"
msgstr ""
-#: models_imports.py:982
+#: models_imports.py:983
msgid "Re-import"
msgstr ""
-#: models_imports.py:985
+#: models_imports.py:986
msgid "Step by step re-import"
msgstr ""
-#: models_imports.py:989
+#: models_imports.py:990
msgid "Archive"
msgstr ""
-#: models_imports.py:991
+#: models_imports.py:992
msgid "Unarchive"
msgstr ""
-#: models_imports.py:992 templates/ishtar/form_delete.html:11 views.py:1847
-#: widgets.py:371 widgets.py:403
+#: models_imports.py:993 templates/ishtar/form_delete.html:11 views.py:1896
+#: widgets.py:379 widgets.py:411
msgid "Delete"
msgstr ""
-#: models_imports.py:1042
+#: models_imports.py:1043
msgid "Error in the CSV file."
msgstr ""
-#: models_imports.py:1070
+#: models_imports.py:1071
msgid "Modification check {} added to the queue"
msgstr ""
-#: models_imports.py:1140
+#: models_imports.py:1141
msgid "Import {} added to the queue"
msgstr ""
-#: models_imports.py:1158
+#: models_imports.py:1159
msgid "Error on imported file: {}"
msgstr ""
-#: models_imports.py:1193
+#: models_imports.py:1194
msgid "Import {} finished with errors"
msgstr ""
-#: models_imports.py:1202
+#: models_imports.py:1203
msgid "Import {} finished with no errors"
msgstr ""
@@ -2544,12 +2557,12 @@ msgid "View on site"
msgstr ""
#: templates/admin/change_form.html:24 templates/admin/change_form.html:27
-#: views.py:1231 views.py:1236
+#: views.py:1254 views.py:1259
msgid "Previous"
msgstr ""
#: templates/admin/change_form.html:32 templates/admin/change_form.html:35
-#: views.py:1239 views.py:1242
+#: views.py:1262 views.py:1265
msgid "Next"
msgstr ""
@@ -2583,49 +2596,53 @@ msgid " items added."
msgstr ""
#: templates/base.html:47
-msgid "yes"
+msgid "Select only one item."
msgstr ""
#: templates/base.html:48
-msgid "no"
+msgid "yes"
msgstr ""
#: templates/base.html:49
-msgid "Autorefresh start. The form is disabled."
+msgid "no"
msgstr ""
#: templates/base.html:50
+msgid "Autorefresh start. The form is disabled."
+msgstr ""
+
+#: templates/base.html:51
msgid "Autorefresh end. The form is re-enabled."
msgstr ""
-#: templates/base.html:81
+#: templates/base.html:82
msgid "Current items"
msgstr ""
-#: templates/base.html:83 templates/ishtar/forms/qa_base.html:34
+#: templates/base.html:84 templates/ishtar/forms/qa_base.html:33
#: templates/ishtar/forms/qa_form.html:21 templates/ishtar/manage_basket.html:4
#: templates/welcome.html:11 templates/welcome.html:12
-#: templates/welcome.html:13 templates/welcome.html:14 wizards.py:423
+#: templates/welcome.html:13 templates/welcome.html:14 wizards.py:435
msgid ":"
msgstr ""
-#: templates/base.html:96
+#: templates/base.html:97
msgid "Sheets"
msgstr ""
-#: templates/base.html:146
+#: templates/base.html:158
msgid "Processing..."
msgstr ""
-#: templates/base.html:148
+#: templates/base.html:160
msgid "This can be long."
msgstr ""
-#: templates/base.html:150
+#: templates/base.html:162
msgid "Time to take a coffee?"
msgstr ""
-#: templates/base.html:152
+#: templates/base.html:164
msgid "Time to take another coffee?"
msgstr ""
@@ -2635,7 +2652,8 @@ msgid "Expand table"
msgstr ""
#: templates/blocks/DataTables.html:53 templates/blocks/JQueryJqGrid.html:26
-#: templates/ishtar/blocks/window_nav.html:59
+#: templates/ishtar/blocks/window_nav.html:62
+#: templates/ishtar/blocks/window_nav.html:68
#: templates/ishtar/blocks/window_tables/dynamic_documents.html:45
msgid "Export"
msgstr ""
@@ -2806,8 +2824,8 @@ msgstr ""
#: templates/ishtar/blocks/modify_toolbar.html:1
#: templates/ishtar/blocks/window_image.html:11
-#: templates/ishtar/blocks/window_nav.html:47
-#: templates/ishtar/forms/qa_base.html:57
+#: templates/ishtar/blocks/window_nav.html:49
+#: templates/ishtar/forms/qa_base.html:56
#: templates/ishtar/organization_form.html:37
#: templates/ishtar/organization_person_form.html:32
#: templates/ishtar/person_form.html:43
@@ -2832,13 +2850,17 @@ msgstr ""
msgid "Data"
msgstr ""
+#: templates/ishtar/blocks/sheet_json.html:9
+msgid "No data"
+msgstr ""
+
#: templates/ishtar/blocks/window_image_detail.html:64
msgid "Licenses"
msgstr ""
#: templates/ishtar/blocks/window_image_detail.html:111
#: templates/ishtar/import_delete.html:20 templatetags/window_field.py:17
-#: views_item.py:486 wizards.py:393
+#: views_item.py:548 wizards.py:405
msgid "Yes"
msgstr ""
@@ -2851,6 +2873,11 @@ msgstr ""
msgid "Web"
msgstr ""
+#: templates/ishtar/blocks/window_image_detail.html:193
+#: templates/ishtar/blocks/window_tables/documents.html:10
+msgid "Related to"
+msgstr ""
+
#: templates/ishtar/blocks/window_nav.html:17
msgid ""
"Are you sure to restore to this version? All changes made since this version "
@@ -2870,26 +2897,22 @@ msgstr ""
msgid "Item pined in your shortcut menu."
msgstr ""
-#: templates/ishtar/blocks/window_nav.html:43
+#: templates/ishtar/blocks/window_nav.html:45
msgid "Actions"
msgstr ""
-#: templates/ishtar/blocks/window_nav.html:61
+#: templates/ishtar/blocks/window_nav.html:73
msgid "Export as OpenOffice.org file"
msgstr ""
-#: templates/ishtar/blocks/window_nav.html:64
+#: templates/ishtar/blocks/window_nav.html:77
msgid "Export as PDF file"
msgstr ""
-#: templates/ishtar/blocks/window_nav.html:72
+#: templates/ishtar/blocks/window_nav.html:92
msgid "Relation between items are not historized."
msgstr ""
-#: templates/ishtar/blocks/window_tables/documents.html:10
-msgid "Related to"
-msgstr ""
-
#: templates/ishtar/blocks/window_tables/documents.html:11
#: templates/ishtar/blocks/window_tables/documents.html:19
msgid "Link"
@@ -2976,12 +2999,12 @@ msgstr ""
msgid "User type"
msgstr ""
-#: templates/ishtar/form.html:20 templates/ishtar/forms/document.html:24
+#: templates/ishtar/form.html:23 templates/ishtar/forms/document.html:24
#: templates/ishtar/wizard/default_wizard.html:43
msgid "Search and select an item in the table"
msgstr ""
-#: templates/ishtar/form.html:26 templates/ishtar/forms/document.html:30
+#: templates/ishtar/form.html:29 templates/ishtar/forms/document.html:30
#: templates/ishtar/forms/search_query.html:77 templates/ishtar/formset.html:8
#: templates/ishtar/formset_import_match.html:51
#: templates/ishtar/import_list.html:30 templates/ishtar/merge.html:30
@@ -2994,12 +3017,12 @@ msgstr ""
msgid "Are you sure you want to delete: "
msgstr ""
-#: templates/ishtar/forms/qa_base.html:25
+#: templates/ishtar/forms/qa_base.html:24
#: templates/ishtar/forms/qa_form.html:12
msgid "Modified items"
msgstr ""
-#: templates/ishtar/forms/qa_base.html:62
+#: templates/ishtar/forms/qa_base.html:61
#: templates/ishtar/import_step_by_step.html:126
#: templates/ishtar/import_step_by_step.html:305
#: templates/ishtar/organization_form.html:40
@@ -3081,7 +3104,7 @@ msgstr ""
msgid "Go"
msgstr ""
-#: templates/ishtar/import_step_by_step.html:63 views.py:1081
+#: templates/ishtar/import_step_by_step.html:63 views.py:1104
msgid "Import step by step"
msgstr ""
@@ -3342,12 +3365,12 @@ msgstr ""
msgid "Responsible for planning service of archaeological files"
msgstr ""
-#: templates/ishtar/wizard/confirm_wizard.html:12
+#: templates/ishtar/wizard/confirm_wizard.html:14
#: templates/ishtar/wizard/wizard_done_summary.html:6
msgid "You have entered the following informations:"
msgstr ""
-#: templates/ishtar/wizard/confirm_wizard.html:50
+#: templates/ishtar/wizard/confirm_wizard.html:56
msgid "Would you like to save them?"
msgstr ""
@@ -3646,15 +3669,15 @@ msgstr ""
msgid "Bookmarks"
msgstr ""
-#: templatetags/window_field.py:22 wizards.py:395
+#: templatetags/window_field.py:22 wizards.py:407
msgid "No"
msgstr ""
-#: templatetags/window_tables.py:88 widgets.py:1065
+#: templatetags/window_tables.py:88 widgets.py:1102
msgid "No results"
msgstr ""
-#: templatetags/window_tables.py:89 widgets.py:1066
+#: templatetags/window_tables.py:89 widgets.py:1103
msgid "Loading..."
msgstr ""
@@ -3662,15 +3685,15 @@ msgstr ""
msgid "You don't have sufficient permissions to do this action."
msgstr ""
-#: utils.py:338
+#: utils.py:344
msgid " (...)"
msgstr ""
-#: utils.py:418
+#: utils.py:424
msgid "Information"
msgstr ""
-#: utils.py:419
+#: utils.py:425
msgid "Load another random image?"
msgstr ""
@@ -3734,116 +3757,125 @@ msgstr ""
msgid "Treatment"
msgstr ""
-#: views.py:724 views_item.py:103
+#: views.py:747 views_item.py:117
msgid "Operation not permitted."
msgstr ""
-#: views.py:741 views.py:799
+#: views.py:764 views.py:822
msgid "Archaeological files"
msgstr ""
-#: views.py:746 views.py:810
+#: views.py:769 views.py:833
msgid "Finds"
msgstr ""
-#: views.py:748 views.py:815
+#: views.py:771 views.py:838
msgid "Treatment requests"
msgstr ""
-#: views.py:749 views.py:821
+#: views.py:772 views.py:844
msgid "Treatments"
msgstr ""
-#: views.py:1423
+#: views.py:1446
msgid "Col. "
msgstr ""
-#: views.py:1429 views.py:1441
+#: views.py:1452 views.py:1464
msgid "* empty *"
msgstr ""
-#: views.py:1482
+#: views.py:1505
msgid "Link unmatched items"
msgstr ""
-#: views.py:1503
+#: views.py:1526
msgid "Delete import"
msgstr ""
-#: views.py:1542
+#: views.py:1565
msgid "Merge persons"
msgstr ""
-#: views.py:1566
+#: views.py:1589
msgid "Select the main person"
msgstr ""
-#: views.py:1575
+#: views.py:1598
msgid "Merge organization"
msgstr ""
-#: views.py:1585
+#: views.py:1608
msgid "Select the main organization"
msgstr ""
-#: views.py:1625 views.py:1641
+#: views.py:1648 views.py:1664
msgid "Corporation manager"
msgstr ""
-#: views.py:1662
+#: views.py:1685
msgid "Document: search"
msgstr ""
-#: views.py:1677
+#: views.py:1700
msgid "Document creation"
msgstr ""
-#: views.py:1710
+#: views.py:1733
msgid "Document modification"
msgstr ""
-#: views.py:1740
+#: views.py:1763
msgid "Document deletion"
msgstr ""
-#: views.py:1823
+#: views.py:1872
msgid "Delete bookmark"
msgstr ""
-#: views.py:1846
+#: views.py:1895
msgid "Bookmark - Delete"
msgstr ""
-#: views_item.py:105
+#: views_item.py:119
#, python-format
msgid "New %s"
msgstr ""
+#: views_item.py:570
+msgctxt "key for text search"
+msgid "today"
+msgstr ""
+
#: widgets.py:174
msgid "The character \" is not accepted."
msgstr ""
-#: widgets.py:517
+#: widgets.py:555
msgid "{} is not a valid key for {}"
msgstr ""
-#: widgets.py:618 widgets.py:752 widgets.py:867
+#: widgets.py:656 widgets.py:790 widgets.py:905
msgid "Search..."
msgstr ""
-#: widgets.py:687
+#: widgets.py:725
msgid "Previous value:"
msgstr ""
-#: widgets.py:1067
+#: widgets.py:1104
msgid "Remove"
msgstr ""
-#: wizards.py:431
+#: wizards.py:171
+msgid "Permission error: you cannot do this action."
+msgstr ""
+
+#: wizards.py:443
msgid "Deleted"
msgstr ""
-#: wizards.py:1757
+#: wizards.py:1769
#, python-format
msgid "[%(app_name)s] Account creation/modification"
msgstr ""
diff --git a/ishtar_common/management/commands/ishtar_import.py b/ishtar_common/management/commands/ishtar_import.py
index aba1e45d5..3b04528f0 100644
--- a/ishtar_common/management/commands/ishtar_import.py
+++ b/ishtar_common/management/commands/ishtar_import.py
@@ -3,22 +3,41 @@
from django.core.management.base import BaseCommand, CommandError
-from ishtar_common import models
+from ishtar_common import models, models_imports
class Command(BaseCommand):
help = "./manage.py ishtar_import <command> <import_id>\n\n"\
"Launch the importation a configured import.\n"\
- "<command> must be: \"analyse\", \"import\" or \"archive\"."
+ "<command> must be: \"list\", \"analyse\", \"import\" or " \
+ "\"archive\"."
+
+ def add_arguments(self, parser):
+ parser.add_argument('command', choices=["list", "analyse", "import",
+ "archive"])
+ parser.add_argument('import_id', nargs='?', default=None)
def handle(self, *args, **options):
- if not args or len(args) < 2:
- raise CommandError("<command> and <import_id> are mandatory")
- command = args[0]
- if args[0] not in ["analyse", "import", "archive"]:
- raise CommandError(
- "<command> must be: \"analyse\", \"import\" or \"archive\"."
- )
+ command = options['command']
+ import_id = options['import_id']
+ if command != "list" and not import_id:
+ raise CommandError("With {} <import_id> is mandatory".format(
+ command))
+ if command == 'list':
+ state = dict(models_imports.IMPORT_STATE)
+ self.stdout.write("*" * 80 + "\n")
+ self.stdout.write(
+ "| pk | type | state "
+ "| name\n")
+ self.stdout.write("*" * 80 + "\n")
+ for imp in models.Import.objects.exclude(state="AC").all():
+ self.stdout.write(u"|{: ^6}| {: ^32} | {: ^12} | {}\n".format(
+ imp.pk, unicode(imp.importer_type)[:32],
+ state[imp.state][:12],
+ imp.name[:128]))
+ self.stdout.write("*" * 80 + "\n")
+ self.stdout.flush()
+ return
try:
imp = models.Import.objects.get(pk=args[1])
except (ValueError, models.Import.DoesNotExist):
diff --git a/ishtar_common/management/commands/reassociate_similar_images.py b/ishtar_common/management/commands/reassociate_similar_images.py
index f6d432327..a0483ed3a 100644
--- a/ishtar_common/management/commands/reassociate_similar_images.py
+++ b/ishtar_common/management/commands/reassociate_similar_images.py
@@ -169,7 +169,7 @@ class Command(BaseCommand):
for m2m in m2ms:
for m2 in getattr(item, m2m).all():
- if m2 not in getattr(ref_item, m2m):
+ if m2 not in getattr(ref_item, m2m).all():
getattr(ref_item, m2m).add(m2)
for rel_attr in Document.RELATED_MODELS:
diff --git a/ishtar_common/management/commands/regenerate_search_vector_cached_label.py b/ishtar_common/management/commands/regenerate_search_vector_cached_label.py
index 59e37d75b..404811acf 100644
--- a/ishtar_common/management/commands/regenerate_search_vector_cached_label.py
+++ b/ishtar_common/management/commands/regenerate_search_vector_cached_label.py
@@ -24,16 +24,32 @@ from django.core.management.base import BaseCommand
from django.apps import apps
+APPS = ['ishtar_common', 'archaeological_operations',
+ 'archaeological_context_records', 'archaeological_finds',
+ 'archaeological_warehouse']
+
+
class Command(BaseCommand):
args = ''
help = 'Regenerate cached labels and search vectors'
+ def add_arguments(self, parser):
+ parser.add_argument('app_name', nargs='?', default=None,
+ choices=APPS)
+ parser.add_argument('model_name', nargs='?', default=None)
+
def handle(self, *args, **options):
- for app in ['ishtar_common', 'archaeological_operations',
- 'archaeological_context_records',
- 'archaeological_finds', 'archaeological_warehouse']:
+ limit = options['app_name']
+ model_name = options['model_name']
+ if model_name:
+ model_name = model_name.lower()
+ for app in APPS:
+ if limit and app != limit:
+ continue
print(u"* app: {}".format(app))
for model in apps.get_app_config(app).get_models():
+ if model_name and model.__name__.lower() != model_name:
+ continue
if model.__name__.startswith('Historical'):
continue
if not bool(
diff --git a/ishtar_common/migrations/0076_migrate_treatmentfile_permissions.py b/ishtar_common/migrations/0076_migrate_treatmentfile_permissions.py
new file mode 100644
index 000000000..4edef4a44
--- /dev/null
+++ b/ishtar_common/migrations/0076_migrate_treatmentfile_permissions.py
@@ -0,0 +1,33 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.10 on 2018-11-22 22:17
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+def migrate_perm(apps, schema_editor):
+ Permission = apps.get_model('auth', 'Permission')
+ Group = apps.get_model('auth', 'Group')
+ for perm in Permission.objects.filter(
+ codename__icontains='filetreatment').exclude(
+ codename__icontains='source').all():
+ new_codename = perm.codename.replace('filetreatment', 'treatmentfile')
+ q = Permission.objects.filter(
+ codename=new_codename).exclude(pk=perm.pk)
+ if q.count():
+ for gp in Group.objects.filter(permissions=q.all()[0]):
+ gp.permissions.add(perm)
+ q.all()[0].delete()
+ perm.codename = new_codename
+ perm.save()
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('ishtar_common', '0075_auto_20181108_1908'),
+ ]
+
+ operations = [
+ migrations.RunPython(migrate_perm)
+ ]
diff --git a/ishtar_common/migrations/0077_auto_20181129_1755.py b/ishtar_common/migrations/0077_auto_20181129_1755.py
new file mode 100644
index 000000000..bd9003946
--- /dev/null
+++ b/ishtar_common/migrations/0077_auto_20181129_1755.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.10 on 2018-11-29 17:55
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('ishtar_common', '0076_migrate_treatmentfile_permissions'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='importertype',
+ name='is_template',
+ field=models.BooleanField(default=False, verbose_name='Can be exported'),
+ ),
+ ]
diff --git a/ishtar_common/migrations/0078_auto_20181203_1442.py b/ishtar_common/migrations/0078_auto_20181203_1442.py
new file mode 100644
index 000000000..282356a55
--- /dev/null
+++ b/ishtar_common/migrations/0078_auto_20181203_1442.py
@@ -0,0 +1,1832 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.10 on 2018-12-03 14:42
+from __future__ import unicode_literals
+
+from django.conf import settings
+import django.contrib.gis.db.models.fields
+import django.contrib.postgres.search
+import django.core.validators
+from django.db import migrations, models
+import django.db.models.deletion
+import re
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('ishtar_common', '0077_auto_20181129_1755'),
+ ]
+
+ operations = [
+ migrations.AlterModelOptions(
+ name='administrationscript',
+ options={'ordering': ['name'], 'verbose_name': "Script d'administration", 'verbose_name_plural': "Scripts d'administration"},
+ ),
+ migrations.AlterModelOptions(
+ name='administrationtask',
+ options={'ordering': ['script'], 'verbose_name': "T\xe2che d'administration", 'verbose_name_plural': "T\xe2ches d'administration"},
+ ),
+ migrations.AlterModelOptions(
+ name='area',
+ options={'ordering': ('label',), 'verbose_name': 'Zone', 'verbose_name_plural': 'Zones'},
+ ),
+ migrations.AlterModelOptions(
+ name='author',
+ options={'ordering': ('author_type__order', 'person__name'), 'permissions': (('view_author', 'Can view all Authors'), ('view_own_author', 'Can view own Author'), ('add_own_author', 'Can add own Author'), ('change_own_author', 'Can change own Author'), ('delete_own_author', 'Can delete own Author')), 'verbose_name': 'Auteur', 'verbose_name_plural': 'Auteurs'},
+ ),
+ migrations.AlterModelOptions(
+ name='authortype',
+ options={'ordering': ['order', 'label'], 'verbose_name': "Type d'auteur", 'verbose_name_plural': "Types d'auteur"},
+ ),
+ migrations.AlterModelOptions(
+ name='customform',
+ options={'ordering': ['name', 'form'], 'verbose_name': 'Formulaire personnalis\xe9', 'verbose_name_plural': 'Formulaires personnalis\xe9s'},
+ ),
+ migrations.AlterModelOptions(
+ name='customformjsonfield',
+ options={'verbose_name': 'Formulaire personnalis\xe9 - Champ de donn\xe9e Json', 'verbose_name_plural': 'Formulaire personnalis\xe9 - Champs de donn\xe9e Json'},
+ ),
+ migrations.AlterModelOptions(
+ name='department',
+ options={'ordering': ['number'], 'verbose_name': 'D\xe9partement', 'verbose_name_plural': 'D\xe9partements'},
+ ),
+ migrations.AlterModelOptions(
+ name='documenttemplate',
+ options={'ordering': ['associated_object_name', 'name'], 'verbose_name': 'Patron de document', 'verbose_name_plural': 'Patrons de document'},
+ ),
+ migrations.AlterModelOptions(
+ name='excludedfield',
+ options={'verbose_name': 'Champ exclus', 'verbose_name_plural': 'Champs exclus'},
+ ),
+ migrations.AlterModelOptions(
+ name='format',
+ options={'ordering': ['label'], 'verbose_name': 'Type de format', 'verbose_name_plural': 'Types de format'},
+ ),
+ migrations.AlterModelOptions(
+ name='formatertype',
+ options={'ordering': ('formater_type', 'options'), 'verbose_name': 'Importeur - Type de mise en forme', 'verbose_name_plural': 'Importeur - Types de mise en forme'},
+ ),
+ migrations.AlterModelOptions(
+ name='globalvar',
+ options={'ordering': ['slug'], 'verbose_name': 'Variable globale', 'verbose_name_plural': 'Variables globales'},
+ ),
+ migrations.AlterModelOptions(
+ name='historicalorganization',
+ options={'get_latest_by': 'history_date', 'ordering': ('-history_date', '-history_id'), 'verbose_name': 'historical Organisation'},
+ ),
+ migrations.AlterModelOptions(
+ name='historicalperson',
+ options={'get_latest_by': 'history_date', 'ordering': ('-history_date', '-history_id'), 'verbose_name': 'historical Personne'},
+ ),
+ migrations.AlterModelOptions(
+ name='importercolumn',
+ options={'ordering': ('importer_type', 'col_number'), 'verbose_name': 'Importeur - Colonne', 'verbose_name_plural': 'Importeur - Colonnes'},
+ ),
+ migrations.AlterModelOptions(
+ name='importerdefault',
+ options={'verbose_name': 'Importeur - Par d\xe9faut', 'verbose_name_plural': 'Importeur - Par d\xe9faut'},
+ ),
+ migrations.AlterModelOptions(
+ name='importerdefaultvalues',
+ options={'verbose_name': 'Importeur - Valeur par d\xe9faut', 'verbose_name_plural': 'Importeur - Valeurs par d\xe9faut'},
+ ),
+ migrations.AlterModelOptions(
+ name='importerduplicatefield',
+ options={'ordering': ('column', 'field_name'), 'verbose_name': 'Importeur - Champ dupliqu\xe9', 'verbose_name_plural': 'Importeur - Champs dupliqu\xe9s'},
+ ),
+ migrations.AlterModelOptions(
+ name='importermodel',
+ options={'ordering': ('name',), 'verbose_name': 'Importeur - Mod\xe8le', 'verbose_name_plural': 'Importeur - Mod\xe8les'},
+ ),
+ migrations.AlterModelOptions(
+ name='importertype',
+ options={'ordering': ('name',), 'verbose_name': 'Importeur - Type', 'verbose_name_plural': 'Importeur - Types'},
+ ),
+ migrations.AlterModelOptions(
+ name='importtarget',
+ options={'verbose_name': 'Importeur - Cible', 'verbose_name_plural': 'Importeur - Cibles'},
+ ),
+ migrations.AlterModelOptions(
+ name='ishtarsiteprofile',
+ options={'ordering': ['label'], 'verbose_name': "Profil d'instance Ishtar", 'verbose_name_plural': "Profils d'instance Ishtar"},
+ ),
+ migrations.AlterModelOptions(
+ name='ishtaruser',
+ options={'verbose_name': "Utilisateur d'Ishtar", 'verbose_name_plural': "Utilisateurs d'Ishtar"},
+ ),
+ migrations.AlterModelOptions(
+ name='jsondatafield',
+ options={'ordering': ['order', 'name'], 'verbose_name': 'Donn\xe9e JSON - Champ', 'verbose_name_plural': 'Donn\xe9e JSON - Champs'},
+ ),
+ migrations.AlterModelOptions(
+ name='jsondatasection',
+ options={'ordering': ['order', 'name'], 'verbose_name': 'Donn\xe9es JSON - Menu', 'verbose_name_plural': 'Donn\xe9es JSON - Menus'},
+ ),
+ migrations.AlterModelOptions(
+ name='licensetype',
+ options={'ordering': ('label',), 'verbose_name': 'Type de licence', 'verbose_name_plural': 'Types de licence'},
+ ),
+ migrations.AlterModelOptions(
+ name='operationtype',
+ options={'ordering': ['judiciary', '-preventive', 'order', 'label'], 'verbose_name': "Type d'op\xe9ration", 'verbose_name_plural': "Types d'op\xe9ration"},
+ ),
+ migrations.AlterModelOptions(
+ name='organization',
+ options={'permissions': (('view_organization', 'Can view all Organizations'), ('view_own_organization', 'Can view own Organization'), ('add_own_organization', 'Can add own Organization'), ('change_own_organization', 'Can change own Organization'), ('delete_own_organization', 'Can delete own Organization')), 'verbose_name': 'Organisation', 'verbose_name_plural': 'Organisations'},
+ ),
+ migrations.AlterModelOptions(
+ name='organizationtype',
+ options={'ordering': ('label',), 'verbose_name': "Type d'organisation", 'verbose_name_plural': "Types d'organisation"},
+ ),
+ migrations.AlterModelOptions(
+ name='person',
+ options={'permissions': (('view_person', 'Can view all Persons'), ('view_own_person', 'Can view own Person'), ('add_own_person', 'Can add own Person'), ('change_own_person', 'Can change own Person'), ('delete_own_person', 'Can delete own Person')), 'verbose_name': 'Personne', 'verbose_name_plural': 'Personnes'},
+ ),
+ migrations.AlterModelOptions(
+ name='persontype',
+ options={'ordering': ('label',), 'verbose_name': 'Type de personne', 'verbose_name_plural': 'Types de personne'},
+ ),
+ migrations.AlterModelOptions(
+ name='profiletype',
+ options={'ordering': ('label',), 'verbose_name': 'Type de profil', 'verbose_name_plural': 'Types de profil'},
+ ),
+ migrations.AlterModelOptions(
+ name='regexp',
+ options={'verbose_name': 'Importeur - Expression r\xe9guli\xe8re', 'verbose_name_plural': 'Importeur - Expressions r\xe9guli\xe8res'},
+ ),
+ migrations.AlterModelOptions(
+ name='searchquery',
+ options={'ordering': ['label'], 'verbose_name': 'Requ\xeate de recherche', 'verbose_name_plural': 'Requ\xeates de recherche'},
+ ),
+ migrations.AlterModelOptions(
+ name='sourcetype',
+ options={'ordering': ['label'], 'verbose_name': 'Type de document', 'verbose_name_plural': 'Types de document'},
+ ),
+ migrations.AlterModelOptions(
+ name='spatialreferencesystem',
+ options={'ordering': ('label',), 'verbose_name': 'Syst\xe8me de r\xe9f\xe9rence spatiale', 'verbose_name_plural': 'Syst\xe8mes de r\xe9f\xe9rence spatiale'},
+ ),
+ migrations.AlterModelOptions(
+ name='state',
+ options={'ordering': ['number'], 'verbose_name': '\xc9tat'},
+ ),
+ migrations.AlterModelOptions(
+ name='supporttype',
+ options={'verbose_name': 'Type de support', 'verbose_name_plural': 'Types de support'},
+ ),
+ migrations.AlterModelOptions(
+ name='targetkey',
+ options={'ordering': ('target', 'key'), 'verbose_name': 'Importeur - Cl\xe9 de rapprochement', 'verbose_name_plural': 'Importeur - Cl\xe9s de rapprochement'},
+ ),
+ migrations.AlterModelOptions(
+ name='targetkeygroup',
+ options={'verbose_name': 'Importeur - Groupe de cl\xe9 de rapprochement', 'verbose_name_plural': 'Importeur - Groupes de cl\xe9 de rapprochement'},
+ ),
+ migrations.AlterModelOptions(
+ name='titletype',
+ options={'ordering': ('label',), 'verbose_name': 'Type de titre', 'verbose_name_plural': 'Types de titre'},
+ ),
+ migrations.AlterModelOptions(
+ name='town',
+ options={'ordering': ['numero_insee'], 'verbose_name': 'Commune', 'verbose_name_plural': 'Communes'},
+ ),
+ migrations.AlterModelOptions(
+ name='userprofile',
+ options={'verbose_name': "Profil d'utilisateur", 'verbose_name_plural': "Profils d'utilisateurs"},
+ ),
+ migrations.AlterField(
+ model_name='administrationscript',
+ name='name',
+ field=models.TextField(blank=True, null=True, verbose_name='Nom'),
+ ),
+ migrations.AlterField(
+ model_name='administrationscript',
+ name='path',
+ field=models.CharField(max_length=30, verbose_name='Nom de fichier'),
+ ),
+ migrations.AlterField(
+ model_name='administrationtask',
+ name='result',
+ field=models.TextField(blank=True, null=True, verbose_name='R\xe9sultat'),
+ ),
+ migrations.AlterField(
+ model_name='administrationtask',
+ name='state',
+ field=models.CharField(choices=[(b'S', 'Planifi\xe9'), (b'P', 'En cours'), (b'FE', 'Termin\xe9 avec des erreurs'), (b'F', 'Termin\xe9')], default=b'S', max_length=2, verbose_name='\xc9tat'),
+ ),
+ migrations.AlterField(
+ model_name='area',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='area',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='area',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='area',
+ name='parent',
+ field=models.ForeignKey(blank=True, help_text='Seulement quatre niveaux de parents sont g\xe9r\xe9s.', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='children', to='ishtar_common.Area', verbose_name='Parent'),
+ ),
+ migrations.AlterField(
+ model_name='area',
+ name='reference',
+ field=models.CharField(blank=True, max_length=200, null=True, verbose_name='R\xe9f\xe9rence'),
+ ),
+ migrations.AlterField(
+ model_name='area',
+ name='towns',
+ field=models.ManyToManyField(blank=True, related_name='areas', to='ishtar_common.Town', verbose_name='Communes'),
+ ),
+ migrations.AlterField(
+ model_name='area',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ migrations.AlterField(
+ model_name='author',
+ name='author_type',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='ishtar_common.AuthorType', verbose_name="Type d'auteur"),
+ ),
+ migrations.AlterField(
+ model_name='author',
+ name='cached_label',
+ field=models.TextField(blank=True, db_index=True, null=True, verbose_name='Nom en cache'),
+ ),
+ migrations.AlterField(
+ model_name='author',
+ name='person',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='author', to='ishtar_common.Person', verbose_name='Personne'),
+ ),
+ migrations.AlterField(
+ model_name='author',
+ name='search_vector',
+ field=django.contrib.postgres.search.SearchVectorField(blank=True, help_text='Auto-rempli \xe0 la sauvegarde', null=True, verbose_name='Vecteur de recherche'),
+ ),
+ migrations.AlterField(
+ model_name='authortype',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='authortype',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='authortype',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='authortype',
+ name='order',
+ field=models.IntegerField(default=1, verbose_name='Ordre'),
+ ),
+ migrations.AlterField(
+ model_name='authortype',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ migrations.AlterField(
+ model_name='customform',
+ name='apply_to_all',
+ field=models.BooleanField(default=False, help_text="Activer ce formulaire pour tous les utilisateurs. Si mis \xe0 Vrai, s\xe9lectionner des utilisateurs ou des types d'utilisateurs est inutile.", verbose_name="S'applique \xe0 tous"),
+ ),
+ migrations.AlterField(
+ model_name='customform',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='customform',
+ name='enabled',
+ field=models.BooleanField(default=True, help_text='D\xe9sactiver avec pr\xe9caution : d\xe9sactiver un formulaire avec des champs obligatoires peut entra\xeener des erreurs dans la base de donn\xe9es.', verbose_name='Activer ce formulaire'),
+ ),
+ migrations.AlterField(
+ model_name='customform',
+ name='form',
+ field=models.CharField(max_length=250, verbose_name='Formulaire'),
+ ),
+ migrations.AlterField(
+ model_name='customform',
+ name='name',
+ field=models.CharField(max_length=250, verbose_name='Nom'),
+ ),
+ migrations.AlterField(
+ model_name='customformjsonfield',
+ name='help_text',
+ field=models.TextField(blank=True, null=True, verbose_name='Aide'),
+ ),
+ migrations.AlterField(
+ model_name='customformjsonfield',
+ name='label',
+ field=models.CharField(blank=True, default=b'', max_length=200, verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='customformjsonfield',
+ name='order',
+ field=models.IntegerField(default=1, verbose_name='Ordre'),
+ ),
+ migrations.AlterField(
+ model_name='department',
+ name='label',
+ field=models.CharField(max_length=30, verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='department',
+ name='number',
+ field=models.CharField(max_length=3, unique=True, verbose_name='Nombre'),
+ ),
+ migrations.AlterField(
+ model_name='department',
+ name='state',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='ishtar_common.State', verbose_name='\xc9tat'),
+ ),
+ migrations.AlterField(
+ model_name='document',
+ name='additional_information',
+ field=models.TextField(blank=True, null=True, verbose_name='Information suppl\xe9mentaire'),
+ ),
+ migrations.AlterField(
+ model_name='document',
+ name='associated_links',
+ field=models.TextField(blank=True, null=True, verbose_name='Liens symboliques'),
+ ),
+ migrations.AlterField(
+ model_name='document',
+ name='associated_url',
+ field=models.URLField(blank=True, max_length=1000, null=True, verbose_name='Ressource num\xe9rique (adresse web)'),
+ ),
+ migrations.AlterField(
+ model_name='document',
+ name='authors',
+ field=models.ManyToManyField(related_name='documents', to='ishtar_common.Author', verbose_name='Auteurs'),
+ ),
+ migrations.AlterField(
+ model_name='document',
+ name='authors_raw',
+ field=models.CharField(blank=True, max_length=250, null=True, verbose_name='Auteurs (brut)'),
+ ),
+ migrations.AlterField(
+ model_name='document',
+ name='cache_related_label',
+ field=models.TextField(blank=True, db_index=True, help_text='Valeur en cache - ne pas \xe9diter', null=True, verbose_name='Li\xe9'),
+ ),
+ migrations.AlterField(
+ model_name='document',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='document',
+ name='creation_date',
+ field=models.DateField(blank=True, null=True, verbose_name='Date de cr\xe9ation'),
+ ),
+ migrations.AlterField(
+ model_name='document',
+ name='duplicate',
+ field=models.NullBooleanField(verbose_name='Existe en doublon'),
+ ),
+ migrations.AlterField(
+ model_name='document',
+ name='external_id',
+ field=models.TextField(blank=True, null=True, verbose_name='Identifiant'),
+ ),
+ migrations.AlterField(
+ model_name='document',
+ name='internal_reference',
+ field=models.TextField(blank=True, null=True, verbose_name='R\xe9f. interne'),
+ ),
+ migrations.AlterField(
+ model_name='document',
+ name='item_number',
+ field=models.IntegerField(default=1, verbose_name="Nombre d'\xe9l\xe9ments"),
+ ),
+ migrations.AlterField(
+ model_name='document',
+ name='licenses',
+ field=models.ManyToManyField(blank=True, to='ishtar_common.LicenseType', verbose_name='Licence'),
+ ),
+ migrations.AlterField(
+ model_name='document',
+ name='receipt_date',
+ field=models.DateField(blank=True, null=True, verbose_name='Date de r\xe9ception'),
+ ),
+ migrations.AlterField(
+ model_name='document',
+ name='receipt_date_in_documentation',
+ field=models.DateField(blank=True, null=True, verbose_name='Date de r\xe9ception en documentation'),
+ ),
+ migrations.AlterField(
+ model_name='document',
+ name='reference',
+ field=models.TextField(blank=True, null=True, verbose_name='R\xe9f.'),
+ ),
+ migrations.AlterField(
+ model_name='document',
+ name='scale',
+ field=models.CharField(blank=True, max_length=30, null=True, verbose_name='\xc9chelle'),
+ ),
+ migrations.AlterField(
+ model_name='document',
+ name='search_vector',
+ field=django.contrib.postgres.search.SearchVectorField(blank=True, help_text='Auto-rempli \xe0 la sauvegarde', null=True, verbose_name='Vecteur de recherche'),
+ ),
+ migrations.AlterField(
+ model_name='document',
+ name='title',
+ field=models.TextField(blank=True, default=b'', verbose_name='Titre'),
+ ),
+ migrations.AlterField(
+ model_name='documenttemplate',
+ name='associated_object_name',
+ field=models.CharField(choices=[(b'archaeological_operations.models.AdministrativeAct', 'Acte administratif')], max_length=100, verbose_name='Objet associ\xe9'),
+ ),
+ migrations.AlterField(
+ model_name='documenttemplate',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='documenttemplate',
+ name='name',
+ field=models.CharField(max_length=100, verbose_name='Nom'),
+ ),
+ migrations.AlterField(
+ model_name='documenttemplate',
+ name='slug',
+ field=models.SlugField(blank=True, max_length=100, null=True, unique=True, verbose_name='Identifiant texte'),
+ ),
+ migrations.AlterField(
+ model_name='documenttemplate',
+ name='template',
+ field=models.FileField(upload_to=b'templates/%Y/', verbose_name='Patron'),
+ ),
+ migrations.AlterField(
+ model_name='excludedfield',
+ name='field',
+ field=models.CharField(max_length=250, verbose_name='Champ'),
+ ),
+ migrations.AlterField(
+ model_name='format',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='format',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='format',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='format',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ migrations.AlterField(
+ model_name='formatertype',
+ name='formater_type',
+ field=models.CharField(choices=[(b'IntegerFormater', 'Entier'), (b'FloatFormater', 'Nombre \xe0 virgule'), (b'UnicodeFormater', 'Cha\xeene de caract\xe8res'), (b'DateFormater', 'Date'), (b'TypeFormater', 'Type'), (b'YearFormater', 'Ann\xe9e'), (b'InseeFormater', 'Code INSEE'), (b'StrToBoolean', 'Cha\xeene de caract\xe8res vers bool\xe9en'), (b'FileFormater', 'Fichier'), (b'UnknowType', 'Type inconnu')], max_length=20, verbose_name='Formater type'),
+ ),
+ migrations.AlterField(
+ model_name='formatertype',
+ name='many_split',
+ field=models.CharField(blank=True, max_length=10, null=True, verbose_name='Caract\xe8re(s) de s\xe9paration'),
+ ),
+ migrations.AlterField(
+ model_name='globalvar',
+ name='description',
+ field=models.TextField(blank=True, null=True, verbose_name='Description de la variable'),
+ ),
+ migrations.AlterField(
+ model_name='globalvar',
+ name='slug',
+ field=models.SlugField(unique=True, verbose_name='Nom de la variable'),
+ ),
+ migrations.AlterField(
+ model_name='globalvar',
+ name='value',
+ field=models.TextField(blank=True, null=True, verbose_name='Valeur'),
+ ),
+ migrations.AlterField(
+ model_name='historicalorganization',
+ name='address',
+ field=models.TextField(blank=True, null=True, verbose_name='Adresse'),
+ ),
+ migrations.AlterField(
+ model_name='historicalorganization',
+ name='address_complement',
+ field=models.TextField(blank=True, null=True, verbose_name="Compl\xe9ment d'adresse"),
+ ),
+ migrations.AlterField(
+ model_name='historicalorganization',
+ name='alt_address',
+ field=models.TextField(blank=True, null=True, verbose_name='Autre adresse : adresse'),
+ ),
+ migrations.AlterField(
+ model_name='historicalorganization',
+ name='alt_address_complement',
+ field=models.TextField(blank=True, null=True, verbose_name="Autre adresse : compl\xe9ment d'adresse"),
+ ),
+ migrations.AlterField(
+ model_name='historicalorganization',
+ name='alt_address_is_prefered',
+ field=models.BooleanField(default=False, verbose_name="L'adresse alternative est pr\xe9f\xe9r\xe9e"),
+ ),
+ migrations.AlterField(
+ model_name='historicalorganization',
+ name='alt_country',
+ field=models.CharField(blank=True, max_length=30, null=True, verbose_name='Autre adresse : pays'),
+ ),
+ migrations.AlterField(
+ model_name='historicalorganization',
+ name='alt_postal_code',
+ field=models.CharField(blank=True, max_length=10, null=True, verbose_name='Autre adresse : code postal'),
+ ),
+ migrations.AlterField(
+ model_name='historicalorganization',
+ name='alt_town',
+ field=models.CharField(blank=True, max_length=70, null=True, verbose_name='Autre adresse : ville'),
+ ),
+ migrations.AlterField(
+ model_name='historicalorganization',
+ name='cached_label',
+ field=models.TextField(blank=True, db_index=True, null=True, verbose_name='Nom en cache'),
+ ),
+ migrations.AlterField(
+ model_name='historicalorganization',
+ name='country',
+ field=models.CharField(blank=True, max_length=30, null=True, verbose_name='Pays'),
+ ),
+ migrations.AlterField(
+ model_name='historicalorganization',
+ name='email',
+ field=models.EmailField(blank=True, max_length=300, null=True, verbose_name='Courriel'),
+ ),
+ migrations.AlterField(
+ model_name='historicalorganization',
+ name='merge_key',
+ field=models.TextField(blank=True, null=True, verbose_name='Cl\xe9 de fusion'),
+ ),
+ migrations.AlterField(
+ model_name='historicalorganization',
+ name='mobile_phone',
+ field=models.CharField(blank=True, max_length=18, null=True, verbose_name='T\xe9l\xe9phone portable'),
+ ),
+ migrations.AlterField(
+ model_name='historicalorganization',
+ name='name',
+ field=models.CharField(max_length=500, verbose_name='Nom'),
+ ),
+ migrations.AlterField(
+ model_name='historicalorganization',
+ name='phone',
+ field=models.CharField(blank=True, max_length=18, null=True, verbose_name='T\xe9l\xe9phone'),
+ ),
+ migrations.AlterField(
+ model_name='historicalorganization',
+ name='phone2',
+ field=models.CharField(blank=True, max_length=18, null=True, verbose_name='Type de t\xe9l\xe9phone 2'),
+ ),
+ migrations.AlterField(
+ model_name='historicalorganization',
+ name='phone3',
+ field=models.CharField(blank=True, max_length=18, null=True, verbose_name='T\xe9l\xe9phone 3'),
+ ),
+ migrations.AlterField(
+ model_name='historicalorganization',
+ name='phone_desc',
+ field=models.CharField(blank=True, max_length=300, null=True, verbose_name='Type de t\xe9l\xe9phone'),
+ ),
+ migrations.AlterField(
+ model_name='historicalorganization',
+ name='phone_desc2',
+ field=models.CharField(blank=True, max_length=300, null=True, verbose_name='Type de t\xe9l\xe9phone 2'),
+ ),
+ migrations.AlterField(
+ model_name='historicalorganization',
+ name='phone_desc3',
+ field=models.CharField(blank=True, max_length=300, null=True, verbose_name='Type de t\xe9l\xe9phone 3'),
+ ),
+ migrations.AlterField(
+ model_name='historicalorganization',
+ name='postal_code',
+ field=models.CharField(blank=True, max_length=10, null=True, verbose_name='Code postal'),
+ ),
+ migrations.AlterField(
+ model_name='historicalorganization',
+ name='raw_phone',
+ field=models.TextField(blank=True, null=True, verbose_name='T\xe9l\xe9phone brut'),
+ ),
+ migrations.AlterField(
+ model_name='historicalorganization',
+ name='search_vector',
+ field=django.contrib.postgres.search.SearchVectorField(blank=True, help_text='Auto-rempli \xe0 la sauvegarde', null=True, verbose_name='Vecteur de recherche'),
+ ),
+ migrations.AlterField(
+ model_name='historicalorganization',
+ name='town',
+ field=models.CharField(blank=True, max_length=70, null=True, verbose_name='Commune'),
+ ),
+ migrations.AlterField(
+ model_name='historicalperson',
+ name='address',
+ field=models.TextField(blank=True, null=True, verbose_name='Adresse'),
+ ),
+ migrations.AlterField(
+ model_name='historicalperson',
+ name='address_complement',
+ field=models.TextField(blank=True, null=True, verbose_name="Compl\xe9ment d'adresse"),
+ ),
+ migrations.AlterField(
+ model_name='historicalperson',
+ name='alt_address',
+ field=models.TextField(blank=True, null=True, verbose_name='Autre adresse : adresse'),
+ ),
+ migrations.AlterField(
+ model_name='historicalperson',
+ name='alt_address_complement',
+ field=models.TextField(blank=True, null=True, verbose_name="Autre adresse : compl\xe9ment d'adresse"),
+ ),
+ migrations.AlterField(
+ model_name='historicalperson',
+ name='alt_address_is_prefered',
+ field=models.BooleanField(default=False, verbose_name="L'adresse alternative est pr\xe9f\xe9r\xe9e"),
+ ),
+ migrations.AlterField(
+ model_name='historicalperson',
+ name='alt_country',
+ field=models.CharField(blank=True, max_length=30, null=True, verbose_name='Autre adresse : pays'),
+ ),
+ migrations.AlterField(
+ model_name='historicalperson',
+ name='alt_postal_code',
+ field=models.CharField(blank=True, max_length=10, null=True, verbose_name='Autre adresse : code postal'),
+ ),
+ migrations.AlterField(
+ model_name='historicalperson',
+ name='alt_town',
+ field=models.CharField(blank=True, max_length=70, null=True, verbose_name='Autre adresse : ville'),
+ ),
+ migrations.AlterField(
+ model_name='historicalperson',
+ name='cached_label',
+ field=models.TextField(blank=True, db_index=True, null=True, verbose_name='Nom en cache'),
+ ),
+ migrations.AlterField(
+ model_name='historicalperson',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='historicalperson',
+ name='contact_type',
+ field=models.CharField(blank=True, max_length=300, null=True, verbose_name='Type de contact'),
+ ),
+ migrations.AlterField(
+ model_name='historicalperson',
+ name='country',
+ field=models.CharField(blank=True, max_length=30, null=True, verbose_name='Pays'),
+ ),
+ migrations.AlterField(
+ model_name='historicalperson',
+ name='email',
+ field=models.EmailField(blank=True, max_length=300, null=True, verbose_name='Courriel'),
+ ),
+ migrations.AlterField(
+ model_name='historicalperson',
+ name='merge_key',
+ field=models.TextField(blank=True, null=True, verbose_name='Cl\xe9 de fusion'),
+ ),
+ migrations.AlterField(
+ model_name='historicalperson',
+ name='mobile_phone',
+ field=models.CharField(blank=True, max_length=18, null=True, verbose_name='T\xe9l\xe9phone portable'),
+ ),
+ migrations.AlterField(
+ model_name='historicalperson',
+ name='name',
+ field=models.CharField(blank=True, max_length=200, null=True, verbose_name='Nom'),
+ ),
+ migrations.AlterField(
+ model_name='historicalperson',
+ name='old_title',
+ field=models.CharField(blank=True, choices=[(b'Mr', 'M.'), (b'Ms', 'Mlle'), (b'Mr and Miss', 'M. et Mme'), (b'Md', 'Mme'), (b'Dr', 'Dr.')], max_length=100, null=True, verbose_name='Titre'),
+ ),
+ migrations.AlterField(
+ model_name='historicalperson',
+ name='phone',
+ field=models.CharField(blank=True, max_length=18, null=True, verbose_name='T\xe9l\xe9phone'),
+ ),
+ migrations.AlterField(
+ model_name='historicalperson',
+ name='phone2',
+ field=models.CharField(blank=True, max_length=18, null=True, verbose_name='Type de t\xe9l\xe9phone 2'),
+ ),
+ migrations.AlterField(
+ model_name='historicalperson',
+ name='phone3',
+ field=models.CharField(blank=True, max_length=18, null=True, verbose_name='T\xe9l\xe9phone 3'),
+ ),
+ migrations.AlterField(
+ model_name='historicalperson',
+ name='phone_desc',
+ field=models.CharField(blank=True, max_length=300, null=True, verbose_name='Type de t\xe9l\xe9phone'),
+ ),
+ migrations.AlterField(
+ model_name='historicalperson',
+ name='phone_desc2',
+ field=models.CharField(blank=True, max_length=300, null=True, verbose_name='Type de t\xe9l\xe9phone 2'),
+ ),
+ migrations.AlterField(
+ model_name='historicalperson',
+ name='phone_desc3',
+ field=models.CharField(blank=True, max_length=300, null=True, verbose_name='Type de t\xe9l\xe9phone 3'),
+ ),
+ migrations.AlterField(
+ model_name='historicalperson',
+ name='postal_code',
+ field=models.CharField(blank=True, max_length=10, null=True, verbose_name='Code postal'),
+ ),
+ migrations.AlterField(
+ model_name='historicalperson',
+ name='raw_name',
+ field=models.CharField(blank=True, max_length=300, null=True, verbose_name='Nom brut'),
+ ),
+ migrations.AlterField(
+ model_name='historicalperson',
+ name='raw_phone',
+ field=models.TextField(blank=True, null=True, verbose_name='T\xe9l\xe9phone brut'),
+ ),
+ migrations.AlterField(
+ model_name='historicalperson',
+ name='salutation',
+ field=models.CharField(blank=True, max_length=200, null=True, verbose_name="Formule d'appel"),
+ ),
+ migrations.AlterField(
+ model_name='historicalperson',
+ name='search_vector',
+ field=django.contrib.postgres.search.SearchVectorField(blank=True, help_text='Auto-rempli \xe0 la sauvegarde', null=True, verbose_name='Vecteur de recherche'),
+ ),
+ migrations.AlterField(
+ model_name='historicalperson',
+ name='surname',
+ field=models.CharField(blank=True, max_length=50, null=True, verbose_name='Pr\xe9nom'),
+ ),
+ migrations.AlterField(
+ model_name='historicalperson',
+ name='town',
+ field=models.CharField(blank=True, max_length=70, null=True, verbose_name='Commune'),
+ ),
+ migrations.AlterField(
+ model_name='import',
+ name='associated_group',
+ field=models.ForeignKey(blank=True, help_text='Si un groupe est s\xe9lectionn\xe9, les cl\xe9s de rapprochement enregistr\xe9es dans ce groupe sont utilis\xe9es.', null=True, on_delete=django.db.models.deletion.CASCADE, to='ishtar_common.TargetKeyGroup'),
+ ),
+ migrations.AlterField(
+ model_name='import',
+ name='changed_checked',
+ field=models.BooleanField(default=False, verbose_name='Les changements ont \xe9t\xe9 v\xe9rifi\xe9s'),
+ ),
+ migrations.AlterField(
+ model_name='import',
+ name='changed_line_numbers',
+ field=models.TextField(blank=True, null=True, validators=[django.core.validators.RegexValidator(re.compile('^\\d+(?:\\,\\d+)*\\Z'), code='invalid', message='Saisissez uniquement des chiffres s\xe9par\xe9s par des virgules.')], verbose_name='Num\xe9ro des lignes modifi\xe9es'),
+ ),
+ migrations.AlterField(
+ model_name='import',
+ name='conservative_import',
+ field=models.BooleanField(default=False, help_text='Si coch\xe9, ne surchargera pas les valeurs existantes.', verbose_name='Import conservateur'),
+ ),
+ migrations.AlterField(
+ model_name='import',
+ name='creation_date',
+ field=models.DateTimeField(auto_now_add=True, null=True, verbose_name='Date de cr\xe9ation'),
+ ),
+ migrations.AlterField(
+ model_name='import',
+ name='current_line',
+ field=models.IntegerField(blank=True, null=True, verbose_name='Ligne actuelle'),
+ ),
+ migrations.AlterField(
+ model_name='import',
+ name='encoding',
+ field=models.CharField(choices=[(b'windows-1252', b'windows-1252'), (b'ISO-8859-15', b'ISO-8859-15'), (b'utf-8', b'utf-8')], default='utf-8', max_length=15, verbose_name='Codage'),
+ ),
+ migrations.AlterField(
+ model_name='import',
+ name='end_date',
+ field=models.DateTimeField(auto_now_add=True, null=True, verbose_name='Date de fin'),
+ ),
+ migrations.AlterField(
+ model_name='import',
+ name='error_file',
+ field=models.FileField(blank=True, max_length=255, null=True, upload_to=b'upload/imports/%Y/%m/', verbose_name='Fichier erreur'),
+ ),
+ migrations.AlterField(
+ model_name='import',
+ name='imported_file',
+ field=models.FileField(max_length=220, upload_to=b'upload/imports/%Y/%m/', verbose_name='Fichier import\xe9'),
+ ),
+ migrations.AlterField(
+ model_name='import',
+ name='imported_images',
+ field=models.FileField(blank=True, max_length=220, null=True, upload_to=b'upload/imports/%Y/%m/', verbose_name='Images associ\xe9es (fichier zip)'),
+ ),
+ migrations.AlterField(
+ model_name='import',
+ name='imported_line_numbers',
+ field=models.TextField(blank=True, null=True, validators=[django.core.validators.RegexValidator(re.compile('^\\d+(?:\\,\\d+)*\\Z'), code='invalid', message='Saisissez uniquement des chiffres s\xe9par\xe9s par des virgules.')], verbose_name='Num\xe9ros des lignes import\xe9es'),
+ ),
+ migrations.AlterField(
+ model_name='import',
+ name='match_file',
+ field=models.FileField(blank=True, max_length=255, null=True, upload_to=b'upload/imports/%Y/%m/', verbose_name='Fichier de correspondance'),
+ ),
+ migrations.AlterField(
+ model_name='import',
+ name='name',
+ field=models.CharField(max_length=500, null=True, verbose_name='Nom'),
+ ),
+ migrations.AlterField(
+ model_name='import',
+ name='number_of_line',
+ field=models.IntegerField(blank=True, null=True, verbose_name='Nombre de lignes'),
+ ),
+ migrations.AlterField(
+ model_name='import',
+ name='result_file',
+ field=models.FileField(blank=True, max_length=255, null=True, upload_to=b'upload/imports/%Y/%m/', verbose_name='Fichier r\xe9sultant'),
+ ),
+ migrations.AlterField(
+ model_name='import',
+ name='seconds_remaining',
+ field=models.IntegerField(blank=True, editable=False, null=True, verbose_name='Secondes restantes'),
+ ),
+ migrations.AlterField(
+ model_name='import',
+ name='skip_lines',
+ field=models.IntegerField(default=1, help_text="Nombre de ligne d'ent\xeate dans votre fichier (peut \xeatre \xe9gal \xe0 z\xe9ro)", verbose_name="Nombre de lignes d'ent\xeate"),
+ ),
+ migrations.AlterField(
+ model_name='import',
+ name='state',
+ field=models.CharField(choices=[(b'C', 'Cr\xe9\xe9'), (b'AP', 'Analyse en cours'), (b'A', 'Analys\xe9'), (b'HQ', 'V\xe9rification des modifications dans la file'), (b'IQ', "Import en file d'attente"), (b'HP', 'V\xe9rification des modifications en cours'), (b'IP', 'Import en cours'), (b'PI', 'Import\xe9 partiellement'), (b'FE', 'Termin\xe9 avec des erreurs'), (b'F', 'Termin\xe9'), (b'AC', 'Archiv\xe9')], default='C', max_length=2, verbose_name='\xc9tat'),
+ ),
+ migrations.AlterField(
+ model_name='importercolumn',
+ name='col_number',
+ field=models.IntegerField(default=1, verbose_name='Num\xe9ro de colonne'),
+ ),
+ migrations.AlterField(
+ model_name='importercolumn',
+ name='export_field_name',
+ field=models.CharField(blank=True, help_text="Remplir ce champ si le nom du champ est ambigu pour l'export, par exemple dans le cas de champs concat\xe9n\xe9s.", max_length=200, null=True, verbose_name='Nom du champ \xe0 exporter'),
+ ),
+ migrations.AlterField(
+ model_name='importercolumn',
+ name='label',
+ field=models.CharField(blank=True, max_length=200, null=True, verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='importercolumn',
+ name='required',
+ field=models.BooleanField(default=False, verbose_name='Requis'),
+ ),
+ migrations.AlterField(
+ model_name='importerduplicatefield',
+ name='concat',
+ field=models.BooleanField(default=False, verbose_name="Concat\xe9ner avec l'existant"),
+ ),
+ migrations.AlterField(
+ model_name='importerduplicatefield',
+ name='concat_str',
+ field=models.CharField(blank=True, max_length=5, null=True, verbose_name='Caract\xe8re de concat\xe9nation'),
+ ),
+ migrations.AlterField(
+ model_name='importerduplicatefield',
+ name='field_name',
+ field=models.CharField(blank=True, max_length=200, null=True, verbose_name='Nom du champ'),
+ ),
+ migrations.AlterField(
+ model_name='importerduplicatefield',
+ name='force_new',
+ field=models.BooleanField(default=False, verbose_name='Forcer la cr\xe9ation de nouveaux \xe9l\xe9ments'),
+ ),
+ migrations.AlterField(
+ model_name='importermodel',
+ name='klass',
+ field=models.CharField(max_length=200, unique=True, verbose_name='Nom de la classe'),
+ ),
+ migrations.AlterField(
+ model_name='importermodel',
+ name='name',
+ field=models.CharField(max_length=200, verbose_name='Nom'),
+ ),
+ migrations.AlterField(
+ model_name='importertype',
+ name='associated_models',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='ishtar_common.ImporterModel', verbose_name='Mod\xe8le associ\xe9'),
+ ),
+ migrations.AlterField(
+ model_name='importertype',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='importertype',
+ name='created_models',
+ field=models.ManyToManyField(blank=True, help_text='Laissez vide pour aucune restriction', related_name='_importertype_created_models_+', to='ishtar_common.ImporterModel', verbose_name='Mod\xe8les qui peuvent accepter de nouveaux \xe9l\xe9ments'),
+ ),
+ migrations.AlterField(
+ model_name='importertype',
+ name='name',
+ field=models.CharField(max_length=200, verbose_name='Nom'),
+ ),
+ migrations.AlterField(
+ model_name='importertype',
+ name='slug',
+ field=models.SlugField(max_length=100, unique=True, verbose_name='Identifiant texte'),
+ ),
+ migrations.AlterField(
+ model_name='importertype',
+ name='unicity_keys',
+ field=models.CharField(blank=True, max_length=500, null=True, verbose_name="Cl\xe9s d'unicit\xe9 (s\xe9parateur \xab ; \xbb)"),
+ ),
+ migrations.AlterField(
+ model_name='importertype',
+ name='users',
+ field=models.ManyToManyField(blank=True, to='ishtar_common.IshtarUser', verbose_name='Utilisateurs'),
+ ),
+ migrations.AlterField(
+ model_name='importtarget',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='importtarget',
+ name='concat',
+ field=models.BooleanField(default=False, verbose_name="Concat\xe9ner avec l'existant"),
+ ),
+ migrations.AlterField(
+ model_name='importtarget',
+ name='concat_str',
+ field=models.CharField(blank=True, max_length=5, null=True, verbose_name='Caract\xe8re de concat\xe9nation'),
+ ),
+ migrations.AlterField(
+ model_name='importtarget',
+ name='force_new',
+ field=models.BooleanField(default=False, verbose_name='Forcer la cr\xe9ation de nouveaux \xe9l\xe9ments'),
+ ),
+ migrations.AlterField(
+ model_name='ishtarsiteprofile',
+ name='active',
+ field=models.BooleanField(default=False, verbose_name='Actuellement utilis\xe9'),
+ ),
+ migrations.AlterField(
+ model_name='ishtarsiteprofile',
+ name='archaeological_site',
+ field=models.BooleanField(default=False, verbose_name='Module Site arch\xe9ologique'),
+ ),
+ migrations.AlterField(
+ model_name='ishtarsiteprofile',
+ name='archaeological_site_label',
+ field=models.CharField(choices=[(b'site', 'Site'), (b'entity', 'Entit\xe9 (EA)')], default=b'site', max_length=200, verbose_name='Type de site arch\xe9ologique'),
+ ),
+ migrations.AlterField(
+ model_name='ishtarsiteprofile',
+ name='base_find_external_id',
+ field=models.TextField(default='{context_record__external_id}-{label}', help_text="Formule pour g\xe9rer les identifiants de mobilier d'origine. \xc0 manipuler avec pr\xe9caution. Une formule incorrecte peut rendre l'application inutilisable et l'import de donn\xe9es externes peut alors \xeatre destructif.", verbose_name="Identifiant de mobilier d'origine"),
+ ),
+ migrations.AlterField(
+ model_name='ishtarsiteprofile',
+ name='container_external_id',
+ field=models.TextField(default='{responsible__external_id}-{index}', help_text="Formule pour g\xe9rer les identifiants de contenant. \xc0 manipuler avec pr\xe9caution. Une formule incorrecte peut rendre l'application inutilisable et l'import de donn\xe9es externes peut alors \xeatre destructif.", verbose_name='ID du contenant'),
+ ),
+ migrations.AlterField(
+ model_name='ishtarsiteprofile',
+ name='context_record',
+ field=models.BooleanField(default=False, verbose_name="Module Unit\xe9s d'Enregistrement"),
+ ),
+ migrations.AlterField(
+ model_name='ishtarsiteprofile',
+ name='context_record_external_id',
+ field=models.TextField(default='{parcel__external_id}-{label}', help_text="Formule pour g\xe9rer les identifiants d'unit\xe9s d'enregistrement. \xc0 manipuler avec pr\xe9caution. Une formule incorrecte peut rendre l'application inutilisable et l'import de donn\xe9es externes peut alors \xeatre destructif.", verbose_name="Identifiant d'unit\xe9 d'enregistrement"),
+ ),
+ migrations.AlterField(
+ model_name='ishtarsiteprofile',
+ name='currency',
+ field=models.CharField(choices=[('\u20ac', 'Euro'), ('$', 'Dollar US')], default='\u20ac', max_length=5, verbose_name='Devise'),
+ ),
+ migrations.AlterField(
+ model_name='ishtarsiteprofile',
+ name='experimental_feature',
+ field=models.BooleanField(default=False, verbose_name='Activer les fonctionnalit\xe9s exp\xe9rimentales'),
+ ),
+ migrations.AlterField(
+ model_name='ishtarsiteprofile',
+ name='file_external_id',
+ field=models.TextField(default='{year}-{numeric_reference}', help_text="Formule pour g\xe9rer les identifiants de dossiers. \xc0 manipuler avec pr\xe9caution. Une formule incorrecte peut rendre l'application inutilisable et l'import de donn\xe9es externes peut alors \xeatre destructif.", verbose_name='Identifiant de fichier'),
+ ),
+ migrations.AlterField(
+ model_name='ishtarsiteprofile',
+ name='files',
+ field=models.BooleanField(default=False, verbose_name='Module Dossiers'),
+ ),
+ migrations.AlterField(
+ model_name='ishtarsiteprofile',
+ name='find',
+ field=models.BooleanField(default=False, help_text="N\xe9cessite le module Unit\xe9s d'Enregistrement", verbose_name='Module Mobilier'),
+ ),
+ migrations.AlterField(
+ model_name='ishtarsiteprofile',
+ name='find_external_id',
+ field=models.TextField(default='{get_first_base_find__context_record__external_id}-{label}', help_text="Formule pour g\xe9rer les identifiants de mobilier. \xc0 manipuler avec pr\xe9caution. Une formule incorrecte peut rendre l'application inutilisable et l'import de donn\xe9es externes peut alors \xeatre destructif.", verbose_name='Identifiant de mobilier'),
+ ),
+ migrations.AlterField(
+ model_name='ishtarsiteprofile',
+ name='find_index',
+ field=models.CharField(choices=[('O', 'Op\xe9rations'), ('CR', "Unit\xe9s d'Enregistrement")], default=b'O', help_text="Pour \xe9viter des index non pertinents, ne changer ce param\xe8tre que s'il n'y a pas encore de mobilier dans cette base de donn\xe9es", max_length=2, verbose_name='Index mobilier bas\xe9 sur'),
+ ),
+ migrations.AlterField(
+ model_name='ishtarsiteprofile',
+ name='homepage',
+ field=models.TextField(blank=True, help_text="Page d'accueil d'Ishtar. Si elle n'est pas d\xe9finie, une page d'accueil par d\xe9faut appara\xeet. Utiliser la syntaxe Markdown. {random_image} peut \xeatre utilis\xe9 pour afficher une image au hasard.", null=True, verbose_name="Page d'accueil"),
+ ),
+ migrations.AlterField(
+ model_name='ishtarsiteprofile',
+ name='label',
+ field=models.TextField(verbose_name='Nom'),
+ ),
+ migrations.AlterField(
+ model_name='ishtarsiteprofile',
+ name='mapping',
+ field=models.BooleanField(default=False, verbose_name='Module cartographique'),
+ ),
+ migrations.AlterField(
+ model_name='ishtarsiteprofile',
+ name='parcel_external_id',
+ field=models.TextField(default='{associated_file__external_id}{operation__code_patriarche}-{town__numero_insee}-{section}{parcel_number}', help_text="Formule pour g\xe9rer les identifiants de parcelles. \xc0 manipuler avec pr\xe9caution. Une formule incorrecte peut rendre l'application inutilisable et l'import de donn\xe9es externes peut alors \xeatre destructif.", verbose_name='Identifiant de parcelle'),
+ ),
+ migrations.AlterField(
+ model_name='ishtarsiteprofile',
+ name='parcel_mandatory',
+ field=models.BooleanField(default=True, verbose_name="Parcelles cadastrales obligatoires pour les Unit\xe9s d'Enregistrement"),
+ ),
+ migrations.AlterField(
+ model_name='ishtarsiteprofile',
+ name='person_raw_name',
+ field=models.TextField(default='{name|upper} {surname}', help_text="Formule pour g\xe9rer le nom brut des personnes. \xc0 manipuler avec pr\xe9caution. Une formule incorrecte peut rendre l'application inutilisable et l'import de donn\xe9es externes peut alors \xeatre destructif.", verbose_name='Nom brut pour une personne'),
+ ),
+ migrations.AlterField(
+ model_name='ishtarsiteprofile',
+ name='preservation',
+ field=models.BooleanField(default=False, verbose_name='Module de conservation'),
+ ),
+ migrations.AlterField(
+ model_name='ishtarsiteprofile',
+ name='slug',
+ field=models.SlugField(unique=True, verbose_name='Identifiant texte'),
+ ),
+ migrations.AlterField(
+ model_name='ishtarsiteprofile',
+ name='underwater',
+ field=models.BooleanField(default=False, verbose_name='Module sous-marin / subaquatique'),
+ ),
+ migrations.AlterField(
+ model_name='ishtarsiteprofile',
+ name='warehouse',
+ field=models.BooleanField(default=False, help_text='N\xe9cessite le module mobilier', verbose_name='Module Lieu de conservation'),
+ ),
+ migrations.AlterField(
+ model_name='ishtarsiteprofile',
+ name='warehouse_external_id',
+ field=models.TextField(default='{name|slug}', help_text="Formule pour g\xe9rer les identifiants de lieu de conservation. \xc0 manipuler avec pr\xe9caution. Une formule incorrecte peut rendre l'application inutilisable et l'import de donn\xe9es externes peut alors \xeatre destructif.", verbose_name='Identifiant du lieu de conservation'),
+ ),
+ migrations.AlterField(
+ model_name='ishtaruser',
+ name='advanced_shortcut_menu',
+ field=models.BooleanField(default=False, verbose_name='Menu de raccourci (avanc\xe9)'),
+ ),
+ migrations.AlterField(
+ model_name='ishtaruser',
+ name='person',
+ field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='ishtaruser', to='ishtar_common.Person', verbose_name='Personne'),
+ ),
+ migrations.AlterField(
+ model_name='ishtaruser',
+ name='search_vector',
+ field=django.contrib.postgres.search.SearchVectorField(blank=True, help_text='Auto-rempli \xe0 la sauvegarde', null=True, verbose_name='Vecteur de recherche'),
+ ),
+ migrations.AlterField(
+ model_name='itemkey',
+ name='importer',
+ field=models.ForeignKey(blank=True, help_text='Cl\xe9 sp\xe9cifique \xe0 un import', null=True, on_delete=django.db.models.deletion.CASCADE, to='ishtar_common.Import'),
+ ),
+ migrations.AlterField(
+ model_name='itemkey',
+ name='key',
+ field=models.TextField(verbose_name='Cl\xe9'),
+ ),
+ migrations.AlterField(
+ model_name='jsondatafield',
+ name='display',
+ field=models.BooleanField(default=True, verbose_name='Afficher'),
+ ),
+ migrations.AlterField(
+ model_name='jsondatafield',
+ name='key',
+ field=models.CharField(help_text="Valeur de la cl\xe9 dans le format JSON. Pour les cl\xe9s hi\xe9rarchiques utiliser \xab __ \xbb. Par exemple pour la cl\xe9 'ma_sousclef' avec des donn\xe9es telles que {'ma_clef': {'ma_sousclef': 'valeur'}}, sa valeur sera atteinte avec : ma_clef__ma_sousclef.", max_length=200, verbose_name='Cl\xe9'),
+ ),
+ migrations.AlterField(
+ model_name='jsondatafield',
+ name='name',
+ field=models.CharField(max_length=200, verbose_name='Nom'),
+ ),
+ migrations.AlterField(
+ model_name='jsondatafield',
+ name='order',
+ field=models.IntegerField(default=10, verbose_name='Ordre'),
+ ),
+ migrations.AlterField(
+ model_name='jsondatafield',
+ name='search_index',
+ field=models.BooleanField(default=False, verbose_name='Utiliser dans les index de recherche'),
+ ),
+ migrations.AlterField(
+ model_name='jsondatafield',
+ name='value_type',
+ field=models.CharField(choices=[(b'T', 'Texte'), (b'LT', 'Texte long'), (b'I', 'Entier'), (b'B', 'Boolean'), (b'F', 'Nombre \xe0 virgule'), (b'D', 'Date'), (b'C', 'Choix')], default=b'T', max_length=10, verbose_name='Type'),
+ ),
+ migrations.AlterField(
+ model_name='jsondatasection',
+ name='name',
+ field=models.CharField(max_length=200, verbose_name='Nom'),
+ ),
+ migrations.AlterField(
+ model_name='jsondatasection',
+ name='order',
+ field=models.IntegerField(default=10, verbose_name='Ordre'),
+ ),
+ migrations.AlterField(
+ model_name='licensetype',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='licensetype',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='licensetype',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='licensetype',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ migrations.AlterField(
+ model_name='operationtype',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='operationtype',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='operationtype',
+ name='judiciary',
+ field=models.BooleanField(default=False, verbose_name='Est judiciaire'),
+ ),
+ migrations.AlterField(
+ model_name='operationtype',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='operationtype',
+ name='order',
+ field=models.IntegerField(default=1, verbose_name='Ordre'),
+ ),
+ migrations.AlterField(
+ model_name='operationtype',
+ name='preventive',
+ field=models.BooleanField(default=True, verbose_name='Est du pr\xe9ventif'),
+ ),
+ migrations.AlterField(
+ model_name='operationtype',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ migrations.AlterField(
+ model_name='organization',
+ name='address',
+ field=models.TextField(blank=True, null=True, verbose_name='Adresse'),
+ ),
+ migrations.AlterField(
+ model_name='organization',
+ name='address_complement',
+ field=models.TextField(blank=True, null=True, verbose_name="Compl\xe9ment d'adresse"),
+ ),
+ migrations.AlterField(
+ model_name='organization',
+ name='alt_address',
+ field=models.TextField(blank=True, null=True, verbose_name='Autre adresse : adresse'),
+ ),
+ migrations.AlterField(
+ model_name='organization',
+ name='alt_address_complement',
+ field=models.TextField(blank=True, null=True, verbose_name="Autre adresse : compl\xe9ment d'adresse"),
+ ),
+ migrations.AlterField(
+ model_name='organization',
+ name='alt_address_is_prefered',
+ field=models.BooleanField(default=False, verbose_name="L'adresse alternative est pr\xe9f\xe9r\xe9e"),
+ ),
+ migrations.AlterField(
+ model_name='organization',
+ name='alt_country',
+ field=models.CharField(blank=True, max_length=30, null=True, verbose_name='Autre adresse : pays'),
+ ),
+ migrations.AlterField(
+ model_name='organization',
+ name='alt_postal_code',
+ field=models.CharField(blank=True, max_length=10, null=True, verbose_name='Autre adresse : code postal'),
+ ),
+ migrations.AlterField(
+ model_name='organization',
+ name='alt_town',
+ field=models.CharField(blank=True, max_length=70, null=True, verbose_name='Autre adresse : ville'),
+ ),
+ migrations.AlterField(
+ model_name='organization',
+ name='cached_label',
+ field=models.TextField(blank=True, db_index=True, null=True, verbose_name='Nom en cache'),
+ ),
+ migrations.AlterField(
+ model_name='organization',
+ name='country',
+ field=models.CharField(blank=True, max_length=30, null=True, verbose_name='Pays'),
+ ),
+ migrations.AlterField(
+ model_name='organization',
+ name='email',
+ field=models.EmailField(blank=True, max_length=300, null=True, verbose_name='Courriel'),
+ ),
+ migrations.AlterField(
+ model_name='organization',
+ name='history_creator',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Cr\xe9ateur'),
+ ),
+ migrations.AlterField(
+ model_name='organization',
+ name='history_modifier',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Dernier \xe9diteur'),
+ ),
+ migrations.AlterField(
+ model_name='organization',
+ name='merge_key',
+ field=models.TextField(blank=True, null=True, verbose_name='Cl\xe9 de fusion'),
+ ),
+ migrations.AlterField(
+ model_name='organization',
+ name='mobile_phone',
+ field=models.CharField(blank=True, max_length=18, null=True, verbose_name='T\xe9l\xe9phone portable'),
+ ),
+ migrations.AlterField(
+ model_name='organization',
+ name='name',
+ field=models.CharField(max_length=500, verbose_name='Nom'),
+ ),
+ migrations.AlterField(
+ model_name='organization',
+ name='phone',
+ field=models.CharField(blank=True, max_length=18, null=True, verbose_name='T\xe9l\xe9phone'),
+ ),
+ migrations.AlterField(
+ model_name='organization',
+ name='phone2',
+ field=models.CharField(blank=True, max_length=18, null=True, verbose_name='Type de t\xe9l\xe9phone 2'),
+ ),
+ migrations.AlterField(
+ model_name='organization',
+ name='phone3',
+ field=models.CharField(blank=True, max_length=18, null=True, verbose_name='T\xe9l\xe9phone 3'),
+ ),
+ migrations.AlterField(
+ model_name='organization',
+ name='phone_desc',
+ field=models.CharField(blank=True, max_length=300, null=True, verbose_name='Type de t\xe9l\xe9phone'),
+ ),
+ migrations.AlterField(
+ model_name='organization',
+ name='phone_desc2',
+ field=models.CharField(blank=True, max_length=300, null=True, verbose_name='Type de t\xe9l\xe9phone 2'),
+ ),
+ migrations.AlterField(
+ model_name='organization',
+ name='phone_desc3',
+ field=models.CharField(blank=True, max_length=300, null=True, verbose_name='Type de t\xe9l\xe9phone 3'),
+ ),
+ migrations.AlterField(
+ model_name='organization',
+ name='postal_code',
+ field=models.CharField(blank=True, max_length=10, null=True, verbose_name='Code postal'),
+ ),
+ migrations.AlterField(
+ model_name='organization',
+ name='raw_phone',
+ field=models.TextField(blank=True, null=True, verbose_name='T\xe9l\xe9phone brut'),
+ ),
+ migrations.AlterField(
+ model_name='organization',
+ name='search_vector',
+ field=django.contrib.postgres.search.SearchVectorField(blank=True, help_text='Auto-rempli \xe0 la sauvegarde', null=True, verbose_name='Vecteur de recherche'),
+ ),
+ migrations.AlterField(
+ model_name='organization',
+ name='town',
+ field=models.CharField(blank=True, max_length=70, null=True, verbose_name='Commune'),
+ ),
+ migrations.AlterField(
+ model_name='organizationtype',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='organizationtype',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='organizationtype',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='organizationtype',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ migrations.AlterField(
+ model_name='person',
+ name='address',
+ field=models.TextField(blank=True, null=True, verbose_name='Adresse'),
+ ),
+ migrations.AlterField(
+ model_name='person',
+ name='address_complement',
+ field=models.TextField(blank=True, null=True, verbose_name="Compl\xe9ment d'adresse"),
+ ),
+ migrations.AlterField(
+ model_name='person',
+ name='alt_address',
+ field=models.TextField(blank=True, null=True, verbose_name='Autre adresse : adresse'),
+ ),
+ migrations.AlterField(
+ model_name='person',
+ name='alt_address_complement',
+ field=models.TextField(blank=True, null=True, verbose_name="Autre adresse : compl\xe9ment d'adresse"),
+ ),
+ migrations.AlterField(
+ model_name='person',
+ name='alt_address_is_prefered',
+ field=models.BooleanField(default=False, verbose_name="L'adresse alternative est pr\xe9f\xe9r\xe9e"),
+ ),
+ migrations.AlterField(
+ model_name='person',
+ name='alt_country',
+ field=models.CharField(blank=True, max_length=30, null=True, verbose_name='Autre adresse : pays'),
+ ),
+ migrations.AlterField(
+ model_name='person',
+ name='alt_postal_code',
+ field=models.CharField(blank=True, max_length=10, null=True, verbose_name='Autre adresse : code postal'),
+ ),
+ migrations.AlterField(
+ model_name='person',
+ name='alt_town',
+ field=models.CharField(blank=True, max_length=70, null=True, verbose_name='Autre adresse : ville'),
+ ),
+ migrations.AlterField(
+ model_name='person',
+ name='attached_to',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='members', to='ishtar_common.Organization', verbose_name='Est rattach\xe9 \xe0'),
+ ),
+ migrations.AlterField(
+ model_name='person',
+ name='cached_label',
+ field=models.TextField(blank=True, db_index=True, null=True, verbose_name='Nom en cache'),
+ ),
+ migrations.AlterField(
+ model_name='person',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='person',
+ name='contact_type',
+ field=models.CharField(blank=True, max_length=300, null=True, verbose_name='Type de contact'),
+ ),
+ migrations.AlterField(
+ model_name='person',
+ name='country',
+ field=models.CharField(blank=True, max_length=30, null=True, verbose_name='Pays'),
+ ),
+ migrations.AlterField(
+ model_name='person',
+ name='email',
+ field=models.EmailField(blank=True, max_length=300, null=True, verbose_name='Courriel'),
+ ),
+ migrations.AlterField(
+ model_name='person',
+ name='history_creator',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Cr\xe9ateur'),
+ ),
+ migrations.AlterField(
+ model_name='person',
+ name='history_modifier',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Dernier \xe9diteur'),
+ ),
+ migrations.AlterField(
+ model_name='person',
+ name='merge_key',
+ field=models.TextField(blank=True, null=True, verbose_name='Cl\xe9 de fusion'),
+ ),
+ migrations.AlterField(
+ model_name='person',
+ name='mobile_phone',
+ field=models.CharField(blank=True, max_length=18, null=True, verbose_name='T\xe9l\xe9phone portable'),
+ ),
+ migrations.AlterField(
+ model_name='person',
+ name='name',
+ field=models.CharField(blank=True, max_length=200, null=True, verbose_name='Nom'),
+ ),
+ migrations.AlterField(
+ model_name='person',
+ name='old_title',
+ field=models.CharField(blank=True, choices=[(b'Mr', 'M.'), (b'Ms', 'Mlle'), (b'Mr and Miss', 'M. et Mme'), (b'Md', 'Mme'), (b'Dr', 'Dr.')], max_length=100, null=True, verbose_name='Titre'),
+ ),
+ migrations.AlterField(
+ model_name='person',
+ name='phone',
+ field=models.CharField(blank=True, max_length=18, null=True, verbose_name='T\xe9l\xe9phone'),
+ ),
+ migrations.AlterField(
+ model_name='person',
+ name='phone2',
+ field=models.CharField(blank=True, max_length=18, null=True, verbose_name='Type de t\xe9l\xe9phone 2'),
+ ),
+ migrations.AlterField(
+ model_name='person',
+ name='phone3',
+ field=models.CharField(blank=True, max_length=18, null=True, verbose_name='T\xe9l\xe9phone 3'),
+ ),
+ migrations.AlterField(
+ model_name='person',
+ name='phone_desc',
+ field=models.CharField(blank=True, max_length=300, null=True, verbose_name='Type de t\xe9l\xe9phone'),
+ ),
+ migrations.AlterField(
+ model_name='person',
+ name='phone_desc2',
+ field=models.CharField(blank=True, max_length=300, null=True, verbose_name='Type de t\xe9l\xe9phone 2'),
+ ),
+ migrations.AlterField(
+ model_name='person',
+ name='phone_desc3',
+ field=models.CharField(blank=True, max_length=300, null=True, verbose_name='Type de t\xe9l\xe9phone 3'),
+ ),
+ migrations.AlterField(
+ model_name='person',
+ name='postal_code',
+ field=models.CharField(blank=True, max_length=10, null=True, verbose_name='Code postal'),
+ ),
+ migrations.AlterField(
+ model_name='person',
+ name='raw_name',
+ field=models.CharField(blank=True, max_length=300, null=True, verbose_name='Nom brut'),
+ ),
+ migrations.AlterField(
+ model_name='person',
+ name='raw_phone',
+ field=models.TextField(blank=True, null=True, verbose_name='T\xe9l\xe9phone brut'),
+ ),
+ migrations.AlterField(
+ model_name='person',
+ name='salutation',
+ field=models.CharField(blank=True, max_length=200, null=True, verbose_name="Formule d'appel"),
+ ),
+ migrations.AlterField(
+ model_name='person',
+ name='search_vector',
+ field=django.contrib.postgres.search.SearchVectorField(blank=True, help_text='Auto-rempli \xe0 la sauvegarde', null=True, verbose_name='Vecteur de recherche'),
+ ),
+ migrations.AlterField(
+ model_name='person',
+ name='surname',
+ field=models.CharField(blank=True, max_length=50, null=True, verbose_name='Pr\xe9nom'),
+ ),
+ migrations.AlterField(
+ model_name='person',
+ name='title',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='ishtar_common.TitleType', verbose_name='Titre'),
+ ),
+ migrations.AlterField(
+ model_name='person',
+ name='town',
+ field=models.CharField(blank=True, max_length=70, null=True, verbose_name='Commune'),
+ ),
+ migrations.AlterField(
+ model_name='persontype',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='persontype',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='persontype',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='persontype',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ migrations.AlterField(
+ model_name='profiletype',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='profiletype',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='profiletype',
+ name='groups',
+ field=models.ManyToManyField(blank=True, to='auth.Group', verbose_name='Groupes'),
+ ),
+ migrations.AlterField(
+ model_name='profiletype',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='profiletype',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ migrations.AlterField(
+ model_name='regexp',
+ name='name',
+ field=models.CharField(max_length=100, unique=True, verbose_name='Nom'),
+ ),
+ migrations.AlterField(
+ model_name='regexp',
+ name='regexp',
+ field=models.CharField(max_length=500, verbose_name='Expression r\xe9guli\xe8re'),
+ ),
+ migrations.AlterField(
+ model_name='searchquery',
+ name='content_type',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType', verbose_name='Type de contenu'),
+ ),
+ migrations.AlterField(
+ model_name='searchquery',
+ name='is_alert',
+ field=models.BooleanField(default=False, verbose_name='Est une alerte'),
+ ),
+ migrations.AlterField(
+ model_name='searchquery',
+ name='label',
+ field=models.TextField(blank=True, verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='searchquery',
+ name='profile',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='ishtar_common.UserProfile', verbose_name='Profil'),
+ ),
+ migrations.AlterField(
+ model_name='searchquery',
+ name='query',
+ field=models.TextField(blank=True, verbose_name='Requ\xeate'),
+ ),
+ migrations.AlterField(
+ model_name='sourcetype',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='sourcetype',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='sourcetype',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='sourcetype',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ migrations.AlterField(
+ model_name='spatialreferencesystem',
+ name='auth_name',
+ field=models.CharField(default='EPSG', max_length=256, verbose_name='Registre'),
+ ),
+ migrations.AlterField(
+ model_name='spatialreferencesystem',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='spatialreferencesystem',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='spatialreferencesystem',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='spatialreferencesystem',
+ name='order',
+ field=models.IntegerField(default=10, verbose_name='Ordre'),
+ ),
+ migrations.AlterField(
+ model_name='spatialreferencesystem',
+ name='srid',
+ field=models.IntegerField(verbose_name='SRID'),
+ ),
+ migrations.AlterField(
+ model_name='spatialreferencesystem',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ migrations.AlterField(
+ model_name='state',
+ name='label',
+ field=models.CharField(max_length=30, verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='state',
+ name='number',
+ field=models.CharField(max_length=3, unique=True, verbose_name='Nombre'),
+ ),
+ migrations.AlterField(
+ model_name='supporttype',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='supporttype',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='supporttype',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='supporttype',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ migrations.AlterField(
+ model_name='targetkey',
+ name='is_set',
+ field=models.BooleanField(default=False, verbose_name='Est d\xe9fini'),
+ ),
+ migrations.AlterField(
+ model_name='targetkey',
+ name='key',
+ field=models.TextField(verbose_name='Cl\xe9'),
+ ),
+ migrations.AlterField(
+ model_name='targetkey',
+ name='value',
+ field=models.TextField(blank=True, null=True, verbose_name='Valeur'),
+ ),
+ migrations.AlterField(
+ model_name='targetkeygroup',
+ name='all_user_can_modify',
+ field=models.BooleanField(default=False, verbose_name='Tous les utilisateurs peuvent le modifier'),
+ ),
+ migrations.AlterField(
+ model_name='targetkeygroup',
+ name='all_user_can_use',
+ field=models.BooleanField(default=False, verbose_name="Tous les utilisateurs peuvent l'utiliser"),
+ ),
+ migrations.AlterField(
+ model_name='targetkeygroup',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='targetkeygroup',
+ name='name',
+ field=models.TextField(unique=True, verbose_name='Nom'),
+ ),
+ migrations.AlterField(
+ model_name='titletype',
+ name='available',
+ field=models.BooleanField(default=True, verbose_name='Disponible'),
+ ),
+ migrations.AlterField(
+ model_name='titletype',
+ name='comment',
+ field=models.TextField(blank=True, null=True, verbose_name='Commentaire'),
+ ),
+ migrations.AlterField(
+ model_name='titletype',
+ name='label',
+ field=models.TextField(verbose_name='D\xe9nomination'),
+ ),
+ migrations.AlterField(
+ model_name='titletype',
+ name='txt_idx',
+ field=models.TextField(help_text='Le "slug" est une version standardis\xe9e du nom. Il ne contient que des lettres en minuscule, des nombres et des tirets (-). Chaque "slug" doit \xeatre unique dans la typologie.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Ce champ ne doit contenir que des lettres, des nombres, des tirets bas _ et des traits d'union.", 'invalid')], verbose_name='Identifiant textuel'),
+ ),
+ migrations.AlterField(
+ model_name='town',
+ name='cached_label',
+ field=models.CharField(blank=True, db_index=True, max_length=500, null=True, verbose_name='Nom en cache'),
+ ),
+ migrations.AlterField(
+ model_name='town',
+ name='children',
+ field=models.ManyToManyField(blank=True, related_name='parents', to='ishtar_common.Town', verbose_name='Communes enfants'),
+ ),
+ migrations.AlterField(
+ model_name='town',
+ name='departement',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='ishtar_common.Department', verbose_name='D\xe9partement'),
+ ),
+ migrations.AlterField(
+ model_name='town',
+ name='limit',
+ field=django.contrib.gis.db.models.fields.MultiPolygonField(blank=True, null=True, srid=4326, verbose_name='Limite'),
+ ),
+ migrations.AlterField(
+ model_name='town',
+ name='name',
+ field=models.CharField(max_length=100, verbose_name='Nom'),
+ ),
+ migrations.AlterField(
+ model_name='town',
+ name='year',
+ field=models.IntegerField(blank=True, help_text='Remplir ce champ est n\xe9cessaire pour distinguer les anciennes communes des nouvelles communes.', null=True, verbose_name='Ann\xe9e de cr\xe9ation'),
+ ),
+ migrations.AlterField(
+ model_name='userprofile',
+ name='areas',
+ field=models.ManyToManyField(blank=True, related_name='profiles', to='ishtar_common.Area', verbose_name='Zones'),
+ ),
+ migrations.AlterField(
+ model_name='userprofile',
+ name='current',
+ field=models.BooleanField(default=False, verbose_name='Profil actuel'),
+ ),
+ migrations.AlterField(
+ model_name='userprofile',
+ name='name',
+ field=models.CharField(blank=True, default='', max_length=100, verbose_name='Nom'),
+ ),
+ migrations.AlterField(
+ model_name='userprofile',
+ name='person',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='profiles', to='ishtar_common.Person', verbose_name='Personne'),
+ ),
+ migrations.AlterField(
+ model_name='userprofile',
+ name='profile_type',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='ishtar_common.ProfileType', verbose_name='Type de profil'),
+ ),
+ ]
diff --git a/ishtar_common/migrations/0079_migrate-importers.py b/ishtar_common/migrations/0079_migrate-importers.py
new file mode 100644
index 000000000..3a66ffb30
--- /dev/null
+++ b/ishtar_common/migrations/0079_migrate-importers.py
@@ -0,0 +1,70 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.10 on 2018-12-13 15:13
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+def migrate_importer(apps, schema):
+ ImporterDuplicateField = apps.get_model('ishtar_common',
+ 'ImporterDuplicateField')
+ ImportTarget = apps.get_model('ishtar_common', 'ImportTarget')
+
+ idx = 0
+ for k, model in (('field_name', ImporterDuplicateField),
+ ('target', ImportTarget),):
+ q = model.objects.filter(
+ **{k + "__icontains": 'container'}
+ ).exclude(
+ **{k + "__icontains": 'container_ref'}
+ )
+ for item in q.all():
+ value = getattr(item, k).replace(
+ 'container', 'container_ref').replace(
+ 'container_ref_type', 'container_type')
+
+ dup_dct = {"column": item.column,
+ "field_name": value}
+ q2 = ImporterDuplicateField.objects.filter(
+ **dup_dct
+ )
+ if q2.count():
+ continue
+ idx += 1
+ if item.concat_str:
+ dup_dct['concat_str'] = item.concat_str
+ if item.concat:
+ dup_dct['concat'] = item.concat
+ ImporterDuplicateField.objects.create(**dup_dct)
+ q = model.objects.filter(
+ **{k + "__icontains": 'set_localisation'}
+ )
+ for item in q.all():
+ value = getattr(item, k).replace(
+ 'set_localisation', 'set_reference_localisation')
+ dup_dct = {"column": item.column,
+ "field_name": value}
+ q2 = ImporterDuplicateField.objects.filter(
+ **dup_dct
+ )
+ if q2.count():
+ continue
+ idx += 1
+ if item.concat_str:
+ dup_dct['concat_str'] = item.concat_str
+ if item.concat:
+ dup_dct['concat'] = item.concat
+ ImporterDuplicateField.objects.create(**dup_dct)
+
+ print("{} dup field created".format(idx))
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('ishtar_common', '0078_auto_20181203_1442'),
+ ]
+
+ operations = [
+ migrations.RunPython(migrate_importer)
+ ]
diff --git a/ishtar_common/models.py b/ishtar_common/models.py
index 1aa94836f..6eb36acdb 100644
--- a/ishtar_common/models.py
+++ b/ishtar_common/models.py
@@ -254,7 +254,7 @@ class OwnPerms(object):
action_own_name, request.session)
and self.is_own(request.user.ishtaruser))
- def is_own(self, user):
+ def is_own(self, user, alt_query_own=None):
"""
Check if the current object is owned by the user
"""
@@ -264,7 +264,10 @@ class OwnPerms(object):
ishtaruser = user.ishtaruser
else:
return False
- query = self.get_query_owns(ishtaruser)
+ if not alt_query_own:
+ query = self.get_query_owns(ishtaruser)
+ else:
+ query = getattr(self, alt_query_own)(ishtaruser)
if not query:
return False
query &= Q(pk=self.pk)
@@ -2181,7 +2184,11 @@ class CustomForm(models.Model):
return []
res = []
for model_name in register_fields[app_name]:
- ct = ContentType.objects.get(app_label=app_name, model=model_name)
+ q = ContentType.objects.filter(app_label=app_name,
+ model=model_name)
+ if not q.count():
+ continue
+ ct = q.all()[0]
for json_field in JsonDataField.objects.filter(
content_type=ct).all():
res.append((json_field.pk, u"{} ({})".format(
@@ -3293,6 +3300,7 @@ post_save.connect(post_save_userprofile, sender=UserProfile)
class IshtarUser(FullSearch):
+ SLUG = "ishtaruser"
TABLE_COLS = ('username', 'person__name', 'person__surname',
'person__email', 'person__person_types_list',
'person__attached_to__name')
@@ -3428,7 +3436,7 @@ class IshtarUser(FullSearch):
return self.person.full_label()
-class Basket(FullSearch):
+class Basket(FullSearch, OwnPerms):
"""
Abstract class for a basket
Subclass must be defined with an "items" ManyToManyField
@@ -3441,9 +3449,13 @@ class Basket(FullSearch):
verbose_name=_(u"Owner"))
available = models.BooleanField(_(u"Available"), default=True)
shared_with = models.ManyToManyField(
- IshtarUser, verbose_name=_(u"Shared with"), blank=True,
+ IshtarUser, verbose_name=_(u"Shared (read) with"), blank=True,
related_name='shared_%(class)ss'
)
+ shared_write_with = models.ManyToManyField(
+ IshtarUser, verbose_name=_(u"Shared (read/edit) with"), blank=True,
+ related_name='shared_write_%(class)ss'
+ )
TABLE_COLS = ['label', 'user']
@@ -3462,12 +3474,17 @@ class Basket(FullSearch):
if not request.user or not getattr(request.user, 'ishtaruser', None):
return Q(pk=None)
ishtaruser = request.user.ishtaruser
- return Q(user=ishtaruser) | Q(shared_with=ishtaruser)
+ return Q(user=ishtaruser) | Q(shared_with=ishtaruser) | Q(
+ shared_write_with=ishtaruser)
@property
def cached_label(self):
return unicode(self)
+ @property
+ def full_label(self):
+ return u"{} - {}".format(self.label, self.user)
+
@classmethod
def get_short_menu_class(cls, pk):
return 'basket'
@@ -3477,6 +3494,38 @@ class Basket(FullSearch):
return "{}-{}".format(datetime.date.today().strftime(
"%Y-%m-%d"), slugify(self.label))
+ @classmethod
+ def get_query_owns(cls, ishtaruser):
+ return Q(user=ishtaruser) | Q(shared_with=ishtaruser) | Q(
+ shared_write_with=ishtaruser)
+
+ @classmethod
+ def get_write_query_owns(cls, ishtaruser):
+ return Q(user=ishtaruser)
+
+ def duplicate(self, label=None, ishtaruser=None):
+ """
+ Duplicate the basket. Items in basket are copied but not shared users
+ :param label: if provided use the name
+ :param ishtaruser: if provided an alternate user is used
+ :return: the new basket
+ """
+ items = list(self.items.all())
+ new_item = self
+ new_item.pk = None
+ if ishtaruser:
+ new_item.user = ishtaruser
+ if not label:
+ label = new_item.label
+ while self.__class__.objects.filter(
+ label=label, user=new_item.user).count():
+ label += unicode(_(u" - duplicate"))
+ new_item.label = label
+ new_item.save()
+ for item in items:
+ new_item.items.add(item)
+ return new_item
+
class AuthorType(GeneralType):
order = models.IntegerField(_(u"Order"), default=1)
@@ -3844,11 +3893,18 @@ class Document(OwnPerms, ImageModel, FullSearch, Imported):
def get_query_owns(cls, ishtaruser):
Operation = cls.operations.rel.related_model
ArchaeologicalSite = cls.sites.rel.related_model
- q = cls._construct_query_own(
- 'operations__', Operation._get_query_owns_dicts(ishtaruser)
- ) | cls._construct_query_own(
- 'sites__', ArchaeologicalSite._get_query_owns_dicts(ishtaruser)
+ query_own_list = (
+ ('operations__', Operation._get_query_owns_dicts(ishtaruser)),
+ ('sites__', ArchaeologicalSite._get_query_owns_dicts(ishtaruser)),
)
+ q = None
+ for prefix, owns in query_own_list:
+ subq = cls._construct_query_own(prefix, owns)
+ if subq:
+ if not q:
+ q = subq
+ else:
+ q |= subq
return q
def get_associated_operation(self):
diff --git a/ishtar_common/models_imports.py b/ishtar_common/models_imports.py
index 9aae1d52d..b5ce3323d 100644
--- a/ishtar_common/models_imports.py
+++ b/ishtar_common/models_imports.py
@@ -133,7 +133,7 @@ class ImporterType(models.Model):
ImporterModel, verbose_name=_(u"Models that can accept new items"),
blank=True, help_text=_(u"Leave blank for no restrictions"),
related_name='+')
- is_template = models.BooleanField(_(u"Is template"), default=False)
+ is_template = models.BooleanField(_(u"Can be exported"), default=False)
unicity_keys = models.CharField(_(u"Unicity keys (separator \";\")"),
blank=True, null=True, max_length=500)
available = models.BooleanField(_(u"Available"), default=True)
@@ -629,6 +629,7 @@ class TargetKey(models.Model):
TARGET_MODELS = [
('OrganizationType', _(u"Organization type")),
('ishtar_common.models.OrganizationType', _(u"Organization type")),
+ ('ishtar_common.models.PersonType', _(u"Person type")),
('TitleType', _(u"Title")),
('SourceType', _(u"Source type")),
('AuthorType', _(u"Author type")),
diff --git a/ishtar_common/static/bootstrap/bootstrap.css b/ishtar_common/static/bootstrap/bootstrap.css
index c6407564d..3026e8f4f 100644
--- a/ishtar_common/static/bootstrap/bootstrap.css
+++ b/ishtar_common/static/bootstrap/bootstrap.css
@@ -3,4 +3,4 @@
* Copyright 2011-2018 The Bootstrap Authors
* Copyright 2011-2018 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- */:root{--blue: #007bff;--indigo: #6610f2;--purple: #6f42c1;--pink: #e83e8c;--red: #dc3545;--orange: #fd7e14;--yellow: #ffc107;--green: #28a745;--teal: #20c997;--cyan: #17a2b8;--white: #fff;--gray: #6c757d;--gray-dark: #343a40;--primary: #007bff;--secondary: #6c757d;--success: #28a745;--info: #17a2b8;--warning: #ffc107;--danger: #dc3545;--light: #f8f9fa;--dark: #343a40;--breakpoint-xs: 0;--breakpoint-sm: 576px;--breakpoint-md: 768px;--breakpoint-lg: 992px;--breakpoint-xl: 1200px;--font-family-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";--font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace}*,*::before,*::after{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:rgba(0,0,0,0)}@-ms-viewport{width:device-width}article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus{outline:0 !important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[title],abbr[data-original-title]{text-decoration:underline;text-decoration:underline dotted;cursor:help;border-bottom:0}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul,dl{margin-top:0;margin-bottom:1rem}ol ol,ul ul,ol ul,ul ol{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}dfn{font-style:italic}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#6f3b93;text-decoration:none;background-color:transparent;-webkit-text-decoration-skip:objects}a:hover{color:#542c6f;text-decoration:none}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):hover,a:not([href]):not([tabindex]):focus{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}pre,code,kbd,samp{font-family:monospace, monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg:not(:root){overflow:hidden}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}input,button,select,optgroup,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}button,html [type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button::-moz-focus-inner,[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner{padding:0;border-style:none}input[type="radio"],input[type="checkbox"]{box-sizing:border-box;padding:0}input[type="date"],input[type="time"],input[type="datetime-local"],input[type="month"]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{outline-offset:-2px;-webkit-appearance:none}[type="search"]::-webkit-search-cancel-button,[type="search"]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none !important}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{margin-bottom:.5rem;font-family:inherit;font-weight:500;line-height:1.2;color:inherit}h1,.h1{font-size:2.5rem}h2,.h2{font-size:2rem}h3,.h3{font-size:1.75rem}h4,.h4{font-size:1.5rem}h5,.h5{font-size:1.25rem}h6,.h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem;font-weight:300;line-height:1.2}.display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.display-4{font-size:3.5rem;font-weight:300;line-height:1.2}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,0.1)}small,.small{font-size:80%;font-weight:400}mark,.mark{padding:.2em;background-color:#fcf8e3}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote-footer{display:block;font-size:80%;color:#6c757d}.blockquote-footer::before{content:"\2014 \00A0"}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#6c757d}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}code{font-size:87.5%;color:#e83e8c;word-break:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width: 576px){.container{max-width:540px}}@media (min-width: 768px){.container{max-width:720px}}@media (min-width: 992px){.container{max-width:960px}}@media (min-width: 1200px){.container{max-width:1140px}}.container-fluid{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{display:flex;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*="col-"]{padding-right:0;padding-left:0}.col-1,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-10,.col-11,.col-12,.col,.col-auto,.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm,.col-sm-auto,.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12,.col-md,.col-md-auto,.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg,.col-lg-auto,.col-xl-1,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl,.col-xl-auto{position:relative;width:100%;min-height:1px;padding-right:15px;padding-left:15px}.col{flex-basis:0;flex-grow:1;max-width:100%}.col-auto{flex:0 0 auto;width:auto;max-width:none}.col-1{flex:0 0 8.33333%;max-width:8.33333%}.col-2{flex:0 0 16.66667%;max-width:16.66667%}.col-3{flex:0 0 25%;max-width:25%}.col-4{flex:0 0 33.33333%;max-width:33.33333%}.col-5{flex:0 0 41.66667%;max-width:41.66667%}.col-6{flex:0 0 50%;max-width:50%}.col-7{flex:0 0 58.33333%;max-width:58.33333%}.col-8{flex:0 0 66.66667%;max-width:66.66667%}.col-9{flex:0 0 75%;max-width:75%}.col-10{flex:0 0 83.33333%;max-width:83.33333%}.col-11{flex:0 0 91.66667%;max-width:91.66667%}.col-12{flex:0 0 100%;max-width:100%}.order-first{order:-1}.order-last{order:13}.order-0{order:0}.order-1{order:1}.order-2{order:2}.order-3{order:3}.order-4{order:4}.order-5{order:5}.order-6{order:6}.order-7{order:7}.order-8{order:8}.order-9{order:9}.order-10{order:10}.order-11{order:11}.order-12{order:12}.offset-1{margin-left:8.33333%}.offset-2{margin-left:16.66667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333%}.offset-5{margin-left:41.66667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333%}.offset-8{margin-left:66.66667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333%}.offset-11{margin-left:91.66667%}@media (min-width: 576px){.col-sm{flex-basis:0;flex-grow:1;max-width:100%}.col-sm-auto{flex:0 0 auto;width:auto;max-width:none}.col-sm-1{flex:0 0 8.33333%;max-width:8.33333%}.col-sm-2{flex:0 0 16.66667%;max-width:16.66667%}.col-sm-3{flex:0 0 25%;max-width:25%}.col-sm-4{flex:0 0 33.33333%;max-width:33.33333%}.col-sm-5{flex:0 0 41.66667%;max-width:41.66667%}.col-sm-6{flex:0 0 50%;max-width:50%}.col-sm-7{flex:0 0 58.33333%;max-width:58.33333%}.col-sm-8{flex:0 0 66.66667%;max-width:66.66667%}.col-sm-9{flex:0 0 75%;max-width:75%}.col-sm-10{flex:0 0 83.33333%;max-width:83.33333%}.col-sm-11{flex:0 0 91.66667%;max-width:91.66667%}.col-sm-12{flex:0 0 100%;max-width:100%}.order-sm-first{order:-1}.order-sm-last{order:13}.order-sm-0{order:0}.order-sm-1{order:1}.order-sm-2{order:2}.order-sm-3{order:3}.order-sm-4{order:4}.order-sm-5{order:5}.order-sm-6{order:6}.order-sm-7{order:7}.order-sm-8{order:8}.order-sm-9{order:9}.order-sm-10{order:10}.order-sm-11{order:11}.order-sm-12{order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333%}.offset-sm-2{margin-left:16.66667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333%}.offset-sm-5{margin-left:41.66667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333%}.offset-sm-8{margin-left:66.66667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333%}.offset-sm-11{margin-left:91.66667%}}@media (min-width: 768px){.col-md{flex-basis:0;flex-grow:1;max-width:100%}.col-md-auto{flex:0 0 auto;width:auto;max-width:none}.col-md-1{flex:0 0 8.33333%;max-width:8.33333%}.col-md-2{flex:0 0 16.66667%;max-width:16.66667%}.col-md-3{flex:0 0 25%;max-width:25%}.col-md-4{flex:0 0 33.33333%;max-width:33.33333%}.col-md-5{flex:0 0 41.66667%;max-width:41.66667%}.col-md-6{flex:0 0 50%;max-width:50%}.col-md-7{flex:0 0 58.33333%;max-width:58.33333%}.col-md-8{flex:0 0 66.66667%;max-width:66.66667%}.col-md-9{flex:0 0 75%;max-width:75%}.col-md-10{flex:0 0 83.33333%;max-width:83.33333%}.col-md-11{flex:0 0 91.66667%;max-width:91.66667%}.col-md-12{flex:0 0 100%;max-width:100%}.order-md-first{order:-1}.order-md-last{order:13}.order-md-0{order:0}.order-md-1{order:1}.order-md-2{order:2}.order-md-3{order:3}.order-md-4{order:4}.order-md-5{order:5}.order-md-6{order:6}.order-md-7{order:7}.order-md-8{order:8}.order-md-9{order:9}.order-md-10{order:10}.order-md-11{order:11}.order-md-12{order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333%}.offset-md-2{margin-left:16.66667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333%}.offset-md-5{margin-left:41.66667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333%}.offset-md-8{margin-left:66.66667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333%}.offset-md-11{margin-left:91.66667%}}@media (min-width: 992px){.col-lg{flex-basis:0;flex-grow:1;max-width:100%}.col-lg-auto{flex:0 0 auto;width:auto;max-width:none}.col-lg-1{flex:0 0 8.33333%;max-width:8.33333%}.col-lg-2{flex:0 0 16.66667%;max-width:16.66667%}.col-lg-3{flex:0 0 25%;max-width:25%}.col-lg-4{flex:0 0 33.33333%;max-width:33.33333%}.col-lg-5{flex:0 0 41.66667%;max-width:41.66667%}.col-lg-6{flex:0 0 50%;max-width:50%}.col-lg-7{flex:0 0 58.33333%;max-width:58.33333%}.col-lg-8{flex:0 0 66.66667%;max-width:66.66667%}.col-lg-9{flex:0 0 75%;max-width:75%}.col-lg-10{flex:0 0 83.33333%;max-width:83.33333%}.col-lg-11{flex:0 0 91.66667%;max-width:91.66667%}.col-lg-12{flex:0 0 100%;max-width:100%}.order-lg-first{order:-1}.order-lg-last{order:13}.order-lg-0{order:0}.order-lg-1{order:1}.order-lg-2{order:2}.order-lg-3{order:3}.order-lg-4{order:4}.order-lg-5{order:5}.order-lg-6{order:6}.order-lg-7{order:7}.order-lg-8{order:8}.order-lg-9{order:9}.order-lg-10{order:10}.order-lg-11{order:11}.order-lg-12{order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333%}.offset-lg-2{margin-left:16.66667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333%}.offset-lg-5{margin-left:41.66667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333%}.offset-lg-8{margin-left:66.66667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333%}.offset-lg-11{margin-left:91.66667%}}@media (min-width: 1200px){.col-xl{flex-basis:0;flex-grow:1;max-width:100%}.col-xl-auto{flex:0 0 auto;width:auto;max-width:none}.col-xl-1{flex:0 0 8.33333%;max-width:8.33333%}.col-xl-2{flex:0 0 16.66667%;max-width:16.66667%}.col-xl-3{flex:0 0 25%;max-width:25%}.col-xl-4{flex:0 0 33.33333%;max-width:33.33333%}.col-xl-5{flex:0 0 41.66667%;max-width:41.66667%}.col-xl-6{flex:0 0 50%;max-width:50%}.col-xl-7{flex:0 0 58.33333%;max-width:58.33333%}.col-xl-8{flex:0 0 66.66667%;max-width:66.66667%}.col-xl-9{flex:0 0 75%;max-width:75%}.col-xl-10{flex:0 0 83.33333%;max-width:83.33333%}.col-xl-11{flex:0 0 91.66667%;max-width:91.66667%}.col-xl-12{flex:0 0 100%;max-width:100%}.order-xl-first{order:-1}.order-xl-last{order:13}.order-xl-0{order:0}.order-xl-1{order:1}.order-xl-2{order:2}.order-xl-3{order:3}.order-xl-4{order:4}.order-xl-5{order:5}.order-xl-6{order:6}.order-xl-7{order:7}.order-xl-8{order:8}.order-xl-9{order:9}.order-xl-10{order:10}.order-xl-11{order:11}.order-xl-12{order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333%}.offset-xl-2{margin-left:16.66667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333%}.offset-xl-5{margin-left:41.66667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333%}.offset-xl-8{margin-left:66.66667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333%}.offset-xl-11{margin-left:91.66667%}}.table{width:100%;max-width:100%;margin-bottom:1rem;background-color:rgba(0,0,0,0)}.table th,.table td{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6}.table thead th{vertical-align:bottom;border-bottom:2px solid #dee2e6}.table tbody+tbody{border-top:2px solid #dee2e6}.table .table{background-color:#fff}.table-sm th,.table-sm td{padding:.3rem}.table-bordered{border:1px solid #dee2e6}.table-bordered th,.table-bordered td{border:1px solid #dee2e6}.table-bordered thead th,.table-bordered thead td{border-bottom-width:2px}.table-borderless th,.table-borderless td,.table-borderless thead th,.table-borderless tbody+tbody{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,0.05)}.table-hover tbody tr:hover{background-color:rgba(0,0,0,0.075)}.table-primary,.table-primary>th,.table-primary>td{background-color:#b8daff}.table-hover .table-primary:hover{background-color:#9fcdff}.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#9fcdff}.table-secondary,.table-secondary>th,.table-secondary>td{background-color:#d6d8db}.table-hover .table-secondary:hover{background-color:#c8cbcf}.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#c8cbcf}.table-success,.table-success>th,.table-success>td{background-color:#c3e6cb}.table-hover .table-success:hover{background-color:#b1dfbb}.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b1dfbb}.table-info,.table-info>th,.table-info>td{background-color:#bee5eb}.table-hover .table-info:hover{background-color:#abdde5}.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abdde5}.table-warning,.table-warning>th,.table-warning>td{background-color:#ffeeba}.table-hover .table-warning:hover{background-color:#ffe8a1}.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffe8a1}.table-danger,.table-danger>th,.table-danger>td{background-color:#f5c6cb}.table-hover .table-danger:hover{background-color:#f1b0b7}.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1b0b7}.table-light,.table-light>th,.table-light>td{background-color:#fdfdfe}.table-hover .table-light:hover{background-color:#ececf6}.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>th,.table-dark>td{background-color:#c6c8ca}.table-hover .table-dark:hover{background-color:#b9bbbe}.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b9bbbe}.table-active,.table-active>th,.table-active>td{background-color:rgba(0,0,0,0.075)}.table-hover .table-active:hover{background-color:rgba(0,0,0,0.075)}.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,0.075)}.table .thead-dark th{color:#fff;background-color:#212529;border-color:#32383e}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dee2e6}.table-dark{color:#fff;background-color:#212529}.table-dark th,.table-dark td,.table-dark thead th{border-color:#32383e}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,0.05)}.table-dark.table-hover tbody tr:hover{background-color:rgba(255,255,255,0.075)}@media (max-width: 575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-sm>.table-bordered{border:0}}@media (max-width: 767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-md>.table-bordered{border:0}}@media (max-width: 991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-lg>.table-bordered{border:0}}@media (max-width: 1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:focus{color:#495057;background-color:#fff;border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,0.25)}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}select.form-control:not([size]):not([multiple]){height:calc(2.25rem + 2px)}select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem;line-height:1.5}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding-top:.375rem;padding-bottom:.375rem;margin-bottom:0;line-height:1.5;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-sm,.input-group-sm>.form-control-plaintext.form-control,.input-group-sm>.input-group-prepend>.form-control-plaintext.input-group-text,.input-group-sm>.input-group-append>.form-control-plaintext.input-group-text,.input-group-sm>.input-group-prepend>.form-control-plaintext.btn,.input-group-sm>.input-group-append>.form-control-plaintext.btn,.form-control-plaintext.form-control-lg,.input-group-lg>.form-control-plaintext.form-control,.input-group-lg>.input-group-prepend>.form-control-plaintext.input-group-text,.input-group-lg>.input-group-append>.form-control-plaintext.input-group-text,.input-group-lg>.input-group-prepend>.form-control-plaintext.btn,.input-group-lg>.input-group-append>.form-control-plaintext.btn{padding-right:0;padding-left:0}.form-control-sm,.input-group-sm>.form-control,.input-group-sm>.input-group-prepend>.input-group-text,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-append>.btn{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}select.form-control-sm:not([size]):not([multiple]),.input-group-sm>select.form-control:not([size]):not([multiple]),.input-group-sm>.input-group-prepend>select.input-group-text:not([size]):not([multiple]),.input-group-sm>.input-group-append>select.input-group-text:not([size]):not([multiple]),.input-group-sm>.input-group-prepend>select.btn:not([size]):not([multiple]),.input-group-sm>.input-group-append>select.btn:not([size]):not([multiple]){height:calc(1.8125rem + 2px)}.form-control-lg,.input-group-lg>.form-control,.input-group-lg>.input-group-prepend>.input-group-text,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-append>.btn{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}select.form-control-lg:not([size]):not([multiple]),.input-group-lg>select.form-control:not([size]):not([multiple]),.input-group-lg>.input-group-prepend>select.input-group-text:not([size]):not([multiple]),.input-group-lg>.input-group-append>select.input-group-text:not([size]):not([multiple]),.input-group-lg>.input-group-prepend>select.btn:not([size]):not([multiple]),.input-group-lg>.input-group-append>select.btn:not([size]):not([multiple]){height:calc(2.875rem + 2px)}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:flex;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*="col-"]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input:disabled ~ .form-check-label{color:#6c757d}.form-check-label{margin-bottom:0}.form-check-inline{display:inline-flex;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#28a745}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.5rem;margin-top:.1rem;font-size:.875rem;line-height:1;color:#fff;background-color:rgba(40,167,69,0.8);border-radius:.2rem}.was-validated .form-control:valid,.form-control.is-valid,.was-validated .custom-select:valid,.custom-select.is-valid{border-color:#28a745}.was-validated .form-control:valid:focus,.form-control.is-valid:focus,.was-validated .custom-select:valid:focus,.custom-select.is-valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,0.25)}.was-validated .form-control:valid ~ .valid-feedback,.was-validated .form-control:valid ~ .valid-tooltip,.form-control.is-valid ~ .valid-feedback,.form-control.is-valid ~ .valid-tooltip,.was-validated .custom-select:valid ~ .valid-feedback,.was-validated .custom-select:valid ~ .valid-tooltip,.custom-select.is-valid ~ .valid-feedback,.custom-select.is-valid ~ .valid-tooltip{display:block}.was-validated .form-check-input:valid ~ .form-check-label,.form-check-input.is-valid ~ .form-check-label{color:#28a745}.was-validated .form-check-input:valid ~ .valid-feedback,.was-validated .form-check-input:valid ~ .valid-tooltip,.form-check-input.is-valid ~ .valid-feedback,.form-check-input.is-valid ~ .valid-tooltip{display:block}.was-validated .custom-control-input:valid ~ .custom-control-label,.custom-control-input.is-valid ~ .custom-control-label{color:#28a745}.was-validated .custom-control-input:valid ~ .custom-control-label::before,.custom-control-input.is-valid ~ .custom-control-label::before{background-color:#71dd8a}.was-validated .custom-control-input:valid ~ .valid-feedback,.was-validated .custom-control-input:valid ~ .valid-tooltip,.custom-control-input.is-valid ~ .valid-feedback,.custom-control-input.is-valid ~ .valid-tooltip{display:block}.was-validated .custom-control-input:valid:checked ~ .custom-control-label::before,.custom-control-input.is-valid:checked ~ .custom-control-label::before{background-color:#34ce57}.was-validated .custom-control-input:valid:focus ~ .custom-control-label::before,.custom-control-input.is-valid:focus ~ .custom-control-label::before{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(40,167,69,0.25)}.was-validated .custom-file-input:valid ~ .custom-file-label,.custom-file-input.is-valid ~ .custom-file-label{border-color:#28a745}.was-validated .custom-file-input:valid ~ .custom-file-label::before,.custom-file-input.is-valid ~ .custom-file-label::before{border-color:inherit}.was-validated .custom-file-input:valid ~ .valid-feedback,.was-validated .custom-file-input:valid ~ .valid-tooltip,.custom-file-input.is-valid ~ .valid-feedback,.custom-file-input.is-valid ~ .valid-tooltip{display:block}.was-validated .custom-file-input:valid:focus ~ .custom-file-label,.custom-file-input.is-valid:focus ~ .custom-file-label{box-shadow:0 0 0 .2rem rgba(40,167,69,0.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.5rem;margin-top:.1rem;font-size:.875rem;line-height:1;color:#fff;background-color:rgba(220,53,69,0.8);border-radius:.2rem}.was-validated .form-control:invalid,.form-control.is-invalid,.was-validated .custom-select:invalid,.custom-select.is-invalid{border-color:#dc3545}.was-validated .form-control:invalid:focus,.form-control.is-invalid:focus,.was-validated .custom-select:invalid:focus,.custom-select.is-invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,0.25)}.was-validated .form-control:invalid ~ .invalid-feedback,.was-validated .form-control:invalid ~ .invalid-tooltip,.form-control.is-invalid ~ .invalid-feedback,.form-control.is-invalid ~ .invalid-tooltip,.was-validated .custom-select:invalid ~ .invalid-feedback,.was-validated .custom-select:invalid ~ .invalid-tooltip,.custom-select.is-invalid ~ .invalid-feedback,.custom-select.is-invalid ~ .invalid-tooltip{display:block}.was-validated .form-check-input:invalid ~ .form-check-label,.form-check-input.is-invalid ~ .form-check-label{color:#dc3545}.was-validated .form-check-input:invalid ~ .invalid-feedback,.was-validated .form-check-input:invalid ~ .invalid-tooltip,.form-check-input.is-invalid ~ .invalid-feedback,.form-check-input.is-invalid ~ .invalid-tooltip{display:block}.was-validated .custom-control-input:invalid ~ .custom-control-label,.custom-control-input.is-invalid ~ .custom-control-label{color:#dc3545}.was-validated .custom-control-input:invalid ~ .custom-control-label::before,.custom-control-input.is-invalid ~ .custom-control-label::before{background-color:#efa2a9}.was-validated .custom-control-input:invalid ~ .invalid-feedback,.was-validated .custom-control-input:invalid ~ .invalid-tooltip,.custom-control-input.is-invalid ~ .invalid-feedback,.custom-control-input.is-invalid ~ .invalid-tooltip{display:block}.was-validated .custom-control-input:invalid:checked ~ .custom-control-label::before,.custom-control-input.is-invalid:checked ~ .custom-control-label::before{background-color:#e4606d}.was-validated .custom-control-input:invalid:focus ~ .custom-control-label::before,.custom-control-input.is-invalid:focus ~ .custom-control-label::before{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(220,53,69,0.25)}.was-validated .custom-file-input:invalid ~ .custom-file-label,.custom-file-input.is-invalid ~ .custom-file-label{border-color:#dc3545}.was-validated .custom-file-input:invalid ~ .custom-file-label::before,.custom-file-input.is-invalid ~ .custom-file-label::before{border-color:inherit}.was-validated .custom-file-input:invalid ~ .invalid-feedback,.was-validated .custom-file-input:invalid ~ .invalid-tooltip,.custom-file-input.is-invalid ~ .invalid-feedback,.custom-file-input.is-invalid ~ .invalid-tooltip{display:block}.was-validated .custom-file-input:invalid:focus ~ .custom-file-label,.custom-file-input.is-invalid:focus ~ .custom-file-label{box-shadow:0 0 0 .2rem rgba(220,53,69,0.25)}.form-inline{display:flex;flex-flow:row wrap;align-items:center}.form-inline .form-check{width:100%}@media (min-width: 576px){.form-inline label{display:flex;align-items:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:flex;flex:0 0 auto;flex-flow:row wrap;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .input-group,.form-inline .custom-select{width:auto}.form-inline .form-check{display:flex;align-items:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{align-items:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{display:inline-block;font-weight:400;text-align:center;white-space:nowrap;vertical-align:middle;user-select:none;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}.btn:hover,.btn:focus{text-decoration:none}.btn:focus,.btn.focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,0.25)}.btn.disabled,.btn:disabled{opacity:.65}.btn:not(:disabled):not(.disabled){cursor:pointer}.btn:not(:disabled):not(.disabled):active,.btn:not(:disabled):not(.disabled).active{background-image:none}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}.btn-primary:focus,.btn-primary.focus{box-shadow:0 0 0 .2rem rgba(0,123,255,0.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:not(:disabled):not(.disabled):active,.btn-primary:not(:disabled):not(.disabled).active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}.btn-primary:not(:disabled):not(.disabled):active:focus,.btn-primary:not(:disabled):not(.disabled).active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,0.5)}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.btn-secondary:focus,.btn-secondary.focus{box-shadow:0 0 0 .2rem rgba(108,117,125,0.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:not(:disabled):not(.disabled):active,.btn-secondary:not(:disabled):not(.disabled).active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.btn-secondary:not(:disabled):not(.disabled):active:focus,.btn-secondary:not(:disabled):not(.disabled).active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,0.5)}.btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.btn-success:focus,.btn-success.focus{box-shadow:0 0 0 .2rem rgba(40,167,69,0.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:not(:disabled):not(.disabled):active,.btn-success:not(:disabled):not(.disabled).active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.btn-success:not(:disabled):not(.disabled):active:focus,.btn-success:not(:disabled):not(.disabled).active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,0.5)}.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.btn-info:focus,.btn-info.focus{box-shadow:0 0 0 .2rem rgba(23,162,184,0.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:not(:disabled):not(.disabled):active,.btn-info:not(:disabled):not(.disabled).active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.btn-info:not(:disabled):not(.disabled):active:focus,.btn-info:not(:disabled):not(.disabled).active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,0.5)}.btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.btn-warning:focus,.btn-warning.focus{box-shadow:0 0 0 .2rem rgba(255,193,7,0.5)}.btn-warning.disabled,.btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:not(:disabled):not(.disabled):active,.btn-warning:not(:disabled):not(.disabled).active,.show>.btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.btn-warning:not(:disabled):not(.disabled):active:focus,.btn-warning:not(:disabled):not(.disabled).active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,0.5)}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.btn-danger:focus,.btn-danger.focus{box-shadow:0 0 0 .2rem rgba(220,53,69,0.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:not(:disabled):not(.disabled):active,.btn-danger:not(:disabled):not(.disabled).active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.btn-danger:not(:disabled):not(.disabled):active:focus,.btn-danger:not(:disabled):not(.disabled).active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,0.5)}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light:focus,.btn-light.focus{box-shadow:0 0 0 .2rem rgba(248,249,250,0.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled):active,.btn-light:not(:disabled):not(.disabled).active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled):active:focus,.btn-light:not(:disabled):not(.disabled).active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,0.5)}.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.btn-dark:focus,.btn-dark.focus{box-shadow:0 0 0 .2rem rgba(52,58,64,0.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:not(:disabled):not(.disabled):active,.btn-dark:not(:disabled):not(.disabled).active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark:not(:disabled):not(.disabled):active:focus,.btn-dark:not(:disabled):not(.disabled).active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,0.5)}.btn-outline-primary{color:#007bff;background-color:transparent;background-image:none;border-color:#007bff}.btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary:focus,.btn-outline-primary.focus{box-shadow:0 0 0 .2rem rgba(0,123,255,0.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#007bff;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled):active,.btn-outline-primary:not(:disabled):not(.disabled).active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,0.5)}.btn-outline-secondary{color:#6c757d;background-color:transparent;background-image:none;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary:focus,.btn-outline-secondary.focus{box-shadow:0 0 0 .2rem rgba(108,117,125,0.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled):active,.btn-outline-secondary:not(:disabled):not(.disabled).active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,0.5)}.btn-outline-success{color:#28a745;background-color:transparent;background-image:none;border-color:#28a745}.btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success:focus,.btn-outline-success.focus{box-shadow:0 0 0 .2rem rgba(40,167,69,0.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#28a745;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled):active,.btn-outline-success:not(:disabled):not(.disabled).active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success:not(:disabled):not(.disabled):active:focus,.btn-outline-success:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,0.5)}.btn-outline-info{color:#17a2b8;background-color:transparent;background-image:none;border-color:#17a2b8}.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:focus,.btn-outline-info.focus{box-shadow:0 0 0 .2rem rgba(23,162,184,0.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled):active,.btn-outline-info:not(:disabled):not(.disabled).active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:not(:disabled):not(.disabled):active:focus,.btn-outline-info:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,0.5)}.btn-outline-warning{color:#ffc107;background-color:transparent;background-image:none;border-color:#ffc107}.btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:focus,.btn-outline-warning.focus{box-shadow:0 0 0 .2rem rgba(255,193,7,0.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled):active,.btn-outline-warning:not(:disabled):not(.disabled).active,.show>.btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,0.5)}.btn-outline-danger{color:#dc3545;background-color:transparent;background-image:none;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger:focus,.btn-outline-danger.focus{box-shadow:0 0 0 .2rem rgba(220,53,69,0.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled):active,.btn-outline-danger:not(:disabled):not(.disabled).active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,0.5)}.btn-outline-light{color:#f8f9fa;background-color:transparent;background-image:none;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:focus,.btn-outline-light.focus{box-shadow:0 0 0 .2rem rgba(248,249,250,0.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled):active,.btn-outline-light:not(:disabled):not(.disabled).active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled):active:focus,.btn-outline-light:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,0.5)}.btn-outline-dark{color:#343a40;background-color:transparent;background-image:none;border-color:#343a40}.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:focus,.btn-outline-dark.focus{box-shadow:0 0 0 .2rem rgba(52,58,64,0.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled):active,.btn-outline-dark:not(:disabled):not(.disabled).active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,0.5)}.btn-link{font-weight:400;color:#6f3b93;background-color:transparent}.btn-link:hover{color:#542c6f;text-decoration:none;background-color:transparent;border-color:transparent}.btn-link:focus,.btn-link.focus{text-decoration:none;border-color:transparent;box-shadow:none}.btn-link:disabled,.btn-link.disabled{color:#6c757d}.btn-lg,.btn-group-lg>.btn{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.btn-sm,.btn-group-sm>.btn{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.fade{opacity:0;transition:opacity 0.15s linear}.fade.show{opacity:1}.collapse{display:none}.collapse.show{display:block}tr.collapse.show{display:table-row}tbody.collapse.show{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;transition:height 0.35s ease}.dropup,.dropdown{position:relative}.dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,0.15);border-radius:.25rem}.dropup .dropdown-menu{margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-menu{margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-toggle::after{vertical-align:0}.dropleft .dropdown-menu{margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:""}.dropleft .dropdown-toggle::after{display:none}.dropleft .dropdown-toggle::before{display:inline-block;width:0;height:0;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty::after{margin-left:0}.dropleft .dropdown-toggle::before{vertical-align:0}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:hover,.dropdown-item:focus{color:#16181b;text-decoration:none;background-color:#f8f9fa}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}.dropdown-item.disabled,.dropdown-item:disabled{color:#6c757d;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#212529}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;flex:0 1 auto}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover{z-index:1}.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn.active{z-index:1}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group,.btn-group-vertical .btn+.btn,.btn-group-vertical .btn+.btn-group,.btn-group-vertical .btn-group+.btn,.btn-group-vertical .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:not(:last-child):not(.dropdown-toggle),.btn-group>.btn-group:not(:last-child)>.btn{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:not(:first-child),.btn-group>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after{margin-left:0}.btn-sm+.dropdown-toggle-split,.btn-group-sm>.btn+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-lg+.dropdown-toggle-split,.btn-group-lg>.btn+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical .btn,.btn-group-vertical .btn-group{width:100%}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle),.btn-group-vertical>.btn-group:not(:last-child)>.btn{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:not(:first-child),.btn-group-vertical>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn input[type="radio"],.btn-group-toggle>.btn input[type="checkbox"],.btn-group-toggle>.btn-group>.btn input[type="radio"],.btn-group-toggle>.btn-group>.btn input[type="checkbox"]{position:absolute;clip:rect(0, 0, 0, 0);pointer-events:none}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.form-control,.input-group>.custom-select,.input-group>.custom-file{position:relative;flex:1 1 auto;width:1%;margin-bottom:0}.input-group>.form-control:focus,.input-group>.custom-select:focus,.input-group>.custom-file:focus{z-index:3}.input-group>.form-control+.form-control,.input-group>.form-control+.custom-select,.input-group>.form-control+.custom-file,.input-group>.custom-select+.form-control,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.custom-file,.input-group>.custom-file+.form-control,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.custom-file{margin-left:-1px}.input-group>.form-control:not(:last-child),.input-group>.custom-select:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.form-control:not(:first-child),.input-group>.custom-select:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:flex;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label::before{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label,.input-group>.custom-file:not(:first-child) .custom-file-label::before{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-prepend,.input-group-append{display:flex}.input-group-prepend .btn,.input-group-append .btn{position:relative;z-index:2}.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.input-group-text,.input-group-append .input-group-text+.btn{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:flex;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-text input[type="radio"],.input-group-text input[type="checkbox"]{margin-top:0}.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text,.input-group>.input-group-append:not(:last-child)>.btn,.input-group>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;display:block;min-height:1.5rem;padding-left:1.5rem}.custom-control-inline{display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;z-index:-1;opacity:0}.custom-control-input:checked ~ .custom-control-label::before{color:#fff;background-color:#007bff}.custom-control-input:focus ~ .custom-control-label::before{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,0.25)}.custom-control-input:active ~ .custom-control-label::before{color:#fff;background-color:#b3d7ff}.custom-control-input:disabled ~ .custom-control-label{color:#6c757d}.custom-control-input:disabled ~ .custom-control-label::before{background-color:#e9ecef}.custom-control-label{margin-bottom:0}.custom-control-label::before{position:absolute;top:.25rem;left:0;display:block;width:1rem;height:1rem;pointer-events:none;content:"";user-select:none;background-color:#dee2e6}.custom-control-label::after{position:absolute;top:.25rem;left:0;display:block;width:1rem;height:1rem;content:"";background-repeat:no-repeat;background-position:center center;background-size:50% 50%}.custom-checkbox .custom-control-label::before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked ~ .custom-control-label::before{background-color:#007bff}.custom-checkbox .custom-control-input:checked ~ .custom-control-label::after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E")}.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::before{background-color:#007bff}.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3E%3Cpath stroke='%23fff' d='M0 2h4'/%3E%3C/svg%3E")}.custom-checkbox .custom-control-input:disabled:checked ~ .custom-control-label::before{background-color:rgba(0,123,255,0.5)}.custom-checkbox .custom-control-input:disabled:indeterminate ~ .custom-control-label::before{background-color:rgba(0,123,255,0.5)}.custom-radio .custom-control-label::before{border-radius:50%}.custom-radio .custom-control-input:checked ~ .custom-control-label::before{background-color:#007bff}.custom-radio .custom-control-input:checked ~ .custom-control-label::after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%23fff'/%3E%3C/svg%3E")}.custom-radio .custom-control-input:disabled:checked ~ .custom-control-label::before{background-color:rgba(0,123,255,0.5)}.custom-select{display:inline-block;width:100%;height:calc(2.25rem + 2px);padding:.375rem 1.75rem .375rem .75rem;line-height:1.5;color:#495057;vertical-align:middle;background:#fff url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") no-repeat right .75rem center;background-size:8px 10px;border:1px solid #ced4da;border-radius:.25rem;appearance:none}.custom-select:focus{border-color:#80bdff;outline:0;box-shadow:inset 0 1px 2px rgba(0,0,0,0.075),0 0 5px rgba(128,189,255,0.5)}.custom-select:focus::-ms-value{color:#495057;background-color:#fff}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#6c757d;background-color:#e9ecef}.custom-select::-ms-expand{opacity:0}.custom-select-sm{height:calc(1.8125rem + 2px);padding-top:.375rem;padding-bottom:.375rem;font-size:75%}.custom-select-lg{height:calc(2.875rem + 2px);padding-top:.375rem;padding-bottom:.375rem;font-size:125%}.custom-file{position:relative;display:inline-block;width:100%;height:calc(2.25rem + 2px);margin-bottom:0}.custom-file-input{position:relative;z-index:2;width:100%;height:calc(2.25rem + 2px);margin:0;opacity:0}.custom-file-input:focus ~ .custom-file-control{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,0.25)}.custom-file-input:focus ~ .custom-file-control::before{border-color:#80bdff}.custom-file-input:lang(en) ~ .custom-file-label::after{content:"Browse"}.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(2.25rem + 2px);padding:.375rem .75rem;line-height:1.5;color:#495057;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem}.custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:calc(calc(2.25rem + 2px) - 1px * 2);padding:.375rem .75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-left:1px solid #ced4da;border-radius:0 .25rem .25rem 0}.nav{display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem}.nav-link:hover,.nav-link:focus{text-decoration:none}.nav-link.disabled{color:#6c757d}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-item{margin-bottom:-1px}.nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:hover,.nav-tabs .nav-link:focus{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-link.active,.nav-tabs .nav-item.show .nav-link{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#007bff}.nav-fill .nav-item{flex:1 1 auto;text-align:center}.nav-justified .nav-item{flex-basis:0;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding:.5rem 1rem}.navbar>.container,.navbar>.container-fluid{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}.navbar-nav{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:hover,.navbar-toggler:focus{text-decoration:none}.navbar-toggler:not(:disabled):not(.disabled){cursor:pointer}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:no-repeat center center;background-size:100% 100%}@media (max-width: 575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{padding-right:0;padding-left:0}}@media (min-width: 576px){.navbar-expand-sm{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .dropdown-menu-right{right:0;left:auto}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{flex-wrap:nowrap}.navbar-expand-sm .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.navbar-expand-sm .dropup .dropdown-menu{top:auto;bottom:100%}}@media (max-width: 767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{padding-right:0;padding-left:0}}@media (min-width: 768px){.navbar-expand-md{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .dropdown-menu-right{right:0;left:auto}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{flex-wrap:nowrap}.navbar-expand-md .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}.navbar-expand-md .dropup .dropdown-menu{top:auto;bottom:100%}}@media (max-width: 991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{padding-right:0;padding-left:0}}@media (min-width: 992px){.navbar-expand-lg{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .dropdown-menu-right{right:0;left:auto}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{flex-wrap:nowrap}.navbar-expand-lg .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}.navbar-expand-lg .dropup .dropdown-menu{top:auto;bottom:100%}}@media (max-width: 1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{padding-right:0;padding-left:0}}@media (min-width: 1200px){.navbar-expand-xl{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .dropdown-menu-right{right:0;left:auto}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{flex-wrap:nowrap}.navbar-expand-xl .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}.navbar-expand-xl .dropup .dropdown-menu{top:auto;bottom:100%}}.navbar-expand{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .dropdown-menu-right{right:0;left:auto}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid{flex-wrap:nowrap}.navbar-expand .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-expand .dropup .dropdown-menu{top:auto;bottom:100%}.navbar-light .navbar-brand{color:rgba(0,0,0,0.9)}.navbar-light .navbar-brand:hover,.navbar-light .navbar-brand:focus{color:rgba(0,0,0,0.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,0.5)}.navbar-light .navbar-nav .nav-link:hover,.navbar-light .navbar-nav .nav-link:focus{color:rgba(0,0,0,0.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,0.3)}.navbar-light .navbar-nav .show>.nav-link,.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .nav-link.active{color:rgba(0,0,0,0.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,0.5);border-color:rgba(0,0,0,0.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(0,0,0,0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E")}.navbar-light .navbar-text{color:rgba(0,0,0,0.5)}.navbar-light .navbar-text a{color:rgba(0,0,0,0.9)}.navbar-light .navbar-text a:hover,.navbar-light .navbar-text a:focus{color:rgba(0,0,0,0.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:hover,.navbar-dark .navbar-brand:focus{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,0.5)}.navbar-dark .navbar-nav .nav-link:hover,.navbar-dark .navbar-nav .nav-link:focus{color:rgba(255,255,255,0.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,0.25)}.navbar-dark .navbar-nav .show>.nav-link,.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .nav-link.active{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,0.5);border-color:rgba(255,255,255,0.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(255,255,255,0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E")}.navbar-dark .navbar-text{color:rgba(255,255,255,0.5)}.navbar-dark .navbar-text a{color:#fff}.navbar-dark .navbar-text a:hover,.navbar-dark .navbar-text a:focus{color:#fff}.card{position:relative;display:flex;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,0.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group:first-child .list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card>.list-group:last-child .list-group-item:last-child{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.card-body{flex:1 1 auto;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:rgba(0,0,0,0.03);border-bottom:1px solid rgba(0,0,0,0.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-header+.list-group .list-group-item:first-child{border-top:0}.card-footer{padding:.75rem 1.25rem;background-color:rgba(0,0,0,0.03);border-top:1px solid rgba(0,0,0,0.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.75rem;margin-left:-.625rem;border-bottom:0}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem}.card-img{width:100%;border-radius:calc(.25rem - 1px)}.card-img-top{width:100%;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img-bottom{width:100%;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-deck{display:flex;flex-direction:column}.card-deck .card{margin-bottom:15px}@media (min-width: 576px){.card-deck{flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.card-deck .card{display:flex;flex:1 0 0%;flex-direction:column;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group{display:flex;flex-direction:column}.card-group>.card{margin-bottom:15px}@media (min-width: 576px){.card-group{flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:first-child{border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:first-child .card-img-top,.card-group>.card:first-child .card-header{border-top-right-radius:0}.card-group>.card:first-child .card-img-bottom,.card-group>.card:first-child .card-footer{border-bottom-right-radius:0}.card-group>.card:last-child{border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:last-child .card-img-top,.card-group>.card:last-child .card-header{border-top-left-radius:0}.card-group>.card:last-child .card-img-bottom,.card-group>.card:last-child .card-footer{border-bottom-left-radius:0}.card-group>.card:only-child{border-radius:.25rem}.card-group>.card:only-child .card-img-top,.card-group>.card:only-child .card-header{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card-group>.card:only-child .card-img-bottom,.card-group>.card:only-child .card-footer{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.card-group>.card:not(:first-child):not(:last-child):not(:only-child){border-radius:0}.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-img-top,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-img-bottom,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-header,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-footer{border-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width: 576px){.card-columns{column-count:3;column-gap:1.25rem}.card-columns .card{display:inline-block;width:100%}}.breadcrumb{display:flex;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item+.breadcrumb-item::before{display:inline-block;padding-right:.5rem;padding-left:.5rem;color:#6c757d;content:"/"}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none}.breadcrumb-item.active{color:#6c757d}.pagination{display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#6f3b93;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{z-index:2;color:#542c6f;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:2;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,0.25)}.page-link:not(:disabled):not(.disabled){cursor:pointer}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-item.active .page-link{z-index:1;color:#fff;background-color:#007bff;border-color:#007bff}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#007bff}.badge-primary[href]:hover,.badge-primary[href]:focus{color:#fff;text-decoration:none;background-color:#0062cc}.badge-secondary{color:#fff;background-color:#6c757d}.badge-secondary[href]:hover,.badge-secondary[href]:focus{color:#fff;text-decoration:none;background-color:#545b62}.badge-success{color:#fff;background-color:#28a745}.badge-success[href]:hover,.badge-success[href]:focus{color:#fff;text-decoration:none;background-color:#1e7e34}.badge-info{color:#fff;background-color:#17a2b8}.badge-info[href]:hover,.badge-info[href]:focus{color:#fff;text-decoration:none;background-color:#117a8b}.badge-warning{color:#212529;background-color:#ffc107}.badge-warning[href]:hover,.badge-warning[href]:focus{color:#212529;text-decoration:none;background-color:#d39e00}.badge-danger{color:#fff;background-color:#dc3545}.badge-danger[href]:hover,.badge-danger[href]:focus{color:#fff;text-decoration:none;background-color:#bd2130}.badge-light{color:#212529;background-color:#f8f9fa}.badge-light[href]:hover,.badge-light[href]:focus{color:#212529;text-decoration:none;background-color:#dae0e5}.badge-dark{color:#fff;background-color:#343a40}.badge-dark[href]:hover,.badge-dark[href]:focus{color:#fff;text-decoration:none;background-color:#1d2124}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:.3rem}@media (min-width: 576px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{position:absolute;top:0;right:0;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.alert-primary hr{border-top-color:#9fcdff}.alert-primary .alert-link{color:#002752}.alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.alert-secondary hr{border-top-color:#c8cbcf}.alert-secondary .alert-link{color:#202326}.alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.alert-success hr{border-top-color:#b1dfbb}.alert-success .alert-link{color:#0b2e13}.alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.alert-info hr{border-top-color:#abdde5}.alert-info .alert-link{color:#062c33}.alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.alert-warning hr{border-top-color:#ffe8a1}.alert-warning .alert-link{color:#533f03}.alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.alert-danger hr{border-top-color:#f1b0b7}.alert-danger .alert-link{color:#491217}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark hr{border-top-color:#b9bbbe}.alert-dark .alert-link{color:#040505}@keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}.progress{display:flex;height:1rem;overflow:hidden;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.progress-bar{display:flex;flex-direction:column;justify-content:center;color:#fff;text-align:center;background-color:#007bff;transition:width 0.6s ease}.progress-bar-striped{background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-size:1rem 1rem}.progress-bar-animated{animation:progress-bar-stripes 1s linear infinite}.media{display:flex;align-items:flex-start}.media-body{flex:1}.list-group{display:flex;flex-direction:column;padding-left:0;margin-bottom:0}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:hover,.list-group-item-action:focus{color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;margin-bottom:-1px;background-color:#fff;border:1px solid rgba(0,0,0,0.125)}.list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.list-group-item:hover,.list-group-item:focus{z-index:1;text-decoration:none}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}.list-group-flush .list-group-item{border-right:0;border-left:0;border-radius:0}.list-group-flush:first-child .list-group-item:first-child{border-top:0}.list-group-flush:last-child .list-group-item:last-child{border-bottom:0}.list-group-item-primary{color:#004085;background-color:#b8daff}.list-group-item-primary.list-group-item-action:hover,.list-group-item-primary.list-group-item-action:focus{color:#004085;background-color:#9fcdff}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004085;border-color:#004085}.list-group-item-secondary{color:#383d41;background-color:#d6d8db}.list-group-item-secondary.list-group-item-action:hover,.list-group-item-secondary.list-group-item-action:focus{color:#383d41;background-color:#c8cbcf}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}.list-group-item-success{color:#155724;background-color:#c3e6cb}.list-group-item-success.list-group-item-action:hover,.list-group-item-success.list-group-item-action:focus{color:#155724;background-color:#b1dfbb}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}.list-group-item-info{color:#0c5460;background-color:#bee5eb}.list-group-item-info.list-group-item-action:hover,.list-group-item-info.list-group-item-action:focus{color:#0c5460;background-color:#abdde5}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}.list-group-item-warning{color:#856404;background-color:#ffeeba}.list-group-item-warning.list-group-item-action:hover,.list-group-item-warning.list-group-item-action:focus{color:#856404;background-color:#ffe8a1}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}.list-group-item-danger{color:#721c24;background-color:#f5c6cb}.list-group-item-danger.list-group-item-action:hover,.list-group-item-danger.list-group-item-action:focus{color:#721c24;background-color:#f1b0b7}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}.list-group-item-light{color:#818182;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:hover,.list-group-item-light.list-group-item-action:focus{color:#818182;background-color:#ececf6}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}.list-group-item-dark.list-group-item-action:hover,.list-group-item-dark.list-group-item-action:focus{color:#1b1e21;background-color:#b9bbbe}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:hover,.close:focus{color:#000;text-decoration:none;opacity:.75}.close:not(:disabled):not(.disabled){cursor:pointer}button.close{padding:0;background-color:transparent;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;outline:0}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:transform 0.3s ease-out;transform:translate(0, -25%)}.modal.show .modal-dialog{transform:translate(0, 0)}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - (.5rem * 2))}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,0.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:flex;align-items:flex-start;justify-content:space-between;padding:1rem;border-bottom:1px solid #e9ecef;border-top-left-radius:.3rem;border-top-right-radius:.3rem}.modal-header .close{padding:1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;flex:1 1 auto;padding:1rem}.modal-footer{display:flex;align-items:center;justify-content:flex-end;padding:1rem;border-top:1px solid #e9ecef}.modal-footer>:not(:first-child){margin-left:.25rem}.modal-footer>:not(:last-child){margin-right:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width: 576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-centered{min-height:calc(100% - (1.75rem * 2))}.modal-sm{max-width:300px}}@media (min-width: 992px){.modal-lg{max-width:800px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-top,.bs-tooltip-auto[x-placement^="top"]{padding:.4rem 0}.bs-tooltip-top .arrow,.bs-tooltip-auto[x-placement^="top"] .arrow{bottom:0}.bs-tooltip-top .arrow::before,.bs-tooltip-auto[x-placement^="top"] .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-right,.bs-tooltip-auto[x-placement^="right"]{padding:0 .4rem}.bs-tooltip-right .arrow,.bs-tooltip-auto[x-placement^="right"] .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-right .arrow::before,.bs-tooltip-auto[x-placement^="right"] .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-bottom,.bs-tooltip-auto[x-placement^="bottom"]{padding:.4rem 0}.bs-tooltip-bottom .arrow,.bs-tooltip-auto[x-placement^="bottom"] .arrow{top:0}.bs-tooltip-bottom .arrow::before,.bs-tooltip-auto[x-placement^="bottom"] .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-left,.bs-tooltip-auto[x-placement^="left"]{padding:0 .4rem}.bs-tooltip-left .arrow,.bs-tooltip-auto[x-placement^="left"] .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-left .arrow::before,.bs-tooltip-auto[x-placement^="left"] .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,0.2);border-radius:.3rem}.popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}.popover .arrow::before,.popover .arrow::after{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-top,.bs-popover-auto[x-placement^="top"]{margin-bottom:.5rem}.bs-popover-top .arrow,.bs-popover-auto[x-placement^="top"] .arrow{bottom:calc((.5rem + 1px) * -1)}.bs-popover-top .arrow::before,.bs-popover-auto[x-placement^="top"] .arrow::before,.bs-popover-top .arrow::after,.bs-popover-auto[x-placement^="top"] .arrow::after{border-width:.5rem .5rem 0}.bs-popover-top .arrow::before,.bs-popover-auto[x-placement^="top"] .arrow::before{bottom:0;border-top-color:rgba(0,0,0,0.25)}.bs-popover-top .arrow::after,.bs-popover-auto[x-placement^="top"] .arrow::after{bottom:1px;border-top-color:#fff}.bs-popover-right,.bs-popover-auto[x-placement^="right"]{margin-left:.5rem}.bs-popover-right .arrow,.bs-popover-auto[x-placement^="right"] .arrow{left:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-right .arrow::before,.bs-popover-auto[x-placement^="right"] .arrow::before,.bs-popover-right .arrow::after,.bs-popover-auto[x-placement^="right"] .arrow::after{border-width:.5rem .5rem .5rem 0}.bs-popover-right .arrow::before,.bs-popover-auto[x-placement^="right"] .arrow::before{left:0;border-right-color:rgba(0,0,0,0.25)}.bs-popover-right .arrow::after,.bs-popover-auto[x-placement^="right"] .arrow::after{left:1px;border-right-color:#fff}.bs-popover-bottom,.bs-popover-auto[x-placement^="bottom"]{margin-top:.5rem}.bs-popover-bottom .arrow,.bs-popover-auto[x-placement^="bottom"] .arrow{top:calc((.5rem + 1px) * -1)}.bs-popover-bottom .arrow::before,.bs-popover-auto[x-placement^="bottom"] .arrow::before,.bs-popover-bottom .arrow::after,.bs-popover-auto[x-placement^="bottom"] .arrow::after{border-width:0 .5rem .5rem .5rem}.bs-popover-bottom .arrow::before,.bs-popover-auto[x-placement^="bottom"] .arrow::before{top:0;border-bottom-color:rgba(0,0,0,0.25)}.bs-popover-bottom .arrow::after,.bs-popover-auto[x-placement^="bottom"] .arrow::after{top:1px;border-bottom-color:#fff}.bs-popover-bottom .popover-header::before,.bs-popover-auto[x-placement^="bottom"] .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7}.bs-popover-left,.bs-popover-auto[x-placement^="left"]{margin-right:.5rem}.bs-popover-left .arrow,.bs-popover-auto[x-placement^="left"] .arrow{right:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-left .arrow::before,.bs-popover-auto[x-placement^="left"] .arrow::before,.bs-popover-left .arrow::after,.bs-popover-auto[x-placement^="left"] .arrow::after{border-width:.5rem 0 .5rem .5rem}.bs-popover-left .arrow::before,.bs-popover-auto[x-placement^="left"] .arrow::before{right:0;border-left-color:rgba(0,0,0,0.25)}.bs-popover-left .arrow::after,.bs-popover-auto[x-placement^="left"] .arrow::after{right:1px;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;color:inherit;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#212529}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-item{position:relative;display:none;align-items:center;width:100%;transition:transform 0.6s ease;backface-visibility:hidden;perspective:1000px}.carousel-item.active,.carousel-item-next,.carousel-item-prev{display:block}.carousel-item-next,.carousel-item-prev{position:absolute;top:0}.carousel-item-next.carousel-item-left,.carousel-item-prev.carousel-item-right{transform:translateX(0)}@supports (transform-style: preserve-3d){.carousel-item-next.carousel-item-left,.carousel-item-prev.carousel-item-right{transform:translate3d(0, 0, 0)}}.carousel-item-next,.active.carousel-item-right{transform:translateX(100%)}@supports (transform-style: preserve-3d){.carousel-item-next,.active.carousel-item-right{transform:translate3d(100%, 0, 0)}}.carousel-item-prev,.active.carousel-item-left{transform:translateX(-100%)}@supports (transform-style: preserve-3d){.carousel-item-prev,.active.carousel-item-left{transform:translate3d(-100%, 0, 0)}}.carousel-fade .carousel-item{opacity:0;transition-duration:.6s;transition-property:opacity}.carousel-fade .carousel-item.active,.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right{opacity:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{opacity:0}.carousel-fade .carousel-item-next,.carousel-fade .carousel-item-prev,.carousel-fade .carousel-item.active,.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-prev{transform:translateX(0)}@supports (transform-style: preserve-3d){.carousel-fade .carousel-item-next,.carousel-fade .carousel-item-prev,.carousel-fade .carousel-item.active,.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-prev{transform:translate3d(0, 0, 0)}}.carousel-control-prev,.carousel-control-next{position:absolute;top:0;bottom:0;display:flex;align-items:center;justify-content:center;width:15%;color:#fff;text-align:center;opacity:.5}.carousel-control-prev:hover,.carousel-control-prev:focus,.carousel-control-next:hover,.carousel-control-next:focus{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-prev-icon,.carousel-control-next-icon{display:inline-block;width:20px;height:20px;background:transparent no-repeat center center;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3E%3C/svg%3E")}.carousel-control-next-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3E%3C/svg%3E")}.carousel-indicators{position:absolute;right:0;bottom:10px;left:0;z-index:15;display:flex;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{position:relative;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;background-color:rgba(255,255,255,0.5)}.carousel-indicators li::before{position:absolute;top:-10px;left:0;display:inline-block;width:100%;height:10px;content:""}.carousel-indicators li::after{position:absolute;bottom:-10px;left:0;display:inline-block;width:100%;height:10px;content:""}.carousel-indicators .active{background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}.align-baseline{vertical-align:baseline !important}.align-top{vertical-align:top !important}.align-middle{vertical-align:middle !important}.align-bottom{vertical-align:bottom !important}.align-text-bottom{vertical-align:text-bottom !important}.align-text-top{vertical-align:text-top !important}.bg-primary{background-color:#007bff !important}a.bg-primary:hover,a.bg-primary:focus,button.bg-primary:hover,button.bg-primary:focus{background-color:#0062cc !important}.bg-secondary{background-color:#6c757d !important}a.bg-secondary:hover,a.bg-secondary:focus,button.bg-secondary:hover,button.bg-secondary:focus{background-color:#545b62 !important}.bg-success{background-color:#28a745 !important}a.bg-success:hover,a.bg-success:focus,button.bg-success:hover,button.bg-success:focus{background-color:#1e7e34 !important}.bg-info{background-color:#17a2b8 !important}a.bg-info:hover,a.bg-info:focus,button.bg-info:hover,button.bg-info:focus{background-color:#117a8b !important}.bg-warning{background-color:#ffc107 !important}a.bg-warning:hover,a.bg-warning:focus,button.bg-warning:hover,button.bg-warning:focus{background-color:#d39e00 !important}.bg-danger{background-color:#dc3545 !important}a.bg-danger:hover,a.bg-danger:focus,button.bg-danger:hover,button.bg-danger:focus{background-color:#bd2130 !important}.bg-light{background-color:#f8f9fa !important}a.bg-light:hover,a.bg-light:focus,button.bg-light:hover,button.bg-light:focus{background-color:#dae0e5 !important}.bg-dark{background-color:#343a40 !important}a.bg-dark:hover,a.bg-dark:focus,button.bg-dark:hover,button.bg-dark:focus{background-color:#1d2124 !important}.bg-white{background-color:#fff !important}.bg-transparent{background-color:transparent !important}.border{border:1px solid #dee2e6 !important}.border-top{border-top:1px solid #dee2e6 !important}.border-right{border-right:1px solid #dee2e6 !important}.border-bottom{border-bottom:1px solid #dee2e6 !important}.border-left{border-left:1px solid #dee2e6 !important}.border-0{border:0 !important}.border-top-0{border-top:0 !important}.border-right-0{border-right:0 !important}.border-bottom-0{border-bottom:0 !important}.border-left-0{border-left:0 !important}.border-primary{border-color:#007bff !important}.border-secondary{border-color:#6c757d !important}.border-success{border-color:#28a745 !important}.border-info{border-color:#17a2b8 !important}.border-warning{border-color:#ffc107 !important}.border-danger{border-color:#dc3545 !important}.border-light{border-color:#f8f9fa !important}.border-dark{border-color:#343a40 !important}.border-white{border-color:#fff !important}.rounded{border-radius:.25rem !important}.rounded-top{border-top-left-radius:.25rem !important;border-top-right-radius:.25rem !important}.rounded-right{border-top-right-radius:.25rem !important;border-bottom-right-radius:.25rem !important}.rounded-bottom{border-bottom-right-radius:.25rem !important;border-bottom-left-radius:.25rem !important}.rounded-left{border-top-left-radius:.25rem !important;border-bottom-left-radius:.25rem !important}.rounded-circle{border-radius:50% !important}.rounded-0{border-radius:0 !important}.clearfix::after{display:block;clear:both;content:""}.d-none{display:none !important}.d-inline{display:inline !important}.d-inline-block{display:inline-block !important}.d-block{display:block !important}.d-table{display:table !important}.d-table-row{display:table-row !important}.d-table-cell{display:table-cell !important}.d-flex{display:flex !important}.d-inline-flex{display:inline-flex !important}@media (min-width: 576px){.d-sm-none{display:none !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-block{display:block !important}.d-sm-table{display:table !important}.d-sm-table-row{display:table-row !important}.d-sm-table-cell{display:table-cell !important}.d-sm-flex{display:flex !important}.d-sm-inline-flex{display:inline-flex !important}}@media (min-width: 768px){.d-md-none{display:none !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-block{display:block !important}.d-md-table{display:table !important}.d-md-table-row{display:table-row !important}.d-md-table-cell{display:table-cell !important}.d-md-flex{display:flex !important}.d-md-inline-flex{display:inline-flex !important}}@media (min-width: 992px){.d-lg-none{display:none !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-block{display:block !important}.d-lg-table{display:table !important}.d-lg-table-row{display:table-row !important}.d-lg-table-cell{display:table-cell !important}.d-lg-flex{display:flex !important}.d-lg-inline-flex{display:inline-flex !important}}@media (min-width: 1200px){.d-xl-none{display:none !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-block{display:block !important}.d-xl-table{display:table !important}.d-xl-table-row{display:table-row !important}.d-xl-table-cell{display:table-cell !important}.d-xl-flex{display:flex !important}.d-xl-inline-flex{display:inline-flex !important}}@media print{.d-print-none{display:none !important}.d-print-inline{display:inline !important}.d-print-inline-block{display:inline-block !important}.d-print-block{display:block !important}.d-print-table{display:table !important}.d-print-table-row{display:table-row !important}.d-print-table-cell{display:table-cell !important}.d-print-flex{display:flex !important}.d-print-inline-flex{display:inline-flex !important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive::before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive iframe,.embed-responsive embed,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9::before{padding-top:42.85714%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-4by3::before{padding-top:75%}.embed-responsive-1by1::before{padding-top:100%}.flex-row{flex-direction:row !important}.flex-column{flex-direction:column !important}.flex-row-reverse{flex-direction:row-reverse !important}.flex-column-reverse{flex-direction:column-reverse !important}.flex-wrap{flex-wrap:wrap !important}.flex-nowrap{flex-wrap:nowrap !important}.flex-wrap-reverse{flex-wrap:wrap-reverse !important}.flex-fill{flex:1 1 auto !important}.justify-content-start{justify-content:flex-start !important}.justify-content-end{justify-content:flex-end !important}.justify-content-center{justify-content:center !important}.justify-content-between{justify-content:space-between !important}.justify-content-around{justify-content:space-around !important}.align-items-start{align-items:flex-start !important}.align-items-end{align-items:flex-end !important}.align-items-center{align-items:center !important}.align-items-baseline{align-items:baseline !important}.align-items-stretch{align-items:stretch !important}.align-content-start{align-content:flex-start !important}.align-content-end{align-content:flex-end !important}.align-content-center{align-content:center !important}.align-content-between{align-content:space-between !important}.align-content-around{align-content:space-around !important}.align-content-stretch{align-content:stretch !important}.align-self-auto{align-self:auto !important}.align-self-start{align-self:flex-start !important}.align-self-end{align-self:flex-end !important}.align-self-center{align-self:center !important}.align-self-baseline{align-self:baseline !important}.align-self-stretch{align-self:stretch !important}@media (min-width: 576px){.flex-sm-row{flex-direction:row !important}.flex-sm-column{flex-direction:column !important}.flex-sm-row-reverse{flex-direction:row-reverse !important}.flex-sm-column-reverse{flex-direction:column-reverse !important}.flex-sm-wrap{flex-wrap:wrap !important}.flex-sm-nowrap{flex-wrap:nowrap !important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse !important}.flex-sm-fill{flex:1 1 auto !important}.justify-content-sm-start{justify-content:flex-start !important}.justify-content-sm-end{justify-content:flex-end !important}.justify-content-sm-center{justify-content:center !important}.justify-content-sm-between{justify-content:space-between !important}.justify-content-sm-around{justify-content:space-around !important}.align-items-sm-start{align-items:flex-start !important}.align-items-sm-end{align-items:flex-end !important}.align-items-sm-center{align-items:center !important}.align-items-sm-baseline{align-items:baseline !important}.align-items-sm-stretch{align-items:stretch !important}.align-content-sm-start{align-content:flex-start !important}.align-content-sm-end{align-content:flex-end !important}.align-content-sm-center{align-content:center !important}.align-content-sm-between{align-content:space-between !important}.align-content-sm-around{align-content:space-around !important}.align-content-sm-stretch{align-content:stretch !important}.align-self-sm-auto{align-self:auto !important}.align-self-sm-start{align-self:flex-start !important}.align-self-sm-end{align-self:flex-end !important}.align-self-sm-center{align-self:center !important}.align-self-sm-baseline{align-self:baseline !important}.align-self-sm-stretch{align-self:stretch !important}}@media (min-width: 768px){.flex-md-row{flex-direction:row !important}.flex-md-column{flex-direction:column !important}.flex-md-row-reverse{flex-direction:row-reverse !important}.flex-md-column-reverse{flex-direction:column-reverse !important}.flex-md-wrap{flex-wrap:wrap !important}.flex-md-nowrap{flex-wrap:nowrap !important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse !important}.flex-md-fill{flex:1 1 auto !important}.justify-content-md-start{justify-content:flex-start !important}.justify-content-md-end{justify-content:flex-end !important}.justify-content-md-center{justify-content:center !important}.justify-content-md-between{justify-content:space-between !important}.justify-content-md-around{justify-content:space-around !important}.align-items-md-start{align-items:flex-start !important}.align-items-md-end{align-items:flex-end !important}.align-items-md-center{align-items:center !important}.align-items-md-baseline{align-items:baseline !important}.align-items-md-stretch{align-items:stretch !important}.align-content-md-start{align-content:flex-start !important}.align-content-md-end{align-content:flex-end !important}.align-content-md-center{align-content:center !important}.align-content-md-between{align-content:space-between !important}.align-content-md-around{align-content:space-around !important}.align-content-md-stretch{align-content:stretch !important}.align-self-md-auto{align-self:auto !important}.align-self-md-start{align-self:flex-start !important}.align-self-md-end{align-self:flex-end !important}.align-self-md-center{align-self:center !important}.align-self-md-baseline{align-self:baseline !important}.align-self-md-stretch{align-self:stretch !important}}@media (min-width: 992px){.flex-lg-row{flex-direction:row !important}.flex-lg-column{flex-direction:column !important}.flex-lg-row-reverse{flex-direction:row-reverse !important}.flex-lg-column-reverse{flex-direction:column-reverse !important}.flex-lg-wrap{flex-wrap:wrap !important}.flex-lg-nowrap{flex-wrap:nowrap !important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse !important}.flex-lg-fill{flex:1 1 auto !important}.justify-content-lg-start{justify-content:flex-start !important}.justify-content-lg-end{justify-content:flex-end !important}.justify-content-lg-center{justify-content:center !important}.justify-content-lg-between{justify-content:space-between !important}.justify-content-lg-around{justify-content:space-around !important}.align-items-lg-start{align-items:flex-start !important}.align-items-lg-end{align-items:flex-end !important}.align-items-lg-center{align-items:center !important}.align-items-lg-baseline{align-items:baseline !important}.align-items-lg-stretch{align-items:stretch !important}.align-content-lg-start{align-content:flex-start !important}.align-content-lg-end{align-content:flex-end !important}.align-content-lg-center{align-content:center !important}.align-content-lg-between{align-content:space-between !important}.align-content-lg-around{align-content:space-around !important}.align-content-lg-stretch{align-content:stretch !important}.align-self-lg-auto{align-self:auto !important}.align-self-lg-start{align-self:flex-start !important}.align-self-lg-end{align-self:flex-end !important}.align-self-lg-center{align-self:center !important}.align-self-lg-baseline{align-self:baseline !important}.align-self-lg-stretch{align-self:stretch !important}}@media (min-width: 1200px){.flex-xl-row{flex-direction:row !important}.flex-xl-column{flex-direction:column !important}.flex-xl-row-reverse{flex-direction:row-reverse !important}.flex-xl-column-reverse{flex-direction:column-reverse !important}.flex-xl-wrap{flex-wrap:wrap !important}.flex-xl-nowrap{flex-wrap:nowrap !important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse !important}.flex-xl-fill{flex:1 1 auto !important}.justify-content-xl-start{justify-content:flex-start !important}.justify-content-xl-end{justify-content:flex-end !important}.justify-content-xl-center{justify-content:center !important}.justify-content-xl-between{justify-content:space-between !important}.justify-content-xl-around{justify-content:space-around !important}.align-items-xl-start{align-items:flex-start !important}.align-items-xl-end{align-items:flex-end !important}.align-items-xl-center{align-items:center !important}.align-items-xl-baseline{align-items:baseline !important}.align-items-xl-stretch{align-items:stretch !important}.align-content-xl-start{align-content:flex-start !important}.align-content-xl-end{align-content:flex-end !important}.align-content-xl-center{align-content:center !important}.align-content-xl-between{align-content:space-between !important}.align-content-xl-around{align-content:space-around !important}.align-content-xl-stretch{align-content:stretch !important}.align-self-xl-auto{align-self:auto !important}.align-self-xl-start{align-self:flex-start !important}.align-self-xl-end{align-self:flex-end !important}.align-self-xl-center{align-self:center !important}.align-self-xl-baseline{align-self:baseline !important}.align-self-xl-stretch{align-self:stretch !important}}.float-left{float:left !important}.float-right{float:right !important}.float-none{float:none !important}@media (min-width: 576px){.float-sm-left{float:left !important}.float-sm-right{float:right !important}.float-sm-none{float:none !important}}@media (min-width: 768px){.float-md-left{float:left !important}.float-md-right{float:right !important}.float-md-none{float:none !important}}@media (min-width: 992px){.float-lg-left{float:left !important}.float-lg-right{float:right !important}.float-lg-none{float:none !important}}@media (min-width: 1200px){.float-xl-left{float:left !important}.float-xl-right{float:right !important}.float-xl-none{float:none !important}}.position-static{position:static !important}.position-relative{position:relative !important}.position-absolute{position:absolute !important}.position-fixed{position:fixed !important}.position-sticky{position:sticky !important}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}@supports (position: sticky){.sticky-top{position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;clip-path:inset(50%);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal;clip-path:none}.w-25{width:25% !important}.w-50{width:50% !important}.w-75{width:75% !important}.w-100{width:100% !important}.w-auto{width:auto !important}.h-25{height:25% !important}.h-50{height:50% !important}.h-75{height:75% !important}.h-100{height:100% !important}.h-auto{height:auto !important}.mw-100{max-width:100% !important}.mh-100{max-height:100% !important}.m-0{margin:0 !important}.mt-0,.my-0{margin-top:0 !important}.mr-0,.mx-0{margin-right:0 !important}.mb-0,.my-0{margin-bottom:0 !important}.ml-0,.mx-0{margin-left:0 !important}.m-1{margin:.25rem !important}.mt-1,.my-1{margin-top:.25rem !important}.mr-1,.mx-1{margin-right:.25rem !important}.mb-1,.my-1{margin-bottom:.25rem !important}.ml-1,.mx-1{margin-left:.25rem !important}.m-2{margin:.5rem !important}.mt-2,.my-2{margin-top:.5rem !important}.mr-2,.mx-2{margin-right:.5rem !important}.mb-2,.my-2{margin-bottom:.5rem !important}.ml-2,.mx-2{margin-left:.5rem !important}.m-3{margin:1rem !important}.mt-3,.my-3{margin-top:1rem !important}.mr-3,.mx-3{margin-right:1rem !important}.mb-3,.my-3{margin-bottom:1rem !important}.ml-3,.mx-3{margin-left:1rem !important}.m-4{margin:1.5rem !important}.mt-4,.my-4{margin-top:1.5rem !important}.mr-4,.mx-4{margin-right:1.5rem !important}.mb-4,.my-4{margin-bottom:1.5rem !important}.ml-4,.mx-4{margin-left:1.5rem !important}.m-5{margin:3rem !important}.mt-5,.my-5{margin-top:3rem !important}.mr-5,.mx-5{margin-right:3rem !important}.mb-5,.my-5{margin-bottom:3rem !important}.ml-5,.mx-5{margin-left:3rem !important}.p-0{padding:0 !important}.pt-0,.py-0{padding-top:0 !important}.pr-0,.px-0{padding-right:0 !important}.pb-0,.py-0{padding-bottom:0 !important}.pl-0,.px-0{padding-left:0 !important}.p-1{padding:.25rem !important}.pt-1,.py-1{padding-top:.25rem !important}.pr-1,.px-1{padding-right:.25rem !important}.pb-1,.py-1{padding-bottom:.25rem !important}.pl-1,.px-1{padding-left:.25rem !important}.p-2{padding:.5rem !important}.pt-2,.py-2{padding-top:.5rem !important}.pr-2,.px-2{padding-right:.5rem !important}.pb-2,.py-2{padding-bottom:.5rem !important}.pl-2,.px-2{padding-left:.5rem !important}.p-3{padding:1rem !important}.pt-3,.py-3{padding-top:1rem !important}.pr-3,.px-3{padding-right:1rem !important}.pb-3,.py-3{padding-bottom:1rem !important}.pl-3,.px-3{padding-left:1rem !important}.p-4{padding:1.5rem !important}.pt-4,.py-4{padding-top:1.5rem !important}.pr-4,.px-4{padding-right:1.5rem !important}.pb-4,.py-4{padding-bottom:1.5rem !important}.pl-4,.px-4{padding-left:1.5rem !important}.p-5{padding:3rem !important}.pt-5,.py-5{padding-top:3rem !important}.pr-5,.px-5{padding-right:3rem !important}.pb-5,.py-5{padding-bottom:3rem !important}.pl-5,.px-5{padding-left:3rem !important}.m-auto{margin:auto !important}.mt-auto,.my-auto{margin-top:auto !important}.mr-auto,.mx-auto{margin-right:auto !important}.mb-auto,.my-auto{margin-bottom:auto !important}.ml-auto,.mx-auto{margin-left:auto !important}@media (min-width: 576px){.m-sm-0{margin:0 !important}.mt-sm-0,.my-sm-0{margin-top:0 !important}.mr-sm-0,.mx-sm-0{margin-right:0 !important}.mb-sm-0,.my-sm-0{margin-bottom:0 !important}.ml-sm-0,.mx-sm-0{margin-left:0 !important}.m-sm-1{margin:.25rem !important}.mt-sm-1,.my-sm-1{margin-top:.25rem !important}.mr-sm-1,.mx-sm-1{margin-right:.25rem !important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem !important}.ml-sm-1,.mx-sm-1{margin-left:.25rem !important}.m-sm-2{margin:.5rem !important}.mt-sm-2,.my-sm-2{margin-top:.5rem !important}.mr-sm-2,.mx-sm-2{margin-right:.5rem !important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem !important}.ml-sm-2,.mx-sm-2{margin-left:.5rem !important}.m-sm-3{margin:1rem !important}.mt-sm-3,.my-sm-3{margin-top:1rem !important}.mr-sm-3,.mx-sm-3{margin-right:1rem !important}.mb-sm-3,.my-sm-3{margin-bottom:1rem !important}.ml-sm-3,.mx-sm-3{margin-left:1rem !important}.m-sm-4{margin:1.5rem !important}.mt-sm-4,.my-sm-4{margin-top:1.5rem !important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem !important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem !important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem !important}.m-sm-5{margin:3rem !important}.mt-sm-5,.my-sm-5{margin-top:3rem !important}.mr-sm-5,.mx-sm-5{margin-right:3rem !important}.mb-sm-5,.my-sm-5{margin-bottom:3rem !important}.ml-sm-5,.mx-sm-5{margin-left:3rem !important}.p-sm-0{padding:0 !important}.pt-sm-0,.py-sm-0{padding-top:0 !important}.pr-sm-0,.px-sm-0{padding-right:0 !important}.pb-sm-0,.py-sm-0{padding-bottom:0 !important}.pl-sm-0,.px-sm-0{padding-left:0 !important}.p-sm-1{padding:.25rem !important}.pt-sm-1,.py-sm-1{padding-top:.25rem !important}.pr-sm-1,.px-sm-1{padding-right:.25rem !important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem !important}.pl-sm-1,.px-sm-1{padding-left:.25rem !important}.p-sm-2{padding:.5rem !important}.pt-sm-2,.py-sm-2{padding-top:.5rem !important}.pr-sm-2,.px-sm-2{padding-right:.5rem !important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem !important}.pl-sm-2,.px-sm-2{padding-left:.5rem !important}.p-sm-3{padding:1rem !important}.pt-sm-3,.py-sm-3{padding-top:1rem !important}.pr-sm-3,.px-sm-3{padding-right:1rem !important}.pb-sm-3,.py-sm-3{padding-bottom:1rem !important}.pl-sm-3,.px-sm-3{padding-left:1rem !important}.p-sm-4{padding:1.5rem !important}.pt-sm-4,.py-sm-4{padding-top:1.5rem !important}.pr-sm-4,.px-sm-4{padding-right:1.5rem !important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem !important}.pl-sm-4,.px-sm-4{padding-left:1.5rem !important}.p-sm-5{padding:3rem !important}.pt-sm-5,.py-sm-5{padding-top:3rem !important}.pr-sm-5,.px-sm-5{padding-right:3rem !important}.pb-sm-5,.py-sm-5{padding-bottom:3rem !important}.pl-sm-5,.px-sm-5{padding-left:3rem !important}.m-sm-auto{margin:auto !important}.mt-sm-auto,.my-sm-auto{margin-top:auto !important}.mr-sm-auto,.mx-sm-auto{margin-right:auto !important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto !important}.ml-sm-auto,.mx-sm-auto{margin-left:auto !important}}@media (min-width: 768px){.m-md-0{margin:0 !important}.mt-md-0,.my-md-0{margin-top:0 !important}.mr-md-0,.mx-md-0{margin-right:0 !important}.mb-md-0,.my-md-0{margin-bottom:0 !important}.ml-md-0,.mx-md-0{margin-left:0 !important}.m-md-1{margin:.25rem !important}.mt-md-1,.my-md-1{margin-top:.25rem !important}.mr-md-1,.mx-md-1{margin-right:.25rem !important}.mb-md-1,.my-md-1{margin-bottom:.25rem !important}.ml-md-1,.mx-md-1{margin-left:.25rem !important}.m-md-2{margin:.5rem !important}.mt-md-2,.my-md-2{margin-top:.5rem !important}.mr-md-2,.mx-md-2{margin-right:.5rem !important}.mb-md-2,.my-md-2{margin-bottom:.5rem !important}.ml-md-2,.mx-md-2{margin-left:.5rem !important}.m-md-3{margin:1rem !important}.mt-md-3,.my-md-3{margin-top:1rem !important}.mr-md-3,.mx-md-3{margin-right:1rem !important}.mb-md-3,.my-md-3{margin-bottom:1rem !important}.ml-md-3,.mx-md-3{margin-left:1rem !important}.m-md-4{margin:1.5rem !important}.mt-md-4,.my-md-4{margin-top:1.5rem !important}.mr-md-4,.mx-md-4{margin-right:1.5rem !important}.mb-md-4,.my-md-4{margin-bottom:1.5rem !important}.ml-md-4,.mx-md-4{margin-left:1.5rem !important}.m-md-5{margin:3rem !important}.mt-md-5,.my-md-5{margin-top:3rem !important}.mr-md-5,.mx-md-5{margin-right:3rem !important}.mb-md-5,.my-md-5{margin-bottom:3rem !important}.ml-md-5,.mx-md-5{margin-left:3rem !important}.p-md-0{padding:0 !important}.pt-md-0,.py-md-0{padding-top:0 !important}.pr-md-0,.px-md-0{padding-right:0 !important}.pb-md-0,.py-md-0{padding-bottom:0 !important}.pl-md-0,.px-md-0{padding-left:0 !important}.p-md-1{padding:.25rem !important}.pt-md-1,.py-md-1{padding-top:.25rem !important}.pr-md-1,.px-md-1{padding-right:.25rem !important}.pb-md-1,.py-md-1{padding-bottom:.25rem !important}.pl-md-1,.px-md-1{padding-left:.25rem !important}.p-md-2{padding:.5rem !important}.pt-md-2,.py-md-2{padding-top:.5rem !important}.pr-md-2,.px-md-2{padding-right:.5rem !important}.pb-md-2,.py-md-2{padding-bottom:.5rem !important}.pl-md-2,.px-md-2{padding-left:.5rem !important}.p-md-3{padding:1rem !important}.pt-md-3,.py-md-3{padding-top:1rem !important}.pr-md-3,.px-md-3{padding-right:1rem !important}.pb-md-3,.py-md-3{padding-bottom:1rem !important}.pl-md-3,.px-md-3{padding-left:1rem !important}.p-md-4{padding:1.5rem !important}.pt-md-4,.py-md-4{padding-top:1.5rem !important}.pr-md-4,.px-md-4{padding-right:1.5rem !important}.pb-md-4,.py-md-4{padding-bottom:1.5rem !important}.pl-md-4,.px-md-4{padding-left:1.5rem !important}.p-md-5{padding:3rem !important}.pt-md-5,.py-md-5{padding-top:3rem !important}.pr-md-5,.px-md-5{padding-right:3rem !important}.pb-md-5,.py-md-5{padding-bottom:3rem !important}.pl-md-5,.px-md-5{padding-left:3rem !important}.m-md-auto{margin:auto !important}.mt-md-auto,.my-md-auto{margin-top:auto !important}.mr-md-auto,.mx-md-auto{margin-right:auto !important}.mb-md-auto,.my-md-auto{margin-bottom:auto !important}.ml-md-auto,.mx-md-auto{margin-left:auto !important}}@media (min-width: 992px){.m-lg-0{margin:0 !important}.mt-lg-0,.my-lg-0{margin-top:0 !important}.mr-lg-0,.mx-lg-0{margin-right:0 !important}.mb-lg-0,.my-lg-0{margin-bottom:0 !important}.ml-lg-0,.mx-lg-0{margin-left:0 !important}.m-lg-1{margin:.25rem !important}.mt-lg-1,.my-lg-1{margin-top:.25rem !important}.mr-lg-1,.mx-lg-1{margin-right:.25rem !important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem !important}.ml-lg-1,.mx-lg-1{margin-left:.25rem !important}.m-lg-2{margin:.5rem !important}.mt-lg-2,.my-lg-2{margin-top:.5rem !important}.mr-lg-2,.mx-lg-2{margin-right:.5rem !important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem !important}.ml-lg-2,.mx-lg-2{margin-left:.5rem !important}.m-lg-3{margin:1rem !important}.mt-lg-3,.my-lg-3{margin-top:1rem !important}.mr-lg-3,.mx-lg-3{margin-right:1rem !important}.mb-lg-3,.my-lg-3{margin-bottom:1rem !important}.ml-lg-3,.mx-lg-3{margin-left:1rem !important}.m-lg-4{margin:1.5rem !important}.mt-lg-4,.my-lg-4{margin-top:1.5rem !important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem !important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem !important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem !important}.m-lg-5{margin:3rem !important}.mt-lg-5,.my-lg-5{margin-top:3rem !important}.mr-lg-5,.mx-lg-5{margin-right:3rem !important}.mb-lg-5,.my-lg-5{margin-bottom:3rem !important}.ml-lg-5,.mx-lg-5{margin-left:3rem !important}.p-lg-0{padding:0 !important}.pt-lg-0,.py-lg-0{padding-top:0 !important}.pr-lg-0,.px-lg-0{padding-right:0 !important}.pb-lg-0,.py-lg-0{padding-bottom:0 !important}.pl-lg-0,.px-lg-0{padding-left:0 !important}.p-lg-1{padding:.25rem !important}.pt-lg-1,.py-lg-1{padding-top:.25rem !important}.pr-lg-1,.px-lg-1{padding-right:.25rem !important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem !important}.pl-lg-1,.px-lg-1{padding-left:.25rem !important}.p-lg-2{padding:.5rem !important}.pt-lg-2,.py-lg-2{padding-top:.5rem !important}.pr-lg-2,.px-lg-2{padding-right:.5rem !important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem !important}.pl-lg-2,.px-lg-2{padding-left:.5rem !important}.p-lg-3{padding:1rem !important}.pt-lg-3,.py-lg-3{padding-top:1rem !important}.pr-lg-3,.px-lg-3{padding-right:1rem !important}.pb-lg-3,.py-lg-3{padding-bottom:1rem !important}.pl-lg-3,.px-lg-3{padding-left:1rem !important}.p-lg-4{padding:1.5rem !important}.pt-lg-4,.py-lg-4{padding-top:1.5rem !important}.pr-lg-4,.px-lg-4{padding-right:1.5rem !important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem !important}.pl-lg-4,.px-lg-4{padding-left:1.5rem !important}.p-lg-5{padding:3rem !important}.pt-lg-5,.py-lg-5{padding-top:3rem !important}.pr-lg-5,.px-lg-5{padding-right:3rem !important}.pb-lg-5,.py-lg-5{padding-bottom:3rem !important}.pl-lg-5,.px-lg-5{padding-left:3rem !important}.m-lg-auto{margin:auto !important}.mt-lg-auto,.my-lg-auto{margin-top:auto !important}.mr-lg-auto,.mx-lg-auto{margin-right:auto !important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto !important}.ml-lg-auto,.mx-lg-auto{margin-left:auto !important}}@media (min-width: 1200px){.m-xl-0{margin:0 !important}.mt-xl-0,.my-xl-0{margin-top:0 !important}.mr-xl-0,.mx-xl-0{margin-right:0 !important}.mb-xl-0,.my-xl-0{margin-bottom:0 !important}.ml-xl-0,.mx-xl-0{margin-left:0 !important}.m-xl-1{margin:.25rem !important}.mt-xl-1,.my-xl-1{margin-top:.25rem !important}.mr-xl-1,.mx-xl-1{margin-right:.25rem !important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem !important}.ml-xl-1,.mx-xl-1{margin-left:.25rem !important}.m-xl-2{margin:.5rem !important}.mt-xl-2,.my-xl-2{margin-top:.5rem !important}.mr-xl-2,.mx-xl-2{margin-right:.5rem !important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem !important}.ml-xl-2,.mx-xl-2{margin-left:.5rem !important}.m-xl-3{margin:1rem !important}.mt-xl-3,.my-xl-3{margin-top:1rem !important}.mr-xl-3,.mx-xl-3{margin-right:1rem !important}.mb-xl-3,.my-xl-3{margin-bottom:1rem !important}.ml-xl-3,.mx-xl-3{margin-left:1rem !important}.m-xl-4{margin:1.5rem !important}.mt-xl-4,.my-xl-4{margin-top:1.5rem !important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem !important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem !important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem !important}.m-xl-5{margin:3rem !important}.mt-xl-5,.my-xl-5{margin-top:3rem !important}.mr-xl-5,.mx-xl-5{margin-right:3rem !important}.mb-xl-5,.my-xl-5{margin-bottom:3rem !important}.ml-xl-5,.mx-xl-5{margin-left:3rem !important}.p-xl-0{padding:0 !important}.pt-xl-0,.py-xl-0{padding-top:0 !important}.pr-xl-0,.px-xl-0{padding-right:0 !important}.pb-xl-0,.py-xl-0{padding-bottom:0 !important}.pl-xl-0,.px-xl-0{padding-left:0 !important}.p-xl-1{padding:.25rem !important}.pt-xl-1,.py-xl-1{padding-top:.25rem !important}.pr-xl-1,.px-xl-1{padding-right:.25rem !important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem !important}.pl-xl-1,.px-xl-1{padding-left:.25rem !important}.p-xl-2{padding:.5rem !important}.pt-xl-2,.py-xl-2{padding-top:.5rem !important}.pr-xl-2,.px-xl-2{padding-right:.5rem !important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem !important}.pl-xl-2,.px-xl-2{padding-left:.5rem !important}.p-xl-3{padding:1rem !important}.pt-xl-3,.py-xl-3{padding-top:1rem !important}.pr-xl-3,.px-xl-3{padding-right:1rem !important}.pb-xl-3,.py-xl-3{padding-bottom:1rem !important}.pl-xl-3,.px-xl-3{padding-left:1rem !important}.p-xl-4{padding:1.5rem !important}.pt-xl-4,.py-xl-4{padding-top:1.5rem !important}.pr-xl-4,.px-xl-4{padding-right:1.5rem !important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem !important}.pl-xl-4,.px-xl-4{padding-left:1.5rem !important}.p-xl-5{padding:3rem !important}.pt-xl-5,.py-xl-5{padding-top:3rem !important}.pr-xl-5,.px-xl-5{padding-right:3rem !important}.pb-xl-5,.py-xl-5{padding-bottom:3rem !important}.pl-xl-5,.px-xl-5{padding-left:3rem !important}.m-xl-auto{margin:auto !important}.mt-xl-auto,.my-xl-auto{margin-top:auto !important}.mr-xl-auto,.mx-xl-auto{margin-right:auto !important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto !important}.ml-xl-auto,.mx-xl-auto{margin-left:auto !important}}.text-justify{text-align:justify !important}.text-nowrap{white-space:nowrap !important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left !important}.text-right{text-align:right !important}.text-center{text-align:center !important}@media (min-width: 576px){.text-sm-left{text-align:left !important}.text-sm-right{text-align:right !important}.text-sm-center{text-align:center !important}}@media (min-width: 768px){.text-md-left{text-align:left !important}.text-md-right{text-align:right !important}.text-md-center{text-align:center !important}}@media (min-width: 992px){.text-lg-left{text-align:left !important}.text-lg-right{text-align:right !important}.text-lg-center{text-align:center !important}}@media (min-width: 1200px){.text-xl-left{text-align:left !important}.text-xl-right{text-align:right !important}.text-xl-center{text-align:center !important}}.text-lowercase{text-transform:lowercase !important}.text-uppercase{text-transform:uppercase !important}.text-capitalize{text-transform:capitalize !important}.font-weight-light{font-weight:300 !important}.font-weight-normal{font-weight:400 !important}.font-weight-bold{font-weight:700 !important}.font-italic{font-style:italic !important}.text-white{color:#fff !important}.text-primary{color:#007bff !important}a.text-primary:hover,a.text-primary:focus{color:#0062cc !important}.text-secondary{color:#6c757d !important}a.text-secondary:hover,a.text-secondary:focus{color:#545b62 !important}.text-success{color:#28a745 !important}a.text-success:hover,a.text-success:focus{color:#1e7e34 !important}.text-info{color:#17a2b8 !important}a.text-info:hover,a.text-info:focus{color:#117a8b !important}.text-warning{color:#ffc107 !important}a.text-warning:hover,a.text-warning:focus{color:#d39e00 !important}.text-danger{color:#dc3545 !important}a.text-danger:hover,a.text-danger:focus{color:#bd2130 !important}.text-light{color:#f8f9fa !important}a.text-light:hover,a.text-light:focus{color:#dae0e5 !important}.text-dark{color:#343a40 !important}a.text-dark:hover,a.text-dark:focus{color:#1d2124 !important}.text-muted{color:#6c757d !important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.visible{visibility:visible !important}.invisible{visibility:hidden !important}@media print{*,*::before,*::after{text-shadow:none !important;box-shadow:none !important}a:not(.btn){text-decoration:underline}abbr[title]::after{content:" (" attr(title) ")"}pre{white-space:pre-wrap !important}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}body{min-width:992px !important}.container{min-width:992px !important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse !important}.table td,.table th{background-color:#fff !important}.table-bordered th,.table-bordered td{border:1px solid #ddd !important}}.switch{font-size:1rem;position:relative}.switch input{position:absolute;height:1px;width:1px;background:none;border:0;clip:rect(0 0 0 0);clip-path:inset(50%);overflow:hidden;padding:0}.switch input+label{position:relative;min-width:calc(calc(2.375rem * .8) * 2);border-radius:calc(2.375rem * .8);height:calc(2.375rem * .8);line-height:calc(2.375rem * .8);display:inline-block;cursor:pointer;outline:none;user-select:none;vertical-align:middle;text-indent:calc(calc(calc(2.375rem * .8) * 2) + .5rem)}.switch input+label::before,.switch input+label::after{content:'';position:absolute;top:0;left:0;width:calc(calc(2.375rem * .8) * 2);bottom:0;display:block}.switch input+label::before{right:0;background-color:#dee2e6;border-radius:calc(2.375rem * .8);transition:0.2s all}.switch input+label::after{top:2px;left:2px;width:calc(calc(2.375rem * .8) - calc(2px * 2));height:calc(calc(2.375rem * .8) - calc(2px * 2));border-radius:50%;background-color:#fff;transition:0.2s all}.switch input:checked+label::before{background-color:#08d}.switch input:checked+label::after{margin-left:calc(2.375rem * .8)}.switch input:focus+label::before{outline:none;box-shadow:0 0 0 .2rem rgba(0,136,221,0.25)}.switch input:disabled+label{color:#868e96;cursor:not-allowed}.switch input:disabled+label::before{background-color:#e9ecef}.switch.switch-sm{font-size:.875rem}.switch.switch-sm input+label{min-width:calc(calc(1.9375rem * .8) * 2);height:calc(1.9375rem * .8);line-height:calc(1.9375rem * .8);text-indent:calc(calc(calc(1.9375rem * .8) * 2) + .5rem)}.switch.switch-sm input+label::before{width:calc(calc(1.9375rem * .8) * 2)}.switch.switch-sm input+label::after{width:calc(calc(1.9375rem * .8) - calc(2px * 2));height:calc(calc(1.9375rem * .8) - calc(2px * 2))}.switch.switch-sm input:checked+label::after{margin-left:calc(1.9375rem * .8)}.switch.switch-lg{font-size:1.25rem}.switch.switch-lg input+label{min-width:calc(calc(3rem * .8) * 2);height:calc(3rem * .8);line-height:calc(3rem * .8);text-indent:calc(calc(calc(3rem * .8) * 2) + .5rem)}.switch.switch-lg input+label::before{width:calc(calc(3rem * .8) * 2)}.switch.switch-lg input+label::after{width:calc(calc(3rem * .8) - calc(2px * 2));height:calc(calc(3rem * .8) - calc(2px * 2))}.switch.switch-lg input:checked+label::after{margin-left:calc(3rem * .8)}.switch+.switch{margin-left:1rem}.switch.danger input:checked+label::before{background-color:#dc3545}.switch.danger input:focus+label::before{box-shadow:0 0 0 .2rem rgba(220,53,69,0.25)}html{font-size:0.8em;background-color:#f8f9fa}body{background-color:transparent;position:relative}label{margin-bottom:.2rem;min-height:1.5rem}.form-group span label{display:inline-block}.form-group label{display:block}.form-group li label{display:inline-block}.form-group li .form-control{width:auto}.form-group li input[type="radio"].form-control,.form-group li input[type="checkbox"].form-control{display:inline}pre{white-space:pre-wrap}.raw-description{white-space:pre-line}.form-control.small-input,.input-group>.form-control.small-input{width:110px;flex:none}.input-group>input[type=checkbox]{margin:0.5em 1em}.form-row.odd{background-color:#e9ecef}.form-row-modal{padding:0.5rem 2rem}.field-tip{position:absolute;right:10px;top:5px;opacity:0.7}.form-group .select2-container--default .select2-selection--multiple{border:1px solid #ced4da}.page-link.imported-page{color:#aa8fda}.page-link.imported-page.current-page,.page-link.current-page{color:black;font-weight:bold}#modal-advanced-search .modal-header{flex-wrap:wrap;padding-bottom:0}#modal-advanced-search .modal-header .alert-secondary{background-color:#fff}.modal-header,.modal-footer{background-color:#e9ecef}.modal-body.body-scroll{max-height:calc(100vh - 200px);overflow-y:auto}.modal-dialog.full{width:98%;height:98%;max-width:none;padding:1%}.modal-dialog.full .display.dataTable{width:100% !important}.modal-dialog.full .modal-content{height:auto;min-height:100%;border-radius:0}.table{background-color:white}.input-progress.form-control:focus,.input-progress{background-color:#dee2e6}.card-header,.input-progress,.table-striped tbody tr:nth-of-type(2n+1),.dt-bootstrap4 table.dataTable.stripe tbody tr.odd,.dt-bootstrap4 table.dataTable.display tbody tr.odd{background-color:#e9ecef}.dropdown-item:hover,.dropdown-item:focus,.dt-bootstrap4 table.dataTable.hover tbody tr:hover,.dt-bootstrap4 table.dataTable.display tbody tr:hover{background-color:#f6f6f6;background-color:#dee2e6}table.dataTable{font-size:0.8em}.table-modal-lg table.dataTable{font-size:1em}div.dt-buttons{float:right}.dt-button{color:#fff;background-color:#007bff;border-color:#007bff;display:inline-block;font-weight:400;text-align:center;white-space:nowrap;vertical-align:middle;border:1px solid transparent;color:#fff;background-color:#6c757d;border-color:#6c757d;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}.dt-button:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.dt-button:focus,.dt-button.focus{box-shadow:0 0 0 .2rem rgba(108,117,125,0.5)}.dt-button.disabled,.dt-button:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.dt-button:not(:disabled):not(.disabled):active,.dt-button:not(:disabled):not(.disabled).active,.show>.dt-button.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.dt-button:not(:disabled):not(.disabled):active:focus,.dt-button:not(:disabled):not(.disabled).active:focus,.show>.dt-button.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,0.5)}.dt-button.btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.dt-button.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.dt-button.btn-success:focus,.dt-button.btn-success.focus{box-shadow:0 0 0 .2rem rgba(40,167,69,0.5)}.dt-button.btn-success.disabled,.dt-button.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.dt-button.btn-success:not(:disabled):not(.disabled):active,.dt-button.btn-success:not(:disabled):not(.disabled).active,.show>.dt-button.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.dt-button.btn-success:not(:disabled):not(.disabled):active:focus,.dt-button.btn-success:not(:disabled):not(.disabled).active:focus,.show>.dt-button.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,0.5)}.dt-button.disabled{background-color:#f8f9fa;border-color:#f8f9fa;color:#adb5bd;cursor:not-allowed}.small-button{padding:0.1em 0.2em}.previous-value{margin:0.4em 0;display:block}h3,.h3{font-size:1.5rem}h4,.h4{font-size:1.1rem}textarea{height:90px}.sheet h4{color:#6c757d}#bookmark-list .input-link{width:100%;padding-right:5px}#window-fixed-menu{background-color:#e9ecef;position:fixed;right:0;margin-top:100px;z-index:50;width:200px}#window-fixed-menu-list li{padding-bottom:0.5em}#window-fixed-menu-list li a.nav-link{background-color:white}#window-fixed-menu-list li a.nav-link.active{background-color:#007bff}#window-menu-title{font-size:1.3em}#window-menu-control{font-size:0.6em;padding-top:0.2em}#window-fixed-menu.hidden{transform:rotate(270deg);transform-origin:right bottom 0}#window-fixed-menu.hidden i.fa-times{transform:rotate(45deg);transform-origin:10px 10px 0;padding-left:0.1em}.form h4,.form h3,.collapse-form .card-header,#window h3{background-color:#ced4da}.collapse-form .card,.collapse-form .card-header{border-radius:0;border:0 solid}.collapse-form .card-header{padding:0;text-align:center}.collapse-form .card-header h4{margin-bottom:0}.collapse-form .card-header .btn.btn-link{color:#212529;width:100%}.collapse-form .card-body{border:1px solid #ced4da}.collapse-form .fa-expand,.collapse-form .collapsed .fa-compress{display:none}.collapse-form .collapsed .fa-expand,.collapse-form .fa-compress{display:inline-block}.clean-table h4,.form h4,.form h3,.collapse-form .card-header h4 .btn,.sheet h4,.sheet h3,.sheet h2{text-align:center;text-shadow:2px 2px 2px rgba(150,150,150,0.7)}.sheet .subsection{background-color:#e9ecef}.sheet .row.toolbar{padding:0.5em 0.75em}.sheet .row{padding:0 0.75em;margin:0}.clean-table h4{margin-top:1em}.container{margin-top:1em;margin-bottom:8em}.bg-dark{background-color:#432776 !important}.navbar{padding:0 0.5rem}.navbar-dark .navbar-nav.action-menu .nav-link{color:#ffe484;border:1px solid #ffe484;border-radius:4px;margin:0.2em;padding:0.3em 0.6em}.navbar-dark .navbar-nav.action-menu .d-none .nav-link{border:0px solid transparent}.navbar-dark .navbar-nav.action-menu .d-none .nav-link:hover{background-color:transparent;color:#ffe484}.navbar-dark .navbar-nav.action-menu .nav-link:hover{background-color:#ffe484;color:#343a40}.navbar-dark .navbar-nav.action-menu .nav-link.dropdown-toggle::after{color:#ffe484}.navbar-dark .navbar-nav.action-menu .nav-link.dropdown-toggle:hover::after{color:#343a40}#context-menu,#reminder,.confirm-message,div#validation-bar{background-color:#6f42c1;color:rgba(255,255,255,0.8)}#reminder{padding:0.6em 1em 0.1em 1em}#alert-list{padding:0.6em 0}#alert-list a{font-size:1.1rem}.confirm-message{text-align:center;margin:0;padding:0.5rem;font-weight:bold}.is-invalid input{border-color:#f99}.errorlist{color:#900}#shortcut-menu{width:700px;padding:1em}#context-menu a.nav-link{color:rgba(255,255,255,0.8);padding:0.8rem 0.5rem 0.7rem 0.5rem}#context-menu .breadcrumb{margin-bottom:0;background-color:transparent}#current_items{width:100%}div#foot{background-color:#432776;color:rgba(255,255,255,0.5)}div#foot a{color:#ddd}div#foot a:hover{color:#fff}.breadcrumb button{border:0 transparent;background-color:transparent}.breadcrumb a:hover{text-decoration:none}.breadcrumb button:hover{cursor:pointer;color:#0062cc}.input-group.date input{border:1px solid #dee2e6;border-radius:.25rem;padding:.375rem .75rem;font-size:1rem;line-height:1.5}.input-group.date .input-group-text:hover{cursor:pointer}.input-group>ul{padding:0.5em;border:1px solid #dee2e6;border-radius:.25rem;margin:0;list-style:none}.help-text{max-height:250px;overflow:auto}.input-link{color:#6c757d}.input-link.disabled{color:#adb5bd}.input-link:hover{color:#343a40;cursor:pointer}.input-link.disabled:hover{color:#adb5bd;cursor:not-allowed}.input-sep{background-color:#fff;padding:0.3rem}.search_button{display:none}.lightgallery-captions{display:none}.lightgallery-subimage{display:inline-block;width:80px;padding:0.2em}.lightgallery-subimage img{width:100%}.lg .lg-sub-html{text-align:left}.lg .lg-sub-html .close{color:#fff}.lg .lg-sub-html .close:hover{opacity:0.9}#basket-manage #foot_pk{display:none}#basket-manage #grid_pk_meta_wrapper{width:50%;float:left;padding-bottom:80px}#basket-add-button{width:8%;float:left;margin:20vh 1% 0 1%}#basket-content-wrapper{width:40%;float:left}#basket-content{text-align:left;overflow:auto;max-height:60vh}.ui-widget-content{border:1px solid #dee2e6;background-color:#fff}.ui-menu-item{padding:0.2em 0.4em;border:1px solid #fff}.ui-menu-item:hover{color:#6f3b93;border:1px solid #6f3b93;cursor:pointer}.ui-autocomplete{font-size:0.7em;z-index:10000 !important;width:350px;border:5px solid #dee2e6;outline:none}.ui-menu{list-style:none;padding:0;margin:0;display:block;outline:none}.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}
+ */:root{--blue: #007bff;--indigo: #6610f2;--purple: #6f42c1;--pink: #e83e8c;--red: #dc3545;--orange: #fd7e14;--yellow: #ffc107;--green: #28a745;--teal: #20c997;--cyan: #17a2b8;--white: #fff;--gray: #6c757d;--gray-dark: #343a40;--primary: #007bff;--secondary: #6c757d;--success: #28a745;--info: #17a2b8;--warning: #ffc107;--danger: #dc3545;--light: #f8f9fa;--dark: #343a40;--breakpoint-xs: 0;--breakpoint-sm: 576px;--breakpoint-md: 768px;--breakpoint-lg: 992px;--breakpoint-xl: 1200px;--font-family-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";--font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace}*,*::before,*::after{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:rgba(0,0,0,0)}@-ms-viewport{width:device-width}article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus{outline:0 !important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[title],abbr[data-original-title]{text-decoration:underline;text-decoration:underline dotted;cursor:help;border-bottom:0}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul,dl{margin-top:0;margin-bottom:1rem}ol ol,ul ul,ol ul,ul ol{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}dfn{font-style:italic}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#6f3b93;text-decoration:none;background-color:transparent;-webkit-text-decoration-skip:objects}a:hover{color:#542c6f;text-decoration:none}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):hover,a:not([href]):not([tabindex]):focus{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}pre,code,kbd,samp{font-family:monospace, monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg:not(:root){overflow:hidden}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}input,button,select,optgroup,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}button,html [type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button::-moz-focus-inner,[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner{padding:0;border-style:none}input[type="radio"],input[type="checkbox"]{box-sizing:border-box;padding:0}input[type="date"],input[type="time"],input[type="datetime-local"],input[type="month"]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{outline-offset:-2px;-webkit-appearance:none}[type="search"]::-webkit-search-cancel-button,[type="search"]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none !important}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{margin-bottom:.5rem;font-family:inherit;font-weight:500;line-height:1.2;color:inherit}h1,.h1{font-size:2.5rem}h2,.h2{font-size:2rem}h3,.h3{font-size:1.75rem}h4,.h4{font-size:1.5rem}h5,.h5{font-size:1.25rem}h6,.h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem;font-weight:300;line-height:1.2}.display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.display-4{font-size:3.5rem;font-weight:300;line-height:1.2}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,0.1)}small,.small{font-size:80%;font-weight:400}mark,.mark{padding:.2em;background-color:#fcf8e3}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote-footer{display:block;font-size:80%;color:#6c757d}.blockquote-footer::before{content:"\2014 \00A0"}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#6c757d}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}code{font-size:87.5%;color:#e83e8c;word-break:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width: 576px){.container{max-width:540px}}@media (min-width: 768px){.container{max-width:720px}}@media (min-width: 992px){.container{max-width:960px}}@media (min-width: 1200px){.container{max-width:1140px}}.container-fluid{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{display:flex;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*="col-"]{padding-right:0;padding-left:0}.col-1,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-10,.col-11,.col-12,.col,.col-auto,.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm,.col-sm-auto,.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12,.col-md,.col-md-auto,.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg,.col-lg-auto,.col-xl-1,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl,.col-xl-auto{position:relative;width:100%;min-height:1px;padding-right:15px;padding-left:15px}.col{flex-basis:0;flex-grow:1;max-width:100%}.col-auto{flex:0 0 auto;width:auto;max-width:none}.col-1{flex:0 0 8.33333%;max-width:8.33333%}.col-2{flex:0 0 16.66667%;max-width:16.66667%}.col-3{flex:0 0 25%;max-width:25%}.col-4{flex:0 0 33.33333%;max-width:33.33333%}.col-5{flex:0 0 41.66667%;max-width:41.66667%}.col-6{flex:0 0 50%;max-width:50%}.col-7{flex:0 0 58.33333%;max-width:58.33333%}.col-8{flex:0 0 66.66667%;max-width:66.66667%}.col-9{flex:0 0 75%;max-width:75%}.col-10{flex:0 0 83.33333%;max-width:83.33333%}.col-11{flex:0 0 91.66667%;max-width:91.66667%}.col-12{flex:0 0 100%;max-width:100%}.order-first{order:-1}.order-last{order:13}.order-0{order:0}.order-1{order:1}.order-2{order:2}.order-3{order:3}.order-4{order:4}.order-5{order:5}.order-6{order:6}.order-7{order:7}.order-8{order:8}.order-9{order:9}.order-10{order:10}.order-11{order:11}.order-12{order:12}.offset-1{margin-left:8.33333%}.offset-2{margin-left:16.66667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333%}.offset-5{margin-left:41.66667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333%}.offset-8{margin-left:66.66667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333%}.offset-11{margin-left:91.66667%}@media (min-width: 576px){.col-sm{flex-basis:0;flex-grow:1;max-width:100%}.col-sm-auto{flex:0 0 auto;width:auto;max-width:none}.col-sm-1{flex:0 0 8.33333%;max-width:8.33333%}.col-sm-2{flex:0 0 16.66667%;max-width:16.66667%}.col-sm-3{flex:0 0 25%;max-width:25%}.col-sm-4{flex:0 0 33.33333%;max-width:33.33333%}.col-sm-5{flex:0 0 41.66667%;max-width:41.66667%}.col-sm-6{flex:0 0 50%;max-width:50%}.col-sm-7{flex:0 0 58.33333%;max-width:58.33333%}.col-sm-8{flex:0 0 66.66667%;max-width:66.66667%}.col-sm-9{flex:0 0 75%;max-width:75%}.col-sm-10{flex:0 0 83.33333%;max-width:83.33333%}.col-sm-11{flex:0 0 91.66667%;max-width:91.66667%}.col-sm-12{flex:0 0 100%;max-width:100%}.order-sm-first{order:-1}.order-sm-last{order:13}.order-sm-0{order:0}.order-sm-1{order:1}.order-sm-2{order:2}.order-sm-3{order:3}.order-sm-4{order:4}.order-sm-5{order:5}.order-sm-6{order:6}.order-sm-7{order:7}.order-sm-8{order:8}.order-sm-9{order:9}.order-sm-10{order:10}.order-sm-11{order:11}.order-sm-12{order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333%}.offset-sm-2{margin-left:16.66667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333%}.offset-sm-5{margin-left:41.66667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333%}.offset-sm-8{margin-left:66.66667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333%}.offset-sm-11{margin-left:91.66667%}}@media (min-width: 768px){.col-md{flex-basis:0;flex-grow:1;max-width:100%}.col-md-auto{flex:0 0 auto;width:auto;max-width:none}.col-md-1{flex:0 0 8.33333%;max-width:8.33333%}.col-md-2{flex:0 0 16.66667%;max-width:16.66667%}.col-md-3{flex:0 0 25%;max-width:25%}.col-md-4{flex:0 0 33.33333%;max-width:33.33333%}.col-md-5{flex:0 0 41.66667%;max-width:41.66667%}.col-md-6{flex:0 0 50%;max-width:50%}.col-md-7{flex:0 0 58.33333%;max-width:58.33333%}.col-md-8{flex:0 0 66.66667%;max-width:66.66667%}.col-md-9{flex:0 0 75%;max-width:75%}.col-md-10{flex:0 0 83.33333%;max-width:83.33333%}.col-md-11{flex:0 0 91.66667%;max-width:91.66667%}.col-md-12{flex:0 0 100%;max-width:100%}.order-md-first{order:-1}.order-md-last{order:13}.order-md-0{order:0}.order-md-1{order:1}.order-md-2{order:2}.order-md-3{order:3}.order-md-4{order:4}.order-md-5{order:5}.order-md-6{order:6}.order-md-7{order:7}.order-md-8{order:8}.order-md-9{order:9}.order-md-10{order:10}.order-md-11{order:11}.order-md-12{order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333%}.offset-md-2{margin-left:16.66667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333%}.offset-md-5{margin-left:41.66667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333%}.offset-md-8{margin-left:66.66667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333%}.offset-md-11{margin-left:91.66667%}}@media (min-width: 992px){.col-lg{flex-basis:0;flex-grow:1;max-width:100%}.col-lg-auto{flex:0 0 auto;width:auto;max-width:none}.col-lg-1{flex:0 0 8.33333%;max-width:8.33333%}.col-lg-2{flex:0 0 16.66667%;max-width:16.66667%}.col-lg-3{flex:0 0 25%;max-width:25%}.col-lg-4{flex:0 0 33.33333%;max-width:33.33333%}.col-lg-5{flex:0 0 41.66667%;max-width:41.66667%}.col-lg-6{flex:0 0 50%;max-width:50%}.col-lg-7{flex:0 0 58.33333%;max-width:58.33333%}.col-lg-8{flex:0 0 66.66667%;max-width:66.66667%}.col-lg-9{flex:0 0 75%;max-width:75%}.col-lg-10{flex:0 0 83.33333%;max-width:83.33333%}.col-lg-11{flex:0 0 91.66667%;max-width:91.66667%}.col-lg-12{flex:0 0 100%;max-width:100%}.order-lg-first{order:-1}.order-lg-last{order:13}.order-lg-0{order:0}.order-lg-1{order:1}.order-lg-2{order:2}.order-lg-3{order:3}.order-lg-4{order:4}.order-lg-5{order:5}.order-lg-6{order:6}.order-lg-7{order:7}.order-lg-8{order:8}.order-lg-9{order:9}.order-lg-10{order:10}.order-lg-11{order:11}.order-lg-12{order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333%}.offset-lg-2{margin-left:16.66667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333%}.offset-lg-5{margin-left:41.66667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333%}.offset-lg-8{margin-left:66.66667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333%}.offset-lg-11{margin-left:91.66667%}}@media (min-width: 1200px){.col-xl{flex-basis:0;flex-grow:1;max-width:100%}.col-xl-auto{flex:0 0 auto;width:auto;max-width:none}.col-xl-1{flex:0 0 8.33333%;max-width:8.33333%}.col-xl-2{flex:0 0 16.66667%;max-width:16.66667%}.col-xl-3{flex:0 0 25%;max-width:25%}.col-xl-4{flex:0 0 33.33333%;max-width:33.33333%}.col-xl-5{flex:0 0 41.66667%;max-width:41.66667%}.col-xl-6{flex:0 0 50%;max-width:50%}.col-xl-7{flex:0 0 58.33333%;max-width:58.33333%}.col-xl-8{flex:0 0 66.66667%;max-width:66.66667%}.col-xl-9{flex:0 0 75%;max-width:75%}.col-xl-10{flex:0 0 83.33333%;max-width:83.33333%}.col-xl-11{flex:0 0 91.66667%;max-width:91.66667%}.col-xl-12{flex:0 0 100%;max-width:100%}.order-xl-first{order:-1}.order-xl-last{order:13}.order-xl-0{order:0}.order-xl-1{order:1}.order-xl-2{order:2}.order-xl-3{order:3}.order-xl-4{order:4}.order-xl-5{order:5}.order-xl-6{order:6}.order-xl-7{order:7}.order-xl-8{order:8}.order-xl-9{order:9}.order-xl-10{order:10}.order-xl-11{order:11}.order-xl-12{order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333%}.offset-xl-2{margin-left:16.66667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333%}.offset-xl-5{margin-left:41.66667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333%}.offset-xl-8{margin-left:66.66667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333%}.offset-xl-11{margin-left:91.66667%}}.table{width:100%;max-width:100%;margin-bottom:1rem;background-color:rgba(0,0,0,0)}.table th,.table td{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6}.table thead th{vertical-align:bottom;border-bottom:2px solid #dee2e6}.table tbody+tbody{border-top:2px solid #dee2e6}.table .table{background-color:#fff}.table-sm th,.table-sm td{padding:.3rem}.table-bordered{border:1px solid #dee2e6}.table-bordered th,.table-bordered td{border:1px solid #dee2e6}.table-bordered thead th,.table-bordered thead td{border-bottom-width:2px}.table-borderless th,.table-borderless td,.table-borderless thead th,.table-borderless tbody+tbody{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,0.05)}.table-hover tbody tr:hover{background-color:rgba(0,0,0,0.075)}.table-primary,.table-primary>th,.table-primary>td{background-color:#b8daff}.table-hover .table-primary:hover{background-color:#9fcdff}.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#9fcdff}.table-secondary,.table-secondary>th,.table-secondary>td{background-color:#d6d8db}.table-hover .table-secondary:hover{background-color:#c8cbcf}.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#c8cbcf}.table-success,.table-success>th,.table-success>td{background-color:#c3e6cb}.table-hover .table-success:hover{background-color:#b1dfbb}.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b1dfbb}.table-info,.table-info>th,.table-info>td{background-color:#bee5eb}.table-hover .table-info:hover{background-color:#abdde5}.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abdde5}.table-warning,.table-warning>th,.table-warning>td{background-color:#ffeeba}.table-hover .table-warning:hover{background-color:#ffe8a1}.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffe8a1}.table-danger,.table-danger>th,.table-danger>td{background-color:#f5c6cb}.table-hover .table-danger:hover{background-color:#f1b0b7}.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1b0b7}.table-light,.table-light>th,.table-light>td{background-color:#fdfdfe}.table-hover .table-light:hover{background-color:#ececf6}.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>th,.table-dark>td{background-color:#c6c8ca}.table-hover .table-dark:hover{background-color:#b9bbbe}.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b9bbbe}.table-active,.table-active>th,.table-active>td{background-color:rgba(0,0,0,0.075)}.table-hover .table-active:hover{background-color:rgba(0,0,0,0.075)}.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,0.075)}.table .thead-dark th{color:#fff;background-color:#212529;border-color:#32383e}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dee2e6}.table-dark{color:#fff;background-color:#212529}.table-dark th,.table-dark td,.table-dark thead th{border-color:#32383e}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,0.05)}.table-dark.table-hover tbody tr:hover{background-color:rgba(255,255,255,0.075)}@media (max-width: 575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-sm>.table-bordered{border:0}}@media (max-width: 767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-md>.table-bordered{border:0}}@media (max-width: 991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-lg>.table-bordered{border:0}}@media (max-width: 1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:focus{color:#495057;background-color:#fff;border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,0.25)}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}select.form-control:not([size]):not([multiple]){height:calc(2.25rem + 2px)}select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem;line-height:1.5}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding-top:.375rem;padding-bottom:.375rem;margin-bottom:0;line-height:1.5;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-sm,.input-group-sm>.form-control-plaintext.form-control,.input-group-sm>.input-group-prepend>.form-control-plaintext.input-group-text,.input-group-sm>.input-group-append>.form-control-plaintext.input-group-text,.input-group-sm>.input-group-prepend>.form-control-plaintext.btn,.input-group-sm>.input-group-append>.form-control-plaintext.btn,.form-control-plaintext.form-control-lg,.input-group-lg>.form-control-plaintext.form-control,.input-group-lg>.input-group-prepend>.form-control-plaintext.input-group-text,.input-group-lg>.input-group-append>.form-control-plaintext.input-group-text,.input-group-lg>.input-group-prepend>.form-control-plaintext.btn,.input-group-lg>.input-group-append>.form-control-plaintext.btn{padding-right:0;padding-left:0}.form-control-sm,.input-group-sm>.form-control,.input-group-sm>.input-group-prepend>.input-group-text,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-append>.btn{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}select.form-control-sm:not([size]):not([multiple]),.input-group-sm>select.form-control:not([size]):not([multiple]),.input-group-sm>.input-group-prepend>select.input-group-text:not([size]):not([multiple]),.input-group-sm>.input-group-append>select.input-group-text:not([size]):not([multiple]),.input-group-sm>.input-group-prepend>select.btn:not([size]):not([multiple]),.input-group-sm>.input-group-append>select.btn:not([size]):not([multiple]){height:calc(1.8125rem + 2px)}.form-control-lg,.input-group-lg>.form-control,.input-group-lg>.input-group-prepend>.input-group-text,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-append>.btn{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}select.form-control-lg:not([size]):not([multiple]),.input-group-lg>select.form-control:not([size]):not([multiple]),.input-group-lg>.input-group-prepend>select.input-group-text:not([size]):not([multiple]),.input-group-lg>.input-group-append>select.input-group-text:not([size]):not([multiple]),.input-group-lg>.input-group-prepend>select.btn:not([size]):not([multiple]),.input-group-lg>.input-group-append>select.btn:not([size]):not([multiple]){height:calc(2.875rem + 2px)}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:flex;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*="col-"]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input:disabled ~ .form-check-label{color:#6c757d}.form-check-label{margin-bottom:0}.form-check-inline{display:inline-flex;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#28a745}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.5rem;margin-top:.1rem;font-size:.875rem;line-height:1;color:#fff;background-color:rgba(40,167,69,0.8);border-radius:.2rem}.was-validated .form-control:valid,.form-control.is-valid,.was-validated .custom-select:valid,.custom-select.is-valid{border-color:#28a745}.was-validated .form-control:valid:focus,.form-control.is-valid:focus,.was-validated .custom-select:valid:focus,.custom-select.is-valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,0.25)}.was-validated .form-control:valid ~ .valid-feedback,.was-validated .form-control:valid ~ .valid-tooltip,.form-control.is-valid ~ .valid-feedback,.form-control.is-valid ~ .valid-tooltip,.was-validated .custom-select:valid ~ .valid-feedback,.was-validated .custom-select:valid ~ .valid-tooltip,.custom-select.is-valid ~ .valid-feedback,.custom-select.is-valid ~ .valid-tooltip{display:block}.was-validated .form-check-input:valid ~ .form-check-label,.form-check-input.is-valid ~ .form-check-label{color:#28a745}.was-validated .form-check-input:valid ~ .valid-feedback,.was-validated .form-check-input:valid ~ .valid-tooltip,.form-check-input.is-valid ~ .valid-feedback,.form-check-input.is-valid ~ .valid-tooltip{display:block}.was-validated .custom-control-input:valid ~ .custom-control-label,.custom-control-input.is-valid ~ .custom-control-label{color:#28a745}.was-validated .custom-control-input:valid ~ .custom-control-label::before,.custom-control-input.is-valid ~ .custom-control-label::before{background-color:#71dd8a}.was-validated .custom-control-input:valid ~ .valid-feedback,.was-validated .custom-control-input:valid ~ .valid-tooltip,.custom-control-input.is-valid ~ .valid-feedback,.custom-control-input.is-valid ~ .valid-tooltip{display:block}.was-validated .custom-control-input:valid:checked ~ .custom-control-label::before,.custom-control-input.is-valid:checked ~ .custom-control-label::before{background-color:#34ce57}.was-validated .custom-control-input:valid:focus ~ .custom-control-label::before,.custom-control-input.is-valid:focus ~ .custom-control-label::before{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(40,167,69,0.25)}.was-validated .custom-file-input:valid ~ .custom-file-label,.custom-file-input.is-valid ~ .custom-file-label{border-color:#28a745}.was-validated .custom-file-input:valid ~ .custom-file-label::before,.custom-file-input.is-valid ~ .custom-file-label::before{border-color:inherit}.was-validated .custom-file-input:valid ~ .valid-feedback,.was-validated .custom-file-input:valid ~ .valid-tooltip,.custom-file-input.is-valid ~ .valid-feedback,.custom-file-input.is-valid ~ .valid-tooltip{display:block}.was-validated .custom-file-input:valid:focus ~ .custom-file-label,.custom-file-input.is-valid:focus ~ .custom-file-label{box-shadow:0 0 0 .2rem rgba(40,167,69,0.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.5rem;margin-top:.1rem;font-size:.875rem;line-height:1;color:#fff;background-color:rgba(220,53,69,0.8);border-radius:.2rem}.was-validated .form-control:invalid,.form-control.is-invalid,.was-validated .custom-select:invalid,.custom-select.is-invalid{border-color:#dc3545}.was-validated .form-control:invalid:focus,.form-control.is-invalid:focus,.was-validated .custom-select:invalid:focus,.custom-select.is-invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,0.25)}.was-validated .form-control:invalid ~ .invalid-feedback,.was-validated .form-control:invalid ~ .invalid-tooltip,.form-control.is-invalid ~ .invalid-feedback,.form-control.is-invalid ~ .invalid-tooltip,.was-validated .custom-select:invalid ~ .invalid-feedback,.was-validated .custom-select:invalid ~ .invalid-tooltip,.custom-select.is-invalid ~ .invalid-feedback,.custom-select.is-invalid ~ .invalid-tooltip{display:block}.was-validated .form-check-input:invalid ~ .form-check-label,.form-check-input.is-invalid ~ .form-check-label{color:#dc3545}.was-validated .form-check-input:invalid ~ .invalid-feedback,.was-validated .form-check-input:invalid ~ .invalid-tooltip,.form-check-input.is-invalid ~ .invalid-feedback,.form-check-input.is-invalid ~ .invalid-tooltip{display:block}.was-validated .custom-control-input:invalid ~ .custom-control-label,.custom-control-input.is-invalid ~ .custom-control-label{color:#dc3545}.was-validated .custom-control-input:invalid ~ .custom-control-label::before,.custom-control-input.is-invalid ~ .custom-control-label::before{background-color:#efa2a9}.was-validated .custom-control-input:invalid ~ .invalid-feedback,.was-validated .custom-control-input:invalid ~ .invalid-tooltip,.custom-control-input.is-invalid ~ .invalid-feedback,.custom-control-input.is-invalid ~ .invalid-tooltip{display:block}.was-validated .custom-control-input:invalid:checked ~ .custom-control-label::before,.custom-control-input.is-invalid:checked ~ .custom-control-label::before{background-color:#e4606d}.was-validated .custom-control-input:invalid:focus ~ .custom-control-label::before,.custom-control-input.is-invalid:focus ~ .custom-control-label::before{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(220,53,69,0.25)}.was-validated .custom-file-input:invalid ~ .custom-file-label,.custom-file-input.is-invalid ~ .custom-file-label{border-color:#dc3545}.was-validated .custom-file-input:invalid ~ .custom-file-label::before,.custom-file-input.is-invalid ~ .custom-file-label::before{border-color:inherit}.was-validated .custom-file-input:invalid ~ .invalid-feedback,.was-validated .custom-file-input:invalid ~ .invalid-tooltip,.custom-file-input.is-invalid ~ .invalid-feedback,.custom-file-input.is-invalid ~ .invalid-tooltip{display:block}.was-validated .custom-file-input:invalid:focus ~ .custom-file-label,.custom-file-input.is-invalid:focus ~ .custom-file-label{box-shadow:0 0 0 .2rem rgba(220,53,69,0.25)}.form-inline{display:flex;flex-flow:row wrap;align-items:center}.form-inline .form-check{width:100%}@media (min-width: 576px){.form-inline label{display:flex;align-items:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:flex;flex:0 0 auto;flex-flow:row wrap;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .input-group,.form-inline .custom-select{width:auto}.form-inline .form-check{display:flex;align-items:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{align-items:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{display:inline-block;font-weight:400;text-align:center;white-space:nowrap;vertical-align:middle;user-select:none;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}.btn:hover,.btn:focus{text-decoration:none}.btn:focus,.btn.focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,0.25)}.btn.disabled,.btn:disabled{opacity:.65}.btn:not(:disabled):not(.disabled){cursor:pointer}.btn:not(:disabled):not(.disabled):active,.btn:not(:disabled):not(.disabled).active{background-image:none}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}.btn-primary:focus,.btn-primary.focus{box-shadow:0 0 0 .2rem rgba(0,123,255,0.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:not(:disabled):not(.disabled):active,.btn-primary:not(:disabled):not(.disabled).active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}.btn-primary:not(:disabled):not(.disabled):active:focus,.btn-primary:not(:disabled):not(.disabled).active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,0.5)}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.btn-secondary:focus,.btn-secondary.focus{box-shadow:0 0 0 .2rem rgba(108,117,125,0.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:not(:disabled):not(.disabled):active,.btn-secondary:not(:disabled):not(.disabled).active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.btn-secondary:not(:disabled):not(.disabled):active:focus,.btn-secondary:not(:disabled):not(.disabled).active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,0.5)}.btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.btn-success:focus,.btn-success.focus{box-shadow:0 0 0 .2rem rgba(40,167,69,0.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:not(:disabled):not(.disabled):active,.btn-success:not(:disabled):not(.disabled).active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.btn-success:not(:disabled):not(.disabled):active:focus,.btn-success:not(:disabled):not(.disabled).active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,0.5)}.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.btn-info:focus,.btn-info.focus{box-shadow:0 0 0 .2rem rgba(23,162,184,0.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:not(:disabled):not(.disabled):active,.btn-info:not(:disabled):not(.disabled).active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.btn-info:not(:disabled):not(.disabled):active:focus,.btn-info:not(:disabled):not(.disabled).active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,0.5)}.btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.btn-warning:focus,.btn-warning.focus{box-shadow:0 0 0 .2rem rgba(255,193,7,0.5)}.btn-warning.disabled,.btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:not(:disabled):not(.disabled):active,.btn-warning:not(:disabled):not(.disabled).active,.show>.btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.btn-warning:not(:disabled):not(.disabled):active:focus,.btn-warning:not(:disabled):not(.disabled).active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,0.5)}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.btn-danger:focus,.btn-danger.focus{box-shadow:0 0 0 .2rem rgba(220,53,69,0.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:not(:disabled):not(.disabled):active,.btn-danger:not(:disabled):not(.disabled).active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.btn-danger:not(:disabled):not(.disabled):active:focus,.btn-danger:not(:disabled):not(.disabled).active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,0.5)}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light:focus,.btn-light.focus{box-shadow:0 0 0 .2rem rgba(248,249,250,0.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled):active,.btn-light:not(:disabled):not(.disabled).active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled):active:focus,.btn-light:not(:disabled):not(.disabled).active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,0.5)}.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.btn-dark:focus,.btn-dark.focus{box-shadow:0 0 0 .2rem rgba(52,58,64,0.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:not(:disabled):not(.disabled):active,.btn-dark:not(:disabled):not(.disabled).active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark:not(:disabled):not(.disabled):active:focus,.btn-dark:not(:disabled):not(.disabled).active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,0.5)}.btn-outline-primary{color:#007bff;background-color:transparent;background-image:none;border-color:#007bff}.btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary:focus,.btn-outline-primary.focus{box-shadow:0 0 0 .2rem rgba(0,123,255,0.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#007bff;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled):active,.btn-outline-primary:not(:disabled):not(.disabled).active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,0.5)}.btn-outline-secondary{color:#6c757d;background-color:transparent;background-image:none;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary:focus,.btn-outline-secondary.focus{box-shadow:0 0 0 .2rem rgba(108,117,125,0.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled):active,.btn-outline-secondary:not(:disabled):not(.disabled).active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,0.5)}.btn-outline-success{color:#28a745;background-color:transparent;background-image:none;border-color:#28a745}.btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success:focus,.btn-outline-success.focus{box-shadow:0 0 0 .2rem rgba(40,167,69,0.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#28a745;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled):active,.btn-outline-success:not(:disabled):not(.disabled).active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success:not(:disabled):not(.disabled):active:focus,.btn-outline-success:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,0.5)}.btn-outline-info{color:#17a2b8;background-color:transparent;background-image:none;border-color:#17a2b8}.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:focus,.btn-outline-info.focus{box-shadow:0 0 0 .2rem rgba(23,162,184,0.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled):active,.btn-outline-info:not(:disabled):not(.disabled).active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:not(:disabled):not(.disabled):active:focus,.btn-outline-info:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,0.5)}.btn-outline-warning{color:#ffc107;background-color:transparent;background-image:none;border-color:#ffc107}.btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:focus,.btn-outline-warning.focus{box-shadow:0 0 0 .2rem rgba(255,193,7,0.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled):active,.btn-outline-warning:not(:disabled):not(.disabled).active,.show>.btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,0.5)}.btn-outline-danger{color:#dc3545;background-color:transparent;background-image:none;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger:focus,.btn-outline-danger.focus{box-shadow:0 0 0 .2rem rgba(220,53,69,0.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled):active,.btn-outline-danger:not(:disabled):not(.disabled).active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,0.5)}.btn-outline-light{color:#f8f9fa;background-color:transparent;background-image:none;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:focus,.btn-outline-light.focus{box-shadow:0 0 0 .2rem rgba(248,249,250,0.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled):active,.btn-outline-light:not(:disabled):not(.disabled).active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled):active:focus,.btn-outline-light:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,0.5)}.btn-outline-dark{color:#343a40;background-color:transparent;background-image:none;border-color:#343a40}.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:focus,.btn-outline-dark.focus{box-shadow:0 0 0 .2rem rgba(52,58,64,0.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled):active,.btn-outline-dark:not(:disabled):not(.disabled).active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,0.5)}.btn-link{font-weight:400;color:#6f3b93;background-color:transparent}.btn-link:hover{color:#542c6f;text-decoration:none;background-color:transparent;border-color:transparent}.btn-link:focus,.btn-link.focus{text-decoration:none;border-color:transparent;box-shadow:none}.btn-link:disabled,.btn-link.disabled{color:#6c757d}.btn-lg,.btn-group-lg>.btn{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.btn-sm,.btn-group-sm>.btn{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.fade{opacity:0;transition:opacity 0.15s linear}.fade.show{opacity:1}.collapse{display:none}.collapse.show{display:block}tr.collapse.show{display:table-row}tbody.collapse.show{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;transition:height 0.35s ease}.dropup,.dropdown{position:relative}.dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,0.15);border-radius:.25rem}.dropup .dropdown-menu{margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-menu{margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-toggle::after{vertical-align:0}.dropleft .dropdown-menu{margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:""}.dropleft .dropdown-toggle::after{display:none}.dropleft .dropdown-toggle::before{display:inline-block;width:0;height:0;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty::after{margin-left:0}.dropleft .dropdown-toggle::before{vertical-align:0}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:hover,.dropdown-item:focus{color:#16181b;text-decoration:none;background-color:#f8f9fa}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}.dropdown-item.disabled,.dropdown-item:disabled{color:#6c757d;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#212529}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;flex:0 1 auto}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover{z-index:1}.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn.active{z-index:1}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group,.btn-group-vertical .btn+.btn,.btn-group-vertical .btn+.btn-group,.btn-group-vertical .btn-group+.btn,.btn-group-vertical .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:not(:last-child):not(.dropdown-toggle),.btn-group>.btn-group:not(:last-child)>.btn{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:not(:first-child),.btn-group>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after{margin-left:0}.btn-sm+.dropdown-toggle-split,.btn-group-sm>.btn+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-lg+.dropdown-toggle-split,.btn-group-lg>.btn+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical .btn,.btn-group-vertical .btn-group{width:100%}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle),.btn-group-vertical>.btn-group:not(:last-child)>.btn{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:not(:first-child),.btn-group-vertical>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn input[type="radio"],.btn-group-toggle>.btn input[type="checkbox"],.btn-group-toggle>.btn-group>.btn input[type="radio"],.btn-group-toggle>.btn-group>.btn input[type="checkbox"]{position:absolute;clip:rect(0, 0, 0, 0);pointer-events:none}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.form-control,.input-group>.custom-select,.input-group>.custom-file{position:relative;flex:1 1 auto;width:1%;margin-bottom:0}.input-group>.form-control:focus,.input-group>.custom-select:focus,.input-group>.custom-file:focus{z-index:3}.input-group>.form-control+.form-control,.input-group>.form-control+.custom-select,.input-group>.form-control+.custom-file,.input-group>.custom-select+.form-control,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.custom-file,.input-group>.custom-file+.form-control,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.custom-file{margin-left:-1px}.input-group>.form-control:not(:last-child),.input-group>.custom-select:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.form-control:not(:first-child),.input-group>.custom-select:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:flex;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label::before{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label,.input-group>.custom-file:not(:first-child) .custom-file-label::before{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-prepend,.input-group-append{display:flex}.input-group-prepend .btn,.input-group-append .btn{position:relative;z-index:2}.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.input-group-text,.input-group-append .input-group-text+.btn{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:flex;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-text input[type="radio"],.input-group-text input[type="checkbox"]{margin-top:0}.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text,.input-group>.input-group-append:not(:last-child)>.btn,.input-group>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;display:block;min-height:1.5rem;padding-left:1.5rem}.custom-control-inline{display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;z-index:-1;opacity:0}.custom-control-input:checked ~ .custom-control-label::before{color:#fff;background-color:#007bff}.custom-control-input:focus ~ .custom-control-label::before{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,0.25)}.custom-control-input:active ~ .custom-control-label::before{color:#fff;background-color:#b3d7ff}.custom-control-input:disabled ~ .custom-control-label{color:#6c757d}.custom-control-input:disabled ~ .custom-control-label::before{background-color:#e9ecef}.custom-control-label{margin-bottom:0}.custom-control-label::before{position:absolute;top:.25rem;left:0;display:block;width:1rem;height:1rem;pointer-events:none;content:"";user-select:none;background-color:#dee2e6}.custom-control-label::after{position:absolute;top:.25rem;left:0;display:block;width:1rem;height:1rem;content:"";background-repeat:no-repeat;background-position:center center;background-size:50% 50%}.custom-checkbox .custom-control-label::before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked ~ .custom-control-label::before{background-color:#007bff}.custom-checkbox .custom-control-input:checked ~ .custom-control-label::after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E")}.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::before{background-color:#007bff}.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3E%3Cpath stroke='%23fff' d='M0 2h4'/%3E%3C/svg%3E")}.custom-checkbox .custom-control-input:disabled:checked ~ .custom-control-label::before{background-color:rgba(0,123,255,0.5)}.custom-checkbox .custom-control-input:disabled:indeterminate ~ .custom-control-label::before{background-color:rgba(0,123,255,0.5)}.custom-radio .custom-control-label::before{border-radius:50%}.custom-radio .custom-control-input:checked ~ .custom-control-label::before{background-color:#007bff}.custom-radio .custom-control-input:checked ~ .custom-control-label::after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%23fff'/%3E%3C/svg%3E")}.custom-radio .custom-control-input:disabled:checked ~ .custom-control-label::before{background-color:rgba(0,123,255,0.5)}.custom-select{display:inline-block;width:100%;height:calc(2.25rem + 2px);padding:.375rem 1.75rem .375rem .75rem;line-height:1.5;color:#495057;vertical-align:middle;background:#fff url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") no-repeat right .75rem center;background-size:8px 10px;border:1px solid #ced4da;border-radius:.25rem;appearance:none}.custom-select:focus{border-color:#80bdff;outline:0;box-shadow:inset 0 1px 2px rgba(0,0,0,0.075),0 0 5px rgba(128,189,255,0.5)}.custom-select:focus::-ms-value{color:#495057;background-color:#fff}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#6c757d;background-color:#e9ecef}.custom-select::-ms-expand{opacity:0}.custom-select-sm{height:calc(1.8125rem + 2px);padding-top:.375rem;padding-bottom:.375rem;font-size:75%}.custom-select-lg{height:calc(2.875rem + 2px);padding-top:.375rem;padding-bottom:.375rem;font-size:125%}.custom-file{position:relative;display:inline-block;width:100%;height:calc(2.25rem + 2px);margin-bottom:0}.custom-file-input{position:relative;z-index:2;width:100%;height:calc(2.25rem + 2px);margin:0;opacity:0}.custom-file-input:focus ~ .custom-file-control{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,0.25)}.custom-file-input:focus ~ .custom-file-control::before{border-color:#80bdff}.custom-file-input:lang(en) ~ .custom-file-label::after{content:"Browse"}.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(2.25rem + 2px);padding:.375rem .75rem;line-height:1.5;color:#495057;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem}.custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:calc(calc(2.25rem + 2px) - 1px * 2);padding:.375rem .75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-left:1px solid #ced4da;border-radius:0 .25rem .25rem 0}.nav{display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem}.nav-link:hover,.nav-link:focus{text-decoration:none}.nav-link.disabled{color:#6c757d}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-item{margin-bottom:-1px}.nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:hover,.nav-tabs .nav-link:focus{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-link.active,.nav-tabs .nav-item.show .nav-link{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#007bff}.nav-fill .nav-item{flex:1 1 auto;text-align:center}.nav-justified .nav-item{flex-basis:0;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding:.5rem 1rem}.navbar>.container,.navbar>.container-fluid{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}.navbar-nav{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:hover,.navbar-toggler:focus{text-decoration:none}.navbar-toggler:not(:disabled):not(.disabled){cursor:pointer}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:no-repeat center center;background-size:100% 100%}@media (max-width: 575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{padding-right:0;padding-left:0}}@media (min-width: 576px){.navbar-expand-sm{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .dropdown-menu-right{right:0;left:auto}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{flex-wrap:nowrap}.navbar-expand-sm .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.navbar-expand-sm .dropup .dropdown-menu{top:auto;bottom:100%}}@media (max-width: 767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{padding-right:0;padding-left:0}}@media (min-width: 768px){.navbar-expand-md{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .dropdown-menu-right{right:0;left:auto}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{flex-wrap:nowrap}.navbar-expand-md .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}.navbar-expand-md .dropup .dropdown-menu{top:auto;bottom:100%}}@media (max-width: 991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{padding-right:0;padding-left:0}}@media (min-width: 992px){.navbar-expand-lg{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .dropdown-menu-right{right:0;left:auto}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{flex-wrap:nowrap}.navbar-expand-lg .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}.navbar-expand-lg .dropup .dropdown-menu{top:auto;bottom:100%}}@media (max-width: 1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{padding-right:0;padding-left:0}}@media (min-width: 1200px){.navbar-expand-xl{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .dropdown-menu-right{right:0;left:auto}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{flex-wrap:nowrap}.navbar-expand-xl .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}.navbar-expand-xl .dropup .dropdown-menu{top:auto;bottom:100%}}.navbar-expand{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .dropdown-menu-right{right:0;left:auto}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid{flex-wrap:nowrap}.navbar-expand .navbar-collapse{display:flex !important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-expand .dropup .dropdown-menu{top:auto;bottom:100%}.navbar-light .navbar-brand{color:rgba(0,0,0,0.9)}.navbar-light .navbar-brand:hover,.navbar-light .navbar-brand:focus{color:rgba(0,0,0,0.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,0.5)}.navbar-light .navbar-nav .nav-link:hover,.navbar-light .navbar-nav .nav-link:focus{color:rgba(0,0,0,0.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,0.3)}.navbar-light .navbar-nav .show>.nav-link,.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .nav-link.active{color:rgba(0,0,0,0.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,0.5);border-color:rgba(0,0,0,0.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(0,0,0,0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E")}.navbar-light .navbar-text{color:rgba(0,0,0,0.5)}.navbar-light .navbar-text a{color:rgba(0,0,0,0.9)}.navbar-light .navbar-text a:hover,.navbar-light .navbar-text a:focus{color:rgba(0,0,0,0.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:hover,.navbar-dark .navbar-brand:focus{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,0.5)}.navbar-dark .navbar-nav .nav-link:hover,.navbar-dark .navbar-nav .nav-link:focus{color:rgba(255,255,255,0.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,0.25)}.navbar-dark .navbar-nav .show>.nav-link,.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .nav-link.active{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,0.5);border-color:rgba(255,255,255,0.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(255,255,255,0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E")}.navbar-dark .navbar-text{color:rgba(255,255,255,0.5)}.navbar-dark .navbar-text a{color:#fff}.navbar-dark .navbar-text a:hover,.navbar-dark .navbar-text a:focus{color:#fff}.card{position:relative;display:flex;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,0.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group:first-child .list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card>.list-group:last-child .list-group-item:last-child{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.card-body{flex:1 1 auto;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:rgba(0,0,0,0.03);border-bottom:1px solid rgba(0,0,0,0.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-header+.list-group .list-group-item:first-child{border-top:0}.card-footer{padding:.75rem 1.25rem;background-color:rgba(0,0,0,0.03);border-top:1px solid rgba(0,0,0,0.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.75rem;margin-left:-.625rem;border-bottom:0}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem}.card-img{width:100%;border-radius:calc(.25rem - 1px)}.card-img-top{width:100%;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img-bottom{width:100%;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-deck{display:flex;flex-direction:column}.card-deck .card{margin-bottom:15px}@media (min-width: 576px){.card-deck{flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.card-deck .card{display:flex;flex:1 0 0%;flex-direction:column;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group{display:flex;flex-direction:column}.card-group>.card{margin-bottom:15px}@media (min-width: 576px){.card-group{flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:first-child{border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:first-child .card-img-top,.card-group>.card:first-child .card-header{border-top-right-radius:0}.card-group>.card:first-child .card-img-bottom,.card-group>.card:first-child .card-footer{border-bottom-right-radius:0}.card-group>.card:last-child{border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:last-child .card-img-top,.card-group>.card:last-child .card-header{border-top-left-radius:0}.card-group>.card:last-child .card-img-bottom,.card-group>.card:last-child .card-footer{border-bottom-left-radius:0}.card-group>.card:only-child{border-radius:.25rem}.card-group>.card:only-child .card-img-top,.card-group>.card:only-child .card-header{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card-group>.card:only-child .card-img-bottom,.card-group>.card:only-child .card-footer{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.card-group>.card:not(:first-child):not(:last-child):not(:only-child){border-radius:0}.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-img-top,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-img-bottom,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-header,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-footer{border-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width: 576px){.card-columns{column-count:3;column-gap:1.25rem}.card-columns .card{display:inline-block;width:100%}}.breadcrumb{display:flex;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item+.breadcrumb-item::before{display:inline-block;padding-right:.5rem;padding-left:.5rem;color:#6c757d;content:"/"}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none}.breadcrumb-item.active{color:#6c757d}.pagination{display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#6f3b93;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{z-index:2;color:#542c6f;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:2;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,0.25)}.page-link:not(:disabled):not(.disabled){cursor:pointer}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-item.active .page-link{z-index:1;color:#fff;background-color:#007bff;border-color:#007bff}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#007bff}.badge-primary[href]:hover,.badge-primary[href]:focus{color:#fff;text-decoration:none;background-color:#0062cc}.badge-secondary{color:#fff;background-color:#6c757d}.badge-secondary[href]:hover,.badge-secondary[href]:focus{color:#fff;text-decoration:none;background-color:#545b62}.badge-success{color:#fff;background-color:#28a745}.badge-success[href]:hover,.badge-success[href]:focus{color:#fff;text-decoration:none;background-color:#1e7e34}.badge-info{color:#fff;background-color:#17a2b8}.badge-info[href]:hover,.badge-info[href]:focus{color:#fff;text-decoration:none;background-color:#117a8b}.badge-warning{color:#212529;background-color:#ffc107}.badge-warning[href]:hover,.badge-warning[href]:focus{color:#212529;text-decoration:none;background-color:#d39e00}.badge-danger{color:#fff;background-color:#dc3545}.badge-danger[href]:hover,.badge-danger[href]:focus{color:#fff;text-decoration:none;background-color:#bd2130}.badge-light{color:#212529;background-color:#f8f9fa}.badge-light[href]:hover,.badge-light[href]:focus{color:#212529;text-decoration:none;background-color:#dae0e5}.badge-dark{color:#fff;background-color:#343a40}.badge-dark[href]:hover,.badge-dark[href]:focus{color:#fff;text-decoration:none;background-color:#1d2124}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:.3rem}@media (min-width: 576px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{position:absolute;top:0;right:0;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.alert-primary hr{border-top-color:#9fcdff}.alert-primary .alert-link{color:#002752}.alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.alert-secondary hr{border-top-color:#c8cbcf}.alert-secondary .alert-link{color:#202326}.alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.alert-success hr{border-top-color:#b1dfbb}.alert-success .alert-link{color:#0b2e13}.alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.alert-info hr{border-top-color:#abdde5}.alert-info .alert-link{color:#062c33}.alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.alert-warning hr{border-top-color:#ffe8a1}.alert-warning .alert-link{color:#533f03}.alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.alert-danger hr{border-top-color:#f1b0b7}.alert-danger .alert-link{color:#491217}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark hr{border-top-color:#b9bbbe}.alert-dark .alert-link{color:#040505}@keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}.progress{display:flex;height:1rem;overflow:hidden;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.progress-bar{display:flex;flex-direction:column;justify-content:center;color:#fff;text-align:center;background-color:#007bff;transition:width 0.6s ease}.progress-bar-striped{background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-size:1rem 1rem}.progress-bar-animated{animation:progress-bar-stripes 1s linear infinite}.media{display:flex;align-items:flex-start}.media-body{flex:1}.list-group{display:flex;flex-direction:column;padding-left:0;margin-bottom:0}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:hover,.list-group-item-action:focus{color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;margin-bottom:-1px;background-color:#fff;border:1px solid rgba(0,0,0,0.125)}.list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.list-group-item:hover,.list-group-item:focus{z-index:1;text-decoration:none}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}.list-group-flush .list-group-item{border-right:0;border-left:0;border-radius:0}.list-group-flush:first-child .list-group-item:first-child{border-top:0}.list-group-flush:last-child .list-group-item:last-child{border-bottom:0}.list-group-item-primary{color:#004085;background-color:#b8daff}.list-group-item-primary.list-group-item-action:hover,.list-group-item-primary.list-group-item-action:focus{color:#004085;background-color:#9fcdff}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004085;border-color:#004085}.list-group-item-secondary{color:#383d41;background-color:#d6d8db}.list-group-item-secondary.list-group-item-action:hover,.list-group-item-secondary.list-group-item-action:focus{color:#383d41;background-color:#c8cbcf}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}.list-group-item-success{color:#155724;background-color:#c3e6cb}.list-group-item-success.list-group-item-action:hover,.list-group-item-success.list-group-item-action:focus{color:#155724;background-color:#b1dfbb}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}.list-group-item-info{color:#0c5460;background-color:#bee5eb}.list-group-item-info.list-group-item-action:hover,.list-group-item-info.list-group-item-action:focus{color:#0c5460;background-color:#abdde5}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}.list-group-item-warning{color:#856404;background-color:#ffeeba}.list-group-item-warning.list-group-item-action:hover,.list-group-item-warning.list-group-item-action:focus{color:#856404;background-color:#ffe8a1}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}.list-group-item-danger{color:#721c24;background-color:#f5c6cb}.list-group-item-danger.list-group-item-action:hover,.list-group-item-danger.list-group-item-action:focus{color:#721c24;background-color:#f1b0b7}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}.list-group-item-light{color:#818182;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:hover,.list-group-item-light.list-group-item-action:focus{color:#818182;background-color:#ececf6}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}.list-group-item-dark.list-group-item-action:hover,.list-group-item-dark.list-group-item-action:focus{color:#1b1e21;background-color:#b9bbbe}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:hover,.close:focus{color:#000;text-decoration:none;opacity:.75}.close:not(:disabled):not(.disabled){cursor:pointer}button.close{padding:0;background-color:transparent;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;outline:0}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:transform 0.3s ease-out;transform:translate(0, -25%)}.modal.show .modal-dialog{transform:translate(0, 0)}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - (.5rem * 2))}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,0.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:flex;align-items:flex-start;justify-content:space-between;padding:1rem;border-bottom:1px solid #e9ecef;border-top-left-radius:.3rem;border-top-right-radius:.3rem}.modal-header .close{padding:1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;flex:1 1 auto;padding:1rem}.modal-footer{display:flex;align-items:center;justify-content:flex-end;padding:1rem;border-top:1px solid #e9ecef}.modal-footer>:not(:first-child){margin-left:.25rem}.modal-footer>:not(:last-child){margin-right:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width: 576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-centered{min-height:calc(100% - (1.75rem * 2))}.modal-sm{max-width:300px}}@media (min-width: 992px){.modal-lg{max-width:800px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-top,.bs-tooltip-auto[x-placement^="top"]{padding:.4rem 0}.bs-tooltip-top .arrow,.bs-tooltip-auto[x-placement^="top"] .arrow{bottom:0}.bs-tooltip-top .arrow::before,.bs-tooltip-auto[x-placement^="top"] .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-right,.bs-tooltip-auto[x-placement^="right"]{padding:0 .4rem}.bs-tooltip-right .arrow,.bs-tooltip-auto[x-placement^="right"] .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-right .arrow::before,.bs-tooltip-auto[x-placement^="right"] .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-bottom,.bs-tooltip-auto[x-placement^="bottom"]{padding:.4rem 0}.bs-tooltip-bottom .arrow,.bs-tooltip-auto[x-placement^="bottom"] .arrow{top:0}.bs-tooltip-bottom .arrow::before,.bs-tooltip-auto[x-placement^="bottom"] .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-left,.bs-tooltip-auto[x-placement^="left"]{padding:0 .4rem}.bs-tooltip-left .arrow,.bs-tooltip-auto[x-placement^="left"] .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-left .arrow::before,.bs-tooltip-auto[x-placement^="left"] .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,0.2);border-radius:.3rem}.popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}.popover .arrow::before,.popover .arrow::after{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-top,.bs-popover-auto[x-placement^="top"]{margin-bottom:.5rem}.bs-popover-top .arrow,.bs-popover-auto[x-placement^="top"] .arrow{bottom:calc((.5rem + 1px) * -1)}.bs-popover-top .arrow::before,.bs-popover-auto[x-placement^="top"] .arrow::before,.bs-popover-top .arrow::after,.bs-popover-auto[x-placement^="top"] .arrow::after{border-width:.5rem .5rem 0}.bs-popover-top .arrow::before,.bs-popover-auto[x-placement^="top"] .arrow::before{bottom:0;border-top-color:rgba(0,0,0,0.25)}.bs-popover-top .arrow::after,.bs-popover-auto[x-placement^="top"] .arrow::after{bottom:1px;border-top-color:#fff}.bs-popover-right,.bs-popover-auto[x-placement^="right"]{margin-left:.5rem}.bs-popover-right .arrow,.bs-popover-auto[x-placement^="right"] .arrow{left:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-right .arrow::before,.bs-popover-auto[x-placement^="right"] .arrow::before,.bs-popover-right .arrow::after,.bs-popover-auto[x-placement^="right"] .arrow::after{border-width:.5rem .5rem .5rem 0}.bs-popover-right .arrow::before,.bs-popover-auto[x-placement^="right"] .arrow::before{left:0;border-right-color:rgba(0,0,0,0.25)}.bs-popover-right .arrow::after,.bs-popover-auto[x-placement^="right"] .arrow::after{left:1px;border-right-color:#fff}.bs-popover-bottom,.bs-popover-auto[x-placement^="bottom"]{margin-top:.5rem}.bs-popover-bottom .arrow,.bs-popover-auto[x-placement^="bottom"] .arrow{top:calc((.5rem + 1px) * -1)}.bs-popover-bottom .arrow::before,.bs-popover-auto[x-placement^="bottom"] .arrow::before,.bs-popover-bottom .arrow::after,.bs-popover-auto[x-placement^="bottom"] .arrow::after{border-width:0 .5rem .5rem .5rem}.bs-popover-bottom .arrow::before,.bs-popover-auto[x-placement^="bottom"] .arrow::before{top:0;border-bottom-color:rgba(0,0,0,0.25)}.bs-popover-bottom .arrow::after,.bs-popover-auto[x-placement^="bottom"] .arrow::after{top:1px;border-bottom-color:#fff}.bs-popover-bottom .popover-header::before,.bs-popover-auto[x-placement^="bottom"] .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7}.bs-popover-left,.bs-popover-auto[x-placement^="left"]{margin-right:.5rem}.bs-popover-left .arrow,.bs-popover-auto[x-placement^="left"] .arrow{right:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-left .arrow::before,.bs-popover-auto[x-placement^="left"] .arrow::before,.bs-popover-left .arrow::after,.bs-popover-auto[x-placement^="left"] .arrow::after{border-width:.5rem 0 .5rem .5rem}.bs-popover-left .arrow::before,.bs-popover-auto[x-placement^="left"] .arrow::before{right:0;border-left-color:rgba(0,0,0,0.25)}.bs-popover-left .arrow::after,.bs-popover-auto[x-placement^="left"] .arrow::after{right:1px;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;color:inherit;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#212529}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-item{position:relative;display:none;align-items:center;width:100%;transition:transform 0.6s ease;backface-visibility:hidden;perspective:1000px}.carousel-item.active,.carousel-item-next,.carousel-item-prev{display:block}.carousel-item-next,.carousel-item-prev{position:absolute;top:0}.carousel-item-next.carousel-item-left,.carousel-item-prev.carousel-item-right{transform:translateX(0)}@supports (transform-style: preserve-3d){.carousel-item-next.carousel-item-left,.carousel-item-prev.carousel-item-right{transform:translate3d(0, 0, 0)}}.carousel-item-next,.active.carousel-item-right{transform:translateX(100%)}@supports (transform-style: preserve-3d){.carousel-item-next,.active.carousel-item-right{transform:translate3d(100%, 0, 0)}}.carousel-item-prev,.active.carousel-item-left{transform:translateX(-100%)}@supports (transform-style: preserve-3d){.carousel-item-prev,.active.carousel-item-left{transform:translate3d(-100%, 0, 0)}}.carousel-fade .carousel-item{opacity:0;transition-duration:.6s;transition-property:opacity}.carousel-fade .carousel-item.active,.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right{opacity:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{opacity:0}.carousel-fade .carousel-item-next,.carousel-fade .carousel-item-prev,.carousel-fade .carousel-item.active,.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-prev{transform:translateX(0)}@supports (transform-style: preserve-3d){.carousel-fade .carousel-item-next,.carousel-fade .carousel-item-prev,.carousel-fade .carousel-item.active,.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-prev{transform:translate3d(0, 0, 0)}}.carousel-control-prev,.carousel-control-next{position:absolute;top:0;bottom:0;display:flex;align-items:center;justify-content:center;width:15%;color:#fff;text-align:center;opacity:.5}.carousel-control-prev:hover,.carousel-control-prev:focus,.carousel-control-next:hover,.carousel-control-next:focus{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-prev-icon,.carousel-control-next-icon{display:inline-block;width:20px;height:20px;background:transparent no-repeat center center;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3E%3C/svg%3E")}.carousel-control-next-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3E%3C/svg%3E")}.carousel-indicators{position:absolute;right:0;bottom:10px;left:0;z-index:15;display:flex;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{position:relative;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;background-color:rgba(255,255,255,0.5)}.carousel-indicators li::before{position:absolute;top:-10px;left:0;display:inline-block;width:100%;height:10px;content:""}.carousel-indicators li::after{position:absolute;bottom:-10px;left:0;display:inline-block;width:100%;height:10px;content:""}.carousel-indicators .active{background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}.align-baseline{vertical-align:baseline !important}.align-top{vertical-align:top !important}.align-middle{vertical-align:middle !important}.align-bottom{vertical-align:bottom !important}.align-text-bottom{vertical-align:text-bottom !important}.align-text-top{vertical-align:text-top !important}.bg-primary{background-color:#007bff !important}a.bg-primary:hover,a.bg-primary:focus,button.bg-primary:hover,button.bg-primary:focus{background-color:#0062cc !important}.bg-secondary{background-color:#6c757d !important}a.bg-secondary:hover,a.bg-secondary:focus,button.bg-secondary:hover,button.bg-secondary:focus{background-color:#545b62 !important}.bg-success{background-color:#28a745 !important}a.bg-success:hover,a.bg-success:focus,button.bg-success:hover,button.bg-success:focus{background-color:#1e7e34 !important}.bg-info{background-color:#17a2b8 !important}a.bg-info:hover,a.bg-info:focus,button.bg-info:hover,button.bg-info:focus{background-color:#117a8b !important}.bg-warning{background-color:#ffc107 !important}a.bg-warning:hover,a.bg-warning:focus,button.bg-warning:hover,button.bg-warning:focus{background-color:#d39e00 !important}.bg-danger{background-color:#dc3545 !important}a.bg-danger:hover,a.bg-danger:focus,button.bg-danger:hover,button.bg-danger:focus{background-color:#bd2130 !important}.bg-light{background-color:#f8f9fa !important}a.bg-light:hover,a.bg-light:focus,button.bg-light:hover,button.bg-light:focus{background-color:#dae0e5 !important}.bg-dark{background-color:#343a40 !important}a.bg-dark:hover,a.bg-dark:focus,button.bg-dark:hover,button.bg-dark:focus{background-color:#1d2124 !important}.bg-white{background-color:#fff !important}.bg-transparent{background-color:transparent !important}.border{border:1px solid #dee2e6 !important}.border-top{border-top:1px solid #dee2e6 !important}.border-right{border-right:1px solid #dee2e6 !important}.border-bottom{border-bottom:1px solid #dee2e6 !important}.border-left{border-left:1px solid #dee2e6 !important}.border-0{border:0 !important}.border-top-0{border-top:0 !important}.border-right-0{border-right:0 !important}.border-bottom-0{border-bottom:0 !important}.border-left-0{border-left:0 !important}.border-primary{border-color:#007bff !important}.border-secondary{border-color:#6c757d !important}.border-success{border-color:#28a745 !important}.border-info{border-color:#17a2b8 !important}.border-warning{border-color:#ffc107 !important}.border-danger{border-color:#dc3545 !important}.border-light{border-color:#f8f9fa !important}.border-dark{border-color:#343a40 !important}.border-white{border-color:#fff !important}.rounded{border-radius:.25rem !important}.rounded-top{border-top-left-radius:.25rem !important;border-top-right-radius:.25rem !important}.rounded-right{border-top-right-radius:.25rem !important;border-bottom-right-radius:.25rem !important}.rounded-bottom{border-bottom-right-radius:.25rem !important;border-bottom-left-radius:.25rem !important}.rounded-left{border-top-left-radius:.25rem !important;border-bottom-left-radius:.25rem !important}.rounded-circle{border-radius:50% !important}.rounded-0{border-radius:0 !important}.clearfix::after{display:block;clear:both;content:""}.d-none{display:none !important}.d-inline{display:inline !important}.d-inline-block{display:inline-block !important}.d-block{display:block !important}.d-table{display:table !important}.d-table-row{display:table-row !important}.d-table-cell{display:table-cell !important}.d-flex{display:flex !important}.d-inline-flex{display:inline-flex !important}@media (min-width: 576px){.d-sm-none{display:none !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-block{display:block !important}.d-sm-table{display:table !important}.d-sm-table-row{display:table-row !important}.d-sm-table-cell{display:table-cell !important}.d-sm-flex{display:flex !important}.d-sm-inline-flex{display:inline-flex !important}}@media (min-width: 768px){.d-md-none{display:none !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-block{display:block !important}.d-md-table{display:table !important}.d-md-table-row{display:table-row !important}.d-md-table-cell{display:table-cell !important}.d-md-flex{display:flex !important}.d-md-inline-flex{display:inline-flex !important}}@media (min-width: 992px){.d-lg-none{display:none !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-block{display:block !important}.d-lg-table{display:table !important}.d-lg-table-row{display:table-row !important}.d-lg-table-cell{display:table-cell !important}.d-lg-flex{display:flex !important}.d-lg-inline-flex{display:inline-flex !important}}@media (min-width: 1200px){.d-xl-none{display:none !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-block{display:block !important}.d-xl-table{display:table !important}.d-xl-table-row{display:table-row !important}.d-xl-table-cell{display:table-cell !important}.d-xl-flex{display:flex !important}.d-xl-inline-flex{display:inline-flex !important}}@media print{.d-print-none{display:none !important}.d-print-inline{display:inline !important}.d-print-inline-block{display:inline-block !important}.d-print-block{display:block !important}.d-print-table{display:table !important}.d-print-table-row{display:table-row !important}.d-print-table-cell{display:table-cell !important}.d-print-flex{display:flex !important}.d-print-inline-flex{display:inline-flex !important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive::before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive iframe,.embed-responsive embed,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9::before{padding-top:42.85714%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-4by3::before{padding-top:75%}.embed-responsive-1by1::before{padding-top:100%}.flex-row{flex-direction:row !important}.flex-column{flex-direction:column !important}.flex-row-reverse{flex-direction:row-reverse !important}.flex-column-reverse{flex-direction:column-reverse !important}.flex-wrap{flex-wrap:wrap !important}.flex-nowrap{flex-wrap:nowrap !important}.flex-wrap-reverse{flex-wrap:wrap-reverse !important}.flex-fill{flex:1 1 auto !important}.justify-content-start{justify-content:flex-start !important}.justify-content-end{justify-content:flex-end !important}.justify-content-center{justify-content:center !important}.justify-content-between{justify-content:space-between !important}.justify-content-around{justify-content:space-around !important}.align-items-start{align-items:flex-start !important}.align-items-end{align-items:flex-end !important}.align-items-center{align-items:center !important}.align-items-baseline{align-items:baseline !important}.align-items-stretch{align-items:stretch !important}.align-content-start{align-content:flex-start !important}.align-content-end{align-content:flex-end !important}.align-content-center{align-content:center !important}.align-content-between{align-content:space-between !important}.align-content-around{align-content:space-around !important}.align-content-stretch{align-content:stretch !important}.align-self-auto{align-self:auto !important}.align-self-start{align-self:flex-start !important}.align-self-end{align-self:flex-end !important}.align-self-center{align-self:center !important}.align-self-baseline{align-self:baseline !important}.align-self-stretch{align-self:stretch !important}@media (min-width: 576px){.flex-sm-row{flex-direction:row !important}.flex-sm-column{flex-direction:column !important}.flex-sm-row-reverse{flex-direction:row-reverse !important}.flex-sm-column-reverse{flex-direction:column-reverse !important}.flex-sm-wrap{flex-wrap:wrap !important}.flex-sm-nowrap{flex-wrap:nowrap !important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse !important}.flex-sm-fill{flex:1 1 auto !important}.justify-content-sm-start{justify-content:flex-start !important}.justify-content-sm-end{justify-content:flex-end !important}.justify-content-sm-center{justify-content:center !important}.justify-content-sm-between{justify-content:space-between !important}.justify-content-sm-around{justify-content:space-around !important}.align-items-sm-start{align-items:flex-start !important}.align-items-sm-end{align-items:flex-end !important}.align-items-sm-center{align-items:center !important}.align-items-sm-baseline{align-items:baseline !important}.align-items-sm-stretch{align-items:stretch !important}.align-content-sm-start{align-content:flex-start !important}.align-content-sm-end{align-content:flex-end !important}.align-content-sm-center{align-content:center !important}.align-content-sm-between{align-content:space-between !important}.align-content-sm-around{align-content:space-around !important}.align-content-sm-stretch{align-content:stretch !important}.align-self-sm-auto{align-self:auto !important}.align-self-sm-start{align-self:flex-start !important}.align-self-sm-end{align-self:flex-end !important}.align-self-sm-center{align-self:center !important}.align-self-sm-baseline{align-self:baseline !important}.align-self-sm-stretch{align-self:stretch !important}}@media (min-width: 768px){.flex-md-row{flex-direction:row !important}.flex-md-column{flex-direction:column !important}.flex-md-row-reverse{flex-direction:row-reverse !important}.flex-md-column-reverse{flex-direction:column-reverse !important}.flex-md-wrap{flex-wrap:wrap !important}.flex-md-nowrap{flex-wrap:nowrap !important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse !important}.flex-md-fill{flex:1 1 auto !important}.justify-content-md-start{justify-content:flex-start !important}.justify-content-md-end{justify-content:flex-end !important}.justify-content-md-center{justify-content:center !important}.justify-content-md-between{justify-content:space-between !important}.justify-content-md-around{justify-content:space-around !important}.align-items-md-start{align-items:flex-start !important}.align-items-md-end{align-items:flex-end !important}.align-items-md-center{align-items:center !important}.align-items-md-baseline{align-items:baseline !important}.align-items-md-stretch{align-items:stretch !important}.align-content-md-start{align-content:flex-start !important}.align-content-md-end{align-content:flex-end !important}.align-content-md-center{align-content:center !important}.align-content-md-between{align-content:space-between !important}.align-content-md-around{align-content:space-around !important}.align-content-md-stretch{align-content:stretch !important}.align-self-md-auto{align-self:auto !important}.align-self-md-start{align-self:flex-start !important}.align-self-md-end{align-self:flex-end !important}.align-self-md-center{align-self:center !important}.align-self-md-baseline{align-self:baseline !important}.align-self-md-stretch{align-self:stretch !important}}@media (min-width: 992px){.flex-lg-row{flex-direction:row !important}.flex-lg-column{flex-direction:column !important}.flex-lg-row-reverse{flex-direction:row-reverse !important}.flex-lg-column-reverse{flex-direction:column-reverse !important}.flex-lg-wrap{flex-wrap:wrap !important}.flex-lg-nowrap{flex-wrap:nowrap !important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse !important}.flex-lg-fill{flex:1 1 auto !important}.justify-content-lg-start{justify-content:flex-start !important}.justify-content-lg-end{justify-content:flex-end !important}.justify-content-lg-center{justify-content:center !important}.justify-content-lg-between{justify-content:space-between !important}.justify-content-lg-around{justify-content:space-around !important}.align-items-lg-start{align-items:flex-start !important}.align-items-lg-end{align-items:flex-end !important}.align-items-lg-center{align-items:center !important}.align-items-lg-baseline{align-items:baseline !important}.align-items-lg-stretch{align-items:stretch !important}.align-content-lg-start{align-content:flex-start !important}.align-content-lg-end{align-content:flex-end !important}.align-content-lg-center{align-content:center !important}.align-content-lg-between{align-content:space-between !important}.align-content-lg-around{align-content:space-around !important}.align-content-lg-stretch{align-content:stretch !important}.align-self-lg-auto{align-self:auto !important}.align-self-lg-start{align-self:flex-start !important}.align-self-lg-end{align-self:flex-end !important}.align-self-lg-center{align-self:center !important}.align-self-lg-baseline{align-self:baseline !important}.align-self-lg-stretch{align-self:stretch !important}}@media (min-width: 1200px){.flex-xl-row{flex-direction:row !important}.flex-xl-column{flex-direction:column !important}.flex-xl-row-reverse{flex-direction:row-reverse !important}.flex-xl-column-reverse{flex-direction:column-reverse !important}.flex-xl-wrap{flex-wrap:wrap !important}.flex-xl-nowrap{flex-wrap:nowrap !important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse !important}.flex-xl-fill{flex:1 1 auto !important}.justify-content-xl-start{justify-content:flex-start !important}.justify-content-xl-end{justify-content:flex-end !important}.justify-content-xl-center{justify-content:center !important}.justify-content-xl-between{justify-content:space-between !important}.justify-content-xl-around{justify-content:space-around !important}.align-items-xl-start{align-items:flex-start !important}.align-items-xl-end{align-items:flex-end !important}.align-items-xl-center{align-items:center !important}.align-items-xl-baseline{align-items:baseline !important}.align-items-xl-stretch{align-items:stretch !important}.align-content-xl-start{align-content:flex-start !important}.align-content-xl-end{align-content:flex-end !important}.align-content-xl-center{align-content:center !important}.align-content-xl-between{align-content:space-between !important}.align-content-xl-around{align-content:space-around !important}.align-content-xl-stretch{align-content:stretch !important}.align-self-xl-auto{align-self:auto !important}.align-self-xl-start{align-self:flex-start !important}.align-self-xl-end{align-self:flex-end !important}.align-self-xl-center{align-self:center !important}.align-self-xl-baseline{align-self:baseline !important}.align-self-xl-stretch{align-self:stretch !important}}.float-left{float:left !important}.float-right{float:right !important}.float-none{float:none !important}@media (min-width: 576px){.float-sm-left{float:left !important}.float-sm-right{float:right !important}.float-sm-none{float:none !important}}@media (min-width: 768px){.float-md-left{float:left !important}.float-md-right{float:right !important}.float-md-none{float:none !important}}@media (min-width: 992px){.float-lg-left{float:left !important}.float-lg-right{float:right !important}.float-lg-none{float:none !important}}@media (min-width: 1200px){.float-xl-left{float:left !important}.float-xl-right{float:right !important}.float-xl-none{float:none !important}}.position-static{position:static !important}.position-relative{position:relative !important}.position-absolute{position:absolute !important}.position-fixed{position:fixed !important}.position-sticky{position:sticky !important}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}@supports (position: sticky){.sticky-top{position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;clip-path:inset(50%);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal;clip-path:none}.w-25{width:25% !important}.w-50{width:50% !important}.w-75{width:75% !important}.w-100{width:100% !important}.w-auto{width:auto !important}.h-25{height:25% !important}.h-50{height:50% !important}.h-75{height:75% !important}.h-100{height:100% !important}.h-auto{height:auto !important}.mw-100{max-width:100% !important}.mh-100{max-height:100% !important}.m-0{margin:0 !important}.mt-0,.my-0{margin-top:0 !important}.mr-0,.mx-0{margin-right:0 !important}.mb-0,.my-0{margin-bottom:0 !important}.ml-0,.mx-0{margin-left:0 !important}.m-1{margin:.25rem !important}.mt-1,.my-1{margin-top:.25rem !important}.mr-1,.mx-1{margin-right:.25rem !important}.mb-1,.my-1{margin-bottom:.25rem !important}.ml-1,.mx-1{margin-left:.25rem !important}.m-2{margin:.5rem !important}.mt-2,.my-2{margin-top:.5rem !important}.mr-2,.mx-2{margin-right:.5rem !important}.mb-2,.my-2{margin-bottom:.5rem !important}.ml-2,.mx-2{margin-left:.5rem !important}.m-3{margin:1rem !important}.mt-3,.my-3{margin-top:1rem !important}.mr-3,.mx-3{margin-right:1rem !important}.mb-3,.my-3{margin-bottom:1rem !important}.ml-3,.mx-3{margin-left:1rem !important}.m-4{margin:1.5rem !important}.mt-4,.my-4{margin-top:1.5rem !important}.mr-4,.mx-4{margin-right:1.5rem !important}.mb-4,.my-4{margin-bottom:1.5rem !important}.ml-4,.mx-4{margin-left:1.5rem !important}.m-5{margin:3rem !important}.mt-5,.my-5{margin-top:3rem !important}.mr-5,.mx-5{margin-right:3rem !important}.mb-5,.my-5{margin-bottom:3rem !important}.ml-5,.mx-5{margin-left:3rem !important}.p-0{padding:0 !important}.pt-0,.py-0{padding-top:0 !important}.pr-0,.px-0{padding-right:0 !important}.pb-0,.py-0{padding-bottom:0 !important}.pl-0,.px-0{padding-left:0 !important}.p-1{padding:.25rem !important}.pt-1,.py-1{padding-top:.25rem !important}.pr-1,.px-1{padding-right:.25rem !important}.pb-1,.py-1{padding-bottom:.25rem !important}.pl-1,.px-1{padding-left:.25rem !important}.p-2{padding:.5rem !important}.pt-2,.py-2{padding-top:.5rem !important}.pr-2,.px-2{padding-right:.5rem !important}.pb-2,.py-2{padding-bottom:.5rem !important}.pl-2,.px-2{padding-left:.5rem !important}.p-3{padding:1rem !important}.pt-3,.py-3{padding-top:1rem !important}.pr-3,.px-3{padding-right:1rem !important}.pb-3,.py-3{padding-bottom:1rem !important}.pl-3,.px-3{padding-left:1rem !important}.p-4{padding:1.5rem !important}.pt-4,.py-4{padding-top:1.5rem !important}.pr-4,.px-4{padding-right:1.5rem !important}.pb-4,.py-4{padding-bottom:1.5rem !important}.pl-4,.px-4{padding-left:1.5rem !important}.p-5{padding:3rem !important}.pt-5,.py-5{padding-top:3rem !important}.pr-5,.px-5{padding-right:3rem !important}.pb-5,.py-5{padding-bottom:3rem !important}.pl-5,.px-5{padding-left:3rem !important}.m-auto{margin:auto !important}.mt-auto,.my-auto{margin-top:auto !important}.mr-auto,.mx-auto{margin-right:auto !important}.mb-auto,.my-auto{margin-bottom:auto !important}.ml-auto,.mx-auto{margin-left:auto !important}@media (min-width: 576px){.m-sm-0{margin:0 !important}.mt-sm-0,.my-sm-0{margin-top:0 !important}.mr-sm-0,.mx-sm-0{margin-right:0 !important}.mb-sm-0,.my-sm-0{margin-bottom:0 !important}.ml-sm-0,.mx-sm-0{margin-left:0 !important}.m-sm-1{margin:.25rem !important}.mt-sm-1,.my-sm-1{margin-top:.25rem !important}.mr-sm-1,.mx-sm-1{margin-right:.25rem !important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem !important}.ml-sm-1,.mx-sm-1{margin-left:.25rem !important}.m-sm-2{margin:.5rem !important}.mt-sm-2,.my-sm-2{margin-top:.5rem !important}.mr-sm-2,.mx-sm-2{margin-right:.5rem !important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem !important}.ml-sm-2,.mx-sm-2{margin-left:.5rem !important}.m-sm-3{margin:1rem !important}.mt-sm-3,.my-sm-3{margin-top:1rem !important}.mr-sm-3,.mx-sm-3{margin-right:1rem !important}.mb-sm-3,.my-sm-3{margin-bottom:1rem !important}.ml-sm-3,.mx-sm-3{margin-left:1rem !important}.m-sm-4{margin:1.5rem !important}.mt-sm-4,.my-sm-4{margin-top:1.5rem !important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem !important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem !important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem !important}.m-sm-5{margin:3rem !important}.mt-sm-5,.my-sm-5{margin-top:3rem !important}.mr-sm-5,.mx-sm-5{margin-right:3rem !important}.mb-sm-5,.my-sm-5{margin-bottom:3rem !important}.ml-sm-5,.mx-sm-5{margin-left:3rem !important}.p-sm-0{padding:0 !important}.pt-sm-0,.py-sm-0{padding-top:0 !important}.pr-sm-0,.px-sm-0{padding-right:0 !important}.pb-sm-0,.py-sm-0{padding-bottom:0 !important}.pl-sm-0,.px-sm-0{padding-left:0 !important}.p-sm-1{padding:.25rem !important}.pt-sm-1,.py-sm-1{padding-top:.25rem !important}.pr-sm-1,.px-sm-1{padding-right:.25rem !important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem !important}.pl-sm-1,.px-sm-1{padding-left:.25rem !important}.p-sm-2{padding:.5rem !important}.pt-sm-2,.py-sm-2{padding-top:.5rem !important}.pr-sm-2,.px-sm-2{padding-right:.5rem !important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem !important}.pl-sm-2,.px-sm-2{padding-left:.5rem !important}.p-sm-3{padding:1rem !important}.pt-sm-3,.py-sm-3{padding-top:1rem !important}.pr-sm-3,.px-sm-3{padding-right:1rem !important}.pb-sm-3,.py-sm-3{padding-bottom:1rem !important}.pl-sm-3,.px-sm-3{padding-left:1rem !important}.p-sm-4{padding:1.5rem !important}.pt-sm-4,.py-sm-4{padding-top:1.5rem !important}.pr-sm-4,.px-sm-4{padding-right:1.5rem !important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem !important}.pl-sm-4,.px-sm-4{padding-left:1.5rem !important}.p-sm-5{padding:3rem !important}.pt-sm-5,.py-sm-5{padding-top:3rem !important}.pr-sm-5,.px-sm-5{padding-right:3rem !important}.pb-sm-5,.py-sm-5{padding-bottom:3rem !important}.pl-sm-5,.px-sm-5{padding-left:3rem !important}.m-sm-auto{margin:auto !important}.mt-sm-auto,.my-sm-auto{margin-top:auto !important}.mr-sm-auto,.mx-sm-auto{margin-right:auto !important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto !important}.ml-sm-auto,.mx-sm-auto{margin-left:auto !important}}@media (min-width: 768px){.m-md-0{margin:0 !important}.mt-md-0,.my-md-0{margin-top:0 !important}.mr-md-0,.mx-md-0{margin-right:0 !important}.mb-md-0,.my-md-0{margin-bottom:0 !important}.ml-md-0,.mx-md-0{margin-left:0 !important}.m-md-1{margin:.25rem !important}.mt-md-1,.my-md-1{margin-top:.25rem !important}.mr-md-1,.mx-md-1{margin-right:.25rem !important}.mb-md-1,.my-md-1{margin-bottom:.25rem !important}.ml-md-1,.mx-md-1{margin-left:.25rem !important}.m-md-2{margin:.5rem !important}.mt-md-2,.my-md-2{margin-top:.5rem !important}.mr-md-2,.mx-md-2{margin-right:.5rem !important}.mb-md-2,.my-md-2{margin-bottom:.5rem !important}.ml-md-2,.mx-md-2{margin-left:.5rem !important}.m-md-3{margin:1rem !important}.mt-md-3,.my-md-3{margin-top:1rem !important}.mr-md-3,.mx-md-3{margin-right:1rem !important}.mb-md-3,.my-md-3{margin-bottom:1rem !important}.ml-md-3,.mx-md-3{margin-left:1rem !important}.m-md-4{margin:1.5rem !important}.mt-md-4,.my-md-4{margin-top:1.5rem !important}.mr-md-4,.mx-md-4{margin-right:1.5rem !important}.mb-md-4,.my-md-4{margin-bottom:1.5rem !important}.ml-md-4,.mx-md-4{margin-left:1.5rem !important}.m-md-5{margin:3rem !important}.mt-md-5,.my-md-5{margin-top:3rem !important}.mr-md-5,.mx-md-5{margin-right:3rem !important}.mb-md-5,.my-md-5{margin-bottom:3rem !important}.ml-md-5,.mx-md-5{margin-left:3rem !important}.p-md-0{padding:0 !important}.pt-md-0,.py-md-0{padding-top:0 !important}.pr-md-0,.px-md-0{padding-right:0 !important}.pb-md-0,.py-md-0{padding-bottom:0 !important}.pl-md-0,.px-md-0{padding-left:0 !important}.p-md-1{padding:.25rem !important}.pt-md-1,.py-md-1{padding-top:.25rem !important}.pr-md-1,.px-md-1{padding-right:.25rem !important}.pb-md-1,.py-md-1{padding-bottom:.25rem !important}.pl-md-1,.px-md-1{padding-left:.25rem !important}.p-md-2{padding:.5rem !important}.pt-md-2,.py-md-2{padding-top:.5rem !important}.pr-md-2,.px-md-2{padding-right:.5rem !important}.pb-md-2,.py-md-2{padding-bottom:.5rem !important}.pl-md-2,.px-md-2{padding-left:.5rem !important}.p-md-3{padding:1rem !important}.pt-md-3,.py-md-3{padding-top:1rem !important}.pr-md-3,.px-md-3{padding-right:1rem !important}.pb-md-3,.py-md-3{padding-bottom:1rem !important}.pl-md-3,.px-md-3{padding-left:1rem !important}.p-md-4{padding:1.5rem !important}.pt-md-4,.py-md-4{padding-top:1.5rem !important}.pr-md-4,.px-md-4{padding-right:1.5rem !important}.pb-md-4,.py-md-4{padding-bottom:1.5rem !important}.pl-md-4,.px-md-4{padding-left:1.5rem !important}.p-md-5{padding:3rem !important}.pt-md-5,.py-md-5{padding-top:3rem !important}.pr-md-5,.px-md-5{padding-right:3rem !important}.pb-md-5,.py-md-5{padding-bottom:3rem !important}.pl-md-5,.px-md-5{padding-left:3rem !important}.m-md-auto{margin:auto !important}.mt-md-auto,.my-md-auto{margin-top:auto !important}.mr-md-auto,.mx-md-auto{margin-right:auto !important}.mb-md-auto,.my-md-auto{margin-bottom:auto !important}.ml-md-auto,.mx-md-auto{margin-left:auto !important}}@media (min-width: 992px){.m-lg-0{margin:0 !important}.mt-lg-0,.my-lg-0{margin-top:0 !important}.mr-lg-0,.mx-lg-0{margin-right:0 !important}.mb-lg-0,.my-lg-0{margin-bottom:0 !important}.ml-lg-0,.mx-lg-0{margin-left:0 !important}.m-lg-1{margin:.25rem !important}.mt-lg-1,.my-lg-1{margin-top:.25rem !important}.mr-lg-1,.mx-lg-1{margin-right:.25rem !important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem !important}.ml-lg-1,.mx-lg-1{margin-left:.25rem !important}.m-lg-2{margin:.5rem !important}.mt-lg-2,.my-lg-2{margin-top:.5rem !important}.mr-lg-2,.mx-lg-2{margin-right:.5rem !important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem !important}.ml-lg-2,.mx-lg-2{margin-left:.5rem !important}.m-lg-3{margin:1rem !important}.mt-lg-3,.my-lg-3{margin-top:1rem !important}.mr-lg-3,.mx-lg-3{margin-right:1rem !important}.mb-lg-3,.my-lg-3{margin-bottom:1rem !important}.ml-lg-3,.mx-lg-3{margin-left:1rem !important}.m-lg-4{margin:1.5rem !important}.mt-lg-4,.my-lg-4{margin-top:1.5rem !important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem !important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem !important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem !important}.m-lg-5{margin:3rem !important}.mt-lg-5,.my-lg-5{margin-top:3rem !important}.mr-lg-5,.mx-lg-5{margin-right:3rem !important}.mb-lg-5,.my-lg-5{margin-bottom:3rem !important}.ml-lg-5,.mx-lg-5{margin-left:3rem !important}.p-lg-0{padding:0 !important}.pt-lg-0,.py-lg-0{padding-top:0 !important}.pr-lg-0,.px-lg-0{padding-right:0 !important}.pb-lg-0,.py-lg-0{padding-bottom:0 !important}.pl-lg-0,.px-lg-0{padding-left:0 !important}.p-lg-1{padding:.25rem !important}.pt-lg-1,.py-lg-1{padding-top:.25rem !important}.pr-lg-1,.px-lg-1{padding-right:.25rem !important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem !important}.pl-lg-1,.px-lg-1{padding-left:.25rem !important}.p-lg-2{padding:.5rem !important}.pt-lg-2,.py-lg-2{padding-top:.5rem !important}.pr-lg-2,.px-lg-2{padding-right:.5rem !important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem !important}.pl-lg-2,.px-lg-2{padding-left:.5rem !important}.p-lg-3{padding:1rem !important}.pt-lg-3,.py-lg-3{padding-top:1rem !important}.pr-lg-3,.px-lg-3{padding-right:1rem !important}.pb-lg-3,.py-lg-3{padding-bottom:1rem !important}.pl-lg-3,.px-lg-3{padding-left:1rem !important}.p-lg-4{padding:1.5rem !important}.pt-lg-4,.py-lg-4{padding-top:1.5rem !important}.pr-lg-4,.px-lg-4{padding-right:1.5rem !important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem !important}.pl-lg-4,.px-lg-4{padding-left:1.5rem !important}.p-lg-5{padding:3rem !important}.pt-lg-5,.py-lg-5{padding-top:3rem !important}.pr-lg-5,.px-lg-5{padding-right:3rem !important}.pb-lg-5,.py-lg-5{padding-bottom:3rem !important}.pl-lg-5,.px-lg-5{padding-left:3rem !important}.m-lg-auto{margin:auto !important}.mt-lg-auto,.my-lg-auto{margin-top:auto !important}.mr-lg-auto,.mx-lg-auto{margin-right:auto !important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto !important}.ml-lg-auto,.mx-lg-auto{margin-left:auto !important}}@media (min-width: 1200px){.m-xl-0{margin:0 !important}.mt-xl-0,.my-xl-0{margin-top:0 !important}.mr-xl-0,.mx-xl-0{margin-right:0 !important}.mb-xl-0,.my-xl-0{margin-bottom:0 !important}.ml-xl-0,.mx-xl-0{margin-left:0 !important}.m-xl-1{margin:.25rem !important}.mt-xl-1,.my-xl-1{margin-top:.25rem !important}.mr-xl-1,.mx-xl-1{margin-right:.25rem !important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem !important}.ml-xl-1,.mx-xl-1{margin-left:.25rem !important}.m-xl-2{margin:.5rem !important}.mt-xl-2,.my-xl-2{margin-top:.5rem !important}.mr-xl-2,.mx-xl-2{margin-right:.5rem !important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem !important}.ml-xl-2,.mx-xl-2{margin-left:.5rem !important}.m-xl-3{margin:1rem !important}.mt-xl-3,.my-xl-3{margin-top:1rem !important}.mr-xl-3,.mx-xl-3{margin-right:1rem !important}.mb-xl-3,.my-xl-3{margin-bottom:1rem !important}.ml-xl-3,.mx-xl-3{margin-left:1rem !important}.m-xl-4{margin:1.5rem !important}.mt-xl-4,.my-xl-4{margin-top:1.5rem !important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem !important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem !important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem !important}.m-xl-5{margin:3rem !important}.mt-xl-5,.my-xl-5{margin-top:3rem !important}.mr-xl-5,.mx-xl-5{margin-right:3rem !important}.mb-xl-5,.my-xl-5{margin-bottom:3rem !important}.ml-xl-5,.mx-xl-5{margin-left:3rem !important}.p-xl-0{padding:0 !important}.pt-xl-0,.py-xl-0{padding-top:0 !important}.pr-xl-0,.px-xl-0{padding-right:0 !important}.pb-xl-0,.py-xl-0{padding-bottom:0 !important}.pl-xl-0,.px-xl-0{padding-left:0 !important}.p-xl-1{padding:.25rem !important}.pt-xl-1,.py-xl-1{padding-top:.25rem !important}.pr-xl-1,.px-xl-1{padding-right:.25rem !important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem !important}.pl-xl-1,.px-xl-1{padding-left:.25rem !important}.p-xl-2{padding:.5rem !important}.pt-xl-2,.py-xl-2{padding-top:.5rem !important}.pr-xl-2,.px-xl-2{padding-right:.5rem !important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem !important}.pl-xl-2,.px-xl-2{padding-left:.5rem !important}.p-xl-3{padding:1rem !important}.pt-xl-3,.py-xl-3{padding-top:1rem !important}.pr-xl-3,.px-xl-3{padding-right:1rem !important}.pb-xl-3,.py-xl-3{padding-bottom:1rem !important}.pl-xl-3,.px-xl-3{padding-left:1rem !important}.p-xl-4{padding:1.5rem !important}.pt-xl-4,.py-xl-4{padding-top:1.5rem !important}.pr-xl-4,.px-xl-4{padding-right:1.5rem !important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem !important}.pl-xl-4,.px-xl-4{padding-left:1.5rem !important}.p-xl-5{padding:3rem !important}.pt-xl-5,.py-xl-5{padding-top:3rem !important}.pr-xl-5,.px-xl-5{padding-right:3rem !important}.pb-xl-5,.py-xl-5{padding-bottom:3rem !important}.pl-xl-5,.px-xl-5{padding-left:3rem !important}.m-xl-auto{margin:auto !important}.mt-xl-auto,.my-xl-auto{margin-top:auto !important}.mr-xl-auto,.mx-xl-auto{margin-right:auto !important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto !important}.ml-xl-auto,.mx-xl-auto{margin-left:auto !important}}.text-justify{text-align:justify !important}.text-nowrap{white-space:nowrap !important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left !important}.text-right{text-align:right !important}.text-center{text-align:center !important}@media (min-width: 576px){.text-sm-left{text-align:left !important}.text-sm-right{text-align:right !important}.text-sm-center{text-align:center !important}}@media (min-width: 768px){.text-md-left{text-align:left !important}.text-md-right{text-align:right !important}.text-md-center{text-align:center !important}}@media (min-width: 992px){.text-lg-left{text-align:left !important}.text-lg-right{text-align:right !important}.text-lg-center{text-align:center !important}}@media (min-width: 1200px){.text-xl-left{text-align:left !important}.text-xl-right{text-align:right !important}.text-xl-center{text-align:center !important}}.text-lowercase{text-transform:lowercase !important}.text-uppercase{text-transform:uppercase !important}.text-capitalize{text-transform:capitalize !important}.font-weight-light{font-weight:300 !important}.font-weight-normal{font-weight:400 !important}.font-weight-bold{font-weight:700 !important}.font-italic{font-style:italic !important}.text-white{color:#fff !important}.text-primary{color:#007bff !important}a.text-primary:hover,a.text-primary:focus{color:#0062cc !important}.text-secondary{color:#6c757d !important}a.text-secondary:hover,a.text-secondary:focus{color:#545b62 !important}.text-success{color:#28a745 !important}a.text-success:hover,a.text-success:focus{color:#1e7e34 !important}.text-info{color:#17a2b8 !important}a.text-info:hover,a.text-info:focus{color:#117a8b !important}.text-warning{color:#ffc107 !important}a.text-warning:hover,a.text-warning:focus{color:#d39e00 !important}.text-danger{color:#dc3545 !important}a.text-danger:hover,a.text-danger:focus{color:#bd2130 !important}.text-light{color:#f8f9fa !important}a.text-light:hover,a.text-light:focus{color:#dae0e5 !important}.text-dark{color:#343a40 !important}a.text-dark:hover,a.text-dark:focus{color:#1d2124 !important}.text-muted{color:#6c757d !important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.visible{visibility:visible !important}.invisible{visibility:hidden !important}@media print{*,*::before,*::after{text-shadow:none !important;box-shadow:none !important}a:not(.btn){text-decoration:underline}abbr[title]::after{content:" (" attr(title) ")"}pre{white-space:pre-wrap !important}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}body{min-width:992px !important}.container{min-width:992px !important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse !important}.table td,.table th{background-color:#fff !important}.table-bordered th,.table-bordered td{border:1px solid #ddd !important}}.switch{font-size:1rem;position:relative}.switch input{position:absolute;height:1px;width:1px;background:none;border:0;clip:rect(0 0 0 0);clip-path:inset(50%);overflow:hidden;padding:0}.switch input+label{position:relative;min-width:calc(calc(2.375rem * .8) * 2);border-radius:calc(2.375rem * .8);height:calc(2.375rem * .8);line-height:calc(2.375rem * .8);display:inline-block;cursor:pointer;outline:none;user-select:none;vertical-align:middle;text-indent:calc(calc(calc(2.375rem * .8) * 2) + .5rem)}.switch input+label::before,.switch input+label::after{content:'';position:absolute;top:0;left:0;width:calc(calc(2.375rem * .8) * 2);bottom:0;display:block}.switch input+label::before{right:0;background-color:#dee2e6;border-radius:calc(2.375rem * .8);transition:0.2s all}.switch input+label::after{top:2px;left:2px;width:calc(calc(2.375rem * .8) - calc(2px * 2));height:calc(calc(2.375rem * .8) - calc(2px * 2));border-radius:50%;background-color:#fff;transition:0.2s all}.switch input:checked+label::before{background-color:#08d}.switch input:checked+label::after{margin-left:calc(2.375rem * .8)}.switch input:focus+label::before{outline:none;box-shadow:0 0 0 .2rem rgba(0,136,221,0.25)}.switch input:disabled+label{color:#868e96;cursor:not-allowed}.switch input:disabled+label::before{background-color:#e9ecef}.switch.switch-sm{font-size:.875rem}.switch.switch-sm input+label{min-width:calc(calc(1.9375rem * .8) * 2);height:calc(1.9375rem * .8);line-height:calc(1.9375rem * .8);text-indent:calc(calc(calc(1.9375rem * .8) * 2) + .5rem)}.switch.switch-sm input+label::before{width:calc(calc(1.9375rem * .8) * 2)}.switch.switch-sm input+label::after{width:calc(calc(1.9375rem * .8) - calc(2px * 2));height:calc(calc(1.9375rem * .8) - calc(2px * 2))}.switch.switch-sm input:checked+label::after{margin-left:calc(1.9375rem * .8)}.switch.switch-lg{font-size:1.25rem}.switch.switch-lg input+label{min-width:calc(calc(3rem * .8) * 2);height:calc(3rem * .8);line-height:calc(3rem * .8);text-indent:calc(calc(calc(3rem * .8) * 2) + .5rem)}.switch.switch-lg input+label::before{width:calc(calc(3rem * .8) * 2)}.switch.switch-lg input+label::after{width:calc(calc(3rem * .8) - calc(2px * 2));height:calc(calc(3rem * .8) - calc(2px * 2))}.switch.switch-lg input:checked+label::after{margin-left:calc(3rem * .8)}.switch+.switch{margin-left:1rem}.switch.danger input:checked+label::before{background-color:#dc3545}.switch.danger input:focus+label::before{box-shadow:0 0 0 .2rem rgba(220,53,69,0.25)}html{font-size:0.8em;background-color:#f8f9fa}body{background-color:transparent;position:relative}label{margin-bottom:.2rem;min-height:1.5rem}.form-group span label{display:inline-block}.form-group label{display:block}.form-group li label{display:inline-block}.form-group li .form-control{width:auto}.form-group li input[type="radio"].form-control,.form-group li input[type="checkbox"].form-control{display:inline}pre{white-space:pre-wrap}.raw-description{white-space:pre-line}.form-control.small-input,.input-group>.form-control.small-input{width:110px;flex:none}.input-group>input[type=checkbox]{margin:0.5em 1em}.form-row.odd{background-color:#e9ecef}.form-row-modal{padding:0.5rem 2rem}.field-tip{position:absolute;right:10px;top:5px;opacity:0.7}.form-group .select2-container--default .select2-selection--multiple{border:1px solid #ced4da}.page-link.imported-page{color:#aa8fda}.page-link.imported-page.current-page,.page-link.current-page{color:black;font-weight:bold}#modal-advanced-search .modal-header{flex-wrap:wrap;padding-bottom:0}#modal-advanced-search .modal-header .alert-secondary{background-color:#fff}.modal-header,.modal-footer{background-color:#e9ecef}.modal-body.body-scroll{max-height:calc(100vh - 200px);overflow-y:auto}.modal-dialog.full{width:98%;height:98%;max-width:none;padding:1%}.modal-dialog.full .display.dataTable{width:100% !important}.modal-dialog.full .modal-content{height:auto;min-height:100%;border-radius:0}.table{background-color:white}.tab-content{padding-top:1em}.input-progress.form-control:focus,.input-progress{background-color:#dee2e6}.card-header,.input-progress,.table-striped tbody tr:nth-of-type(2n+1),.dt-bootstrap4 table.dataTable.stripe tbody tr.odd,.dt-bootstrap4 table.dataTable.display tbody tr.odd{background-color:#e9ecef}.dropdown-item:hover,.dropdown-item:focus,.dt-bootstrap4 table.dataTable.hover tbody tr:hover,.dt-bootstrap4 table.dataTable.display tbody tr:hover{background-color:#f6f6f6;background-color:#dee2e6}table.dataTable{font-size:0.8em}.table-modal-lg table.dataTable{font-size:1em}div.dt-buttons{float:right}.dt-button{color:#fff;background-color:#007bff;border-color:#007bff;display:inline-block;font-weight:400;text-align:center;white-space:nowrap;vertical-align:middle;border:1px solid transparent;color:#fff;background-color:#6c757d;border-color:#6c757d;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out}.dt-button:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.dt-button:focus,.dt-button.focus{box-shadow:0 0 0 .2rem rgba(108,117,125,0.5)}.dt-button.disabled,.dt-button:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.dt-button:not(:disabled):not(.disabled):active,.dt-button:not(:disabled):not(.disabled).active,.show>.dt-button.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.dt-button:not(:disabled):not(.disabled):active:focus,.dt-button:not(:disabled):not(.disabled).active:focus,.show>.dt-button.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,0.5)}.dt-button.btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.dt-button.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.dt-button.btn-success:focus,.dt-button.btn-success.focus{box-shadow:0 0 0 .2rem rgba(40,167,69,0.5)}.dt-button.btn-success.disabled,.dt-button.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.dt-button.btn-success:not(:disabled):not(.disabled):active,.dt-button.btn-success:not(:disabled):not(.disabled).active,.show>.dt-button.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.dt-button.btn-success:not(:disabled):not(.disabled):active:focus,.dt-button.btn-success:not(:disabled):not(.disabled).active:focus,.show>.dt-button.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,0.5)}.dt-button.disabled{background-color:#f8f9fa;border-color:#f8f9fa;color:#adb5bd;cursor:not-allowed}.small-button{padding:0.1em 0.2em}.previous-value{margin:0.4em 0;display:block}h3,.h3{font-size:1.5rem}h4,.h4{font-size:1.1rem}textarea{height:90px}.sheet h4{color:#6c757d}#bookmark-list .input-link{width:100%;padding-right:5px}#window-fixed-menu{background-color:#e9ecef;position:fixed;right:0;margin-top:100px;z-index:50;width:200px}#window-fixed-menu-list li{padding-bottom:0.5em}#window-fixed-menu-list li a.nav-link{background-color:white}#window-fixed-menu-list li a.nav-link.active{background-color:#007bff}#window-menu-title{font-size:1.3em}#window-menu-control{font-size:0.6em;padding-top:0.2em}#window-fixed-menu.hidden{transform:rotate(270deg);transform-origin:right bottom 0}#window-fixed-menu.hidden i.fa-times{transform:rotate(45deg);transform-origin:10px 10px 0;padding-left:0.1em}.form h4,.form h3,.collapse-form .card-header,#window h3{background-color:#ced4da}.collapse-form .card,.collapse-form .card-header{border-radius:0;border:0 solid}.collapse-form .card-header{padding:0;text-align:center}.collapse-form .card-header h4{margin-bottom:0}.collapse-form .card-header .btn.btn-link{color:#212529;width:100%}.collapse-form .card-body{border:1px solid #ced4da}.collapse-form .fa-expand,.collapse-form .collapsed .fa-compress{display:none}.collapse-form .collapsed .fa-expand,.collapse-form .fa-compress{display:inline-block}.clean-table h4,.form h4,.form h3,.collapse-form .card-header h4 .btn,.sheet h4,.sheet h3,.sheet h2{text-align:center;text-shadow:2px 2px 2px rgba(150,150,150,0.7)}.sheet .subsection{background-color:#e9ecef}.sheet .row.toolbar{padding:0.5em 0.75em}.sheet .row{padding:0 0.75em;margin:0}.clean-table h4{margin-top:1em}.container{margin-top:1em;margin-bottom:8em}.bg-dark{background-color:#432776 !important}.navbar{padding:0 0.5rem}.navbar-dark .navbar-nav.action-menu .nav-link{color:#ffe484;border:1px solid #ffe484;border-radius:4px;margin:0.2em;padding:0.3em 0.6em}.navbar-dark .navbar-nav.action-menu .d-none .nav-link{border:0px solid transparent}.navbar-dark .navbar-nav.action-menu .d-none .nav-link:hover{background-color:transparent;color:#ffe484}.navbar-dark .navbar-nav.action-menu .nav-link:hover{background-color:#ffe484;color:#343a40}.navbar-dark .navbar-nav.action-menu .nav-link.dropdown-toggle::after{color:#ffe484}.navbar-dark .navbar-nav.action-menu .nav-link.dropdown-toggle:hover::after{color:#343a40}#context-menu,#reminder,.confirm-message,div#validation-bar{background-color:#6f42c1;color:rgba(255,255,255,0.8)}#reminder{padding:0.6em 1em 0.1em 1em}#alert-list{padding:0.6em 0}#alert-list a{font-size:1.1rem}.confirm-message{text-align:center;margin:0;padding:0.5rem;font-weight:bold}.is-invalid input{border-color:#f99}.errorlist{color:#900}#shortcut-menu{width:700px;padding:1em}#context-menu a.nav-link{color:rgba(255,255,255,0.8);padding:0.8rem 0.5rem 0.7rem 0.5rem}#context-menu .breadcrumb{margin-bottom:0;background-color:transparent}#current_items{width:100%}div#foot{background-color:#432776;color:rgba(255,255,255,0.5)}div#foot a{color:#ddd}div#foot a:hover{color:#fff}.breadcrumb button{border:0 transparent;background-color:transparent}.breadcrumb a:hover{text-decoration:none}.breadcrumb button:hover{cursor:pointer;color:#0062cc}.input-group.date input{border:1px solid #dee2e6;border-radius:.25rem;padding:.375rem .75rem;font-size:1rem;line-height:1.5}.input-group.date .input-group-text:hover{cursor:pointer}.input-group>ul{padding:0.5em;border:1px solid #dee2e6;border-radius:.25rem;margin:0;list-style:none}ul.compact{padding:0;margin:0}.help-text{max-height:250px;overflow:auto}.input-link{color:#6c757d}.input-link.disabled{color:#adb5bd}.input-link:hover{color:#343a40;cursor:pointer}.input-link.disabled:hover{color:#adb5bd;cursor:not-allowed}.input-sep{background-color:#fff;padding:0.3rem}.search_button{display:none}.lightgallery-captions{display:none}.lightgallery-subimage{display:inline-block;width:80px;padding:0.2em}.lightgallery-subimage img{width:100%}.lg .lg-sub-html{text-align:left}.lg .lg-sub-html .close{color:#fff}.lg .lg-sub-html .close:hover{opacity:0.9}#basket-manage #foot_pk{display:none}#basket-manage #grid_pk_meta_wrapper{width:50%;float:left;padding-bottom:80px}#basket-add-button{width:8%;float:left;margin:20vh 1% 0 1%}#basket-content-wrapper{width:40%;float:left}#basket-content{text-align:left;overflow:auto;max-height:60vh}.ui-widget-content{border:1px solid #dee2e6;background-color:#fff}.ui-menu-item{padding:0.2em 0.4em;border:1px solid #fff}.ui-menu-item:hover{color:#6f3b93;border:1px solid #6f3b93;cursor:pointer}.ui-autocomplete{font-size:0.7em;z-index:10000 !important;width:350px;border:5px solid #dee2e6;outline:none}.ui-menu{list-style:none;padding:0;margin:0;display:block;outline:none;font-size:1.1em}.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}
diff --git a/ishtar_common/static/js/ishtar.js b/ishtar_common/static/js/ishtar.js
index ff8e43b54..ea0ccc516 100644
--- a/ishtar_common/static/js/ishtar.js
+++ b/ishtar_common/static/js/ishtar.js
@@ -70,6 +70,7 @@ var datatables_static_default = {
var activate_all_search_msg = "Searches in the shortcut menu deals with all items.";
var activate_own_search_msg = "Searches in the shortcut menu deals with only your items.";
var added_message = " items added.";
+var select_only_one_msg = "Select only one item.";
var search_pinned_msg = "";
var advanced_menu = false;
@@ -956,3 +957,25 @@ var qa_action_register = function(url) {
);
});
};
+
+var dt_single_enable_disable_submit_button = function(e, dt, type, indexes){
+ var rows = dt.rows( { selected: true } ).count();
+ if (rows == 1) {
+ $("#validation-bar #submit_form").prop('title', "");
+ $("#validation-bar #submit_form").prop('disabled', false);
+ } else {
+ $("#validation-bar #submit_form").prop('title', select_only_one_msg);
+ $("#validation-bar #submit_form").prop('disabled', true);
+ }
+};
+
+var dt_multi_enable_disable_submit_button = function(e, dt, type, indexes){
+ var rows = dt.rows( { selected: true } ).count();
+ if (rows >= 1) {
+ $("#validation-bar #submit_form").prop('title', "");
+ $("#validation-bar #submit_form").prop('disabled', false);
+ } else {
+ $("#validation-bar #submit_form").prop('title', select_only_one_msg);
+ $("#validation-bar #submit_form").prop('disabled', true);
+ }
+};
diff --git a/ishtar_common/templates/actions.html b/ishtar_common/templates/actions.html
index bd70ddf15..97d95c726 100644
--- a/ishtar_common/templates/actions.html
+++ b/ishtar_common/templates/actions.html
@@ -6,7 +6,7 @@
{% if MENU.current_subsections %}
<li class="nav-item d-none d-lg-block">
- <span class="nav-link">&gt;</span>
+ <span class="nav-link">›</span>
</li>
{% with MENU.current_subsection as section_label %}
{% with MENU.current_subsections as sections %}
@@ -16,7 +16,7 @@
{% if MENU.current_subsubsections %}
<li class="nav-item d-none d-lg-block">
- <span class="nav-link">&gt;</span>
+ <span class="nav-link">›</span>
</li>
{% with MENU.current_subsubsection as section_label %}
{% with MENU.current_subsubsections as sections %}
diff --git a/ishtar_common/templates/base.html b/ishtar_common/templates/base.html
index 652df14b3..e5af101d5 100644
--- a/ishtar_common/templates/base.html
+++ b/ishtar_common/templates/base.html
@@ -44,6 +44,7 @@
var activate_own_search_msg = "{% trans 'Searches in the shortcut menu deal with only your items.' %}";
var search_pinned_msg = "{% trans 'Search pinned' %}";
var added_message = "{% trans " items added." %}";
+ var select_only_one_msg = "{% trans "Select only one item." %}";
var YES = "{% trans 'yes' %}";
var NO = "{% trans 'no' %}";
var autorefresh_message_start = "{% trans 'Autorefresh start. The form is disabled.' %}";
@@ -107,20 +108,28 @@
<ul class="nav nav-pills flex-column" id="window-fixed-menu-list">
</ul>
</nav>
- <div id="window_wrapper">
- <div id="window" role="tablist"></div>
- </div>
<div id="message_list">
- {% if MESSAGES %}{% for message, message_type in MESSAGES %}
- <div class="alert alert-{{message_type}} alert-dismissible fade show"
- role="alert">
- {{message}}
- <button type="button" class="close" data-dismiss="alert"
- aria-label="Close">
- <span aria-hidden="true">&times;</span>
- </button>
- </div>
- {% endfor %}{% endif %}
+ {% if messages %}
+ {% for message in messages %}
+ <div class="alert alert-{{ message.tags }} alert-dismissible fade show"
+ role="alert">
+ {{message|safe}}
+ <button type="button" class="close" data-dismiss="alert"
+ aria-label="Close">
+ <span aria-hidden="true">&times;</span>
+ </button>
+ </div>{% endfor %}
+ {% endif %}
+ {% if MESSAGES %}{% for message, message_type in MESSAGES %}
+ <div class="alert alert-{{message_type}} alert-dismissible fade show"
+ role="alert">
+ {{message}}
+ <button type="button" class="close" data-dismiss="alert"
+ aria-label="Close">
+ <span aria-hidden="true">&times;</span>
+ </button>
+ </div>
+ {% endfor %}{% endif %}
</div>
{% if warnings %}{% for warning in warnings %}
<div class="alert alert-warning alert-dismissible fade show" role="alert">
@@ -129,6 +138,9 @@
</button>
</div>
{% endfor %}{% endif %}
+ <div id="window_wrapper">
+ <div id="window" role="tablist"></div>
+ </div>
{% block content %}{% endblock %}
</div>
diff --git a/ishtar_common/templates/blocks/CentimeterMeterWidget.html b/ishtar_common/templates/blocks/CentimeterMeterWidget.html
new file mode 100644
index 000000000..00c1614b5
--- /dev/null
+++ b/ishtar_common/templates/blocks/CentimeterMeterWidget.html
@@ -0,0 +1,21 @@
+<div class="input-group">
+ <input class="area_widget form-control" type="text"{{final_attrs|safe}}>
+ <div class="input-group-append">
+ <div class="input-group-text">
+ {{unit}} (<span id="meter_{{id}}">0</span>&nbsp;m)
+ </div>
+ </div>
+</div>
+<script type="text/javascript"><!--//
+ function evaluate_{{safe_id}}(){
+ value = parseFloat($("#{{id}}").val());
+ if(!isNaN(value)){
+ value = value/100;
+ } else {
+ value = 0;
+ }
+ $("#meter_{{id}}").html(value);
+ }
+ $("#{{id}}").keyup(evaluate_{{safe_id}});
+ $(document).ready(evaluate_{{safe_id}}());
+//--></script>
diff --git a/ishtar_common/templates/blocks/DataTables.html b/ishtar_common/templates/blocks/DataTables.html
index b5f669963..096650115 100644
--- a/ishtar_common/templates/blocks/DataTables.html
+++ b/ishtar_common/templates/blocks/DataTables.html
@@ -152,7 +152,7 @@ jQuery(document).ready(function(){
}
},
"select": {
- "style": {% if multiple_select %}'multi'{% else %}'single'{% endif %}
+ "style": {% if multiple_select or quick_actions %}'multi'{% else %}'single'{% endif %}
},
{% if multiple_select or quick_actions %}"buttons": [
{% for url, title, icon, target in quick_actions %}
@@ -170,7 +170,7 @@ jQuery(document).ready(function(){
}
},
{% if not forloop.last %},{% endif %}
- {% endfor %}{% if multiple_select %}{% if quick_actions%},{% endif %}
+ {% endfor %}{% if quick_actions%},{% endif %}
{
extend: 'selectAll',
text: '<i class="fa fa-check-circle-o"></i>',
@@ -181,7 +181,6 @@ jQuery(document).ready(function(){
text: '<i class="fa fa-times"></i>',
titleAttr: "{% trans 'Deselect' %}"
}
- {% endif %}
],
"dom": 'lBtip',
{% else %}
@@ -192,7 +191,12 @@ jQuery(document).ready(function(){
{ "data": "link", "orderable": false },{% for col in extra_cols %}
{ "data": "{{col}}", "defaultContent": "-",
"render": $.fn.dataTable.render.ellipsis( 70, true ) }{% if not forloop.last %},{% endif %}{% endfor %}
- ]
+ ],
+ "initComplete": function(settings, json) {
+ var api = new $.fn.dataTable.Api(settings);
+ {% if not multiple_select %}dt_single_enable_disable_submit_button(null, api);
+ {% else %}dt_multi_enable_disable_submit_button(null, api);{% endif %}
+ }
};
if (!debug) $.fn.dataTable.ext.errMode = 'none';
@@ -201,6 +205,14 @@ jQuery(document).ready(function(){
if (datatables_i18n) datatable_options['language'] = datatables_i18n;
datatable_{{sname}} = jQuery("#grid_{{name}}").DataTable(datatable_options);
+ {% if not multiple_select %}
+ datatable_{{sname}}.on('select', dt_single_enable_disable_submit_button);
+ datatable_{{sname}}.on('deselect', dt_single_enable_disable_submit_button);
+ {% else %}
+ datatable_{{sname}}.on('select', dt_multi_enable_disable_submit_button);
+ datatable_{{sname}}.on('deselect', dt_multi_enable_disable_submit_button);
+ {% endif %}
+
{% if multiple %}
jQuery("#add_button_{{name}}").click(function (){
var mygrid = jQuery("#grid_{{name}}");
diff --git a/ishtar_common/templates/blocks/GramKilogramWidget.html b/ishtar_common/templates/blocks/GramKilogramWidget.html
new file mode 100644
index 000000000..27c066d13
--- /dev/null
+++ b/ishtar_common/templates/blocks/GramKilogramWidget.html
@@ -0,0 +1,21 @@
+<div class="input-group">
+ <input class="area_widget form-control" type="text"{{final_attrs|safe}}>
+ <div class="input-group-append">
+ <div class="input-group-text">
+ {{unit}} (<span id="kg_{{id}}">0</span>&nbsp;kg)
+ </div>
+ </div>
+</div>
+<script type="text/javascript"><!--//
+ function evaluate_{{safe_id}}(){
+ value = parseFloat($("#{{id}}").val());
+ if(!isNaN(value)){
+ value = value/1000;
+ } else {
+ value = 0;
+ }
+ $("#kg_{{id}}").html(value);
+ }
+ $("#{{id}}").keyup(evaluate_{{safe_id}});
+ $(document).ready(evaluate_{{safe_id}}());
+//--></script>
diff --git a/ishtar_common/templates/blocks/action_list.html b/ishtar_common/templates/blocks/action_list.html
index 50a6554c4..384082ad4 100644
--- a/ishtar_common/templates/blocks/action_list.html
+++ b/ishtar_common/templates/blocks/action_list.html
@@ -1,12 +1,12 @@
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle"
data-toggle="dropdown" href="#" role="button" aria-haspopup="true"
- aria-expanded="false">{{section_label}}</a>
+ aria-expanded="false">{{section_label|safe}}</a>
<div class="dropdown-menu">
{% for label, url, has_children in sections %}
<a class="dropdown-item{% if has_children%} font-weight-bold{%endif%}" href="{{url}}">
- {{ label }}
+ {{ label|safe }}
</a>{% endfor %}
</div>
</li>
diff --git a/ishtar_common/templates/blocks/bs_field_snippet.html b/ishtar_common/templates/blocks/bs_field_snippet.html
index 830dd4cfa..f46b15209 100644
--- a/ishtar_common/templates/blocks/bs_field_snippet.html
+++ b/ishtar_common/templates/blocks/bs_field_snippet.html
@@ -1,5 +1,5 @@
{% load i18n %}
- <div class="form-group {% if field.field.widget.attrs.cols %}col-lg-12{% else %}col-lg-6{% endif %}{% if field.errors %} is-invalid{% endif %}{% if field.field.required %} required{% endif %}"
+ <div class="form-group {% if field.field.widget.attrs.cols or force_large_col %}col-lg-12{% else %}col-lg-6{% endif %}{% if field.errors %} is-invalid{% endif %}{% if field.field.required %} required{% endif %}"
data-alt-name="{{field.field.alt_name}}">
{% if field.label %}{{ field.label_tag }}{% endif %}
{% if show_field_number and field.field.order_number %}<span class="badge badge-pill badge-success field-tip">
diff --git a/ishtar_common/templates/ishtar/blocks/sheet_json.html b/ishtar_common/templates/ishtar/blocks/sheet_json.html
index 8927eb057..df9340c6f 100644
--- a/ishtar_common/templates/ishtar/blocks/sheet_json.html
+++ b/ishtar_common/templates/ishtar/blocks/sheet_json.html
@@ -5,5 +5,7 @@
{% if forloop.first %}<div class='row'>{% endif %}
{% field_flex label value %}
{% if forloop.last %}</div>{% endif %}
+{% empty %}
+{% trans "No data" %}
{% endfor %}
{% endfor %}
diff --git a/ishtar_common/templates/ishtar/blocks/window_field_flex_multiple_full.html b/ishtar_common/templates/ishtar/blocks/window_field_flex_multiple_full.html
new file mode 100644
index 000000000..b70c1d2fc
--- /dev/null
+++ b/ishtar_common/templates/ishtar/blocks/window_field_flex_multiple_full.html
@@ -0,0 +1,8 @@
+{% load i18n %}{% if data.count %}
+ <dl class="col-12 row">
+ <dt class="col-12">{% trans caption %}</dt>
+ <dd class="col-12">{% for d in data.distinct.all %}
+ {% if forloop.counter0 %} ; {% endif %}{{ d }}
+ {% endfor %}</dd>
+ </dl>
+{% endif %}
diff --git a/ishtar_common/templates/ishtar/blocks/window_nav.html b/ishtar_common/templates/ishtar/blocks/window_nav.html
index 6cd4bff40..62caff142 100644
--- a/ishtar_common/templates/ishtar/blocks/window_nav.html
+++ b/ishtar_common/templates/ishtar/blocks/window_nav.html
@@ -27,9 +27,9 @@
{% endif %}
</div>
</div>
- <div class='offset-md-6 col-md-4 text-right'>
+ <div class='offset-md-4 col-md-6 text-right'>
{% else %}
- <div class='offset-md-8 col-md-4 text-right'>
+ <div class='offset-md-6 col-md-6 text-right'>
{% endif %}
{% if pin_action and item.SLUG %}
<div class="btn-group btn-group-sm" role="group"
@@ -38,6 +38,8 @@
onclick='$.get("{% url "pin" item.SLUG item.pk %}", function(){load_shortcut_menu(); display_info("{% trans 'Item pined in your shortcut menu.' %}")});' title="{% trans 'Pin' %}">
<i class="fa fa-thumb-tack"></i>
</a>
+ {% block post_pin %}
+ {% endblock %}
</div>
{% endif %}
<div class="btn-group btn-group-sm" role="group" aria-label="{% trans 'Actions' %}">
@@ -55,15 +57,33 @@
</a>
{% endfor %}
</div>
+
<div class="btn-group btn-group-sm" role="group"
aria-label="{% trans 'Export' %}">
- <a class="btn btn-secondary" href='{% url show_url item.pk "odt" %}'
- title='{% trans "Export as OpenOffice.org file"%}'>
- ODT <i class="fa fa-file-word-o" aria-hidden="true"></i>
- <a class="btn btn-secondary" href='{% url show_url item.pk "pdf" %}'
- title='{% trans "Export as PDF file"%}'>
- PDF <i class="fa fa-file-pdf-o" aria-hidden="true"></i>
- </a>
+ <div class="dropdown btn-secondary">
+ <button class="btn btn-sm btn-secondary dropdown-toggle" type="button"
+ id="dropdown-sheet-export-{{window_id}}"
+ data-toggle="dropdown"aria-haspopup="true"
+ aria-expanded="false">
+ <i class="fa fa-file-word-o"></i> {% trans "Export" %}
+ </button>
+ <div class="dropdown-menu"
+ aria-labelledby="dropdown-sheet-export-{{window_id}}">
+ <a class="dropdown-item" href='{% url show_url item.pk "odt" %}'
+ title='{% trans "Export as OpenOffice.org file"%}'>
+ ODT <i class="fa fa-file-word-o" aria-hidden="true"></i>
+ </a>
+ <a class="dropdown-item" href='{% url show_url item.pk "pdf" %}'
+ title='{% trans "Export as PDF file"%}'>
+ PDF <i class="fa fa-file-pdf-o" aria-hidden="true"></i>
+ </a>{% for template_name, template_url in extra_templates %}
+ <a class="dropdown-item" href='{{template_url}}'>
+ {{template_name}} <i class="fa fa-file-word-o" aria-hidden="true"></i>
+ </a>{% endfor %}
+ </div>
+ </div>
+
+
</div>
</div>
</div>
diff --git a/ishtar_common/templates/ishtar/form.html b/ishtar_common/templates/ishtar/form.html
index b99d504a0..bcd69959e 100644
--- a/ishtar_common/templates/ishtar/form.html
+++ b/ishtar_common/templates/ishtar/form.html
@@ -1,5 +1,8 @@
{% extends "base.html" %}
{% load i18n inline_formset table_form %}
+{% block extra_head %}
+{{form.media}}
+{% endblock %}
{% block pre_container %}
<form enctype="multipart/form-data" action="." method="post"{% if confirm %}
onsubmit='return confirm("{{confirm}}");'{% endif %}>{% csrf_token %}
diff --git a/ishtar_common/templates/ishtar/forms/qa_base.html b/ishtar_common/templates/ishtar/forms/qa_base.html
index 70fe70e65..367acfcd8 100644
--- a/ishtar_common/templates/ishtar/forms/qa_base.html
+++ b/ishtar_common/templates/ishtar/forms/qa_base.html
@@ -1,7 +1,6 @@
{% load i18n inline_formset table_form %}
-<div
- class="modal-dialog {% if modal_size == 'large' %}modal-lg {% elif modal_size == 'small'%}modal-sm {% endif%}modal-dialog-centered">
+<div class="modal-dialog {% if modal_size == 'large' %}modal-lg {% elif modal_size == 'small'%}modal-sm {% endif%}modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h2>{{page_name|safe}}</h2>
diff --git a/ishtar_common/templates/ishtar/wizard/confirm_wizard.html b/ishtar_common/templates/ishtar/wizard/confirm_wizard.html
index 401fe570c..9829058a8 100644
--- a/ishtar_common/templates/ishtar/wizard/confirm_wizard.html
+++ b/ishtar_common/templates/ishtar/wizard/confirm_wizard.html
@@ -9,7 +9,12 @@
<form action="." method="post">{% csrf_token %}
<div class='form'>
{% block "warning_informations" %}{% endblock %}
- <p>{% if confirm_msg %}{{confirm_msg|safe}}{%else%}{% trans "You have entered the following informations:" %}{%endif%}</p>
+ {% block "warning_message" %}
+ <div class="alert alert-info">
+ {% if confirm_msg %}{{confirm_msg|safe}}{%else%}{% trans "You have entered the following informations:" %}{%endif%}
+ </div>
+ {% endblock %}
+ {% block "detailed_informations" %}
{% for form_label, form_data in datas %}
<div class="card">
@@ -42,6 +47,7 @@
{{ extra_form }}
</table>
{% endif %}
+ {% endblock %}
{% block "extra_informations" %}{% endblock %}
{% block "footer" %}
diff --git a/ishtar_common/templatetags/ishtar_helpers.py b/ishtar_common/templatetags/ishtar_helpers.py
new file mode 100644
index 000000000..88dd68b57
--- /dev/null
+++ b/ishtar_common/templatetags/ishtar_helpers.py
@@ -0,0 +1,19 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from datetime import datetime
+
+from django.template import Library
+from django.utils.translation import ugettext as _
+
+register = Library()
+
+
+@register.filter
+def or_(value1, value2):
+ return value1 or value2
+
+
+@register.filter
+def and_(value1, value2):
+ return value1 and value2
diff --git a/ishtar_common/templatetags/window_field.py b/ishtar_common/templatetags/window_field.py
index 46329a3fa..a5bae3b72 100644
--- a/ishtar_common/templatetags/window_field.py
+++ b/ishtar_common/templatetags/window_field.py
@@ -108,6 +108,14 @@ def field_flex_multiple(caption, data, small=False):
return field_multiple(caption, data, size=size)
+@register.inclusion_tag('ishtar/blocks/window_field_flex_multiple_full.html')
+def field_flex_multiple_full(caption, data, small=False):
+ size = None
+ if small:
+ size = 2
+ return field_multiple(caption, data, size=size)
+
+
@register.inclusion_tag('ishtar/blocks/window_field_detail.html')
def field_detail(caption, item, li=False, size=None):
return {'caption': caption, 'item': item, 'link': link_to_window(item),
diff --git a/ishtar_common/templatetags/window_header.py b/ishtar_common/templatetags/window_header.py
index 18dc793bf..bbd923d41 100644
--- a/ishtar_common/templatetags/window_header.py
+++ b/ishtar_common/templatetags/window_header.py
@@ -10,8 +10,17 @@ def window_nav(context, item, window_id, show_url, modify_url='', histo_url='',
extra_actions = []
if hasattr(item, 'get_extra_actions'):
extra_actions = item.get_extra_actions(context['request'])
- if modify_url and hasattr(item, 'can_do') and hasattr(item, 'SLUG') and \
- not item.can_do(context['request'], 'change_' + item.SLUG):
+ extra_templates = []
+ if hasattr(item, 'get_extra_templates'):
+ extra_templates = item.get_extra_templates(context['request'])
+
+ slug = None
+ if hasattr(item, "LONG_SLUG"):
+ slug = item.LONG_SLUG
+ elif hasattr(item, "SLUG"):
+ slug = item.SLUG
+ if modify_url and hasattr(item, 'can_do') and slug and \
+ not item.can_do(context['request'], 'change_' + slug):
modify_url = ""
return {
'show_url': show_url,
@@ -23,7 +32,21 @@ def window_nav(context, item, window_id, show_url, modify_url='', histo_url='',
'previous': previous,
'next': nxt,
'extra_actions': extra_actions,
- 'pin_action': pin_action}
+ 'pin_action': pin_action,
+ 'extra_templates': extra_templates,
+ }
+
+
+@register.inclusion_tag('ishtar/blocks/window_find_nav.html',
+ takes_context=True)
+def window_find_nav(context, item, window_id, show_url, modify_url='',
+ histo_url='', revert_url='', previous=None, nxt=None,
+ pin_action=False, baskets=None):
+ dct = window_nav(context, item, window_id, show_url, modify_url=modify_url,
+ histo_url=histo_url, revert_url=revert_url,
+ previous=previous, nxt=nxt, pin_action=pin_action)
+ dct['baskets'] = baskets
+ return dct
@register.inclusion_tag('ishtar/blocks/window_file_nav.html',
diff --git a/ishtar_common/tests.py b/ishtar_common/tests.py
index bd1833594..cf9f599c4 100644
--- a/ishtar_common/tests.py
+++ b/ishtar_common/tests.py
@@ -1235,10 +1235,14 @@ class ShortMenuTest(TestCase):
self.assertFalse(str(tf.cached_label) in response.content)
def _create_treatment(self):
- from archaeological_finds.models import Treatment
+ from archaeological_finds.models import Treatment, TreatmentState
+ completed, created = TreatmentState.objects.get_or_create(
+ txt_idx='completed', defaults={"executed": True, "label": u"Done"}
+ )
return Treatment.objects.create(
label="My treatment",
- year=2052
+ year=2052,
+ treatment_state=completed
)
def test_treatment(self):
diff --git a/ishtar_common/urls.py b/ishtar_common/urls.py
index 8d06b6862..aea419d08 100644
--- a/ishtar_common/urls.py
+++ b/ishtar_common/urls.py
@@ -174,6 +174,8 @@ urlpatterns += [
views.new_person_noorga, name='new-person-noorga'),
url(r'autocomplete-user/$',
views.autocomplete_user, name='autocomplete-user'),
+ url(r'autocomplete-ishtaruser/$',
+ views.autocomplete_ishtaruser, name='autocomplete-ishtaruser'),
url(r'autocomplete-person(?:/([0-9_]+))?(?:/([0-9_]*))?/(user)?$',
views.autocomplete_person, name='autocomplete-person'),
url(r'autocomplete-person-permissive(?:/([0-9_]+))?(?:/([0-9_]*))?'
diff --git a/ishtar_common/utils.py b/ishtar_common/utils.py
index 4f968af31..ff67fc470 100644
--- a/ishtar_common/utils.py
+++ b/ishtar_common/utils.py
@@ -145,18 +145,24 @@ def check_model_access_control(request, model, available_perms=None):
return allowed, own
-def update_data(data_1, data_2):
+def update_data(data_1, data_2, merge=False):
"""
Update a data directory taking account of key detail
"""
res = {}
if not isinstance(data_1, dict) or not isinstance(data_2, dict):
+ if data_2 and not data_1:
+ return data_2
+ if not merge:
+ return data_1
+ if data_2 and data_2 != data_1:
+ return data_1 + u" ; " + data_2
return data_1
for k in data_1:
if k not in data_2:
res[k] = data_1[k]
else:
- res[k] = update_data(data_1[k], data_2[k])
+ res[k] = update_data(data_1[k], data_2[k], merge=merge)
for k in data_2:
if k not in data_1:
res[k] = data_2[k]
diff --git a/ishtar_common/views.py b/ishtar_common/views.py
index 3d64535d4..72418e4fa 100644
--- a/ishtar_common/views.py
+++ b/ishtar_common/views.py
@@ -527,6 +527,29 @@ def autocomplete_user(request):
return HttpResponse(data, content_type='text/plain')
+def autocomplete_ishtaruser(request):
+ if not request.user.has_perm('ishtar_common.view_person', models.Person):
+ return HttpResponse('[]', content_type='text/plain')
+ q = request.GET.get('term', '')
+ limit = request.GET.get('limit', 20)
+ try:
+ limit = int(limit)
+ except ValueError:
+ return HttpResponseBadRequest()
+ query = Q()
+ for q in q.split(' '):
+ qu = (Q(person__name__icontains=q) |
+ Q(person__surname__icontains=q) |
+ Q(person__raw_name__icontains=q))
+ query = query & qu
+ users = models.IshtarUser.objects.filter(query)[:limit]
+ data = json.dumps([
+ {'id': user.pk,
+ 'value': unicode(user)}
+ for user in users])
+ return HttpResponse(data, content_type='text/plain')
+
+
def autocomplete_person(request, person_types=None, attached_to=None,
is_ishtar_user=None, permissive=False):
all_items = request.user.has_perm('ishtar_common.view_person',
@@ -1754,6 +1777,32 @@ def get_bookmark(request, pk):
)
+def gen_generate_doc(model):
+
+ def func(request, pk, template_pk=None):
+ if not request.user.has_perm('view_' + model.SLUG, model):
+ return HttpResponse(content_type='text/plain')
+ try:
+ item = model.objects.get(pk=pk)
+ doc = item.publish(template_pk)
+ except model.DoesNotExist:
+ doc = None
+ if doc:
+ MIMES = {'odt': 'application/vnd.oasis.opendocument.text',
+ 'ods': 'application/vnd.oasis.opendocument.spreadsheet'}
+ ext = doc.split('.')[-1]
+ doc_name = item.get_filename() + "." + ext
+ mimetype = 'text/csv'
+ if ext in MIMES:
+ mimetype = MIMES[ext]
+ response = HttpResponse(open(doc), content_type=mimetype)
+ response['Content-Disposition'] = 'attachment; filename=%s' % \
+ doc_name
+ return response
+ return HttpResponse(content_type='text/plain')
+ return func
+
+
class SearchQueryMixin(object):
"""
Manage content type and profile init
@@ -1978,3 +2027,5 @@ class QAItemEditForm(QAItemForm):
def form_save(self, form):
form.save(self.items, self.request.user)
return HttpResponseRedirect(reverse("success"))
+
+
diff --git a/ishtar_common/views_item.py b/ishtar_common/views_item.py
index cde3f8d87..6f4abdee9 100644
--- a/ishtar_common/views_item.py
+++ b/ishtar_common/views_item.py
@@ -22,7 +22,8 @@ from django.db.models.fields import FieldDoesNotExist
from django.http import HttpResponse
from django.shortcuts import render
from django.template import loader
-from django.utils.translation import ugettext, ugettext_lazy as _
+from django.utils.translation import ugettext, ugettext_lazy as _, \
+ activate, deactivate, pgettext_lazy
from tidylib import tidy_document as tidy
from unidecode import unidecode
from weasyprint import HTML, CSS
@@ -65,17 +66,29 @@ CURRENT_ITEM_KEYS = (
CURRENT_ITEM_KEYS_DICT = dict(CURRENT_ITEM_KEYS)
+def get_autocomplete_query(request, label_attributes, extra=None):
+ q = request.GET.get('term') or ""
+ if not label_attributes:
+ return Q(pk__isnull=True)
+ query = Q()
+ if extra:
+ query = Q(**extra)
+ for q in q.split(' '):
+ if not q:
+ continue
+ sub_q = Q(**{label_attributes[0] + "__icontains": q})
+ for other_label in label_attributes[1:]:
+ sub_q = sub_q | Q(**{other_label + "__icontains": q})
+ query = query & sub_q
+ return query
+
+
def get_autocomplete_item(model, extra=None):
if not extra:
extra = {}
def func(request, current_right=None):
- q = request.GET.get('term') or ""
- query = Q(**extra)
- for q in q.split(' '):
- if not q:
- continue
- query = query & Q(cached_label__icontains=q)
+ query = get_autocomplete_query(request, ['cached_label'], extra=extra)
limit = 20
objects = model.objects.filter(query)[:limit]
data = json.dumps([{'id': obj.pk, 'value': obj.cached_label}
@@ -133,22 +146,25 @@ def display_item(model, extra_dct=None, show_url=None):
return func
-def show_item(model, name, extra_dct=None):
+def show_item(model, name, extra_dct=None, model_for_perms=None):
def func(request, pk, **dct):
- allowed, own = check_model_access_control(request, model)
+ check_model = model
+ if model_for_perms:
+ check_model = model_for_perms
+ allowed, own = check_model_access_control(request, check_model)
if not allowed:
return HttpResponse('', content_type="application/xhtml")
q = model.objects
if own:
if not hasattr(request.user, 'ishtaruser'):
- return HttpResponse('NOK')
+ return HttpResponse('')
query_own = model.get_query_owns(request.user.ishtaruser)
if query_own:
q = q.filter(query_own).distinct()
try:
item = q.get(pk=pk)
- except ObjectDoesNotExist:
- return HttpResponse('NOK')
+ except (ObjectDoesNotExist, ValueError):
+ return HttpResponse('')
doc_type = 'type' in dct and dct.pop('type')
url_name = u"/".join(reverse('show-' + name, args=['0', '']
).split('/')[:-2]) + u"/"
@@ -325,6 +341,12 @@ def _push_to_list(obj, current_group, depth):
current_group.append(obj)
+def is_true_string(val):
+ val = unicode(val).lower().replace(u'"', u"")
+ if val in (u"1", u"true", unicode(_(u"True")).lower()):
+ return True
+
+
def _parse_parentheses(s):
"""
Parse parentheses into list.
@@ -368,14 +390,31 @@ def _parse_query_string(string, request_keys, current_dct, exc_dct):
if excluded:
term = term[1:]
if term in request_keys:
- term = request_keys[term]
dct = current_dct
- if excluded:
- dct = exc_dct
- if term in dct:
- dct[term] += u";" + query
+ term = request_keys[term]
+ # callable request key for complex queries
+ if callable(term):
+ is_true = is_true_string(query)
+ if excluded:
+ is_true = not is_true
+ cfltr, cexclude, cextra = term(is_true=is_true)
+ if cfltr:
+ if 'and_reqs' not in dct:
+ dct['and_reqs'] = []
+ dct['and_reqs'].append(cfltr)
+ if cexclude:
+ if 'exc_and_reqs' not in dct:
+ dct['exc_and_reqs'] = []
+ dct['exc_and_reqs'].append(cexclude)
+ if cextra:
+ dct['extras'].append(cextra)
else:
- dct[term] = query
+ if excluded:
+ dct = exc_dct
+ if term in dct:
+ dct[term] += u";" + query
+ else:
+ dct[term] = query
return u""
for reserved_char in FORBIDDEN_CHAR:
string = string.replace(reserved_char, u"")
@@ -487,6 +526,8 @@ def _search_manage_search_vector(model, dct, exc_dct, request_keys):
search_query = \
search_query.replace(u'(', u'').replace(u')', u'').strip()
if search_query:
+ if 'extras' not in dct:
+ dct['extras'] = []
dct['extras'].append(
{'where': [model._meta.db_table +
".search_vector @@ (to_tsquery(%s, %s)) = true"],
@@ -526,13 +567,47 @@ def _manage_bool_fields(model, bool_fields, reversed_bool_fields, dct, or_reqs):
pass
+today_lbl = pgettext_lazy("key for text search", u"today"),
+TODAYS = ['today']
+
+for language_code, language_lbl in settings.LANGUAGES:
+ activate(language_code)
+ TODAYS.append(unicode(today_lbl))
+ deactivate()
+
+
def _manage_dated_fields(dated_fields, dct):
for k in dated_fields:
if k in dct:
if not dct[k]:
dct.pop(k)
+ continue
+ value = dct[k].replace('"', '').strip()
+ has_today = False
+ for today in TODAYS:
+ if value.startswith(today):
+ base_date = datetime.date.today()
+ value = value[len(today):].replace(' ', '')
+ if value and value[0] in (u"-", u"+"):
+ sign = value[0]
+ try:
+ days = int(value[1:])
+ except ValueError:
+ days = 0
+ if days:
+ if sign == u"-":
+ base_date = base_date - datetime.timedelta(
+ days=days)
+ else:
+ base_date = base_date + datetime.timedelta(
+ days=days)
+ dct[k] = base_date.strftime('%Y-%m-%d')
+ has_today = True
+ break
+ if has_today:
+ continue
try:
- items = dct[k].replace('"', '').split('/')
+ items = value.split('/')
assert len(items) == 3
dct[k] = virtualtime.datetime(*map(lambda x: int(x),
reversed(items))) \
@@ -795,7 +870,12 @@ def _construct_query(relation_types, dct, or_reqs, and_reqs):
query |= Q(**alt_dct)
query = _manage_relation_types(relation_types, dct, query, or_reqs)
+ done = []
for and_req in and_reqs:
+ str_q = unicode(and_req)
+ if str_q in done:
+ continue
+ done.append(str_q)
query = query & and_req
return query
@@ -880,11 +960,13 @@ DEFAULT_ROW_NUMBER = 10
EXCLUDED_FIELDS = ['length']
-def get_item(model, func_name, default_name, extra_request_keys=[],
- base_request=None, bool_fields=[], reversed_bool_fields=[],
- dated_fields=[], associated_models=[], relative_session_names=[],
- specific_perms=[], own_table_cols=None, relation_types_prefix={},
- do_not_deduplicate=False):
+def get_item(model, func_name, default_name, extra_request_keys=None,
+ base_request=None, bool_fields=None, reversed_bool_fields=None,
+ dated_fields=None, associated_models=None,
+ relative_session_names=None, specific_perms=None,
+ own_table_cols=None, relation_types_prefix=None,
+ do_not_deduplicate=False, model_for_perms=None,
+ alt_query_own=None):
"""
Generic treatment of tables
@@ -904,6 +986,8 @@ def get_item(model, func_name, default_name, extra_request_keys=[],
:param do_not_deduplicate: duplication of id can occurs on large queryset a
mecanism of deduplication is used. But duplicate ids can be normal (for
instance for record_relations view).
+ :param model_for_perms: use another model to check permission
+ :param alt_query_own: name of alternate method to get query_own
:return:
"""
def func(request, data_type='json', full=False, force_own=False,
@@ -915,10 +999,15 @@ def get_item(model, func_name, default_name, extra_request_keys=[],
if 'type' in dct:
data_type = dct.pop('type')
if not data_type:
- EMPTY = '[]'
data_type = 'json'
+ if data_type == "json":
+ EMPTY = '[]'
- allowed, own = check_model_access_control(request, model,
+ model_to_check = model
+ if model_for_perms:
+ model_to_check = model_for_perms
+
+ allowed, own = check_model_access_control(request, model_to_check,
available_perms)
if not allowed:
return HttpResponse(EMPTY, content_type='text/plain')
@@ -934,13 +1023,16 @@ def get_item(model, func_name, default_name, extra_request_keys=[],
q = models.IshtarUser.objects.filter(user_ptr=request.user)
if not q.count():
return HttpResponse(EMPTY, content_type='text/plain')
- query_own = model.get_query_owns(q.all()[0])
+ if alt_query_own:
+ query_own = getattr(model, alt_query_own)(q.all()[0])
+ else:
+ query_own = model.get_query_owns(q.all()[0])
# get defaults from model
if not extra_request_keys and hasattr(model, 'EXTRA_REQUEST_KEYS'):
my_extra_request_keys = copy(model.EXTRA_REQUEST_KEYS)
else:
- my_extra_request_keys = copy(extra_request_keys)
+ my_extra_request_keys = copy(extra_request_keys or [])
if base_request is None and hasattr(model, 'BASE_REQUEST'):
if callable(model.BASE_REQUEST):
my_base_request = model.BASE_REQUEST(request)
@@ -953,32 +1045,35 @@ def get_item(model, func_name, default_name, extra_request_keys=[],
if not bool_fields and hasattr(model, 'BOOL_FIELDS'):
my_bool_fields = model.BOOL_FIELDS[:]
else:
- my_bool_fields = bool_fields[:]
+ my_bool_fields = bool_fields[:] if bool_fields else []
if not reversed_bool_fields and hasattr(model, 'REVERSED_BOOL_FIELDS'):
my_reversed_bool_fields = model.REVERSED_BOOL_FIELDS[:]
else:
- my_reversed_bool_fields = reversed_bool_fields[:]
+ my_reversed_bool_fields = reversed_bool_fields[:] \
+ if reversed_bool_fields else []
if not dated_fields and hasattr(model, 'DATED_FIELDS'):
my_dated_fields = model.DATED_FIELDS[:]
else:
- my_dated_fields = dated_fields[:]
+ my_dated_fields = dated_fields[:] if dated_fields else []
if not associated_models and hasattr(model, 'ASSOCIATED_MODELS'):
my_associated_models = model.ASSOCIATED_MODELS[:]
else:
- my_associated_models = associated_models[:]
+ my_associated_models = associated_models[:] \
+ if associated_models else []
if not relative_session_names and hasattr(model,
'RELATIVE_SESSION_NAMES'):
my_relative_session_names = model.RELATIVE_SESSION_NAMES[:]
else:
- my_relative_session_names = relative_session_names[:]
+ my_relative_session_names = relative_session_names[:] \
+ if relative_session_names else []
if not relation_types_prefix and hasattr(model,
'RELATION_TYPES_PREFIX'):
my_relation_types_prefix = copy(model.RELATION_TYPES_PREFIX)
else:
- my_relation_types_prefix = copy(relation_types_prefix)
+ my_relation_types_prefix = copy(relation_types_prefix) \
+ if relation_types_prefix else {}
- fields = [model._meta.get_field(k)
- for k in get_all_field_names(model)]
+ fields = [model._meta.get_field(k) for k in get_all_field_names(model)]
request_keys = dict([
(field.name,
@@ -1039,6 +1134,7 @@ def get_item(model, func_name, default_name, extra_request_keys=[],
excluded_dct = {}
and_reqs, or_reqs = [], []
exc_and_reqs, exc_or_reqs = [], []
+ dct['extras'], dct['and_reqs'], dct['exc_and_reqs'] = [], [], []
if full == 'shortcut':
if model.SLUG == "warehouse":
@@ -1057,7 +1153,10 @@ def get_item(model, func_name, default_name, extra_request_keys=[],
if not val:
continue
req_keys = request_keys[k]
- if type(req_keys) not in (list, tuple):
+ if callable(req_keys):
+ # callable request key for complex queries not managed on GET
+ continue
+ elif type(req_keys) not in (list, tuple):
dct[req_keys] = val
continue
# multiple choice target
@@ -1080,7 +1179,6 @@ def get_item(model, func_name, default_name, extra_request_keys=[],
else:
request.session[func_name] = dct
- dct['extras'] = []
dct, excluded_dct = _search_manage_search_vector(
model, dct, excluded_dct, request_keys)
search_vector = ""
@@ -1116,7 +1214,13 @@ def get_item(model, func_name, default_name, extra_request_keys=[],
_manage_facet_search(model, dct, and_reqs)
_manage_facet_search(model, excluded_dct, exc_and_reqs)
- extras = dct.pop('extras')
+ extras = []
+ if 'extras' in dct:
+ extras = dct.pop('extras')
+ if 'and_reqs' in dct:
+ and_reqs += dct.pop('and_reqs')
+ if 'exc_and_reqs' in dct:
+ exc_and_reqs += dct.pop('exc_and_reqs')
_manage_clean_search_field(dct)
_manage_clean_search_field(excluded_dct)
diff --git a/ishtar_common/widgets.py b/ishtar_common/widgets.py
index 7d9e06926..5853c9675 100644
--- a/ishtar_common/widgets.py
+++ b/ishtar_common/widgets.py
@@ -224,6 +224,10 @@ class Select2Base(Select2Media):
else:
attrs['style'] = "width: 370px"
+ if value:
+ if type(value) not in (list, tuple):
+ value = value.split(',')
+
options = ""
if self.remote:
options = """{
@@ -248,8 +252,6 @@ class Select2Base(Select2Media):
}""" % self.remote
if value:
choices = []
- if type(value) not in (list, tuple):
- value = value.split(',')
for v in value:
try:
choices.append((v, self.model.objects.get(pk=v)))
@@ -300,7 +302,7 @@ class CheckboxSelectMultiple(CheckboxSelectMultipleBase):
def render(self, name, value, attrs=None, choices=()):
if type(value) in (str, unicode):
value = value.split(',')
- if type(value) not in (list, tuple):
+ if not isinstance(value, (list, tuple)):
value = [value]
return super(CheckboxSelectMultiple, self).render(name, value, attrs)
@@ -356,6 +358,14 @@ class Select2BaseField(object):
class Select2MultipleField(Select2BaseField, forms.MultipleChoiceField):
multiple = True
+ def to_python(self, value):
+ if not isinstance(value, (list, tuple)):
+ if value:
+ value = value.split(',')
+ else:
+ value = []
+ return super(Select2MultipleField, self).to_python(value)
+
class Select2SimpleField(Select2BaseField, forms.ChoiceField):
pass
@@ -470,6 +480,36 @@ class SquareMeterWidget(forms.TextInput):
return mark_safe(rendered)
+class GramKilogramWidget(forms.TextInput):
+ def render(self, name, value, attrs=None, renderer=None):
+ if not value:
+ value = u""
+ final_attrs = flatatt(
+ self.build_attrs(attrs, {"name": name, "value": value}))
+ dct = {'final_attrs': final_attrs,
+ 'unit': u"g",
+ 'id': attrs['id'],
+ "safe_id": attrs['id'].replace('-', '_')}
+ t = loader.get_template('blocks/GramKilogramWidget.html')
+ rendered = t.render(dct)
+ return mark_safe(rendered)
+
+
+class CentimeterMeterWidget(forms.TextInput):
+ def render(self, name, value, attrs=None, renderer=None):
+ if not value:
+ value = u""
+ final_attrs = flatatt(
+ self.build_attrs(attrs, {"name": name, "value": value}))
+ dct = {'final_attrs': final_attrs,
+ 'unit': u"cm",
+ 'id': attrs['id'],
+ "safe_id": attrs['id'].replace('-', '_')}
+ t = loader.get_template('blocks/CentimeterMeterWidget.html')
+ rendered = t.render(dct)
+ return mark_safe(rendered)
+
+
AreaWidget = forms.TextInput
if settings.SURFACE_UNIT == 'square-metre':
@@ -927,7 +967,7 @@ class DataTable(Select2Media, forms.RadioSelect):
:param new:
:param new_message:
:param source_full: url to get full listing
- :param multiple_select:
+ :param multiple_select: select multiple is available
:param sortname: column name (model attribute) to use to sort
:param col_prefix: prefix to remove to col_names
"""
@@ -1055,7 +1095,6 @@ class DataTable(Select2Media, forms.RadioSelect):
if hasattr(self.associated_model, "QUICK_ACTIONS"):
dct['quick_actions'] = \
self.associated_model.get_quick_actions(user=self.user)
- self.multiple_select = True
source = unicode(self.source)
dct.update({'name': name,
'col_names': col_names,
diff --git a/ishtar_common/wizards.py b/ishtar_common/wizards.py
index a439cc014..47355dd06 100644
--- a/ishtar_common/wizards.py
+++ b/ishtar_common/wizards.py
@@ -23,6 +23,7 @@ import os
# from functools import wraps
from django.conf import settings
+from django.contrib import messages
from formtools.wizard.views import NamedUrlWizardView, normalize_name, \
get_storage, StepsHelper
@@ -115,6 +116,7 @@ class Wizard(IshtarWizard):
)
main_item_select_keys = ('selec-',)
formset_pop_deleted = True
+ alt_is_own_method = None # alternate method name for "is_own" check
saved_args = {} # argument to pass on object save
@@ -145,29 +147,39 @@ class Wizard(IshtarWizard):
form, other_check)
return kwargs
+ def check_own_permissions(self, request, step=None, *args, **kwargs):
+ # reinit default dispatch of a wizard - not clean...
+ self.request = request
+ self.session = request.session
+ self.prefix = self.get_prefix(request, *args, **kwargs)
+ self.storage = get_storage(
+ self.storage_name, self.prefix, request,
+ getattr(self, 'file_storage', None))
+ self.steps = StepsHelper(self)
+
+ current_object = self.get_current_object()
+ ishtaruser = request.user.ishtaruser \
+ if hasattr(request.user, 'ishtaruser') else None
+
+ # not the first step and current object is not owned
+ if self.steps and self.steps.first != step and current_object:
+ is_own = current_object.is_own(
+ ishtaruser, alt_query_own=self.alt_is_own_method)
+ if not is_own:
+ messages.add_message(
+ request, messages.WARNING,
+ _(u"Permission error: you cannot do this action.")
+ )
+ self.session_reset(request, self.url_name)
+ return
+ return True
+
def dispatch(self, request, *args, **kwargs):
self.current_right = kwargs.get('current_right', None)
step = kwargs.get('step', None)
# check that the current object is really owned by the current user
if step and self.current_right and '_own_' in self.current_right:
-
- # reinit default dispatch of a wizard - not clean...
- self.request = request
- self.session = request.session
- self.prefix = self.get_prefix(request, *args, **kwargs)
- self.storage = get_storage(
- self.storage_name, self.prefix, request,
- getattr(self, 'file_storage', None))
- self.steps = StepsHelper(self)
-
- current_object = self.get_current_object()
- ishtaruser = request.user.ishtaruser \
- if hasattr(request.user, 'ishtaruser') else None
-
- # not the fisrt step and current object is not owned
- if self.steps and self.steps.first != step and\
- current_object and not current_object.is_own(ishtaruser):
- self.session_reset(request, self.url_name)
+ if not self.check_own_permissions(request, *args, **kwargs):
return HttpResponseRedirect('/')
# extra filter on forms
self.filter_owns_items = True
@@ -439,7 +451,7 @@ class Wizard(IshtarWizard):
datas.append((form.form_label, form_datas))
return datas
- def get_extra_model(self, dct, form_list):
+ def get_extra_model(self, dct, m2m, form_list):
dct['history_modifier'] = self.request.user
return dct
@@ -552,7 +564,7 @@ class Wizard(IshtarWizard):
def save_model(self, dct, m2m, whole_associated_models, form_list,
return_object):
- dct = self.get_extra_model(dct, form_list)
+ dct = self.get_extra_model(dct, m2m, form_list)
obj = self.get_current_saved_object()
data = {}
if obj and hasattr(obj, 'data'):
@@ -1181,7 +1193,7 @@ class Wizard(IshtarWizard):
return vals
def get_current_object(self):
- """Get the current object for an instancied wizard"""
+ """Get the current object for an instanced wizard"""
current_obj = None
for key in self.main_item_select_keys:
main_form_key = key + self.url_name
@@ -1787,8 +1799,8 @@ class AccountWizard(Wizard):
class SourceWizard(Wizard):
model = None
- def get_extra_model(self, dct, form_list):
- dct = super(SourceWizard, self).get_extra_model(dct, form_list)
+ def get_extra_model(self, dct, m2m, form_list):
+ dct = super(SourceWizard, self).get_extra_model(dct, m2m, form_list)
if 'history_modifier' in dct:
dct.pop('history_modifier')
return dct
diff --git a/scss/custom.scss b/scss/custom.scss
index 788220466..56dbffab6 100644
--- a/scss/custom.scss
+++ b/scss/custom.scss
@@ -136,6 +136,11 @@ pre {
background-color: white;
}
+
+.tab-content{
+ padding-top: 1em;
+}
+
.input-progress.form-control:focus,
.input-progress{
background-color: $gray-300;
@@ -477,6 +482,11 @@ div#foot a:hover {
list-style: none;
}
+ul.compact{
+ padding: 0;
+ margin: 0;
+}
+
.help-text{
max-height: 250px;
overflow: auto;
@@ -600,6 +610,7 @@ div#foot a:hover {
margin: 0;
display: block;
outline: none;
+ font-size: 1.1em;
}
.ui-helper-hidden {
diff --git a/translations/de/ishtar_common.po b/translations/de/ishtar_common.po
index 46a8e7b7f..bb535ee56 100644
--- a/translations/de/ishtar_common.po
+++ b/translations/de/ishtar_common.po
@@ -36,12 +36,12 @@ msgstr ""
msgid "Export selected as CSV file"
msgstr ""
-#: admin.py:207 models.py:1686 templates/navbar.html:31
+#: admin.py:207 models.py:1703 templates/navbar.html:31
msgid "Profile"
msgstr ""
#: admin.py:208 forms_common.py:782 forms_common.py:801 forms_common.py:802
-#: models.py:3039
+#: models.py:3063
msgid "Profiles"
msgstr ""
@@ -63,7 +63,7 @@ msgstr ""
msgid "These parents are missing: {}"
msgstr ""
-#: admin.py:386 admin.py:405 models.py:883 models.py:4141
+#: admin.py:386 admin.py:405 models.py:905 models.py:4214
msgid "Parent"
msgstr ""
@@ -71,11 +71,11 @@ msgstr ""
msgid "Center"
msgstr ""
-#: admin.py:395 models.py:4003
+#: admin.py:395 models.py:4076
msgid "Limit"
msgstr ""
-#: admin.py:398 models.py:4013
+#: admin.py:398 models.py:4086
msgid "Town children"
msgstr ""
@@ -123,16 +123,16 @@ msgstr ""
msgid "Hide selected"
msgstr ""
-#: admin.py:931 models.py:2080
+#: admin.py:931 models.py:2098
msgid "Form"
msgstr ""
-#: admin.py:933 models.py:2105 models_imports.py:127
+#: admin.py:933 models.py:2123 models_imports.py:127
#: templates/ishtar/dashboards/dashboard_main.html:39
msgid "Users"
msgstr ""
-#: admin.py:953 models.py:2180
+#: admin.py:953 models.py:2202
msgid "Field"
msgstr ""
@@ -226,7 +226,7 @@ msgstr ""
msgid "Too many cols (%(user_col)d) when maximum is %(ref_col)d"
msgstr ""
-#: data_importer.py:730 views.py:1177
+#: data_importer.py:730 views.py:1200
msgid "No data provided"
msgstr ""
@@ -255,7 +255,7 @@ msgid ""
"source file."
msgstr ""
-#: data_importer.py:1236 views.py:1255 views.py:1265
+#: data_importer.py:1236 views.py:1278 views.py:1288
msgid "Not imported"
msgstr ""
@@ -320,7 +320,7 @@ msgstr ""
msgid "Enter a valid name consisting of letters, spaces and hyphens."
msgstr ""
-#: forms.py:96 forms_common.py:808 views.py:1968
+#: forms.py:96 forms_common.py:808 views.py:2017
msgid "Confirm"
msgstr ""
@@ -328,36 +328,44 @@ msgstr ""
msgid "Are you sure you want to delete?"
msgstr ""
-#: forms.py:379
+#: forms.py:410
msgid "There are identical items."
msgstr ""
-#: forms.py:535
+#: forms.py:566
msgid "Last modified by"
msgstr ""
-#: forms.py:541
+#: forms.py:572
msgid "Modified since"
msgstr ""
-#: forms.py:565 forms.py:566
+#: forms.py:596 forms.py:597
msgid "Closing date"
msgstr ""
-#: forms.py:578 forms_common.py:1272
+#: forms.py:609 forms_common.py:1272
msgid "You should select an item."
msgstr ""
-#: forms.py:579
+#: forms.py:610
msgid "Add a new item"
msgstr ""
-#: forms.py:769 models.py:2434
+#: forms.py:757
+msgid " - append to existing"
+msgstr ""
+
+#: forms.py:760
+msgid " - replace"
+msgstr ""
+
+#: forms.py:803 models.py:2457
msgid "Template"
msgstr ""
#: forms_common.py:54 forms_common.py:72 forms_common.py:317
-#: forms_common.py:556 models.py:2568 models.py:4020
+#: forms_common.py:556 models.py:2591 models.py:4093
#: templates/blocks/JQueryAdvancedTown.html:19
msgid "Town"
msgstr ""
@@ -372,8 +380,8 @@ msgid ""
"french town Saint-Denis in the Seine-Saint-Denis department.</p>"
msgstr ""
-#: forms_common.py:81 forms_common.py:1293 ishtar_menu.py:48 models.py:2952
-#: models.py:3204 models.py:3332 models.py:3495
+#: forms_common.py:81 forms_common.py:1293 ishtar_menu.py:48 models.py:2976
+#: models.py:3228 models.py:3357 models.py:3561
#: templates/ishtar/sheet_person.html:4
msgid "Person"
msgstr ""
@@ -425,17 +433,17 @@ msgid "all users"
msgstr ""
#: forms_common.py:305 forms_common.py:475 forms_common.py:609
-#: ishtar_menu.py:76 models.py:2773 models.py:2890 models.py:3292
+#: ishtar_menu.py:76 models.py:2796 models.py:2914 models.py:3317
#: templates/ishtar/sheet_organization.html:4
msgid "Organization"
msgstr ""
#: forms_common.py:308 forms_common.py:351 forms_common.py:470
#: forms_common.py:526 forms_common.py:604 forms_common.py:790
-#: forms_common.py:823 models.py:1056 models.py:1080 models.py:1879
-#: models.py:2079 models.py:2430 models.py:2765 models.py:2936 models.py:3192
-#: models.py:3999 models.py:4262 models_imports.py:98 models_imports.py:123
-#: models_imports.py:445 models_imports.py:537 models_imports.py:827
+#: forms_common.py:823 models.py:1078 models.py:1102 models.py:1897
+#: models.py:2097 models.py:2453 models.py:2788 models.py:2960 models.py:3216
+#: models.py:4072 models.py:4337 models_imports.py:98 models_imports.py:123
+#: models_imports.py:445 models_imports.py:537 models_imports.py:828
#: templates/ishtar/import_step_by_step.html:102
#: templates/ishtar/import_step_by_step.html:270
#: templates/ishtar/import_table.html:27
@@ -443,40 +451,40 @@ msgstr ""
msgid "Name"
msgstr "Name"
-#: forms_common.py:309 models.py:2721 models_imports.py:630
+#: forms_common.py:309 models.py:2744 models_imports.py:630
#: models_imports.py:631
msgid "Organization type"
msgstr ""
-#: forms_common.py:311 forms_common.py:550 models.py:2563
+#: forms_common.py:311 forms_common.py:550 models.py:2586
#: templates/ishtar/blocks/sheet_address_section.html:4
msgid "Address"
msgstr ""
-#: forms_common.py:313 forms_common.py:553 models.py:2564
+#: forms_common.py:313 forms_common.py:553 models.py:2587
msgid "Address complement"
msgstr ""
-#: forms_common.py:315 forms_common.py:554 models.py:2566
+#: forms_common.py:315 forms_common.py:554 models.py:2589
msgid "Postal code"
msgstr "Postleitzahl"
-#: forms_common.py:318 forms_common.py:557 models.py:2569
+#: forms_common.py:318 forms_common.py:557 models.py:2592
msgid "Country"
msgstr ""
#: forms_common.py:320 forms_common.py:472 forms_common.py:530
-#: forms_common.py:606 forms_common.py:731 models.py:2596
+#: forms_common.py:606 forms_common.py:731 models.py:2619
msgid "Email"
msgstr "E-Mail-Adresse"
-#: forms_common.py:321 forms_common.py:533 models.py:2581
+#: forms_common.py:321 forms_common.py:533 models.py:2604
#: templates/ishtar/sheet_person.html:27
#: templates/ishtar/wizard/wizard_person.html:33
msgid "Phone"
msgstr ""
-#: forms_common.py:322 forms_common.py:542 models.py:2593
+#: forms_common.py:322 forms_common.py:542 models.py:2616
#: templates/ishtar/sheet_person.html:45
#: templates/ishtar/wizard/wizard_person.html:54
msgid "Mobile phone"
@@ -488,8 +496,8 @@ msgid "Full text search"
msgstr ""
#: forms_common.py:352 forms_common.py:473 forms_common.py:607
-#: forms_common.py:788 models.py:1089 models.py:2767 models.py:3738
-#: models_imports.py:680 templates/ishtar/blocks/window_image_detail.html:24
+#: forms_common.py:788 models.py:1111 models.py:2790 models.py:3804
+#: models_imports.py:681 templates/ishtar/blocks/window_image_detail.html:24
#: templates/ishtar/blocks/window_tables/documents.html:8
#: templates/ishtar/import_table.html:28
#: templates/ishtar/sheet_organization.html:25
@@ -512,7 +520,7 @@ msgstr ""
msgid "Organization to merge"
msgstr ""
-#: forms_common.py:471 forms_common.py:524 forms_common.py:605 models.py:2934
+#: forms_common.py:471 forms_common.py:524 forms_common.py:605 models.py:2958
#: templates/ishtar/sheet_organization.html:24
msgid "Surname"
msgstr ""
@@ -529,25 +537,25 @@ msgstr ""
msgid "Identity"
msgstr ""
-#: forms_common.py:521 forms_common.py:1095 forms_common.py:1217 models.py:2928
-#: models.py:2930 models.py:3729 models_imports.py:632
+#: forms_common.py:521 forms_common.py:1095 forms_common.py:1217 models.py:2952
+#: models.py:2954 models.py:3795 models_imports.py:633
#: templates/ishtar/blocks/window_tables/documents.html:7
msgid "Title"
msgstr ""
-#: forms_common.py:522 models.py:2932
+#: forms_common.py:522 models.py:2956
msgid "Salutation"
msgstr ""
-#: forms_common.py:528 models.py:2938
+#: forms_common.py:528 models.py:2962
msgid "Raw name"
msgstr ""
-#: forms_common.py:531 models.py:2582
+#: forms_common.py:531 models.py:2605
msgid "Phone description"
msgstr ""
-#: forms_common.py:534 models.py:2584 models.py:2586
+#: forms_common.py:534 models.py:2607 models.py:2609
msgid "Phone description 2"
msgstr ""
@@ -555,11 +563,11 @@ msgstr ""
msgid "Phone 2"
msgstr ""
-#: forms_common.py:538 models.py:2590
+#: forms_common.py:538 models.py:2613
msgid "Phone description 3"
msgstr ""
-#: forms_common.py:540 models.py:2588
+#: forms_common.py:540 models.py:2611
msgid "Phone 3"
msgstr ""
@@ -567,23 +575,23 @@ msgstr ""
msgid "Current organization"
msgstr ""
-#: forms_common.py:559 models.py:2571
+#: forms_common.py:559 models.py:2594
msgid "Other address: address"
msgstr ""
-#: forms_common.py:562 models.py:2574
+#: forms_common.py:562 models.py:2597
msgid "Other address: address complement"
msgstr ""
-#: forms_common.py:564 models.py:2575
+#: forms_common.py:564 models.py:2598
msgid "Other address: postal code"
msgstr ""
-#: forms_common.py:566 models.py:2577
+#: forms_common.py:566 models.py:2600
msgid "Other address: town"
msgstr ""
-#: forms_common.py:568 models.py:2579
+#: forms_common.py:568 models.py:2602
msgid "Other address: country"
msgstr ""
@@ -591,7 +599,7 @@ msgstr ""
msgid "Already has an account"
msgstr ""
-#: forms_common.py:603 models.py:3293
+#: forms_common.py:603 models.py:3318
msgid "Username"
msgstr "Benutzername"
@@ -599,7 +607,8 @@ msgstr "Benutzername"
msgid "Account search"
msgstr ""
-#: forms_common.py:669 forms_common.py:709 forms_common.py:713 models.py:2829
+#: forms_common.py:669 forms_common.py:709 forms_common.py:713 models.py:2853
+#: models_imports.py:632
msgid "Person type"
msgstr ""
@@ -607,7 +616,7 @@ msgstr ""
msgid "Account"
msgstr ""
-#: forms_common.py:734 wizards.py:1639
+#: forms_common.py:734 wizards.py:1651
msgid "New password"
msgstr ""
@@ -627,7 +636,7 @@ msgstr ""
msgid "This username already exists."
msgstr ""
-#: forms_common.py:789 models.py:3195 models.py:4148
+#: forms_common.py:789 models.py:3219 models.py:4221
msgid "Areas"
msgstr ""
@@ -635,11 +644,11 @@ msgstr ""
msgid "Send the new password by email?"
msgstr ""
-#: forms_common.py:821 models.py:3197 views.py:968
+#: forms_common.py:821 models.py:3221 views.py:991
msgid "Current profile"
msgstr ""
-#: forms_common.py:824 models.py:3175 models.py:3194
+#: forms_common.py:824 models.py:3199 models.py:3218
msgid "Profile type"
msgstr ""
@@ -667,8 +676,8 @@ msgstr ""
msgid " (duplicate)"
msgstr ""
-#: forms_common.py:932 forms_common.py:946 forms_common.py:947 models.py:4021
-#: models.py:4136
+#: forms_common.py:932 forms_common.py:946 forms_common.py:947 models.py:4094
+#: models.py:4209
msgid "Towns"
msgstr ""
@@ -695,19 +704,19 @@ msgstr ""
msgid "Document - General"
msgstr ""
-#: forms_common.py:1098 forms_common.py:1218 models.py:3543
-#: models_imports.py:633
+#: forms_common.py:1098 forms_common.py:1218 models.py:3609
+#: models_imports.py:634
msgid "Source type"
msgstr ""
#: forms_common.py:1101 forms_common.py:1152 forms_common.py:1333
-#: forms_common.py:1334 models.py:3504 models.py:3612 models.py:3748
+#: forms_common.py:1334 models.py:3570 models.py:3678 models.py:3814
#: templates/ishtar/blocks/window_image_detail.html:9
#: templates/ishtar/blocks/window_tables/documents.html:9
msgid "Authors"
msgstr ""
-#: forms_common.py:1105 models.py:3754
+#: forms_common.py:1105 models.py:3820
msgid "Numerical ressource (web address)"
msgstr ""
@@ -720,7 +729,7 @@ msgctxt "Not directory"
msgid "File"
msgstr ""
-#: forms_common.py:1113 forms_common.py:1219 models.py:4138
+#: forms_common.py:1113 forms_common.py:1219 models.py:4211
msgid "Reference"
msgstr ""
@@ -728,38 +737,38 @@ msgstr ""
msgid "Internal reference"
msgstr ""
-#: forms_common.py:1118 models.py:3756
+#: forms_common.py:1118 models.py:3822
#: templates/ishtar/blocks/window_image_detail.html:150
msgid "Receipt date"
msgstr ""
-#: forms_common.py:1120 models.py:3758 models_imports.py:859
+#: forms_common.py:1120 models.py:3824 models_imports.py:860
#: templates/ishtar/blocks/window_image_detail.html:54
msgid "Creation date"
msgstr "Gründungsdatum"
-#: forms_common.py:1123 models.py:3761
+#: forms_common.py:1123 models.py:3827
#: templates/ishtar/blocks/window_image_detail.html:160
msgid "Receipt date in documentation"
msgstr ""
-#: forms_common.py:1125 forms_common.py:1222 models.py:473 models.py:2942
-#: models.py:3421 models.py:3764 models_imports.py:483
+#: forms_common.py:1125 forms_common.py:1222 models.py:496 models.py:2966
+#: models.py:3446 models.py:3830 models_imports.py:483
#: templates/ishtar/blocks/window_image_detail.html:170
msgid "Comment"
msgstr ""
-#: forms_common.py:1127 forms_common.py:1221 models.py:1884 models.py:3763
+#: forms_common.py:1127 forms_common.py:1221 models.py:1902 models.py:3829
#: models_imports.py:125 models_imports.py:372 models_imports.py:446
msgid "Description"
msgstr "Beschreibung"
-#: forms_common.py:1130 models.py:3765
+#: forms_common.py:1130 models.py:3831
#: templates/ishtar/blocks/window_image_detail.html:182
msgid "Additional information"
msgstr ""
-#: forms_common.py:1132 forms_common.py:1225 models.py:3767
+#: forms_common.py:1132 forms_common.py:1225 models.py:3833
#: templates/ishtar/blocks/window_image_detail.html:108
msgid "Has a duplicate"
msgstr ""
@@ -790,11 +799,11 @@ msgid "You should at least fill one of this field: title, url, image or file."
msgstr ""
#: forms_common.py:1179
-msgid "A document have to attached at least to one item"
+msgid "A document has to be attached at least to one item"
msgstr ""
#: forms_common.py:1214 forms_common.py:1286 forms_common.py:1321
-#: models.py:3503 templates/ishtar/wizard/wizard_person_deletion.html:139
+#: models.py:3569 templates/ishtar/wizard/wizard_person_deletion.html:139
msgid "Author"
msgstr ""
@@ -822,7 +831,7 @@ msgstr ""
msgid "Would you like to delete this documentation?"
msgstr ""
-#: forms_common.py:1294 models.py:3468 models.py:3497 models_imports.py:634
+#: forms_common.py:1294 models.py:3534 models.py:3563 models_imports.py:635
msgid "Author type"
msgstr ""
@@ -834,11 +843,11 @@ msgstr ""
msgid "There are identical authors."
msgstr ""
-#: forms_common.py:1339 models.py:1683
+#: forms_common.py:1339 models.py:1700
msgid "Query"
msgstr ""
-#: forms_common.py:1344 models.py:1687
+#: forms_common.py:1344 models.py:1704
msgid "Is an alert"
msgstr ""
@@ -878,7 +887,7 @@ msgstr ""
msgid "Deletion"
msgstr ""
-#: ishtar_menu.py:40 models.py:2209 views.py:992
+#: ishtar_menu.py:40 models.py:2231 views.py:1015
msgid "Global variables"
msgstr ""
@@ -898,7 +907,7 @@ msgid "Creation"
msgstr "Gründung"
#: ishtar_menu.py:59 ishtar_menu.py:89 ishtar_menu.py:139
-#: templates/ishtar/forms/qa_base.html:29
+#: templates/ishtar/forms/qa_base.html:28
#: templates/ishtar/forms/qa_form.html:16
msgid "Modification"
msgstr ""
@@ -911,19 +920,19 @@ msgstr ""
msgid "Manual merge"
msgstr ""
-#: ishtar_menu.py:110 models_imports.py:882
+#: ishtar_menu.py:110 models_imports.py:883
msgid "Imports"
msgstr ""
-#: ishtar_menu.py:113 views.py:1000
+#: ishtar_menu.py:113 views.py:1023
msgid "New import"
msgstr ""
-#: ishtar_menu.py:117 views.py:1019
+#: ishtar_menu.py:117 views.py:1042
msgid "Current imports"
msgstr ""
-#: ishtar_menu.py:121 views.py:1468
+#: ishtar_menu.py:121 views.py:1491
msgid "Old imports"
msgstr ""
@@ -935,35 +944,35 @@ msgstr ""
msgid "Not a valid item."
msgstr ""
-#: models.py:211
+#: models.py:212
msgid "A selected item is not a valid item."
msgstr ""
-#: models.py:222
+#: models.py:224
msgid "This item already exists."
msgstr ""
-#: models.py:465 models.py:1682 models.py:2191 models.py:2528 models.py:2544
-#: models.py:3420 models_imports.py:368
+#: models.py:488 models.py:1699 models.py:2213 models.py:2551 models.py:2567
+#: models.py:3445 models_imports.py:368
msgid "Label"
msgstr ""
-#: models.py:467
+#: models.py:490
msgid "Textual ID"
msgstr ""
-#: models.py:470
+#: models.py:493
msgid ""
"The slug is the standardized version of the name. It contains only lowercase "
"letters, numbers and hyphens. Each slug must be unique."
msgstr ""
-#: models.py:474 models.py:2081 models.py:2437 models.py:3425
+#: models.py:497 models.py:2099 models.py:2460 models.py:3450
#: models_imports.py:139 models_imports.py:542
msgid "Available"
msgstr ""
-#: models.py:898 models.py:1083 models_imports.py:563
+#: models.py:920 models.py:1105 models_imports.py:563
#: templates/ishtar/formset_import_match.html:21
#: templates/ishtar/import_step_by_step.html:171
#: templates/ishtar/import_step_by_step.html:199
@@ -972,473 +981,473 @@ msgstr ""
msgid "Key"
msgstr ""
-#: models.py:904
+#: models.py:926
msgid "Specific key to an import"
msgstr ""
-#: models.py:1043
+#: models.py:1065
msgid "Generated relation image (SVG)"
msgstr ""
-#: models.py:1057 models.py:1091 models.py:1604 models.py:2193 models.py:3465
-#: models.py:4165 models.py:4247
+#: models.py:1079 models.py:1113 models.py:1621 models.py:2215 models.py:3531
+#: models.py:4238 models.py:4320
msgid "Order"
msgstr ""
-#: models.py:1060
+#: models.py:1082
msgid "Json data - Menu"
msgstr ""
-#: models.py:1061
+#: models.py:1083
msgid "Json data - Menus"
msgstr ""
-#: models.py:1069
+#: models.py:1091
msgid "Text"
msgstr ""
-#: models.py:1070
+#: models.py:1092
msgid "Long text"
msgstr ""
-#: models.py:1071 models_imports.py:676
+#: models.py:1093 models_imports.py:677
msgid "Integer"
msgstr ""
-#: models.py:1072
+#: models.py:1094
msgid "Boolean"
msgstr ""
-#: models.py:1073 models_imports.py:677
+#: models.py:1095 models_imports.py:678
msgid "Float"
msgstr ""
-#: models.py:1074 models_imports.py:679
+#: models.py:1096 models_imports.py:680
msgid "Date"
msgstr ""
-#: models.py:1075
+#: models.py:1097
msgid "Choices"
msgstr ""
-#: models.py:1084
+#: models.py:1106
msgid ""
"Value of the key in the JSON schema. For hierarchical key use \"__\" to "
"explain it. For instance for the key 'my_subkey' with data such as {'my_key':"
" {'my_subkey': 'value'}}, its value will be reached with my_key__my_subkey."
msgstr ""
-#: models.py:1088
+#: models.py:1110
msgid "Display"
msgstr ""
-#: models.py:1092
+#: models.py:1114
msgid "Use in search indexes"
msgstr ""
-#: models.py:1099
+#: models.py:1121
msgid "Json data - Field"
msgstr ""
-#: models.py:1100
+#: models.py:1122
msgid "Json data - Fields"
msgstr ""
-#: models.py:1111
+#: models.py:1133
msgid "Content types of the field and of the menu do not match"
msgstr ""
-#: models.py:1171
+#: models.py:1193
msgid "Search vector"
msgstr ""
-#: models.py:1172
+#: models.py:1194
msgid "Auto filled at save"
msgstr ""
-#: models.py:1392
+#: models.py:1409
msgid "Add document/image"
msgstr ""
-#: models.py:1394
+#: models.py:1411
msgid "doc./image"
msgstr ""
-#: models.py:1413
+#: models.py:1430
msgid "Last editor"
msgstr ""
-#: models.py:1416
+#: models.py:1433
msgid "Creator"
msgstr ""
-#: models.py:1597
+#: models.py:1614
msgid "Above"
msgstr ""
-#: models.py:1598
+#: models.py:1615
msgid "Bellow"
msgstr ""
-#: models.py:1599
+#: models.py:1616
msgid "Equal"
msgstr ""
-#: models.py:1605
+#: models.py:1622
msgid "Symmetrical"
msgstr ""
-#: models.py:1606
+#: models.py:1623
msgid "Tiny label"
msgstr ""
-#: models.py:1609
+#: models.py:1626
msgid "Inverse relation"
msgstr ""
-#: models.py:1612
+#: models.py:1629
msgid "Logical relation"
msgstr ""
-#: models.py:1622
+#: models.py:1639
msgid "Cannot have symmetrical and an inverse_relation"
msgstr ""
-#: models.py:1685
+#: models.py:1702
msgid "Content type"
msgstr ""
-#: models.py:1690
+#: models.py:1707
msgid "Search query"
msgstr ""
-#: models.py:1691
+#: models.py:1708
msgid "Search queries"
msgstr ""
-#: models.py:1855
+#: models.py:1873
msgid "Euro"
msgstr ""
-#: models.py:1856
+#: models.py:1874
msgid "US dollar"
msgstr ""
-#: models.py:1857 views.py:742 views.py:803
+#: models.py:1875 views.py:765 views.py:826
msgid "Operations"
msgstr ""
-#: models.py:1858 views.py:744 views.py:807
+#: models.py:1876 views.py:767 views.py:830
msgid "Context records"
msgstr ""
-#: models.py:1859
+#: models.py:1877
msgid "Site"
msgstr ""
-#: models.py:1859
+#: models.py:1877
msgid "Archaeological entity"
msgstr ""
-#: models.py:1863
+#: models.py:1881
msgid "Site search"
msgstr ""
-#: models.py:1864
+#: models.py:1882
msgid "New site"
msgstr ""
-#: models.py:1865
+#: models.py:1883
msgid "Site modification"
msgstr ""
-#: models.py:1866
+#: models.py:1884
msgid "Site deletion"
msgstr ""
-#: models.py:1869
+#: models.py:1887
msgid "Archaeological entity search"
msgstr ""
-#: models.py:1870
+#: models.py:1888
msgid "New archaeological entity"
msgstr ""
-#: models.py:1871
+#: models.py:1889
msgid "Archaeological entity modification"
msgstr ""
-#: models.py:1872
+#: models.py:1890
msgid "Archaeological entity deletion"
msgstr ""
-#: models.py:1880 models.py:2431 models_imports.py:124
+#: models.py:1898 models.py:2454 models_imports.py:124
msgid "Slug"
msgstr ""
-#: models.py:1881
+#: models.py:1899
msgid "Current active"
msgstr ""
-#: models.py:1883
+#: models.py:1901
msgid "Activate experimental feature"
msgstr ""
-#: models.py:1886
+#: models.py:1904
msgid "Alternate configuration"
msgstr ""
-#: models.py:1888
+#: models.py:1906
msgid "Choose an alternate configuration for label, index management"
msgstr ""
-#: models.py:1892
+#: models.py:1910
msgid "Files module"
msgstr ""
-#: models.py:1894
+#: models.py:1912
msgid "Archaeological site module"
msgstr ""
-#: models.py:1896
+#: models.py:1914
msgid "Archaeological site type"
msgstr ""
-#: models.py:1900
+#: models.py:1918
msgid "Context records module"
msgstr ""
-#: models.py:1902
+#: models.py:1920
msgid "Finds module"
msgstr ""
-#: models.py:1903
+#: models.py:1921
msgid "Need context records module"
msgstr ""
-#: models.py:1905
+#: models.py:1923
msgid "Find index is based on"
msgstr ""
-#: models.py:1907
+#: models.py:1925
msgid ""
"To prevent irrelevant indexes, change this parameter only if there is no "
"find in the database"
msgstr ""
-#: models.py:1910
+#: models.py:1928
msgid "Warehouses module"
msgstr ""
-#: models.py:1911
+#: models.py:1929
msgid "Need finds module"
msgstr ""
-#: models.py:1912
+#: models.py:1930
msgid "Preservation module"
msgstr ""
-#: models.py:1914
+#: models.py:1932
msgid "Mapping module"
msgstr ""
-#: models.py:1915
+#: models.py:1933
msgid "Underwater module"
msgstr ""
-#: models.py:1917
+#: models.py:1935
msgid "Parcel are mandatory for context records"
msgstr ""
-#: models.py:1919
+#: models.py:1937
msgid "Home page"
msgstr ""
-#: models.py:1920
+#: models.py:1938
#, python-brace-format
msgid ""
"Homepage of Ishtar - if not defined a default homepage will appear. Use the "
"markdown syntax. {random_image} can be used to display a random image."
msgstr ""
-#: models.py:1924
+#: models.py:1942
msgid "Main operation code prefix"
msgstr ""
-#: models.py:1928
+#: models.py:1946
msgid "Default operation code prefix"
msgstr ""
-#: models.py:1932
+#: models.py:1950
msgid "Operation region code"
msgstr ""
-#: models.py:1936
+#: models.py:1954
msgid "File external id"
msgstr ""
-#: models.py:1938
+#: models.py:1956
msgid ""
"Formula to manage file external ID. Change this with care. With incorrect "
"formula, the application might be unusable and import of external data can "
"be destructive."
msgstr ""
-#: models.py:1943
+#: models.py:1961
msgid "Parcel external id"
msgstr ""
-#: models.py:1946
+#: models.py:1964
msgid ""
"Formula to manage parcel external ID. Change this with care. With incorrect "
"formula, the application might be unusable and import of external data can "
"be destructive."
msgstr ""
-#: models.py:1951
+#: models.py:1969
msgid "Context record external id"
msgstr ""
-#: models.py:1953
+#: models.py:1971
msgid ""
"Formula to manage context record external ID. Change this with care. With "
"incorrect formula, the application might be unusable and import of external "
"data can be destructive."
msgstr ""
-#: models.py:1958
+#: models.py:1976
msgid "Base find external id"
msgstr ""
-#: models.py:1960
+#: models.py:1978
msgid ""
"Formula to manage base find external ID. Change this with care. With "
"incorrect formula, the application might be unusable and import of external "
"data can be destructive."
msgstr ""
-#: models.py:1965
+#: models.py:1983
msgid "Find external id"
msgstr ""
-#: models.py:1967
+#: models.py:1985
msgid ""
"Formula to manage find external ID. Change this with care. With incorrect "
"formula, the application might be unusable and import of external data can "
"be destructive."
msgstr ""
-#: models.py:1972
+#: models.py:1990
msgid "Container external id"
msgstr ""
-#: models.py:1974
+#: models.py:1992
msgid ""
"Formula to manage container external ID. Change this with care. With "
"incorrect formula, the application might be unusable and import of external "
"data can be destructive."
msgstr ""
-#: models.py:1979
+#: models.py:1997
msgid "Warehouse external id"
msgstr ""
-#: models.py:1981
+#: models.py:1999
msgid ""
"Formula to manage warehouse external ID. Change this with care. With "
"incorrect formula, the application might be unusable and import of external "
"data can be destructive."
msgstr ""
-#: models.py:1986
+#: models.py:2004
msgid "Raw name for person"
msgstr ""
-#: models.py:1988
+#: models.py:2006
msgid ""
"Formula to manage person raw_name. Change this with care. With incorrect "
"formula, the application might be unusable and import of external data can "
"be destructive."
msgstr ""
-#: models.py:1992
+#: models.py:2010
msgid "Use auto index for finds"
msgstr ""
-#: models.py:1994
+#: models.py:2012
msgid "Currency"
msgstr ""
-#: models.py:1998
+#: models.py:2016
msgid "Ishtar site profile"
msgstr ""
-#: models.py:1999
+#: models.py:2017
msgid "Ishtar site profiles"
msgstr ""
-#: models.py:2083
+#: models.py:2101
msgid "Enable this form"
msgstr ""
-#: models.py:2084
+#: models.py:2102
msgid ""
"Disable with caution: disabling a form with mandatory fields may lead to "
"database errors."
msgstr ""
-#: models.py:2087
+#: models.py:2105
msgid "Apply to all"
msgstr ""
-#: models.py:2088
+#: models.py:2106
msgid ""
"Apply this form to all users. If set to True, selecting user and user type "
"is useless."
msgstr ""
-#: models.py:2094
+#: models.py:2112
msgid "Custom form"
msgstr ""
-#: models.py:2095
+#: models.py:2113
msgid "Custom forms"
msgstr ""
-#: models.py:2111
+#: models.py:2129
msgid "User types"
msgstr ""
-#: models.py:2183
+#: models.py:2205
msgid "Excluded field"
msgstr ""
-#: models.py:2184
+#: models.py:2206
msgid "Excluded fields"
msgstr ""
-#: models.py:2194 templates/blocks/form_flex_snippet.html:18
+#: models.py:2216 templates/blocks/form_flex_snippet.html:18
#: templates/blocks/table_form_snippet.html:9
msgid "Help"
msgstr ""
-#: models.py:2197
+#: models.py:2219
msgid "Custom form - Json data field"
msgstr ""
-#: models.py:2198
+#: models.py:2220
msgid "Custom form - Json data fields"
msgstr ""
-#: models.py:2202
+#: models.py:2224
msgid "Variable name"
msgstr ""
-#: models.py:2203
+#: models.py:2225
msgid "Description of the variable"
msgstr ""
-#: models.py:2205 models_imports.py:564
+#: models.py:2227 models_imports.py:564
#: templates/ishtar/formset_import_match.html:22
#: templates/ishtar/import_step_by_step.html:172
#: templates/ishtar/import_step_by_step.html:200
@@ -1446,560 +1455,564 @@ msgstr ""
msgid "Value"
msgstr ""
-#: models.py:2208
+#: models.py:2230
msgid "Global variable"
msgstr ""
-#: models.py:2335 models.py:2365
+#: models.py:2358 models.py:2388
msgid "Total"
msgstr ""
-#: models.py:2342 models.py:2529 models.py:2545
+#: models.py:2365 models.py:2552 models.py:2568
#: templates/ishtar/dashboards/dashboard_main_detail.html:211
#: templates/ishtar/dashboards/dashboard_main_detail_users.html:5
#: templates/ishtar/sheet_person.html:30
msgid "Number"
msgstr ""
-#: models.py:2429
+#: models.py:2452
msgid "Administrative Act"
msgstr ""
-#: models.py:2436
+#: models.py:2459
msgid "Associated object"
msgstr ""
-#: models.py:2441
+#: models.py:2464
msgid "Document template"
msgstr ""
-#: models.py:2442
+#: models.py:2465
msgid "Document templates"
msgstr ""
-#: models.py:2533 models.py:2546 models.py:4285 models_imports.py:853
+#: models.py:2556 models.py:2569 models.py:4360 models_imports.py:854
msgid "State"
msgstr ""
-#: models.py:2551 models.py:4007 templates/blocks/JQueryAdvancedTown.html:12
+#: models.py:2574 models.py:4080 templates/blocks/JQueryAdvancedTown.html:12
msgid "Department"
msgstr ""
-#: models.py:2552
+#: models.py:2575
msgid "Departments"
msgstr ""
-#: models.py:2592
+#: models.py:2615
msgid "Raw phone"
msgstr ""
-#: models.py:2598
+#: models.py:2621
msgid "Alternative address is prefered"
msgstr ""
-#: models.py:2637
+#: models.py:2660
msgid "Tel: "
msgstr ""
-#: models.py:2641
+#: models.py:2664
msgid "Mobile: "
msgstr ""
-#: models.py:2645
+#: models.py:2668
msgid "Email: "
msgstr "E-Mail-Adresse:"
-#: models.py:2650
+#: models.py:2673
msgid "Merge key"
msgstr ""
-#: models.py:2722
+#: models.py:2745
msgid "Organization types"
msgstr ""
-#: models.py:2749 models.py:2896 models.py:3303
+#: models.py:2772 models.py:2920 models.py:3328
msgctxt "key for text search"
msgid "name"
msgstr ""
-#: models.py:2753 models.py:2908 models.py:3315 models.py:3639
+#: models.py:2776 models.py:2932 models.py:3340 models.py:3705
msgctxt "key for text search"
msgid "type"
msgstr ""
-#: models.py:2768 models.py:2947 models.py:3498 models.py:4015
+#: models.py:2791 models.py:2971 models.py:3564 models.py:4088
msgid "Cached name"
msgstr ""
-#: models.py:2774
+#: models.py:2797
msgid "Organizations"
msgstr ""
-#: models.py:2804
+#: models.py:2828
msgid "unknown organization"
msgstr ""
-#: models.py:2830
+#: models.py:2854
msgid "Person types"
msgstr ""
-#: models.py:2843 models_imports.py:670
+#: models.py:2867 models_imports.py:671
msgid "Title type"
msgstr ""
-#: models.py:2844
+#: models.py:2868
msgid "Title types"
msgstr ""
-#: models.py:2868
+#: models.py:2892
msgid "Mr"
msgstr ""
-#: models.py:2869
+#: models.py:2893
msgid "Miss"
msgstr ""
-#: models.py:2870
+#: models.py:2894
msgid "Mr and Mrs"
msgstr ""
-#: models.py:2871
+#: models.py:2895
msgid "Mrs"
msgstr ""
-#: models.py:2872
+#: models.py:2896
msgid "Doctor"
msgstr ""
-#: models.py:2900 models.py:3307
+#: models.py:2924 models.py:3332
msgctxt "key for text search"
msgid "surname"
msgstr ""
-#: models.py:2904 models.py:3311
+#: models.py:2928 models.py:3336
msgctxt "key for text search"
msgid "email"
msgstr ""
-#: models.py:2912 models.py:3319
+#: models.py:2936 models.py:3344
msgctxt "key for text search"
msgid "organization"
msgstr ""
-#: models.py:2916
+#: models.py:2940
msgctxt "key for text search"
msgid "has-account"
msgstr ""
-#: models.py:2940
+#: models.py:2964
msgid "Contact type"
msgstr ""
-#: models.py:2943 models.py:3033
+#: models.py:2967 models.py:3057
msgid "Types"
msgstr ""
-#: models.py:2946
+#: models.py:2970
msgid "Is attached to"
msgstr ""
-#: models.py:2953
+#: models.py:2977
msgid "Persons"
msgstr ""
-#: models.py:3171
+#: models.py:3195
msgid "Groups"
msgstr ""
-#: models.py:3176
+#: models.py:3200
msgid "Profile types"
msgstr ""
-#: models.py:3187
+#: models.py:3211
msgid "Profile type summary"
msgstr ""
-#: models.py:3188
+#: models.py:3212
msgid "Profile types summary"
msgstr ""
-#: models.py:3199
+#: models.py:3223
msgid "Show field number"
msgstr ""
-#: models.py:3200
+#: models.py:3224
msgid "Automatically pin"
msgstr ""
-#: models.py:3201
+#: models.py:3225
msgid "Display pin menu"
msgstr ""
-#: models.py:3207
+#: models.py:3231
msgid "User profile"
msgstr ""
-#: models.py:3208
+#: models.py:3232
msgid "User profiles"
msgstr ""
-#: models.py:3243
+#: models.py:3267 models.py:3522
msgid " - duplicate"
msgstr ""
-#: models.py:3299
+#: models.py:3324
msgctxt "key for text search"
msgid "username"
msgstr ""
-#: models.py:3335
+#: models.py:3360
msgid "Advanced shortcut menu"
msgstr ""
-#: models.py:3338
+#: models.py:3363
msgid "Ishtar user"
msgstr ""
-#: models.py:3339
+#: models.py:3364
msgid "Ishtar users"
msgstr ""
-#: models.py:3424
+#: models.py:3449
msgid "Owner"
msgstr ""
-#: models.py:3427
-msgid "Shared with"
+#: models.py:3452
+msgid "Shared (read) with"
+msgstr ""
+
+#: models.py:3456
+msgid "Shared (read/edit) with"
msgstr ""
-#: models.py:3469
+#: models.py:3535
msgid "Author types"
msgstr ""
-#: models.py:3544
+#: models.py:3610
msgid "Source types"
msgstr ""
-#: models.py:3554 models_imports.py:669
+#: models.py:3620 models_imports.py:670
msgid "Support type"
msgstr ""
-#: models.py:3555
+#: models.py:3621
msgid "Support types"
msgstr ""
-#: models.py:3564
+#: models.py:3630
msgid "Format type"
msgstr ""
-#: models.py:3565
+#: models.py:3631
msgid "Format types"
msgstr ""
-#: models.py:3574
+#: models.py:3640
msgid "URL"
msgstr ""
-#: models.py:3577
+#: models.py:3643
msgid "License type"
msgstr ""
-#: models.py:3578
+#: models.py:3644
msgid "License types"
msgstr ""
-#: models.py:3631
+#: models.py:3697
msgctxt "key for text search"
msgid "author"
msgstr ""
-#: models.py:3635
+#: models.py:3701
msgctxt "key for text search"
msgid "title"
msgstr ""
-#: models.py:3643
+#: models.py:3709
msgctxt "key for text search"
msgid "reference"
msgstr ""
-#: models.py:3647
+#: models.py:3713
msgctxt "key for text search"
msgid "internal-reference"
msgstr ""
-#: models.py:3651
+#: models.py:3717
msgctxt "key for text search"
msgid "description"
msgstr ""
-#: models.py:3655
+#: models.py:3721
msgctxt "key for text search"
msgid "comment"
msgstr ""
-#: models.py:3659
+#: models.py:3725
msgctxt "key for text search"
msgid "additional-information"
msgstr ""
-#: models.py:3663
+#: models.py:3729
msgctxt "key for text search"
msgid "has-duplicate"
msgstr ""
-#: models.py:3667 models.py:3714
+#: models.py:3733 models.py:3780
msgctxt "key for text search"
msgid "operation"
msgstr ""
-#: models.py:3671 models.py:3717
+#: models.py:3737 models.py:3783
msgctxt "key for text search"
msgid "context-record"
msgstr ""
-#: models.py:3675 models.py:3719
+#: models.py:3741 models.py:3785
msgctxt "key for text search"
msgid "find"
msgstr ""
-#: models.py:3679 models.py:3718
+#: models.py:3745 models.py:3784
msgctxt "key for text search"
msgid "file"
msgstr ""
-#: models.py:3683 models.py:3720
+#: models.py:3749 models.py:3786
msgctxt "key for text search"
msgid "site"
msgstr ""
-#: models.py:3687 models.py:3721
+#: models.py:3753 models.py:3787
msgctxt "key for text search"
msgid "warehouse"
msgstr ""
-#: models.py:3723
+#: models.py:3789
msgctxt "key for text search"
msgid "treatment"
msgstr ""
-#: models.py:3726
+#: models.py:3792
msgctxt "key for text search"
msgid "treatment-file"
msgstr ""
-#: models.py:3732
+#: models.py:3798
msgid "Index"
msgstr ""
-#: models.py:3734
+#: models.py:3800
msgid "External ID"
msgstr ""
-#: models.py:3735 templates/ishtar/blocks/window_image_detail.html:34
+#: models.py:3801 templates/ishtar/blocks/window_image_detail.html:34
msgid "Ref."
msgstr ""
-#: models.py:3736 templates/ishtar/blocks/window_image_detail.html:44
+#: models.py:3802 templates/ishtar/blocks/window_image_detail.html:44
msgid "Internal ref."
msgstr ""
-#: models.py:3740
+#: models.py:3806
msgid "License"
msgstr ""
-#: models.py:3742 templates/ishtar/blocks/window_image_detail.html:78
+#: models.py:3808 templates/ishtar/blocks/window_image_detail.html:78
msgid "Support"
msgstr ""
-#: models.py:3744 models_imports.py:635
+#: models.py:3810 models_imports.py:636
#: templates/ishtar/blocks/window_image_detail.html:88
msgid "Format"
msgstr ""
-#: models.py:3746 templates/ishtar/blocks/window_image_detail.html:98
+#: models.py:3812 templates/ishtar/blocks/window_image_detail.html:98
msgid "Scale"
msgstr ""
-#: models.py:3750
+#: models.py:3816
msgid "Authors (raw)"
msgstr ""
-#: models.py:3762 templates/ishtar/blocks/window_image_detail.html:118
+#: models.py:3828 templates/ishtar/blocks/window_image_detail.html:118
msgid "Number of items"
msgstr ""
-#: models.py:3769
+#: models.py:3835
msgid "Symbolic links"
msgstr ""
-#: models.py:3772
+#: models.py:3838
msgid "Related"
msgstr ""
-#: models.py:3773
+#: models.py:3839
msgid "Cached value - do not edit"
msgstr ""
-#: models.py:3776 templates/ishtar/sheet_document.html:4
+#: models.py:3842 templates/ishtar/sheet_document.html:4
msgid "Document"
msgstr ""
-#: models.py:3777 templates/ishtar/sheet_person.html:113
+#: models.py:3843 templates/ishtar/sheet_person.html:113
msgid "Documents"
msgstr ""
-#: models.py:3781
+#: models.py:3847
msgid "Can view all Documents"
msgstr ""
-#: models.py:3783
+#: models.py:3849
msgid "Can view own Document"
msgstr ""
-#: models.py:3785
+#: models.py:3851
msgid "Can add own Document"
msgstr ""
-#: models.py:3787
+#: models.py:3853
msgid "Can change own Document"
msgstr ""
-#: models.py:3789
+#: models.py:3855
msgid "Can delete own Document"
msgstr ""
-#: models.py:4000
+#: models.py:4073
msgid "Surface (m2)"
msgstr ""
-#: models.py:4001
+#: models.py:4074
msgid "Localisation"
msgstr "Lokalisierung"
-#: models.py:4009
+#: models.py:4082
msgid "Year of creation"
msgstr ""
-#: models.py:4010
+#: models.py:4083
msgid ""
"Filling this field is relevant to distinguish old towns from new towns."
msgstr ""
-#: models.py:4142
+#: models.py:4215
msgid "Only four level of parent are managed."
msgstr ""
-#: models.py:4147
+#: models.py:4220
msgid "Area"
msgstr ""
-#: models.py:4166
+#: models.py:4239
msgid "Is preventive"
msgstr ""
-#: models.py:4167
+#: models.py:4240
msgid "Is judiciary"
msgstr ""
-#: models.py:4170 models_imports.py:636
+#: models.py:4243 models_imports.py:637
msgid "Operation type"
msgstr ""
-#: models.py:4171
+#: models.py:4244
msgid "Operation types"
msgstr ""
-#: models.py:4210
+#: models.py:4283
msgid "Judiciary"
msgstr ""
-#: models.py:4212
+#: models.py:4285
msgid "Preventive"
msgstr ""
-#: models.py:4214
+#: models.py:4287
msgid "Research"
msgstr ""
-#: models.py:4249
+#: models.py:4322
msgid "Authority name"
msgstr ""
-#: models.py:4250
+#: models.py:4323
msgid "Authority SRID"
msgstr ""
-#: models.py:4253 models_imports.py:668
+#: models.py:4326 models_imports.py:669
msgid "Spatial reference system"
msgstr ""
-#: models.py:4254
+#: models.py:4327
msgid "Spatial reference systems"
msgstr ""
-#: models.py:4261
+#: models.py:4336
msgid "Filename"
msgstr ""
-#: models.py:4266
+#: models.py:4341
msgid "Administration script"
msgstr ""
-#: models.py:4267
+#: models.py:4342
msgid "Administration scripts"
msgstr ""
-#: models.py:4274
+#: models.py:4349
msgid "Scheduled"
msgstr ""
-#: models.py:4275
+#: models.py:4350
msgid "In progress"
msgstr ""
-#: models.py:4276 models_imports.py:792
+#: models.py:4351 models_imports.py:793
msgid "Finished with errors"
msgstr ""
-#: models.py:4277 models_imports.py:793
+#: models.py:4352 models_imports.py:794
msgid "Finished"
msgstr ""
-#: models.py:4290
+#: models.py:4365
msgid "Result"
msgstr ""
-#: models.py:4293
+#: models.py:4368
msgid "Administration task"
msgstr ""
-#: models.py:4294
+#: models.py:4369
msgid "Administration tasks"
msgstr ""
-#: models.py:4298
+#: models.py:4373
msgid "Unknown"
msgstr ""
-#: models.py:4313
+#: models.py:4388
msgid ""
"ISHTAR_SCRIPT_DIR is not set in your local_settings. Contact your "
"administrator."
msgstr ""
-#: models.py:4322
+#: models.py:4397
msgid ""
"Your ISHTAR_SCRIPT_DIR is containing dots \"..\". As it can refer to "
"relative paths, it can be a security issue and this is not allowed. Only put "
"a full path."
msgstr ""
-#: models.py:4333
+#: models.py:4408
msgid "Your ISHTAR_SCRIPT_DIR: \"{}\" is not a valid directory."
msgstr ""
-#: models.py:4349
+#: models.py:4424
msgid ""
"Script \"{}\" is not available in your script directory. Check your "
"configuration."
@@ -2030,7 +2043,7 @@ msgid "Leave blank for no restrictions"
msgstr ""
#: models_imports.py:136
-msgid "Is template"
+msgid "Can be exported"
msgstr ""
#: models_imports.py:137
@@ -2138,11 +2151,11 @@ msgstr ""
msgid "Importer - Targets"
msgstr ""
-#: models_imports.py:525 views_item.py:847
+#: models_imports.py:525 views_item.py:346 views_item.py:950
msgid "True"
msgstr ""
-#: models_imports.py:526 views_item.py:849
+#: models_imports.py:526 views_item.py:952
msgid "False"
msgstr ""
@@ -2174,327 +2187,327 @@ msgstr ""
msgid "Importer - Targets keys"
msgstr ""
-#: models_imports.py:637
+#: models_imports.py:638
msgid "Period"
msgstr ""
-#: models_imports.py:638
+#: models_imports.py:639
msgid "Report state"
msgstr ""
-#: models_imports.py:639
+#: models_imports.py:640
msgid "Remain type"
msgstr ""
-#: models_imports.py:640
+#: models_imports.py:641
msgid "Unit"
msgstr ""
-#: models_imports.py:642
+#: models_imports.py:643
msgid "Activity type"
msgstr ""
-#: models_imports.py:644
+#: models_imports.py:645
msgid "Documentation type"
msgstr ""
-#: models_imports.py:645
+#: models_imports.py:646
msgid "Material"
msgstr ""
-#: models_imports.py:647
+#: models_imports.py:648
msgid "Conservatory state"
msgstr ""
-#: models_imports.py:648
+#: models_imports.py:649
msgid "Container type"
msgstr ""
-#: models_imports.py:650
+#: models_imports.py:651
msgid "Warehouse division"
msgstr ""
-#: models_imports.py:651
+#: models_imports.py:652
msgid "Warehouse type"
msgstr ""
-#: models_imports.py:652
+#: models_imports.py:653
msgid "Treatment type"
msgstr ""
-#: models_imports.py:654
+#: models_imports.py:655
msgid "Treatment emergency type"
msgstr ""
-#: models_imports.py:655
+#: models_imports.py:656
msgid "Object type"
msgstr ""
-#: models_imports.py:656
+#: models_imports.py:657
msgid "Integrity type"
msgstr ""
-#: models_imports.py:658
+#: models_imports.py:659
msgid "Remarkability type"
msgstr ""
-#: models_imports.py:659
+#: models_imports.py:660
msgid "Alteration type"
msgstr ""
-#: models_imports.py:661
+#: models_imports.py:662
msgid "Alteration cause type"
msgstr ""
-#: models_imports.py:662
+#: models_imports.py:663
msgid "Batch type"
msgstr ""
-#: models_imports.py:663
+#: models_imports.py:664
msgid "Checked type"
msgstr ""
-#: models_imports.py:665
+#: models_imports.py:666
msgid "Identification type"
msgstr ""
-#: models_imports.py:667
+#: models_imports.py:668
msgid "Context record relation type"
msgstr ""
-#: models_imports.py:678
+#: models_imports.py:679
msgid "String"
msgstr ""
-#: models_imports.py:681
+#: models_imports.py:682
#: templates/ishtar/dashboards/dashboard_main_detail.html:196
msgid "Year"
msgstr ""
-#: models_imports.py:682
+#: models_imports.py:683
msgid "INSEE code"
msgstr ""
-#: models_imports.py:683
+#: models_imports.py:684
msgid "String to boolean"
msgstr ""
-#: models_imports.py:684
+#: models_imports.py:685
msgctxt "filesystem"
msgid "File"
msgstr ""
-#: models_imports.py:685
+#: models_imports.py:686
msgid "Unknow type"
msgstr ""
-#: models_imports.py:702
+#: models_imports.py:703
msgid "4 digit year. e.g.: \"2015\""
msgstr ""
-#: models_imports.py:703
+#: models_imports.py:704
msgid "4 digit year/month/day. e.g.: \"2015/02/04\""
msgstr ""
-#: models_imports.py:704
+#: models_imports.py:705
msgid "Day/month/4 digit year. e.g.: \"04/02/2015\""
msgstr ""
-#: models_imports.py:720
+#: models_imports.py:721
msgid "Options"
msgstr ""
-#: models_imports.py:722
+#: models_imports.py:723
msgid "Split character(s)"
msgstr ""
-#: models_imports.py:727
+#: models_imports.py:728
msgid "Importer - Formater type"
msgstr ""
-#: models_imports.py:728
+#: models_imports.py:729
msgid "Importer - Formater types"
msgstr ""
-#: models_imports.py:784
+#: models_imports.py:785
#: templates/ishtar/dashboards/dashboard_main_detail.html:132
msgid "Created"
msgstr ""
-#: models_imports.py:785
+#: models_imports.py:786
msgid "Analyse in progress"
msgstr ""
-#: models_imports.py:786
+#: models_imports.py:787
msgid "Analysed"
msgstr ""
-#: models_imports.py:787
+#: models_imports.py:788
msgid "Check modified in queue"
msgstr ""
-#: models_imports.py:788
+#: models_imports.py:789
msgid "Import in queue"
msgstr ""
-#: models_imports.py:789
+#: models_imports.py:790
msgid "Check modified in progress"
msgstr ""
-#: models_imports.py:790
+#: models_imports.py:791
msgid "Import in progress"
msgstr ""
-#: models_imports.py:791
+#: models_imports.py:792
msgid "Partially imported"
msgstr ""
-#: models_imports.py:794
+#: models_imports.py:795
msgid "Archived"
msgstr ""
-#: models_imports.py:830
+#: models_imports.py:831
msgid "Imported file"
msgstr ""
-#: models_imports.py:832
+#: models_imports.py:833
msgid "Associated images (zip file)"
msgstr ""
-#: models_imports.py:836
+#: models_imports.py:837
msgid "If a group is selected, target key saved in this group will be used."
msgstr ""
-#: models_imports.py:839
+#: models_imports.py:840
msgid "Encoding"
msgstr ""
-#: models_imports.py:842
+#: models_imports.py:843
msgid "Skip lines"
msgstr ""
-#: models_imports.py:843
+#: models_imports.py:844
msgid "Number of header lines in your file (can be 0)."
msgstr ""
-#: models_imports.py:844
+#: models_imports.py:845
msgid "Error file"
msgstr ""
-#: models_imports.py:847
+#: models_imports.py:848
msgid "Result file"
msgstr ""
-#: models_imports.py:850
+#: models_imports.py:851
msgid "Match file"
msgstr ""
-#: models_imports.py:856
+#: models_imports.py:857
msgid "Conservative import"
msgstr ""
-#: models_imports.py:857
+#: models_imports.py:858
msgid "If set to true, do not overload existing values."
msgstr ""
-#: models_imports.py:860
+#: models_imports.py:861
msgid "End date"
msgstr ""
-#: models_imports.py:863
+#: models_imports.py:864
msgid "Remaining seconds"
msgstr ""
-#: models_imports.py:865
+#: models_imports.py:866
msgid "Current line"
msgstr ""
-#: models_imports.py:867
+#: models_imports.py:868
msgid "Number of line"
msgstr ""
-#: models_imports.py:870
+#: models_imports.py:871
msgid "Imported line numbers"
msgstr ""
-#: models_imports.py:873
+#: models_imports.py:874
msgid "Changed have been checked"
msgstr ""
-#: models_imports.py:876
+#: models_imports.py:877
msgid "Changed line numbers"
msgstr ""
-#: models_imports.py:881
+#: models_imports.py:882
msgid "Import"
msgstr ""
-#: models_imports.py:970
+#: models_imports.py:971
msgid "Analyse"
msgstr ""
-#: models_imports.py:972 models_imports.py:981
+#: models_imports.py:973 models_imports.py:982
msgid "Re-analyse"
msgstr ""
-#: models_imports.py:973
+#: models_imports.py:974
msgid "Launch import"
msgstr ""
-#: models_imports.py:976
+#: models_imports.py:977
msgid "Step by step import"
msgstr ""
-#: models_imports.py:977 models_imports.py:986
+#: models_imports.py:978 models_imports.py:987
msgid "Re-check for changes"
msgstr ""
-#: models_imports.py:979 models_imports.py:988
+#: models_imports.py:980 models_imports.py:989
msgid "Check for changes"
msgstr ""
-#: models_imports.py:982
+#: models_imports.py:983
msgid "Re-import"
msgstr ""
-#: models_imports.py:985
+#: models_imports.py:986
msgid "Step by step re-import"
msgstr ""
-#: models_imports.py:989
+#: models_imports.py:990
msgid "Archive"
msgstr ""
-#: models_imports.py:991
+#: models_imports.py:992
msgid "Unarchive"
msgstr ""
-#: models_imports.py:992 templates/ishtar/form_delete.html:11 views.py:1847
-#: widgets.py:371 widgets.py:403
+#: models_imports.py:993 templates/ishtar/form_delete.html:11 views.py:1896
+#: widgets.py:379 widgets.py:411
msgid "Delete"
msgstr ""
-#: models_imports.py:1042
+#: models_imports.py:1043
msgid "Error in the CSV file."
msgstr ""
-#: models_imports.py:1070
+#: models_imports.py:1071
msgid "Modification check {} added to the queue"
msgstr ""
-#: models_imports.py:1140
+#: models_imports.py:1141
msgid "Import {} added to the queue"
msgstr ""
-#: models_imports.py:1158
+#: models_imports.py:1159
msgid "Error on imported file: {}"
msgstr ""
-#: models_imports.py:1193
+#: models_imports.py:1194
msgid "Import {} finished with errors"
msgstr ""
-#: models_imports.py:1202
+#: models_imports.py:1203
msgid "Import {} finished with no errors"
msgstr ""
@@ -2546,12 +2559,12 @@ msgid "View on site"
msgstr ""
#: templates/admin/change_form.html:24 templates/admin/change_form.html:27
-#: views.py:1231 views.py:1236
+#: views.py:1254 views.py:1259
msgid "Previous"
msgstr ""
#: templates/admin/change_form.html:32 templates/admin/change_form.html:35
-#: views.py:1239 views.py:1242
+#: views.py:1262 views.py:1265
msgid "Next"
msgstr ""
@@ -2585,49 +2598,53 @@ msgid " items added."
msgstr ""
#: templates/base.html:47
-msgid "yes"
+msgid "Select only one item."
msgstr ""
#: templates/base.html:48
-msgid "no"
+msgid "yes"
msgstr ""
#: templates/base.html:49
-msgid "Autorefresh start. The form is disabled."
+msgid "no"
msgstr ""
#: templates/base.html:50
+msgid "Autorefresh start. The form is disabled."
+msgstr ""
+
+#: templates/base.html:51
msgid "Autorefresh end. The form is re-enabled."
msgstr ""
-#: templates/base.html:81
+#: templates/base.html:82
msgid "Current items"
msgstr ""
-#: templates/base.html:83 templates/ishtar/forms/qa_base.html:34
+#: templates/base.html:84 templates/ishtar/forms/qa_base.html:33
#: templates/ishtar/forms/qa_form.html:21 templates/ishtar/manage_basket.html:4
#: templates/welcome.html:11 templates/welcome.html:12
-#: templates/welcome.html:13 templates/welcome.html:14 wizards.py:423
+#: templates/welcome.html:13 templates/welcome.html:14 wizards.py:435
msgid ":"
msgstr ""
-#: templates/base.html:96
+#: templates/base.html:97
msgid "Sheets"
msgstr ""
-#: templates/base.html:146
+#: templates/base.html:158
msgid "Processing..."
msgstr ""
-#: templates/base.html:148
+#: templates/base.html:160
msgid "This can be long."
msgstr ""
-#: templates/base.html:150
+#: templates/base.html:162
msgid "Time to take a coffee?"
msgstr ""
-#: templates/base.html:152
+#: templates/base.html:164
msgid "Time to take another coffee?"
msgstr ""
@@ -2637,7 +2654,8 @@ msgid "Expand table"
msgstr ""
#: templates/blocks/DataTables.html:53 templates/blocks/JQueryJqGrid.html:26
-#: templates/ishtar/blocks/window_nav.html:59
+#: templates/ishtar/blocks/window_nav.html:62
+#: templates/ishtar/blocks/window_nav.html:68
#: templates/ishtar/blocks/window_tables/dynamic_documents.html:45
msgid "Export"
msgstr ""
@@ -2808,8 +2826,8 @@ msgstr ""
#: templates/ishtar/blocks/modify_toolbar.html:1
#: templates/ishtar/blocks/window_image.html:11
-#: templates/ishtar/blocks/window_nav.html:47
-#: templates/ishtar/forms/qa_base.html:57
+#: templates/ishtar/blocks/window_nav.html:49
+#: templates/ishtar/forms/qa_base.html:56
#: templates/ishtar/organization_form.html:37
#: templates/ishtar/organization_person_form.html:32
#: templates/ishtar/person_form.html:43
@@ -2834,13 +2852,17 @@ msgstr ""
msgid "Data"
msgstr ""
+#: templates/ishtar/blocks/sheet_json.html:9
+msgid "No data"
+msgstr ""
+
#: templates/ishtar/blocks/window_image_detail.html:64
msgid "Licenses"
msgstr ""
#: templates/ishtar/blocks/window_image_detail.html:111
#: templates/ishtar/import_delete.html:20 templatetags/window_field.py:17
-#: views_item.py:486 wizards.py:393
+#: views_item.py:548 wizards.py:405
msgid "Yes"
msgstr ""
@@ -2853,6 +2875,11 @@ msgstr ""
msgid "Web"
msgstr ""
+#: templates/ishtar/blocks/window_image_detail.html:193
+#: templates/ishtar/blocks/window_tables/documents.html:10
+msgid "Related to"
+msgstr ""
+
#: templates/ishtar/blocks/window_nav.html:17
msgid ""
"Are you sure to restore to this version? All changes made since this version "
@@ -2872,26 +2899,22 @@ msgstr ""
msgid "Item pined in your shortcut menu."
msgstr ""
-#: templates/ishtar/blocks/window_nav.html:43
+#: templates/ishtar/blocks/window_nav.html:45
msgid "Actions"
msgstr ""
-#: templates/ishtar/blocks/window_nav.html:61
+#: templates/ishtar/blocks/window_nav.html:73
msgid "Export as OpenOffice.org file"
msgstr ""
-#: templates/ishtar/blocks/window_nav.html:64
+#: templates/ishtar/blocks/window_nav.html:77
msgid "Export as PDF file"
msgstr ""
-#: templates/ishtar/blocks/window_nav.html:72
+#: templates/ishtar/blocks/window_nav.html:92
msgid "Relation between items are not historized."
msgstr ""
-#: templates/ishtar/blocks/window_tables/documents.html:10
-msgid "Related to"
-msgstr ""
-
#: templates/ishtar/blocks/window_tables/documents.html:11
#: templates/ishtar/blocks/window_tables/documents.html:19
msgid "Link"
@@ -2978,12 +3001,12 @@ msgstr ""
msgid "User type"
msgstr ""
-#: templates/ishtar/form.html:20 templates/ishtar/forms/document.html:24
+#: templates/ishtar/form.html:23 templates/ishtar/forms/document.html:24
#: templates/ishtar/wizard/default_wizard.html:43
msgid "Search and select an item in the table"
msgstr ""
-#: templates/ishtar/form.html:26 templates/ishtar/forms/document.html:30
+#: templates/ishtar/form.html:29 templates/ishtar/forms/document.html:30
#: templates/ishtar/forms/search_query.html:77 templates/ishtar/formset.html:8
#: templates/ishtar/formset_import_match.html:51
#: templates/ishtar/import_list.html:30 templates/ishtar/merge.html:30
@@ -2996,12 +3019,12 @@ msgstr ""
msgid "Are you sure you want to delete: "
msgstr ""
-#: templates/ishtar/forms/qa_base.html:25
+#: templates/ishtar/forms/qa_base.html:24
#: templates/ishtar/forms/qa_form.html:12
msgid "Modified items"
msgstr ""
-#: templates/ishtar/forms/qa_base.html:62
+#: templates/ishtar/forms/qa_base.html:61
#: templates/ishtar/import_step_by_step.html:126
#: templates/ishtar/import_step_by_step.html:305
#: templates/ishtar/organization_form.html:40
@@ -3083,7 +3106,7 @@ msgstr ""
msgid "Go"
msgstr ""
-#: templates/ishtar/import_step_by_step.html:63 views.py:1081
+#: templates/ishtar/import_step_by_step.html:63 views.py:1104
msgid "Import step by step"
msgstr ""
@@ -3344,12 +3367,12 @@ msgstr ""
msgid "Responsible for planning service of archaeological files"
msgstr ""
-#: templates/ishtar/wizard/confirm_wizard.html:12
+#: templates/ishtar/wizard/confirm_wizard.html:14
#: templates/ishtar/wizard/wizard_done_summary.html:6
msgid "You have entered the following informations:"
msgstr ""
-#: templates/ishtar/wizard/confirm_wizard.html:50
+#: templates/ishtar/wizard/confirm_wizard.html:56
msgid "Would you like to save them?"
msgstr ""
@@ -3648,15 +3671,15 @@ msgstr ""
msgid "Bookmarks"
msgstr ""
-#: templatetags/window_field.py:22 wizards.py:395
+#: templatetags/window_field.py:22 wizards.py:407
msgid "No"
msgstr ""
-#: templatetags/window_tables.py:88 widgets.py:1065
+#: templatetags/window_tables.py:88 widgets.py:1102
msgid "No results"
msgstr ""
-#: templatetags/window_tables.py:89 widgets.py:1066
+#: templatetags/window_tables.py:89 widgets.py:1103
msgid "Loading..."
msgstr ""
@@ -3664,15 +3687,15 @@ msgstr ""
msgid "You don't have sufficient permissions to do this action."
msgstr ""
-#: utils.py:338
+#: utils.py:344
msgid " (...)"
msgstr ""
-#: utils.py:418
+#: utils.py:424
msgid "Information"
msgstr ""
-#: utils.py:419
+#: utils.py:425
msgid "Load another random image?"
msgstr ""
@@ -3736,116 +3759,125 @@ msgstr ""
msgid "Treatment"
msgstr ""
-#: views.py:724 views_item.py:103
+#: views.py:747 views_item.py:117
msgid "Operation not permitted."
msgstr ""
-#: views.py:741 views.py:799
+#: views.py:764 views.py:822
msgid "Archaeological files"
msgstr ""
-#: views.py:746 views.py:810
+#: views.py:769 views.py:833
msgid "Finds"
msgstr ""
-#: views.py:748 views.py:815
+#: views.py:771 views.py:838
msgid "Treatment requests"
msgstr ""
-#: views.py:749 views.py:821
+#: views.py:772 views.py:844
msgid "Treatments"
msgstr ""
-#: views.py:1423
+#: views.py:1446
msgid "Col. "
msgstr ""
-#: views.py:1429 views.py:1441
+#: views.py:1452 views.py:1464
msgid "* empty *"
msgstr ""
-#: views.py:1482
+#: views.py:1505
msgid "Link unmatched items"
msgstr ""
-#: views.py:1503
+#: views.py:1526
msgid "Delete import"
msgstr ""
-#: views.py:1542
+#: views.py:1565
msgid "Merge persons"
msgstr ""
-#: views.py:1566
+#: views.py:1589
msgid "Select the main person"
msgstr ""
-#: views.py:1575
+#: views.py:1598
msgid "Merge organization"
msgstr ""
-#: views.py:1585
+#: views.py:1608
msgid "Select the main organization"
msgstr ""
-#: views.py:1625 views.py:1641
+#: views.py:1648 views.py:1664
msgid "Corporation manager"
msgstr ""
-#: views.py:1662
+#: views.py:1685
msgid "Document: search"
msgstr ""
-#: views.py:1677
+#: views.py:1700
msgid "Document creation"
msgstr ""
-#: views.py:1710
+#: views.py:1733
msgid "Document modification"
msgstr ""
-#: views.py:1740
+#: views.py:1763
msgid "Document deletion"
msgstr ""
-#: views.py:1823
+#: views.py:1872
msgid "Delete bookmark"
msgstr ""
-#: views.py:1846
+#: views.py:1895
msgid "Bookmark - Delete"
msgstr ""
-#: views_item.py:105
+#: views_item.py:119
#, python-format
msgid "New %s"
msgstr ""
+#: views_item.py:570
+msgctxt "key for text search"
+msgid "today"
+msgstr ""
+
#: widgets.py:174
msgid "The character \" is not accepted."
msgstr ""
-#: widgets.py:517
+#: widgets.py:555
msgid "{} is not a valid key for {}"
msgstr ""
-#: widgets.py:618 widgets.py:752 widgets.py:867
+#: widgets.py:656 widgets.py:790 widgets.py:905
msgid "Search..."
msgstr ""
-#: widgets.py:687
+#: widgets.py:725
msgid "Previous value:"
msgstr ""
-#: widgets.py:1067
+#: widgets.py:1104
msgid "Remove"
msgstr ""
-#: wizards.py:431
+#: wizards.py:171
+msgid "Permission error: you cannot do this action."
+msgstr ""
+
+#: wizards.py:443
msgid "Deleted"
msgstr ""
-#: wizards.py:1757
+#: wizards.py:1769
#, python-format
msgid "[%(app_name)s] Account creation/modification"
msgstr ""
diff --git a/translations/fr/archaeological_context_records.po b/translations/fr/archaeological_context_records.po
index d20a86c19..74188a0fb 100644
--- a/translations/fr/archaeological_context_records.po
+++ b/translations/fr/archaeological_context_records.po
@@ -11,7 +11,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Transfer-Encoding: 8bit\n"
"Content-Type: text/plain; charset=UTF-8\n"
-"PO-Revision-Date: 2018-11-12 09:32+0000\n"
+"PO-Revision-Date: 2018-12-04 12:48+0000\n"
"Last-Translator: Étienne Loks <etienne.loks@iggdrasil.net>\n"
"Language-Team: \n"
"Language: fr\n"
@@ -22,242 +22,242 @@ msgstr ""
msgid "Point"
msgstr "Point"
-#: admin.py:51 models.py:410
+#: admin.py:51 models.py:427
msgid "Multi polygon"
msgstr "Polygones multi-parties"
-#: forms.py:47 forms.py:53 models.py:352 wizards.py:81
+#: forms.py:48 forms.py:54 models.py:369 wizards.py:81
msgid "Operation"
msgstr "Opération"
-#: forms.py:48
+#: forms.py:49
msgid "Context record - 010 - Operation choice"
msgstr "Unité d'enregistrement - 010 - Choix de l'opération"
-#: forms.py:63
+#: forms.py:64
msgid "Context record - 001 - Search"
msgstr "Unité d'enregistrement - 001 - Recherche"
-#: forms.py:66
+#: forms.py:67
msgid "Full text search"
msgstr "Recherche en texte intégral"
-#: forms.py:69 forms.py:155 models.py:357 models.py:737
+#: forms.py:70 forms.py:156 forms.py:386 models.py:374 models.py:754
msgid "ID"
msgstr "Identifiant"
-#: forms.py:75
+#: forms.py:76
msgid "Code PATRIARCHE"
msgstr "Code PATRIARCHE"
-#: forms.py:76
+#: forms.py:77
msgid "Operation's year"
msgstr "Année de l'opération"
-#: forms.py:78
+#: forms.py:79
msgid "Operation's number (index by year)"
msgstr "Numéro de l'opération (index par année)"
-#: forms.py:80 models.py:355
+#: forms.py:81 models.py:372
msgid "Archaeological site"
msgstr "Entité archéologique"
-#: forms.py:86
+#: forms.py:87
msgid "Search within related operations"
msgstr "Rechercher parmi les opérations liées"
-#: forms.py:87 forms.py:288 models.py:66
+#: forms.py:88 forms.py:289 models.py:66
msgid "Period"
msgstr "Période"
-#: forms.py:88
+#: forms.py:89
msgid "Unit type"
msgstr "Type d'unité"
-#: forms.py:89 forms.py:148 models.py:231 models.py:232 models.py:347
-#: models.py:739
+#: forms.py:90 forms.py:149 models.py:248 models.py:249 models.py:364
+#: models.py:756
msgid "Parcel"
msgstr "Parcelle"
-#: forms.py:91
+#: forms.py:92
msgid "Search within relations"
msgstr "Rechercher parmi les relations"
-#: forms.py:115 views.py:95
+#: forms.py:116 views.py:99
msgid "Context record search"
msgstr "Rechercher une Unité d'Enregistrement"
-#: forms.py:130
+#: forms.py:131
msgid "You should at least select one context record."
msgstr "Vous devez sélectionner au moins une Unité d'Enregistrement."
-#: forms.py:136
+#: forms.py:137
msgid "General"
msgstr "Général"
-#: forms.py:137
+#: forms.py:138
msgid "Context record - 020 - General"
msgstr "Unité d'enregistrement - 020 - Général"
-#: forms.py:149 models.py:228 models.py:229 models.py:350
+#: forms.py:150 forms.py:380 models.py:245 models.py:246 models.py:367
msgid "Town"
msgstr "Commune"
-#: forms.py:152
+#: forms.py:153 forms.py:383
msgid "Only the items associated to the operation can be selected."
msgstr "Seuls les éléments associés à l'opération peuvent être sélectionnés."
-#: forms.py:157 models.py:358 models.py:740
+#: forms.py:158 forms.py:388 models.py:396 models.py:755
+msgid "Context record type"
+msgstr "Type d'Unité d'Enregistrement"
+
+#: forms.py:160 models.py:375 models.py:757
#: templates/ishtar/sheet_contextrecord.html:45
msgid "Description"
msgstr "Description"
-#: forms.py:159 models.py:359
+#: forms.py:162 models.py:376
msgid "General comment"
msgstr "Commentaire général"
-#: forms.py:162 models.py:405
+#: forms.py:165 models.py:422
msgid "Excavation technique"
msgstr "Méthode de fouille"
-#: forms.py:163 models.py:363
+#: forms.py:166 models.py:380
msgid "Length (m)"
msgstr "Taille (m)"
-#: forms.py:164 models.py:364
+#: forms.py:167 models.py:381
msgid "Width (m)"
msgstr "Largeur (m)"
-#: forms.py:165 models.py:365
+#: forms.py:168 models.py:382
msgid "Thickness (m)"
msgstr "Épaisseur (m)"
-#: forms.py:166 models.py:367
+#: forms.py:169 models.py:384
msgid "Diameter (m)"
msgstr "Diamètre (m)"
-#: forms.py:167 models.py:368
+#: forms.py:170 models.py:385
msgid "Depth (m)"
msgstr "Profondeur (m)"
-#: forms.py:169 models.py:370
+#: forms.py:172 models.py:387
msgid "Depth of appearance (m)"
msgstr "Profondeur d'apparition (m)"
-#: forms.py:170 models.py:379 models.py:738
-msgid "Context record type"
-msgstr "Type d'Unité d'Enregistrement"
-
-#: forms.py:172 models.py:360
+#: forms.py:173 models.py:377
msgid "Opening date"
msgstr "Date d'ouverture"
-#: forms.py:174 models.py:362 templates/ishtar/sheet_contextrecord.html:140
+#: forms.py:175 models.py:379 templates/ishtar/sheet_contextrecord.html:140
msgid "Closing date"
msgstr "Date de clôture"
-#: forms.py:177
+#: forms.py:178
msgid "Documentation"
msgstr "Documentation"
-#: forms.py:180 models.py:372
+#: forms.py:181 models.py:389
msgid "Location"
msgstr "Localisation"
-#: forms.py:273
+#: forms.py:274
msgid "This ID already exists for this operation."
msgstr "Cet identifiant existe déjà pour cette opération."
-#: forms.py:277
+#: forms.py:278
msgid "You have to choose a town or a parcel."
msgstr "Vous devez choisir une commune ou une parcelle."
-#: forms.py:283 forms.py:304 models.py:77
+#: forms.py:284 forms.py:305 models.py:77
msgid "Dating"
msgstr "Datation"
-#: forms.py:289 models.py:67
+#: forms.py:290 models.py:67
msgid "Start date"
msgstr "Date de début"
-#: forms.py:290 models.py:68
+#: forms.py:291 models.py:68
msgid "End date"
msgstr "Date de fin"
-#: forms.py:291 models.py:71
+#: forms.py:292 models.py:71
msgid "Quality"
msgstr "Qualité"
-#: forms.py:292 models.py:45 models.py:69
+#: forms.py:293 models.py:45 models.py:69
msgid "Dating type"
msgstr "Type de datation"
-#: forms.py:305
+#: forms.py:306
msgid "Context record - 030 - Dating"
msgstr "Unité d'enregistrement - 030 - Datation"
-#: forms.py:315 ishtar_menu.py:29 models.py:91
+#: forms.py:316 ishtar_menu.py:29 models.py:108 views.py:185
msgid "Context record"
msgstr "Unité d'Enregistrement"
-#: forms.py:331
+#: forms.py:332
msgid "Relations"
msgstr "Relations"
-#: forms.py:332
+#: forms.py:333
msgid "Context record - 050 - Relations"
msgstr "Unité d'enregistrement - 050 - Relations"
-#: forms.py:337 forms.py:348 models.py:382
+#: forms.py:338 forms.py:349 models.py:399
#: templates/ishtar/sheet_contextrecord.html:64
msgid "Interpretation"
msgstr "Interprétation"
-#: forms.py:338
+#: forms.py:339
msgid "Context record - 040 - Interpretation"
msgstr "Unité d'enregistrement - 040 - Interprétation"
-#: forms.py:344
+#: forms.py:345
msgid "Comments on dating"
msgstr "Commentaire relatif à la datation"
-#: forms.py:346 models.py:381
+#: forms.py:347 models.py:398
msgid "Filling"
msgstr "Remplissage"
-#: forms.py:350 models.py:402
+#: forms.py:351 models.py:419
msgid "Activity"
msgstr "Activité"
-#: forms.py:352 models.py:400
+#: forms.py:353 models.py:417
msgid "Identification"
msgstr "Identification"
-#: forms.py:354 models.py:385
+#: forms.py:355 models.py:402
msgid "TAQ"
msgstr "TAQ"
-#: forms.py:355 models.py:389
+#: forms.py:356 models.py:406
msgid "Estimated TAQ"
msgstr "TAQ estimé"
-#: forms.py:357 models.py:392
+#: forms.py:358 models.py:409
msgid "TPQ"
msgstr "TPQ"
-#: forms.py:358 models.py:396
+#: forms.py:359 models.py:413
msgid "Estimated TPQ"
msgstr "TPQ estimé"
-#: forms.py:368
+#: forms.py:369
msgid "Operation search"
msgstr "Rechercher une opération"
-#: forms.py:370
+#: forms.py:371
msgid "You should select an operation."
msgstr "Vous devez sélectionner une Opération."
-#: forms.py:375
+#: forms.py:376
msgid "Would you like to delete this context record?"
msgstr "Voulez-vous supprimer cette Unité d'Enregistrement ?"
@@ -297,163 +297,163 @@ msgstr "Datation précise"
msgid "Datings"
msgstr "Datations"
-#: models.py:98
+#: models.py:115
msgid "Find"
msgstr "Mobilier"
-#: models.py:117 models.py:136 models.py:152
+#: models.py:134 models.py:153 models.py:169
msgid "Order"
msgstr "Ordre"
-#: models.py:119
+#: models.py:136
msgid "Parent context record type"
msgstr "Type d'UE parent"
-#: models.py:123
+#: models.py:140
msgid "Context record Type"
msgstr "Type d'Unité d'Enregistrement"
-#: models.py:124
+#: models.py:141
msgid "Context record Types"
msgstr "Types d'Unité d'Enregistrement"
-#: models.py:139
+#: models.py:156
msgid "Activity Type"
msgstr "Type d'activité"
-#: models.py:140
+#: models.py:157
msgid "Activity Types"
msgstr "Types d'activité"
-#: models.py:155
+#: models.py:172
msgid "Identification Type"
msgstr "Type d'identification"
-#: models.py:156
+#: models.py:173
msgid "Identification Types"
msgstr "Types d'identification"
-#: models.py:169
+#: models.py:186
msgid "Excavation technique type"
msgstr "Type de méthode de fouille"
-#: models.py:170
+#: models.py:187
msgid "Excavation technique types"
msgstr "Types de méthode de fouille"
-#: models.py:180
+#: models.py:197
msgid "Documentation type"
msgstr "Type de documentation"
-#: models.py:181
+#: models.py:198
msgid "Documentation types"
msgstr "Types de documentation"
-#: models.py:222 models.py:741
+#: models.py:239 models.py:758
msgid "Periods"
msgstr "Périodes"
-#: models.py:223
+#: models.py:240
msgid "Datings (period)"
msgstr "Datations (période)"
-#: models.py:224
+#: models.py:241
msgid "Related context records"
msgstr "Unités d'Enregistrement liées"
-#: models.py:225
+#: models.py:242
msgid "Operation (Patriarche code)"
msgstr "Opération (code Patriarche)"
-#: models.py:226
+#: models.py:243
msgid "Operation (name)"
msgstr "Opération (nom)"
-#: models.py:227
+#: models.py:244
msgid "Parcel (external ID)"
msgstr "Parcelle (identifiant)"
-#: models.py:230
+#: models.py:247
msgid "Parcel (year)"
msgstr "Parcelle (année)"
-#: models.py:265
+#: models.py:282
msgctxt "key for text search"
msgid "id"
msgstr "id"
-#: models.py:269
+#: models.py:286
msgctxt "key for text search"
msgid "town"
msgstr "commune"
-#: models.py:273
+#: models.py:290
msgctxt "key for text search"
msgid "operation-year"
msgstr "operation-annee"
-#: models.py:277
+#: models.py:294
msgctxt "key for text search"
msgid "patriarche"
msgstr "patriarche"
-#: models.py:281
+#: models.py:298
msgctxt "key for text search"
msgid "operation-code"
msgstr "operation-code"
-#: models.py:285 models.py:327
+#: models.py:302 models.py:344
msgctxt "key for text search"
msgid "operation"
msgstr "operation"
-#: models.py:289 models.py:330
+#: models.py:306 models.py:347
msgctxt "key for text search"
msgid "site"
msgstr "site"
-#: models.py:293
+#: models.py:310
msgctxt "key for text search"
msgid "operation-relation-type"
msgstr "operation-type-relation"
-#: models.py:297
+#: models.py:314
msgctxt "key for text search"
msgid "period"
msgstr "periode"
-#: models.py:301
+#: models.py:318
msgctxt "key for text search"
msgid "unit-type"
msgstr "type"
-#: models.py:305
+#: models.py:322
msgctxt "key for text search"
msgid "parcel"
msgstr "parcelle"
-#: models.py:309
+#: models.py:326
msgctxt "key for text search"
msgid "record-relation-type"
msgstr "ue-type-relation"
-#: models.py:343
+#: models.py:360
msgid "External ID"
msgstr "Identifiant"
-#: models.py:345
+#: models.py:362
msgid "External ID is set automatically"
msgstr "L'identifiant est attribué automatiquement"
-#: models.py:373
+#: models.py:390
msgid "A short description of the location of the context record"
msgstr "Une courte description de la localisation de l'Unité d'Enregistrement"
-#: models.py:377
+#: models.py:394
msgid "Comment on datings"
msgstr "Commentaire relatif aux datations"
-#: models.py:386
+#: models.py:403
msgid ""
"\"Terminus Ante Quem\" the context record can't have been created after this "
"date"
@@ -461,11 +461,11 @@ msgstr ""
"« Terminus Ante Quem ». L'Unité d'Enregistrement ne peut avoir été créée "
"après cette date."
-#: models.py:390
+#: models.py:407
msgid "Estimation of a \"Terminus Ante Quem\""
msgstr "Estimation d'un « Terminus Ante Quem »."
-#: models.py:393
+#: models.py:410
msgid ""
"\"Terminus Post Quem\" the context record can't have been created before "
"this date"
@@ -473,91 +473,103 @@ msgstr ""
"« Terminus Post Quem ». L'Unité d'Enregistrement ne peut avoir été créée "
"avant cette date."
-#: models.py:397
+#: models.py:414
msgid "Estimation of a \"Terminus Post Quem\""
msgstr "Estimation d'un « Terminus Post Quem »."
-#: models.py:408
+#: models.py:425
msgid "Point (2D)"
msgstr "Point (2D)"
-#: models.py:409
+#: models.py:426
msgid "Point (3D)"
msgstr "Point (3D)"
-#: models.py:413
+#: models.py:430
msgid "Documents"
msgstr "Documents"
-#: models.py:415
+#: models.py:432
msgid "Cached name"
msgstr "Nom en cache"
-#: models.py:419 models.py:420 templates/ishtar/sheet_contextrecord.html:4
+#: models.py:436 models.py:437 templates/ishtar/sheet_contextrecord.html:4
msgid "Context Record"
msgstr "Unité d'Enregistrement"
-#: models.py:439
+#: models.py:456
msgctxt "short"
msgid "Context record"
msgstr "UE"
-#: models.py:668 models.py:691 models.py:736
+#: models.py:685 models.py:708 models.py:753
msgid "Relation type"
msgstr "Type de relation"
-#: models.py:669
+#: models.py:686
msgid "Relation types"
msgstr "Types de relation"
-#: models.py:686
+#: models.py:703
msgid "ID (left)"
msgstr "Identifiant (gauche)"
-#: models.py:687
+#: models.py:704
msgid "Context record type (left)"
msgstr "Type d'UE (gauche)"
-#: models.py:688
+#: models.py:705
msgid "Parcel (left)"
msgstr "Parcelle (gauche)"
-#: models.py:689
+#: models.py:706
msgid "Description (left)"
msgstr "Description (gauche)"
-#: models.py:690
+#: models.py:707
msgid "Periods (left)"
msgstr "Périodes (gauche)"
-#: models.py:692
+#: models.py:709
msgid "ID (right)"
msgstr "Identifiant (droit)"
-#: models.py:693
+#: models.py:710
msgid "Context record type (right)"
msgstr "Type d'UE (droite)"
-#: models.py:694
+#: models.py:711
msgid "Parcel (right)"
msgstr "Parcelle (droite)"
-#: models.py:695
+#: models.py:712
msgid "Description (right)"
msgstr "Description (droite)"
-#: models.py:696
+#: models.py:713
msgid "Periods (right)"
msgstr "Périodes (droite)"
-#: models.py:705
+#: models.py:722
msgid "Record relation"
msgstr "Relation entre Unités d'Enregistrement"
-#: models.py:706
+#: models.py:723
msgid "Record relations"
msgstr "Relations entre Unités d'Enregistrement"
+#: templates/ishtar/forms/qa_operation_contextrecord.html:11
+msgid "Quick add context record"
+msgstr "Ajouter rapide d'Unité d'enregistrement"
+
+#: templates/ishtar/forms/qa_operation_contextrecord.html:25
+msgid ""
+"To put more information to the context record use the full form on the top "
+"menu: \\"
+msgstr ""
+"Pour ajouter plus d'information à l'Unité d'enregistrement utilisez le "
+"formulaire complet depuis le menu en haut : \\"
+
#: templates/ishtar/sheet_contextrecord.html:75
msgid "Datations"
msgstr "Datations"
@@ -626,19 +638,23 @@ msgstr "Mobilier"
msgid "Documents from associated finds"
msgstr "Documents du mobilier associé"
-#: views.py:109
+#: views.py:113
msgid "New context record"
msgstr "Ajouter une Unité d'Enregistrement"
-#: views.py:125
+#: views.py:129
msgid "Context record modification"
msgstr "Modifier une Unité d'Enregistrement"
-#: views.py:136
+#: views.py:140
msgid "You don't have sufficient permissions to do this action."
msgstr ""
"Vous n'avez pas les permissions suffisantes pour effectuer cette action."
-#: views.py:149
+#: views.py:153
msgid "Context record deletion"
msgstr "Supprimer une Unité d'Enregistrement"
+
+#: views.py:190
+msgid "Add context record"
+msgstr "Ajouter Unité d'enregistrement"
diff --git a/translations/fr/archaeological_files.po b/translations/fr/archaeological_files.po
index f86f274a3..d6256f8a2 100644
--- a/translations/fr/archaeological_files.po
+++ b/translations/fr/archaeological_files.po
@@ -6,13 +6,12 @@
# Étienne Loks <etienne.loks@iggdrasil.net>, 2016. #zanata
# Valérie-Emma Leroux <emma@iggdrasil.net>, 2017. #zanata
# Valérie-Emma Leroux <emma@iggdrasil.net>, 2018. #zanata
-# Étienne Loks <etienne.loks@iggdrasil.net>, 2018. #zanata
msgid ""
msgstr ""
"MIME-Version: 1.0\n"
"Content-Transfer-Encoding: 8bit\n"
"Content-Type: text/plain; charset=UTF-8\n"
-"PO-Revision-Date: 2018-08-15 03:30+0000\n"
+"PO-Revision-Date: 2018-11-30 09:08+0000\n"
"Last-Translator: Étienne Loks <etienne.loks@iggdrasil.net>\n"
"Language-Team: \n"
"Language: fr\n"
@@ -307,19 +306,15 @@ msgstr "Suppression"
msgid "Administrative act"
msgstr "Acte administratif"
-#: ishtar_menu.py:77 models.py:321
-msgid "Documents"
-msgstr "Documents"
-
-#: ishtar_menu.py:83
+#: ishtar_menu.py:79
msgid "Dashboard"
msgstr "Tableau de bord"
-#: ishtar_menu.py:86
+#: ishtar_menu.py:82
msgid "General informations"
msgstr "Informations générales"
-#: ishtar_menu.py:89 models.py:339
+#: ishtar_menu.py:85 models.py:339
#: templates/ishtar/dashboards/dashboard_file.html:7
msgid "Archaeological files"
msgstr "Dossiers archéologiques"
@@ -397,7 +392,7 @@ msgstr "type-saisine"
#: models.py:177
msgctxt "key for text search"
msgid "permit-type"
-msgstr "type-permit"
+msgstr "type-permis"
#: models.py:181
msgctxt "key for text search"
@@ -490,6 +485,10 @@ msgstr "Organisation"
msgid "Research archaeology comment"
msgstr "Commentaire relatif à l'archéologie programmée"
+#: models.py:321
+msgid "Documents"
+msgstr "Documents"
+
#: models.py:324
msgid "Cached name"
msgstr "Nom en cache"
diff --git a/translations/fr/archaeological_finds.po b/translations/fr/archaeological_finds.po
index 996b61dca..d0332d11d 100644
--- a/translations/fr/archaeological_finds.po
+++ b/translations/fr/archaeological_finds.po
@@ -11,249 +11,266 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Transfer-Encoding: 8bit\n"
"Content-Type: text/plain; charset=UTF-8\n"
-"PO-Revision-Date: 2018-11-12 03:35+0000\n"
+"PO-Revision-Date: 2018-12-13 05:53+0000\n"
"Last-Translator: Étienne Loks <etienne.loks@iggdrasil.net>\n"
"Language-Team: \n"
"Language: fr\n"
"Plural-Forms: nplurals=2; plural=n>1;\n"
"X-Generator: Zanata 4.6.2\n"
-#: admin.py:39 models_finds.py:288
+#: admin.py:39 models_finds.py:303
msgid "Point (2D)"
msgstr "Point (2D)"
-#: admin.py:41 models_finds.py:290
+#: admin.py:41 models_finds.py:305
msgid "Line"
msgstr "Ligne"
-#: admin.py:43 models_finds.py:291
+#: admin.py:43 models_finds.py:306
msgid "Multi polygon"
msgstr "Polygones multi-parties"
-#: forms.py:91 forms.py:97 forms.py:340 forms.py:353 forms.py:631
-#: models_finds.py:660 models_finds.py:1213 wizards.py:75
+#: forms.py:96 forms.py:102 forms.py:556 forms.py:569 forms.py:876
+#: models_finds.py:722 models_finds.py:1337 wizards.py:86
msgid "Context record"
msgstr "Unité d'Enregistrement"
-#: forms.py:92
+#: forms.py:97
msgid "Find - 010 - Context record choice"
msgstr "Mobilier - 010 - Choix de l'unité d'enregistrement"
-#: forms.py:126 ishtar_menu.py:32 models_finds.py:1089 models_finds.py:1717
-#: models_treatments.py:349 templates/ishtar/sheet_find.html:4
+#: forms.py:134 forms.py:268 ishtar_menu.py:32 models_finds.py:1192
+#: models_finds.py:1959 models_treatments.py:585
+#: templates/ishtar/sheet_find.html:4
msgid "Find"
msgstr "Mobilier"
-#: forms.py:127
-msgid "Find - 020 - General"
-msgstr "Mobilier - 020 - Général"
+#: forms.py:135
+msgid "Simple find - 020 - General"
+msgstr "Mobilier simple - 020 - Général"
-#: forms.py:142 forms.py:341 templates/ishtar/sheet_find.html:40
+#: forms.py:157 forms.py:409 forms.py:557 templates/ishtar/sheet_find.html:110
msgid "Identification"
msgstr "Identification"
-#: forms.py:145 forms.py:360 forms.py:600 forms.py:889 models_finds.py:253
-#: models_finds.py:968
+#: forms.py:160 forms.py:412 forms.py:576 forms.py:845 forms.py:1155
+#: models_finds.py:268 models_finds.py:1060
msgid "Free ID"
msgstr "Identifiant libre"
-#: forms.py:147 forms.py:362 forms.py:601 forms.py:932 models_finds.py:969
+#: forms.py:162 forms.py:414 forms.py:578 forms.py:846 forms.py:1220
+#: models_finds.py:1061
msgid "Denomination"
msgstr "Dénomination"
-#: forms.py:148 forms.py:363 models_finds.py:1042
+#: forms.py:163 forms.py:579 models_finds.py:1141
msgid "Previous ID"
msgstr "Identifiant précédent"
-#: forms.py:150 forms.py:365 models_finds.py:257
-msgid "Excavation ID"
-msgstr "Identifiant fouille"
-
-#: forms.py:151 forms.py:366 models_finds.py:970
+#: forms.py:164 forms.py:582 models_finds.py:1062
msgid "Museum ID"
msgstr "Identifiant musée"
-#: forms.py:152 forms.py:367 models_finds.py:965
+#: forms.py:165 forms.py:583 models_finds.py:1057
msgid "Seal number"
msgstr "Numéro de scellé"
-#: forms.py:153 forms.py:368 models_finds.py:1038
+#: forms.py:166 forms.py:584 models_finds.py:1137
msgid "Mark"
msgstr "Marquage"
-#: forms.py:155 forms.py:156 forms.py:342 forms.py:371 forms.py:652
-#: forms_treatments.py:139 models_finds.py:258 models_finds.py:971
-#: models_treatments.py:146 templates/ishtar/sheet_find.html:58
+#: forms.py:168 forms.py:169 forms.py:417 forms.py:419 forms.py:558
+#: forms.py:587 forms.py:897 forms_treatments.py:141 models_finds.py:273
+#: models_finds.py:1063 models_treatments.py:164
+#: templates/ishtar/sheet_find.html:128
msgid "Description"
msgstr "Description"
-#: forms.py:159 models_finds.py:265
-msgid "Discovery date (exact or TPQ)"
-msgstr "Date de découverte (exacte ou TPQ)"
-
-#: forms.py:162 models_finds.py:267 templates/ishtar/sheet_basefind.html:29
-msgid "Discovery date (TAQ)"
-msgstr "Date de découverte (TAQ)"
-
-#: forms.py:164 forms.py:654 models_finds.py:269
-msgid "Batch/object"
-msgstr "Lot/objet"
-
-#: forms.py:166 models_finds.py:1003
+#: forms.py:171 forms.py:421 models_finds.py:1100
msgid "Is complete?"
msgstr "Est complet ?"
-#: forms.py:169 forms.py:373 models_finds.py:57 models_finds.py:685
-#: models_finds.py:977
+#: forms.py:174 forms.py:423 forms.py:589 models_finds.py:57
+#: models_finds.py:748 models_finds.py:1069
msgid "Material types"
msgstr "Types de matériau"
-#: forms.py:172 models_finds.py:982
+#: forms.py:177 forms.py:426 models_finds.py:1074
msgid "Material type quality"
msgstr "Qualité du type de matériaux"
-#: forms.py:174 forms.py:376 models_finds.py:152 models_finds.py:686
-#: models_finds.py:1006
+#: forms.py:179 forms.py:428 forms.py:592 models_finds.py:167
+#: models_finds.py:749 models_finds.py:1103
msgid "Object types"
msgstr "Types d'objet"
-#: forms.py:177 models_finds.py:1011
+#: forms.py:182 forms.py:431 models_finds.py:1108
msgid "Object type quality"
msgstr "Qualité du type d'objet"
-#: forms.py:178 forms.py:896 models_finds.py:989
+#: forms.py:183 forms.py:433 forms.py:1162 models_finds.py:1081
msgid "Find number"
msgstr "Mobilier (en nombre)"
-#: forms.py:180 models_finds.py:1024
+#: forms.py:185 forms.py:435 models_finds.py:1121
msgid "Minimum number of individuals (MNI)"
msgstr "Nombre minimum d'individus (NMI)"
-#: forms.py:182 models_finds.py:972
+#: forms.py:187 forms.py:438 models_finds.py:1064
msgid "Decoration"
msgstr "Décor"
-#: forms.py:184 models_finds.py:973
+#: forms.py:189 forms.py:440 models_finds.py:1065
msgid "Inscription"
msgstr "Inscription"
-#: forms.py:187 forms.py:379 models_finds.py:975
+#: forms.py:192 forms.py:442 forms.py:595 models_finds.py:1067
msgid "Manufacturing place"
msgstr "Lieu de fabrication"
-#: forms.py:189 forms.py:381 models_finds.py:1021
+#: forms.py:194 forms.py:444 forms.py:597 models_finds.py:1118
msgid "Communicability"
msgstr "Communicabilité"
-#: forms.py:191 forms.py:384 forms.py:955 forms_treatments.py:141
-#: forms_treatments.py:578 models_finds.py:259 models_finds.py:1039
-#: models_treatments.py:145 models_treatments.py:609
+#: forms.py:196 forms.py:446 forms.py:600 forms.py:1260 forms_treatments.py:143
+#: forms_treatments.py:657 models_finds.py:274 models_finds.py:1138
+#: models_treatments.py:163 models_treatments.py:847
msgid "Comment"
msgstr "Commentaire général"
-#: forms.py:194 forms.py:394 models_finds.py:1040
+#: forms.py:199 forms.py:449 forms.py:610 models_finds.py:1139
msgid "Comment on dating"
msgstr "Commentaire relatif aux datations"
-#: forms.py:196 templates/ishtar/sheet_find.html:76
+#: forms.py:201 forms.py:451 templates/ishtar/sheet_find.html:146
msgid "Dimensions"
msgstr "Dimensions"
-#: forms.py:197 models_finds.py:1025
+#: forms.py:202 forms.py:452 models_finds.py:1122
msgid "Length (cm)"
msgstr "Longueur (cm)"
-#: forms.py:198 models_finds.py:1026
+#: forms.py:204 forms.py:453 models_finds.py:1123
msgid "Width (cm)"
msgstr "Largeur (cm)"
-#: forms.py:199 models_finds.py:1027
+#: forms.py:206 forms.py:454 models_finds.py:1124
msgid "Height (cm)"
msgstr "Hauteur (cm)"
-#: forms.py:200 models_finds.py:1028
+#: forms.py:208 forms.py:458 models_finds.py:1128
+msgid "Thickness (cm)"
+msgstr "Épaisseur (cm)"
+
+#: forms.py:210 forms.py:455 models_finds.py:1125
msgid "Diameter (cm)"
msgstr "Diamètre (cm)"
-#: forms.py:201 models_finds.py:1029
-msgid "Thickness (cm)"
-msgstr "Épaisseur (cm)"
+#: forms.py:213 forms.py:456 models_finds.py:1126
+msgid "Circumference (cm)"
+msgstr "Circonférence (cm)"
-#: forms.py:202 forms.py:894 models_finds.py:985
+#: forms.py:215 forms.py:459 forms.py:1160 models_finds.py:1077
msgid "Volume (l)"
msgstr "Volume (l)"
-#: forms.py:203 forms.py:895 templates/ishtar/sheet_find.html:84
+#: forms.py:216 forms.py:460 forms.py:1161 templates/ishtar/sheet_find.html:155
msgid "Weight (g)"
msgstr "Poids (g)"
-#: forms.py:205
+#: forms.py:219 forms.py:462
msgid "Clutter long side (cm)"
msgstr "Encombrement grand côté (cm)"
-#: forms.py:207
+#: forms.py:222 forms.py:464
msgid "Clutter short side (cm)"
msgstr "Encombrement petit côté (cm)"
-#: forms.py:209
+#: forms.py:225 forms.py:466
msgid "Clutter height (cm)"
msgstr "Encombrement hauteur (cm)"
-#: forms.py:211 models_finds.py:1036
+#: forms.py:228 forms.py:468 models_finds.py:1135
msgid "Dimensions comment"
msgstr "Commentaire relatif aux dimensions"
-#: forms.py:214 templates/ishtar/sheet_basefind.html:46
-#: templates/ishtar/sheet_basefind.html:50
+#: forms.py:230 forms.py:470 forms.py:559
+#: templates/ishtar/sheet_basefind.html:70 templates/ishtar/sheet_find.html:164
+msgid "Sheet"
+msgstr "Fiche"
+
+#: forms.py:231 forms.py:471 forms.py:603 forms.py:900 models_finds.py:1143
+msgid "Check"
+msgstr "Vérification"
+
+#: forms.py:233 forms.py:474 forms.py:605 models_finds.py:1145
+msgid "Check date"
+msgstr "Date de vérification"
+
+#: forms.py:260
+msgid "Clutter: short side cannot be bigger than the long side."
+msgstr ""
+"Encombrement : le petit côté court ne peut pas être plus grand que le grand "
+"côté."
+
+#: forms.py:269
+msgid "Find - 020 - General"
+msgstr "Mobilier - 020 - Général"
+
+#: forms.py:299 forms.py:581 models_finds.py:272
+msgid "Excavation ID"
+msgstr "Identifiant fouille"
+
+#: forms.py:302 models_finds.py:280
+msgid "Discovery date (exact or TPQ)"
+msgstr "Date de découverte (exacte ou TPQ)"
+
+#: forms.py:305 models_finds.py:282 templates/ishtar/sheet_basefind.html:33
+msgid "Discovery date (TAQ)"
+msgstr "Date de découverte (TAQ)"
+
+#: forms.py:307 forms.py:899 models_finds.py:284
+msgid "Batch/object"
+msgstr "Lot/objet"
+
+#: forms.py:310 templates/ishtar/sheet_basefind.html:50
+#: templates/ishtar/sheet_basefind.html:54
msgid "Coordinates"
msgstr "Coordonnées"
-#: forms.py:215 models_finds.py:276
+#: forms.py:311 models_finds.py:291
msgid "X"
-msgstr "X"
+msgstr "X/Long"
-#: forms.py:217 models_finds.py:279
+#: forms.py:313 models_finds.py:294
msgid "Estimated error for X"
msgstr "Erreur estimée pour X"
-#: forms.py:218 models_finds.py:277
+#: forms.py:314 models_finds.py:292
msgid "Y"
-msgstr "Y"
+msgstr "Y/Lat"
-#: forms.py:220 models_finds.py:281
+#: forms.py:316 models_finds.py:296
msgid "Estimated error for Y"
msgstr "Erreur estimée pour Y"
-#: forms.py:221 models_finds.py:278
+#: forms.py:317 models_finds.py:293
msgid "Z"
msgstr "Z"
-#: forms.py:223 models_finds.py:283
+#: forms.py:319 models_finds.py:298
msgid "Estimated error for Z"
msgstr "Erreur estimée pour Z"
-#: forms.py:225 models_finds.py:286
+#: forms.py:321 models_finds.py:301
msgid "Spatial Reference System"
msgstr "Système de référence spatiale"
-#: forms.py:228 models_finds.py:274
+#: forms.py:324 models_finds.py:289
msgid "Point of topographic reference"
msgstr "Point topographique"
-#: forms.py:232 forms.py:343 templates/ishtar/sheet_basefind.html:66
-#: templates/ishtar/sheet_find.html:93
-msgid "Sheet"
-msgstr "Fiche"
-
-#: forms.py:233 forms.py:387 forms.py:655 models_finds.py:1044
-msgid "Check"
-msgstr "Vérification"
-
-#: forms.py:235 forms.py:389 models_finds.py:1046
-msgid "Check date"
-msgstr "Date de vérification"
-
-#: forms.py:274
+#: forms.py:352
msgid ""
"Discovery date: if a TAQ date is provided a TPQ date has to be informed. If "
"you have a precise date fill only the TPQ - discovery date field."
@@ -262,434 +279,508 @@ msgstr ""
"renseignée. Si vous avez une date précise, remplissez seulement le champ « "
"date de découverte (exacte ou TPQ) »."
-#: forms.py:280
+#: forms.py:358
msgid "Discovery date: TAQ date must be older than TPQ date."
msgstr "Date de découverte : la date TAQ doit être postérieure à la date TPQ."
-#: forms.py:290
-msgid "Clutter: short side cannot be bigger than the long side."
-msgstr ""
-"Encombrement : le petit côté court ne peut pas être plus grand que le grand "
-"côté."
-
-#: forms.py:307
+#: forms.py:374
msgid ""
"You should at least provide X, Y and the spatial reference system used."
msgstr ""
"Vous devez au minimum fournir X, Y et le système de référence spatiale "
"utilisé."
-#: forms.py:316
+#: forms.py:383
msgid ""
"Coordinates are not relevant for the spatial reference system used: {}."
msgstr ""
"Les coordonnées ne sont pas pertinentes pour le système de référence "
"spatiale utilisé : {}."
-#: forms.py:322
+#: forms.py:396 forms.py:1152
+msgid "Resulting find"
+msgstr "Mobilier résultant"
+
+#: forms.py:397
+msgid "Treatment n-1 - 030 - Resulting find"
+msgstr "Traitement n-1 - 030 - Mobilier résultant"
+
+#: forms.py:493 forms.py:1171
+msgid "Resulting finds"
+msgstr "Mobiliers résultants"
+
+#: forms.py:494
+msgid "Treatment 1-n - 030 - Resulting finds"
+msgstr "Traitement 1-n - 030 - Mobiliers résultants"
+
+#: forms.py:499
+msgid "Number of resulting finds"
+msgstr "Nombre de mobiliers résultants"
+
+#: forms.py:503
+msgid "Prefix label for resulting finds"
+msgstr "Préfixe du libellé des mobiliers résultants"
+
+#: forms.py:506
+msgid ""
+"E.g.: with a prefix \"item-\", each resulting item will be named \"item-1\", "
+"\"item-2\", \"item-3\""
+msgstr ""
+"Par exemple : avec un préfixe « élément- », chaque élément résultant sera "
+"nommé « élément-1 », « élément-2 », « élément-3 »..."
+
+#: forms.py:510
+msgid "Numbering starting from"
+msgstr "Numérotation commençant depuis"
+
+#: forms.py:513
+msgid "Name of the new basket containing the resulting items"
+msgstr "Nom du nouveau panier contenant les éléments résultants"
+
+#: forms.py:531 forms.py:697 forms.py:733
+msgid "A basket with this label already exists."
+msgstr "Un panier avec ce libellé existe déjà."
+
+#: forms.py:537
msgid "Find - Quick action - Modify"
msgstr "Mobilier - Action rapide - Modification"
-#: forms.py:344
+#: forms.py:560
msgid "Datation"
msgstr "Datation"
-#: forms.py:392 forms.py:565 forms.py:641 templates/ishtar/sheet_find.html:123
+#: forms.py:608 forms.py:810 forms.py:886 templates/ishtar/sheet_find.html:196
msgid "Period"
msgstr "Période"
-#: forms.py:436
+#: forms.py:652
msgid "Find - Quick action - Modify single"
-msgstr "Mobilier - Action rapide - Modification simpe"
+msgstr "Mobilier - Action rapide - Modification simple"
-#: forms.py:449
+#: forms.py:665
msgid "Create"
msgstr "Création"
-#: forms.py:450
+#: forms.py:666
msgid "Update"
msgstr "Mise à jour"
-#: forms.py:452 forms.py:636 forms.py:982 forms.py:986 forms_treatments.py:180
-#: ishtar_menu.py:57 models_finds.py:926
-#: templates/ishtar/sheet_findbasket.html:4 views.py:646
+#: forms.py:668 forms.py:881 forms.py:1308 forms.py:1312 ishtar_menu.py:57
+#: models_finds.py:605 models_finds.py:1018
+#: templates/ishtar/sheet_findbasket.html:4 views.py:824 wizards.py:360
msgid "Basket"
msgstr "Panier"
-#: forms.py:474
+#: forms.py:690
msgid "On update, you have to select a basket."
msgstr "Pour la mise à jour, vous avez à sélectionner un panier."
-#: forms.py:478
+#: forms.py:694 forms.py:730
msgid "A label is required."
msgstr "Un libellé est obligatoire"
-#: forms.py:481
-msgid "A basket with this label already exists."
-msgstr "Un panier avec ce libellé existe déjà."
+#: forms.py:725
+msgid " - duplicate"
+msgstr " - copie"
-#: forms.py:498 templates/ishtar/sheet_find.html:102
+#: forms.py:743 templates/ishtar/sheet_find.html:175
msgid "Preservation"
msgstr "Conservation"
-#: forms.py:499
+#: forms.py:744
msgid "Find - 030 - Preservation"
msgstr "Mobilier - 030 - Conservation"
-#: forms.py:513 forms.py:648 models_finds.py:1015
+#: forms.py:758 forms.py:893 models_finds.py:1112
msgid "Integrity / interest"
msgstr "Intégrité / intérêt"
-#: forms.py:516 forms.py:650 models_finds.py:1018
+#: forms.py:761 forms.py:895 models_finds.py:1115
msgid "Remarkability"
msgstr "Remarquabilité"
-#: forms.py:518 forms.py:646 models_finds.py:1056
+#: forms.py:763 forms.py:891 models_finds.py:1155
msgid "Conservatory state"
msgstr "État sanitaire"
-#: forms.py:521 models_finds.py:1065
+#: forms.py:766 models_finds.py:1164
msgid "Alteration"
msgstr "Altération"
-#: forms.py:524 models_finds.py:1069
+#: forms.py:769 models_finds.py:1168
msgid "Alteration cause"
msgstr "Cause d'altération"
-#: forms.py:527 models_finds.py:1062
+#: forms.py:772 models_finds.py:1161
msgid "Recommended treatments"
msgstr "Traitements recommandés"
-#: forms.py:529 models_finds.py:1073
+#: forms.py:774 models_finds.py:1172
msgid "Treatment emergency"
msgstr "Urgence du traitement"
-#: forms.py:531 models_finds.py:1048
+#: forms.py:776 models_finds.py:1147
msgid "Estimated value"
msgstr "Valeur estimée"
-#: forms.py:532 models_finds.py:1076
+#: forms.py:777 models_finds.py:1175
msgid "Insurance value"
msgstr "Valeur d'assurance"
-#: forms.py:534 models_finds.py:1078
+#: forms.py:779 models_finds.py:1177
msgid "Appraisal date"
msgstr "Date d'évaluation"
-#: forms.py:536 models_finds.py:1058
+#: forms.py:781 models_finds.py:1157
msgid "Conservatory comment"
msgstr "Commentaire relatif à la conservation"
-#: forms.py:560 forms.py:584 models_finds.py:997
-#: templates/ishtar/sheet_find.html:119
+#: forms.py:805 forms.py:829 models_finds.py:1089
+#: templates/ishtar/sheet_find.html:192
msgid "Dating"
msgstr "Datation"
-#: forms.py:566 forms_treatments.py:143 forms_treatments.py:370
-#: forms_treatments.py:580 models_finds.py:1722 models_treatments.py:148
-#: models_treatments.py:360 templates/ishtar/sheet_find.html:124
-#: templates/ishtar/sheet_find.html:185 templates/ishtar/sheet_find.html:223
+#: forms.py:811 forms_treatments.py:128 forms_treatments.py:442
+#: forms_treatments.py:659 models_finds.py:1964 models_treatments.py:166
+#: models_treatments.py:596 templates/ishtar/sheet_find.html:197
+#: templates/ishtar/sheet_find.html:265 templates/ishtar/sheet_find.html:302
+#: templates/ishtar/sheet_find.html:340
msgid "Start date"
msgstr "Date de début"
-#: forms.py:568 models_finds.py:1723 models_treatments.py:361
-#: templates/ishtar/sheet_find.html:125 templates/ishtar/sheet_find.html:186
-#: templates/ishtar/sheet_find.html:224
+#: forms.py:813 models_finds.py:1965 models_treatments.py:597
+#: templates/ishtar/sheet_find.html:198 templates/ishtar/sheet_find.html:266
+#: templates/ishtar/sheet_find.html:303 templates/ishtar/sheet_find.html:341
msgid "End date"
msgstr "Date de fin"
-#: forms.py:569 templates/ishtar/sheet_find.html:127
+#: forms.py:814 templates/ishtar/sheet_find.html:200
msgid "Quality"
msgstr "Qualité"
-#: forms.py:571 templates/ishtar/sheet_find.html:126
+#: forms.py:816 templates/ishtar/sheet_find.html:199
msgid "Dating type"
msgstr "Type de datation"
-#: forms.py:573 templates/ishtar/sheet_find.html:128
+#: forms.py:818 templates/ishtar/sheet_find.html:201
msgid "Precise dating"
msgstr "Datation précise"
-#: forms.py:585
+#: forms.py:830
msgid "Find - 040 - Dating"
msgstr "Mobilier - 040 - Datation"
-#: forms.py:592
+#: forms.py:837
msgid "Find - 001 - Search"
msgstr "Mobilier - 001 - Recherche"
-#: forms.py:595 forms.py:928 forms_treatments.py:50 forms_treatments.py:419
-#: forms_treatments.py:493 forms_treatments.py:686
+#: forms.py:840 forms.py:1216 forms_treatments.py:49 forms_treatments.py:491
+#: forms_treatments.py:565 forms_treatments.py:765
msgid "Full text search"
msgstr "Recherche en texte intégral"
-#: forms.py:598 models_finds.py:294
+#: forms.py:843 models_finds.py:309
msgid "Short ID"
msgstr "Identifiant court"
-#: forms.py:599 models_finds.py:297
+#: forms.py:844 models_finds.py:312
msgid "Complete ID"
msgstr "Identifiant complet"
-#: forms.py:604 forms_treatments.py:56 forms_treatments.py:101
-#: forms_treatments.py:295 forms_treatments.py:423 forms_treatments.py:498
-#: forms_treatments.py:550 forms_treatments.py:690 models_treatments.py:122
-#: models_treatments.py:582
+#: forms.py:849 forms_treatments.py:55 forms_treatments.py:100
+#: forms_treatments.py:363 forms_treatments.py:495 forms_treatments.py:570
+#: forms_treatments.py:624 forms_treatments.py:769 models_treatments.py:137
+#: models_treatments.py:820
msgid "Year"
msgstr "Année"
-#: forms.py:606
+#: forms.py:851
msgid "Operation's number (index by year)"
msgstr "Numéro de l'opération (index par année)"
-#: forms.py:609
+#: forms.py:854
msgid "Code PATRIARCHE"
msgstr "Code PATRIARCHE"
-#: forms.py:613
+#: forms.py:858
msgid "Operation type"
msgstr "Type d'opération"
-#: forms.py:616
+#: forms.py:861
msgid "Areas"
msgstr "Zones"
-#: forms.py:619
+#: forms.py:864
msgid "Archaeological site (attached to the operation)"
msgstr "Site archéologique (attaché à l'opération)"
-#: forms.py:625
+#: forms.py:870
msgid "Archaeological site (attached to the context record)"
msgstr "Site archéologique (attaché à l'UE)"
-#: forms.py:638
+#: forms.py:883
msgid "Search within related operations"
msgstr "Rechercher parmi les opérations liées"
-#: forms.py:640
+#: forms.py:885
msgid "Search within related context records"
msgstr "Recherche parmi les Unités d'Enregistrement associées"
-#: forms.py:642 forms.py:893 models_finds.py:56
+#: forms.py:887 forms.py:1159 models_finds.py:56
msgid "Material type"
msgstr "Type de matériau"
-#: forms.py:643 models_finds.py:151
+#: forms.py:888 models_finds.py:166
msgid "Object type"
msgstr "Type d'objet"
-#: forms.py:645
+#: forms.py:890
msgid "Preservation type"
msgstr "Type de conservation"
-#: forms.py:656 forms_treatments.py:59
+#: forms.py:901 forms_treatments.py:58
msgid "Has an image?"
msgstr "Dispose d'une image ?"
-#: forms.py:703
-msgid "Warehouse (location)"
-msgstr "Lieu de conservation (localisation)"
+#: forms.py:902
+msgid "Loan?"
+msgstr "Prêt ?"
-#: forms.py:709
-msgid "Warehouse (responsible)"
-msgstr "Lieu de conservation (responsable)"
+#: forms.py:904
+msgid "Treatment file end date before"
+msgstr "Dossier de traitement - date de clotûre avant"
-#: forms.py:714
-msgid "Container ID"
-msgstr "Identifiant du contenant"
+#: forms.py:953
+msgid "Reference container - Warehouse (location)"
+msgstr "Contenant de référence - Lieu de conservation (localisation)"
-#: forms.py:715
-msgid "Container ref."
-msgstr "Réf. contenant"
+#: forms.py:959
+msgid "Reference container - Warehouse (responsible)"
+msgstr "Contenant de référence - Lieu de conservation (responsable)"
-#: forms.py:720 forms.py:744 views.py:185
+#: forms.py:965
+msgid "Reference container ID"
+msgstr "Identifiant du contenant de référence"
+
+#: forms.py:967
+msgid "Reference container ref."
+msgstr "Réf. du contenant de référence"
+
+#: forms.py:969
+msgid "Current container - Warehouse (location)"
+msgstr "Contenant actuel - Lieu de conservation (localisation)"
+
+#: forms.py:975
+msgid "Current container - Warehouse (responsible)"
+msgstr "Contenant actuel - Lieu de conservation (responsable)"
+
+#: forms.py:980
+msgid "Current container ID"
+msgstr "Identifiant du contenant actuel"
+
+#: forms.py:981
+msgid "Current container ref."
+msgstr "Réf. du contenant actuel"
+
+#: forms.py:986 forms.py:1010 views.py:241
msgid "Find search"
msgstr "Rechercher un mobilier"
-#: forms.py:769 models_treatments.py:258
-#: templates/ishtar/sheet_treatment.html:56
+#: forms.py:1035 forms.py:1180 models_treatments.py:280
+#: templates/ishtar/sheet_treatment.html:102
msgid "Upstream finds"
msgstr "Mobilier amont"
-#: forms.py:771 models_finds.py:1090
+#: forms.py:1037 models_finds.py:1193
#: templates/ishtar/forms/qa_find_treatment.html:11
+#: templates/ishtar/sheet_treatment.html:24
msgid "Finds"
msgstr "Mobilier"
-#: forms.py:783
+#: forms.py:1049
msgid "You should at least select one archaeological find."
msgstr "Vous devez sélectionner au moins un mobilier archéologique."
-#: forms.py:886
-msgid "Resulting find"
-msgstr "Mobilier résultant"
-
-#: forms.py:891
+#: forms.py:1157
msgid "Precise description"
msgstr "Description précise"
-#: forms.py:905
-msgid "Resulting finds"
-msgstr "Mobiliers résultants"
-
-#: forms.py:910
+#: forms.py:1176
msgid "Would you like to delete this find?"
msgstr "Voulez-vous supprimer ce mobilier ?"
-#: forms.py:914 models_treatments.py:68
-msgid "Upstream find"
-msgstr "Mobilier amont"
-
-#: forms.py:925
+#: forms.py:1213
msgid "Find basket - 001 - Search"
msgstr "Panier mobilier - 001 - Recherche"
-#: forms.py:937 views.py:122
+#: forms.py:1225 forms.py:1240 views.py:164
msgid "Basket search"
msgstr "Recherche de panier"
-#: forms.py:951
+#: forms.py:1254
msgid "Find basket"
msgstr "Panier de mobilier"
-#: forms.py:953 forms_treatments.py:54 forms_treatments.py:97
-#: models_treatments.py:118 templates/ishtar/sheet_find.html:179
-#: templates/ishtar/sheet_find.html:217
+#: forms.py:1258 forms_treatments.py:53 forms_treatments.py:122
+#: models_treatments.py:133
+#: templates/ishtar/forms/qa_findbasket_duplicate.html:15
+#: templates/ishtar/sheet_find.html:259 templates/ishtar/sheet_find.html:296
+#: templates/ishtar/sheet_find.html:334
msgid "Label"
msgstr "Dénomination"
-#: forms.py:972
+#: forms.py:1264 forms.py:1277
+msgid "Shared (read) with"
+msgstr "Partagé (lecture) avec"
+
+#: forms.py:1269 forms.py:1282
+msgid "Shared (read/edit) with"
+msgstr "Partagé (lecture/édition) avec"
+
+#: forms.py:1298
msgid "Another basket already exists with this name."
msgstr "Un autre panier existant utilise déjà ce nom."
-#: forms_treatments.py:55 forms_treatments.py:100 models_treatments.py:120
+#: forms_treatments.py:54 forms_treatments.py:125 models_treatments.py:135
msgid "Other ref."
msgstr "Autre réf."
-#: forms_treatments.py:57 forms_treatments.py:232 forms_treatments.py:424
-#: forms_treatments.py:486 forms_treatments.py:499 forms_treatments.py:603
-#: forms_treatments.py:691 forms_treatments.py:758 models_treatments.py:123
-#: models_treatments.py:583
+#: forms_treatments.py:56 forms_treatments.py:295 forms_treatments.py:496
+#: forms_treatments.py:558 forms_treatments.py:571 forms_treatments.py:682
+#: forms_treatments.py:770 forms_treatments.py:837 models_treatments.py:138
+#: models_treatments.py:821
msgid "Index"
msgstr "Index"
-#: forms_treatments.py:58 forms_treatments.py:106 forms_treatments.py:378
-#: forms_treatments.py:440 models_finds.py:106 models_treatments.py:128
-#: models_treatments.py:359
+#: forms_treatments.py:57 forms_treatments.py:97 forms_treatments.py:450
+#: forms_treatments.py:512 models_finds.py:121 models_treatments.py:143
+#: models_treatments.py:595
msgid "Treatment type"
msgstr "Type de traitement"
-#: forms_treatments.py:71 views.py:420
+#: forms_treatments.py:70 views.py:479
msgid "Treatment search"
msgstr "Rechercher un traitement"
-#: forms_treatments.py:83
-msgid "Base treatment"
-msgstr "Traitement de base"
+#: forms_treatments.py:82 ishtar_menu.py:143 models_treatments.py:187
+#: models_treatments.py:587 templates/ishtar/sheet_treatment.html:4
+#: templates/ishtar/sheet_treatment.html:17
+msgid "Treatment"
+msgstr "Traitement"
-#: forms_treatments.py:84
+#: forms_treatments.py:83
msgid "Treatment - 020 - General"
msgstr "Traitement - 020 - Général"
-#: forms_treatments.py:108 models_treatments.py:70 models_treatments.py:130
-#: templates/ishtar/sheet_find.html:181 templates/ishtar/sheet_find.html:219
+#: forms_treatments.py:99 models_treatments.py:83 models_treatments.py:145
+#: templates/ishtar/sheet_find.html:261 templates/ishtar/sheet_find.html:298
+#: templates/ishtar/sheet_find.html:336
msgid "State"
msgstr "État"
-#: forms_treatments.py:110
-msgid "Target"
-msgstr "Destination"
+#: forms_treatments.py:105 models_treatments.py:151 models_treatments.py:598
+msgid "Location"
+msgstr "Localisation"
-#: forms_treatments.py:112 forms_treatments.py:301 forms_treatments.py:561
-#: models_treatments.py:71 models_treatments.py:138
+#: forms_treatments.py:111 forms_treatments.py:369 forms_treatments.py:635
+#: models_treatments.py:84 models_treatments.py:156
msgid "Responsible"
msgstr "Responsable"
-#: forms_treatments.py:118 forms_treatments.py:307 models_treatments.py:141
+#: forms_treatments.py:117 forms_treatments.py:375 models_treatments.py:159
msgid "Organization"
msgstr "Organisation"
-#: forms_treatments.py:124 models_treatments.py:133 models_treatments.py:362
-msgid "Location"
-msgstr "Localisation"
-
-#: forms_treatments.py:130
-msgid "Container (relevant for packaging)"
-msgstr "Contenant (pertinent dans le cadre du conditionnement)"
+#: forms_treatments.py:130 forms_treatments.py:442 forms_treatments.py:665
+#: forms_treatments.py:718 models_treatments.py:167 models_treatments.py:841
+msgid "Closing date"
+msgstr "Date de clôture"
-#: forms_treatments.py:136 forms_treatments.py:557
-msgid "External ref."
-msgstr "Référence"
+#: forms_treatments.py:133
+msgid "Destination container (relevant for treatment that change location)"
+msgstr ""
+"Contenant de destination (pertinent pour des traitements changeant la "
+"localisation)"
-#: forms_treatments.py:137 models_treatments.py:147
+#: forms_treatments.py:139 models_treatments.py:165
msgid "Goal"
msgstr "But"
-#: forms_treatments.py:145 forms_treatments.py:370 forms_treatments.py:586
-#: forms_treatments.py:639 models_treatments.py:149 models_treatments.py:603
-msgid "Closing date"
-msgstr "Date de clôture"
-
-#: forms_treatments.py:147
+#: forms_treatments.py:145
#, python-brace-format
msgid "Estimated cost ({currency})"
msgstr "Coût estimé ({currency})"
-#: forms_treatments.py:149
+#: forms_treatments.py:147
#, python-brace-format
msgid "Quoted cost ({currency})"
msgstr "Coût devisé ({currency})"
-#: forms_treatments.py:151
+#: forms_treatments.py:149
#, python-brace-format
msgid "Realized cost ({currency})"
msgstr "Coût réalisé ({currency})"
-#: forms_treatments.py:153
+#: forms_treatments.py:151
#, python-brace-format
msgid "Insurance cost ({currency})"
msgstr "Coût d''assurance ({currency})"
-#: forms_treatments.py:180
-msgid "Single find"
-msgstr "Mobilier isolé"
+#: forms_treatments.py:212
+msgid "Unknow treatment type"
+msgstr "Type de traitement inconnu"
+
+#: forms_treatments.py:233 forms_treatments.py:242
+msgid "{} is not compatible with {} treatment(s)."
+msgstr "{} n'est pas compatible avec le(s) traitement(s) {}."
-#: forms_treatments.py:204
+#: forms_treatments.py:253
msgid ""
-"The container field is attached to the treatment. If no packaging treatment "
-"is done it is not relevant."
+"The container field is attached to the treatment but no treatment with "
+"container change is defined."
msgstr ""
-"Le champ concernant le contenant est rattaché au traitement. Si aucun "
-"conditionnement n'est réalisé, il n'est pas pertinent."
+"Le champ concernant le contenant est rattaché au traitement mais aucun "
+"traitement changeant le contenant n'est sélectionné."
-#: forms_treatments.py:209
-msgid "If a packaging treatment is done, the container field must be filled."
+#: forms_treatments.py:258
+msgid ""
+"A treatment with location change is defined, the container field must be "
+"filled."
msgstr ""
-"Si un conditionnement est fait, le champ du contenant doit être rempli."
+"Un traitement avec un changement de localisation est défini, le champ "
+"contenant doit être rempli."
-#: forms_treatments.py:213
+#: forms_treatments.py:262
msgid "A responsible or an organization must be defined."
msgstr "Un responsable ou une organisation doit être défini."
-#: forms_treatments.py:256
+#: forms_treatments.py:267
+msgid "Treatment n-1 - 020 - General"
+msgstr "Traitement n-1 - 020 - Général"
+
+#: forms_treatments.py:281
+msgid "Treatment 1-n - 020 - General"
+msgstr "Traitement 1-n - 020 - Général"
+
+#: forms_treatments.py:319
msgid "Another treatment with this index exists for {}."
msgstr "Un autre traitement avec cet index existe pour {}."
-#: forms_treatments.py:262 models_treatments.py:126
+#: forms_treatments.py:325 models_treatments.py:141
msgid "Associated request"
msgstr "Demande associée"
-#: forms_treatments.py:263
+#: forms_treatments.py:326
msgid "Treatment - 010 - Request choice"
msgstr "Traitement - 010 - Choix de la demande de traitement"
-#: forms_treatments.py:268 forms_treatments.py:541 ishtar_menu.py:95
-#: models_treatments.py:618 models_treatments.py:646
-#: templates/ishtar/sheet_treatmentfile.html:4 wizards.py:207
+#: forms_treatments.py:331 forms_treatments.py:613 ishtar_menu.py:95
+#: models_treatments.py:860 models_treatments.py:882
+#: templates/ishtar/sheet_treatmentfile.html:4 wizards.py:465
msgid "Treatment request"
msgstr "Demande de traitement"
-#: forms_treatments.py:277
+#: forms_treatments.py:340
msgid ""
"Are you sure you want to delete this treatment? All changes made to the "
"associated finds since this treatment record will be lost!"
@@ -698,190 +789,212 @@ msgstr ""
"sur le mobilier associé réalisées depuis l'enregistrement de ce traitement "
"seront perdues !"
-#: forms_treatments.py:280
+#: forms_treatments.py:343
msgid "Would you like to delete this treatment?"
msgstr "Voulez-vous supprimer ce traitement ?"
-#: forms_treatments.py:285 models_finds.py:683 models_finds.py:1000
-#: models_treatments.py:150 models_treatments.py:363
-#: templates/ishtar/sheet_find.html:184 templates/ishtar/sheet_find.html:222
+#: forms_treatments.py:348 models_finds.py:1092 models_treatments.py:169
+#: models_treatments.py:599 templates/ishtar/sheet_find.html:264
+#: templates/ishtar/sheet_find.html:301 templates/ishtar/sheet_find.html:339
msgid "Container"
msgstr "Contenant"
-#: forms_treatments.py:291
+#: forms_treatments.py:354 templates/ishtar/forms/qa_find_treatment.html:31
+msgid "Change the reference container"
+msgstr "Changer le contenant de référence"
+
+#: forms_treatments.py:356
+msgid "If unchecked the current container will be changed"
+msgstr "Si c'est décoché, le contenant actuel va être changé"
+
+#: forms_treatments.py:359
msgid "Create a treatment"
msgstr "Créer un traitement"
-#: forms_treatments.py:298
+#: forms_treatments.py:366
msgid "Precise date"
msgstr "Date précise"
-#: forms_treatments.py:340
+#: forms_treatments.py:408
msgid "At least a year is required."
msgstr "Au minimum une année doit être précisée."
-#: forms_treatments.py:369
+#: forms_treatments.py:416 models_finds.py:1022 models_finds.py:1304
+#: templates/ishtar/forms/qa_find_treatment.html:16 views.py:844
+msgid "Packaging"
+msgstr "Conditionnement"
+
+#: forms_treatments.py:441
msgid "months"
msgstr "mois"
-#: forms_treatments.py:369
+#: forms_treatments.py:441
msgid "years"
msgstr "années"
-#: forms_treatments.py:374 forms_treatments.py:643
+#: forms_treatments.py:446 forms_treatments.py:722
msgid "Slicing"
msgstr "Découpage"
-#: forms_treatments.py:377 forms_treatments.py:646
+#: forms_treatments.py:449 forms_treatments.py:725
msgid "Date get from"
msgstr "Date utilisée"
-#: forms_treatments.py:380 forms_treatments.py:649
+#: forms_treatments.py:452 forms_treatments.py:728
msgid "Date after"
msgstr "Date après"
-#: forms_treatments.py:382 forms_treatments.py:651
+#: forms_treatments.py:454 forms_treatments.py:730
msgid "Date before"
msgstr "Date avant"
-#: forms_treatments.py:425 forms_treatments.py:475 forms_treatments.py:692
-#: forms_treatments.py:747
+#: forms_treatments.py:497 forms_treatments.py:547 forms_treatments.py:771
+#: forms_treatments.py:826
msgid "Act type"
msgstr "Type d'acte"
-#: forms_treatments.py:426 forms_treatments.py:693
+#: forms_treatments.py:498 forms_treatments.py:772
msgid "Indexed?"
msgstr "Indexé ?"
-#: forms_treatments.py:427 forms_treatments.py:694
+#: forms_treatments.py:499 forms_treatments.py:773
msgid "Object"
msgstr "Objet"
-#: forms_treatments.py:431 forms_treatments.py:698
+#: forms_treatments.py:503 forms_treatments.py:777
msgid "Signature date after"
msgstr "Date de signature après"
-#: forms_treatments.py:433 forms_treatments.py:700
+#: forms_treatments.py:505 forms_treatments.py:779
msgid "Signature date before"
msgstr "Date de signature avant"
-#: forms_treatments.py:435
+#: forms_treatments.py:507
msgid "Treatment name"
msgstr "Nom du traitement"
-#: forms_treatments.py:436
+#: forms_treatments.py:508
msgid "Treatment year"
msgstr "Année du traitement"
-#: forms_treatments.py:437
+#: forms_treatments.py:509
msgid "Treatment index"
msgstr "Index du traitement"
-#: forms_treatments.py:439
+#: forms_treatments.py:511
msgid "Treatment internal reference"
msgstr "Référence interne du traitement"
-#: forms_treatments.py:443 forms_treatments.py:714
+#: forms_treatments.py:515 forms_treatments.py:793
msgid "Modified by"
msgstr "Modifié par"
-#: forms_treatments.py:473
+#: forms_treatments.py:545
msgid "Treatment - Administrative act - General"
msgstr "Traitement - Acte administratif - Général"
-#: forms_treatments.py:496 forms_treatments.py:548 models_treatments.py:588
+#: forms_treatments.py:568 forms_treatments.py:622 models_treatments.py:826
msgid "Name"
msgstr "Nom"
-#: forms_treatments.py:497 forms_treatments.py:555
+#: forms_treatments.py:569 forms_treatments.py:629
msgid "Internal ref."
msgstr "Réf. interne"
-#: forms_treatments.py:500 forms_treatments.py:559 models_treatments.py:69
-#: templates/ishtar/sheet_find.html:180 templates/ishtar/sheet_find.html:218
+#: forms_treatments.py:572 forms_treatments.py:633 models_treatments.py:82
+#: templates/ishtar/sheet_find.html:260 templates/ishtar/sheet_find.html:297
+#: templates/ishtar/sheet_find.html:335
msgid "Type"
msgstr "Type"
-#: forms_treatments.py:503
+#: forms_treatments.py:575
msgid "In charge"
msgstr "Responsable"
-#: forms_treatments.py:509 forms_treatments.py:567 models_treatments.py:597
-#: templates/ishtar/sheet_treatmentfile.html:45
+#: forms_treatments.py:581 forms_treatments.py:641 models_treatments.py:835
+#: templates/ishtar/sheet_treatmentfile.html:46
msgid "Applicant"
msgstr "Demandeur"
-#: forms_treatments.py:515 forms_treatments.py:573 models_treatments.py:601
-#: templates/ishtar/sheet_treatmentfile.html:53
+#: forms_treatments.py:587 forms_treatments.py:647 models_treatments.py:839
+#: templates/ishtar/sheet_treatmentfile.html:54
msgid "Applicant organisation"
msgstr "Organisation du demandeur"
-#: forms_treatments.py:529 views.py:524
+#: forms_treatments.py:601 views.py:681
msgid "Treatment request search"
msgstr "Rechercher une demande de traitement"
-#: forms_treatments.py:584 forms_treatments.py:638 models_treatments.py:607
+#: forms_treatments.py:631
+msgid "External ref."
+msgstr "Référence"
+
+#: forms_treatments.py:653
+msgid "Associated basket"
+msgstr "Panier associé"
+
+#: forms_treatments.py:663 forms_treatments.py:717 models_treatments.py:845
msgid "Reception date"
msgstr "Date de réception"
-#: forms_treatments.py:626
+#: forms_treatments.py:705
msgid "Another treatment request with this index exists for {}."
msgstr "Une autre demande de traitement avec cet index existe pour {}."
-#: forms_treatments.py:632
+#: forms_treatments.py:711
msgid "Are you sure you want to delete this treatment request?"
msgstr "Êtes-vous sûr de vouloir supprimer cette demande de traitement ? "
-#: forms_treatments.py:633
+#: forms_treatments.py:712
msgid "Would you like to delete this treatment request?"
msgstr "Voulez-vous supprimer cette demande de traitement ?"
-#: forms_treatments.py:637 models_treatments.py:605
+#: forms_treatments.py:716 models_treatments.py:843
msgid "Creation date"
msgstr "Date de création"
-#: forms_treatments.py:647 forms_treatments.py:711 models_treatments.py:519
-#: models_treatments.py:590
+#: forms_treatments.py:726 forms_treatments.py:790 models_treatments.py:757
+#: models_treatments.py:828
msgid "Treatment request type"
msgstr "Type de demande de traitement"
-#: forms_treatments.py:703
+#: forms_treatments.py:782
msgid "Treatment request name"
msgstr "Nom du dossier de traitement"
-#: forms_treatments.py:705
+#: forms_treatments.py:784
msgid "Treatment request year"
msgstr "Année du dossier de traitement"
-#: forms_treatments.py:707
+#: forms_treatments.py:786
msgid "Treatment request index"
msgstr "Index de la demande de traitement"
-#: forms_treatments.py:709
+#: forms_treatments.py:788
msgid "Treatment request internal reference"
msgstr "Référence interne de la demande de traitement"
-#: forms_treatments.py:745
+#: forms_treatments.py:824
msgid "Treatment request - Administrative act - General"
msgstr "Demande de traitement - Acte administratif - Général"
#: ishtar_menu.py:37 ishtar_menu.py:60 ishtar_menu.py:100 ishtar_menu.py:123
-#: ishtar_menu.py:155 ishtar_menu.py:179
+#: ishtar_menu.py:148 ishtar_menu.py:181
msgid "Search"
msgstr "Recherche"
#: ishtar_menu.py:42 ishtar_menu.py:65 ishtar_menu.py:105 ishtar_menu.py:127
-#: ishtar_menu.py:160 ishtar_menu.py:183
+#: ishtar_menu.py:185
msgid "Creation"
msgstr "Ajout"
#: ishtar_menu.py:47 ishtar_menu.py:70 ishtar_menu.py:110 ishtar_menu.py:131
-#: ishtar_menu.py:165 ishtar_menu.py:188
+#: ishtar_menu.py:168 ishtar_menu.py:190
msgid "Modification"
msgstr "Modification"
#: ishtar_menu.py:52 ishtar_menu.py:82 ishtar_menu.py:115 ishtar_menu.py:134
-#: ishtar_menu.py:170 ishtar_menu.py:191
+#: ishtar_menu.py:173 ishtar_menu.py:193
msgid "Deletion"
msgstr "Suppression"
@@ -889,23 +1002,21 @@ msgstr "Suppression"
msgid "Manage items"
msgstr "Gestion des éléments"
-#: ishtar_menu.py:120 ishtar_menu.py:176 models_finds.py:1719
+#: ishtar_menu.py:120 ishtar_menu.py:178 models_finds.py:1961
msgid "Administrative act"
msgstr "Acte administratif"
-#: ishtar_menu.py:138 ishtar_menu.py:195 models_finds.py:1081
-#: models_treatments.py:163 models_treatments.py:611
-msgid "Documents"
-msgstr "Documents"
+#: ishtar_menu.py:154
+msgid "Simple treatment - creation"
+msgstr "Traitement simple - création"
-#: ishtar_menu.py:147 models_treatments.py:170 models_treatments.py:351
-#: templates/ishtar/sheet_treatment.html:4
-msgid "Treatment"
-msgstr "Traitement"
+#: ishtar_menu.py:159
+msgid "Treatment many to one - creation"
+msgstr "Traitement de plusieurs à un - création"
-#: ishtar_menu.py:152
-msgid "Simple treatments"
-msgstr "Traitements simples"
+#: ishtar_menu.py:164
+msgid "Treatment one to many - creation"
+msgstr "Traitement de un à plusieurs - création"
#: models_finds.py:51
msgid "Code"
@@ -915,9 +1026,9 @@ msgstr "Code"
msgid "Recommendation"
msgstr "Recommandation"
-#: models_finds.py:66 models_finds.py:79 models_finds.py:92 models_finds.py:138
-#: models_finds.py:161 models_finds.py:218 models_finds.py:967
-#: models_treatments.py:355
+#: models_finds.py:66 models_finds.py:79 models_finds.py:92 models_finds.py:153
+#: models_finds.py:176 models_finds.py:233 models_finds.py:1059
+#: models_treatments.py:45 models_treatments.py:591
msgid "Order"
msgstr "Ordre"
@@ -941,581 +1052,712 @@ msgstr "Types d'état de conservation"
msgid "Virtual"
msgstr "Virtuel"
-#: models_finds.py:95
+#: models_finds.py:94
+msgid "Destructive"
+msgstr "Destructif"
+
+#: models_finds.py:96
+msgid "Create a new find"
+msgstr "Créer un nouvel élément"
+
+#: models_finds.py:97
+msgid ""
+"If True when this treatment is applied a new version of the object will be "
+"created."
+msgstr ""
+"Si mis à Vrai quand le traitement est appliqué une nouvelle version de "
+"l'objet sera créée."
+
+#: models_finds.py:100
msgid "Upstream is many"
msgstr "Les éléments amont sont multiples"
-#: models_finds.py:97
+#: models_finds.py:102
msgid "Check this if for this treatment from many finds you'll get one."
msgstr ""
"Cochez cela si, pour ce traitement, à partir de plusieurs éléments vous en "
"obtenez un seul."
-#: models_finds.py:100
+#: models_finds.py:105
msgid "Downstream is many"
msgstr "Les éléments aval sont multiples"
-#: models_finds.py:102
+#: models_finds.py:107
msgid "Check this if for this treatment from one find you'll get many."
msgstr ""
"Cochez cela si, pour ce traitement, à partir d'un seul élément vous en "
"obtenez plusieurs."
-#: models_finds.py:107 models_treatments.py:240
+#: models_finds.py:110
+msgid "Change reference location"
+msgstr "Change la localisation de référence"
+
+#: models_finds.py:111
+msgid "The treatment change the reference location."
+msgstr "Le traitement change la localisation de référence."
+
+#: models_finds.py:113
+msgid "Change current location"
+msgstr "Change la localisation actuelle"
+
+#: models_finds.py:114
+msgid "The treatment change the current location."
+msgstr "Le traitement change la localisation actuelle."
+
+#: models_finds.py:116
+msgid "Restore the reference location"
+msgstr "Restaure la localisation de référence"
+
+#: models_finds.py:117
+msgid ""
+"The treatment change restore reference location to the current location."
+msgstr ""
+"Le traitement restaure la localisation de référence sur la localisation "
+"actuelle."
+
+#: models_finds.py:122 models_treatments.py:262
msgid "Treatment types"
msgstr "Types de traitement"
-#: models_finds.py:117
+#: models_finds.py:132
msgid "Integrity / interest type"
msgstr "Type d'intégrité / intérêt"
-#: models_finds.py:118
+#: models_finds.py:133
msgid "Integrity / interest types"
msgstr "Types d'intégrité / intérêt"
-#: models_finds.py:128
+#: models_finds.py:143
msgid "Remarkability type"
msgstr "Type de remarquabilité"
-#: models_finds.py:129
+#: models_finds.py:144
msgid "Remarkability types"
msgstr "Types de remarquabilité"
-#: models_finds.py:140
+#: models_finds.py:155
msgid "Batch type"
msgstr "Type de lot"
-#: models_finds.py:141
+#: models_finds.py:156
msgid "Batch types"
msgstr "Types de lot"
-#: models_finds.py:164
+#: models_finds.py:179
msgid "Object type quality type"
msgstr "Type de qualité du type d'objet"
-#: models_finds.py:165
+#: models_finds.py:180
msgid "Object type quality types"
msgstr "Types de qualité du type d'objet"
-#: models_finds.py:175
+#: models_finds.py:190
msgid "Alteration type"
msgstr "Type d'altération"
-#: models_finds.py:176
+#: models_finds.py:191
msgid "Alteration types"
msgstr "Types d'altération"
-#: models_finds.py:186
+#: models_finds.py:201
msgid "Alteration cause type"
msgstr "Type de cause d'altération"
-#: models_finds.py:187
+#: models_finds.py:202
msgid "Alteration cause types"
msgstr "Types de cause d'altération"
-#: models_finds.py:197
+#: models_finds.py:212
msgid "Treatment emergency type"
msgstr "Type d'urgence du traitement"
-#: models_finds.py:198
+#: models_finds.py:213
msgid "Treatment emergency types"
msgstr "Types d'urgence du traitement"
-#: models_finds.py:208
+#: models_finds.py:223
msgid "Communicability type"
msgstr "Type de communicabilité"
-#: models_finds.py:209
+#: models_finds.py:224
msgid "Communicability types"
msgstr "Types de communicabilité"
-#: models_finds.py:221
+#: models_finds.py:236
msgid "Checked type"
msgstr "Type de vérification"
-#: models_finds.py:222
+#: models_finds.py:237
msgid "Checked types"
msgstr "Types de vérification"
-#: models_finds.py:254 models_finds.py:960 models_treatments.py:143
-#: models_treatments.py:586
+#: models_finds.py:269 models_finds.py:1052 models_treatments.py:161
+#: models_treatments.py:824
msgid "External ID"
msgstr "Identifiant"
-#: models_finds.py:256 models_finds.py:962
+#: models_finds.py:271 models_finds.py:1054
msgid "External ID is set automatically"
msgstr "L'identifiant est attribué automatiquement"
-#: models_finds.py:260
+#: models_finds.py:275
msgid "Special interest"
msgstr "Intérêt spécifique"
-#: models_finds.py:264
+#: models_finds.py:279
msgid "Context Record"
msgstr "Unité d'Enregistrement"
-#: models_finds.py:272
+#: models_finds.py:287
msgid "Material index"
msgstr "Index matériel"
-#: models_finds.py:289
+#: models_finds.py:304
msgid "Point (3D)"
msgstr "Point (3D)"
-#: models_finds.py:295 models_finds.py:298
+#: models_finds.py:310 models_finds.py:313
msgid "Cached value - do not edit"
msgstr "Valeur en cache - ne pas éditer"
-#: models_finds.py:308 models_finds.py:958
+#: models_finds.py:323 models_finds.py:1050
msgid "Base find"
msgstr "Mobilier d'origine"
-#: models_finds.py:309
+#: models_finds.py:324
msgid "Base finds"
msgstr "Mobilier d'origine"
-#: models_finds.py:565
+#: models_finds.py:589
msgid "g"
msgstr "g"
-#: models_finds.py:566
+#: models_finds.py:590
msgid "kg"
msgstr "kg"
-#: models_finds.py:592 views.py:301
+#: models_finds.py:600 views.py:863 views.py:882
+msgid "Duplicate"
+msgstr "Dupliquer"
+
+#: models_finds.py:626 views.py:379
msgid "Manage basket"
msgstr "Gérer un panier"
-#: models_finds.py:661
+#: models_finds.py:633 models_finds.py:1299
+msgid "Add treatment"
+msgstr "Ajouter un traitement"
+
+#: models_finds.py:723
msgid "Base find - Short ID"
msgstr "Mobilier d'origine - ID court"
-#: models_finds.py:662
+#: models_finds.py:724
msgid "Base find - Complete ID"
msgstr "Mobilier d'origine - ID complet"
-#: models_finds.py:664
+#: models_finds.py:726
msgid "Operation (code)"
msgstr "Opération (code)"
-#: models_finds.py:666
+#: models_finds.py:728
msgid "Town"
msgstr "Ville"
-#: models_finds.py:668
+#: models_finds.py:730
msgid "Operation (name)"
msgstr "Opération (nom)"
-#: models_finds.py:672
+#: models_finds.py:734
msgid "Parcel"
msgstr "Parcelle"
-#: models_finds.py:673
+#: models_finds.py:735
msgid "Batch"
msgstr "Lot"
-#: models_finds.py:674
+#: models_finds.py:736
msgid "Base find - Comment"
msgstr "Mobilier d'origine - Commentaires"
-#: models_finds.py:675
+#: models_finds.py:737
msgid "Base find - Description"
msgstr "Mobilier d'origine - Description"
-#: models_finds.py:676
+#: models_finds.py:738
msgid "Base find - Topographic localisation"
msgstr "Mobilier d'origine - Localisation topographique"
-#: models_finds.py:678
+#: models_finds.py:740
msgid "Base find - Special interest"
msgstr "Mobilier d'origine - Intérêt spécifique"
-#: models_finds.py:680
+#: models_finds.py:742
msgid "Base find - Discovery date (exact or TPQ)"
msgstr "Mobilier d'origine - Date de découverte (exacte ou TPQ)"
-#: models_finds.py:682
+#: models_finds.py:744
msgid "Base find - Discovery date (TAQ)"
msgstr "Mobilier d'origine - Date de découverte (TAQ)"
-#: models_finds.py:684
+#: models_finds.py:745
+msgid "Current container"
+msgstr "Contenant actuel"
+
+#: models_finds.py:746 models_finds.py:1097
+msgid "Reference container"
+msgstr "Contenant de référence"
+
+#: models_finds.py:747
msgid "Periods"
msgstr "Périodes"
-#: models_finds.py:760
+#: models_finds.py:823
msgctxt "key for text search"
msgid "short-id"
msgstr "id-court"
-#: models_finds.py:764
+#: models_finds.py:827
msgctxt "key for text search"
msgid "complete-id"
msgstr "id-complet"
-#: models_finds.py:768
+#: models_finds.py:831
msgctxt "key for text search"
msgid "free-id"
msgstr "id-libre"
-#: models_finds.py:772
+#: models_finds.py:835
msgctxt "key for text search"
msgid "denomination"
msgstr "denomination"
-#: models_finds.py:776
+#: models_finds.py:839
msgctxt "key for text search"
msgid "town"
msgstr "commune"
-#: models_finds.py:780 models_treatments.py:87 models_treatments.py:551
+#: models_finds.py:843 models_treatments.py:102 models_treatments.py:789
msgctxt "key for text search"
msgid "year"
msgstr "annee"
-#: models_finds.py:784
+#: models_finds.py:847
msgctxt "key for text search"
msgid "operation-code"
msgstr "operation-code"
-#: models_finds.py:788
+#: models_finds.py:851
msgctxt "key for text search"
msgid "code-patriarche"
msgstr "code-patriarche"
-#: models_finds.py:792
+#: models_finds.py:855
msgctxt "key for text search"
msgid "operation-type"
msgstr "operation-type"
-#: models_finds.py:797
+#: models_finds.py:860
msgctxt "key for text search"
msgid "area"
msgstr "zone"
-#: models_finds.py:801
+#: models_finds.py:864
msgctxt "key for text search"
msgid "site"
msgstr "site"
-#: models_finds.py:806 models_finds.py:945
+#: models_finds.py:869 models_finds.py:1037
msgctxt "key for text search"
msgid "context-record-site"
msgstr "ue-site"
-#: models_finds.py:811 models_finds.py:939
+#: models_finds.py:874 models_finds.py:1031
msgctxt "key for text search"
msgid "context-record"
msgstr "ue"
-#: models_finds.py:815
+#: models_finds.py:878
msgctxt "key for text search"
msgid "operation-relation-type"
msgstr "operation-type-relation"
-#: models_finds.py:819
+#: models_finds.py:882
msgctxt "key for text search"
msgid "context-record-relation-type"
msgstr "ue-type-relation"
-#: models_finds.py:823
+#: models_finds.py:886
msgctxt "key for text search"
msgid "period"
msgstr "periode"
-#: models_finds.py:827
+#: models_finds.py:890
msgctxt "key for text search"
msgid "material"
msgstr "materiau"
-#: models_finds.py:831
+#: models_finds.py:894
msgctxt "key for text search"
msgid "object-type"
msgstr "type-objet"
-#: models_finds.py:835
+#: models_finds.py:898
msgctxt "key for text search"
msgid "preservation"
msgstr "preservation"
-#: models_finds.py:839
+#: models_finds.py:902
msgctxt "key for text search"
msgid "conservatory"
msgstr "conservation"
-#: models_finds.py:843
+#: models_finds.py:906
msgctxt "key for text search"
msgid "integrity"
msgstr "integrite"
-#: models_finds.py:847
+#: models_finds.py:910
msgctxt "key for text search"
msgid "remarkability"
msgstr "remarquabilite"
-#: models_finds.py:851
+#: models_finds.py:914
msgctxt "key for text search"
msgid "description"
msgstr "description"
-#: models_finds.py:855
+#: models_finds.py:918
msgctxt "key for text search"
msgid "batch"
msgstr "lot"
-#: models_finds.py:859
+#: models_finds.py:922
msgctxt "key for text search"
msgid "checked"
msgstr "verifie"
-#: models_finds.py:863 models_treatments.py:95
+#: models_finds.py:926 models_treatments.py:110
msgctxt "key for text search"
msgid "has-image"
msgstr "a-une-image"
-#: models_finds.py:867 models_finds.py:942
+#: models_finds.py:930 models_finds.py:1034
msgctxt "key for text search"
msgid "location"
msgstr "localisation"
-#: models_finds.py:871
+#: models_finds.py:934
msgctxt "key for text search"
msgid "warehouse"
msgstr "depot"
-#: models_finds.py:875
+#: models_finds.py:938
msgctxt "key for text search"
msgid "container-index"
msgstr "contenant-index"
-#: models_finds.py:879
+#: models_finds.py:942
msgctxt "key for text search"
msgid "container-ref"
msgstr "contenant-ref"
-#: models_finds.py:883
+#: models_finds.py:946
+msgctxt "key for text search"
+msgid "current-location"
+msgstr "localisation-actuelle"
+
+#: models_finds.py:950
+msgctxt "key for text search"
+msgid "current-warehouse"
+msgstr "depot-actuel"
+
+#: models_finds.py:954
+msgctxt "key for text search"
+msgid "current-container-index"
+msgstr "contenant-actuel-index"
+
+#: models_finds.py:958
+msgctxt "key for text search"
+msgid "current-container-ref"
+msgstr "contenant-actuel-ref"
+
+#: models_finds.py:962 wizards.py:399
msgctxt "key for text search"
msgid "basket"
msgstr "panier"
-#: models_finds.py:887 models_finds.py:936
+#: models_finds.py:966 models_finds.py:1028
msgctxt "key for text search"
msgid "operation"
msgstr "operation"
-#: models_finds.py:891
+#: models_finds.py:970
msgctxt "key for text search"
msgid "last-modified-by"
msgstr "modifie-en-dernier-par"
-#: models_finds.py:895
+#: models_finds.py:974
msgctxt "key for text search"
msgid "modified-since"
msgstr "modifie-depuis"
-#: models_finds.py:919
-msgid "Bulk update"
-msgstr "Mise à jour multiple"
+#: models_finds.py:978
+msgctxt "key for text search"
+msgid "created-by"
+msgstr "cree-par"
-#: models_finds.py:930 models_finds.py:1180
-#: templates/ishtar/forms/qa_find_treatment.html:16 views.py:666
-msgid "Packaging"
-msgstr "Conditionnement"
+#: models_finds.py:982
+msgctxt "key for text search"
+msgid "loan"
+msgstr "pret"
#: models_finds.py:986
+msgctxt "key for text search"
+msgid "treatment-end-date-before"
+msgstr "fin-de-traitement-avant"
+
+#: models_finds.py:1011
+msgid "Bulk update"
+msgstr "Mise à jour multiple"
+
+#: models_finds.py:1078
msgid "Weight"
msgstr "Poids"
-#: models_finds.py:987
+#: models_finds.py:1079
msgid "Weight unit"
msgstr "Unité de poids"
-#: models_finds.py:993 templates/ishtar/sheet_find.html:174
+#: models_finds.py:1085 templates/ishtar/sheet_find.html:291
msgid "Upstream treatment"
msgstr "Traitement amont"
-#: models_finds.py:996 templates/ishtar/sheet_find.html:212
+#: models_finds.py:1088 templates/ishtar/sheet_find.html:329
msgid "Downstream treatment"
msgstr "Traitement aval"
-#: models_finds.py:1031
+#: models_finds.py:1130
msgid "Clutter - long side (cm)"
msgstr "Encombrement - grand côté (cm)"
-#: models_finds.py:1033
+#: models_finds.py:1132
msgid "Clutter - short side (cm)"
msgstr "Encombrement - petit côté (cm)"
-#: models_finds.py:1035
+#: models_finds.py:1134
msgid "Clutter - height (cm)"
msgstr "Encombrement - hauteur (cm)"
-#: models_finds.py:1051
+#: models_finds.py:1150
msgid "Collection"
msgstr "Collection"
-#: models_finds.py:1083 models_treatments.py:165 models_treatments.py:613
+#: models_finds.py:1180 models_treatments.py:180 models_treatments.py:849
+#: templates/ishtar/sheet_find.html:56 templates/ishtar/sheet_treatment.html:32
+msgid "Documents"
+msgstr "Documents"
+
+#: models_finds.py:1183 models_treatments.py:188
+#: templates/ishtar/sheet_find.html:254
+#: templates/ishtar/sheet_treatmentfile.html:62
+msgid "Treatments"
+msgstr "Traitements"
+
+#: models_finds.py:1185
+msgid "Related treatments when no new find is created"
+msgstr ""
+"Traitements associés quand il n'y a pas de création de nouveau mobilier"
+
+#: models_finds.py:1186 models_treatments.py:182 models_treatments.py:855
msgid "Cached name"
msgstr "Nom en cache"
-#: models_finds.py:1105
+#: models_finds.py:1208
msgid "FIND"
msgstr "MOBILIER"
-#: models_finds.py:1174
+#: models_finds.py:1296
msgid "Add to basket"
msgstr "Ajouter au panier"
-#: models_finds.py:1222 wizards.py:74 wizards.py:219
+#: models_finds.py:1346 wizards.py:85 wizards.py:477
msgid "Operation"
msgstr "Opération (OA)"
-#: models_finds.py:1544
+#: models_finds.py:1738
+msgid "No reference container have been set - the localisation cannot be set."
+msgstr ""
+"Aucun contenant de référence n'a été défini - la localisation ne peut être "
+"paramétrée."
+
+#: models_finds.py:1742
msgid "No container have been set - the localisation cannot be set."
msgstr ""
"Aucun contenant n'a été défini - la localisation ne peut être définie."
-#: models_finds.py:1550
+#: models_finds.py:1748
msgid "The division number {} have not been set for the warehouse {}."
msgstr ""
"La division numéro {} n'a pas été définie pour le lieu de conservation {}."
-#: models_finds.py:1720
+#: models_finds.py:1962
msgid "Person"
msgstr "Individu"
-#: models_finds.py:1726
+#: models_finds.py:1968
msgid "Property"
msgstr "Propriété"
-#: models_finds.py:1727
+#: models_finds.py:1969
msgid "Properties"
msgstr "Propriétés"
-#: models_treatments.py:42
+#: models_treatments.py:44
+msgid "Treatment is executed"
+msgstr "Le traitement est réalisé"
+
+#: models_treatments.py:48
msgid "Treatment state type"
msgstr "Type d'état de traitement"
-#: models_treatments.py:43
+#: models_treatments.py:49
msgid "Treatment state types"
msgstr "Types d'état de traitement"
-#: models_treatments.py:67
+#: models_treatments.py:80
msgid "Downstream find"
msgstr "Mobilier aval"
-#: models_treatments.py:79
+#: models_treatments.py:81
+msgid "Upstream find"
+msgstr "Mobilier amont"
+
+#: models_treatments.py:94
msgctxt "key for text search"
msgid "label"
msgstr "libelle"
-#: models_treatments.py:83
+#: models_treatments.py:98
msgctxt "key for text search"
msgid "other-reference"
msgstr "autre-reference"
-#: models_treatments.py:91 models_treatments.py:555
+#: models_treatments.py:106 models_treatments.py:793
msgctxt "key for text search"
msgid "index"
msgstr "index"
-#: models_treatments.py:99 models_treatments.py:559
+#: models_treatments.py:114 models_treatments.py:797
msgctxt "key for text search"
msgid "type"
msgstr "type"
-#: models_treatments.py:135
+#: models_treatments.py:149
+msgid "Treatment have been executed"
+msgstr "Le traitement a été réalisé"
+
+#: models_treatments.py:153
msgid "Location where the treatment is done. Target warehouse for a move."
msgstr ""
"Endroit où le traitement est réalisé. Renseignez le lieu de conservation de "
"destination pour un déplacement."
-#: models_treatments.py:152
+#: models_treatments.py:171
msgid "Estimated cost"
msgstr "Coût estimé"
-#: models_treatments.py:154
+#: models_treatments.py:173
msgid "Quoted cost"
msgstr "Coût devisé"
-#: models_treatments.py:156
+#: models_treatments.py:175
msgid "Realized cost"
msgstr "Coût réalisé"
-#: models_treatments.py:158
+#: models_treatments.py:177
msgid "Insurance cost"
msgstr "Coût d'assurance"
-#: models_treatments.py:160
-msgid "Target a basket"
-msgstr "Appliquer à un panier"
-
-#: models_treatments.py:171 templates/ishtar/sheet_find.html:171
-#: templates/ishtar/sheet_treatmentfile.html:61
-msgid "Treatments"
-msgstr "Traitements"
-
-#: models_treatments.py:190
+#: models_treatments.py:208
msgid "TREATMENT"
msgstr "TRAITEMENT"
-#: models_treatments.py:249 templates/ishtar/sheet_treatment.html:61
+#: models_treatments.py:271 templates/ishtar/sheet_treatment.html:107
msgid "Downstream finds"
msgstr "Mobilier aval"
-#: models_treatments.py:364 templates/ishtar/sheet_find.html:183
-#: templates/ishtar/sheet_find.html:221
+#: models_treatments.py:289 models_treatments.py:911
+msgid "Add associated administrative act"
+msgstr "Ajouter un acte administratif associé"
+
+#: models_treatments.py:290 models_treatments.py:912
+msgid "admin. act"
+msgstr "acte admin."
+
+#: models_treatments.py:600 templates/ishtar/sheet_find.html:263
+#: templates/ishtar/sheet_find.html:300 templates/ishtar/sheet_find.html:338
msgid "Doer"
msgstr "Opérateur"
-#: models_treatments.py:365 models_treatments.py:366
+#: models_treatments.py:601 models_treatments.py:602
+#: templates/ishtar/sheet_treatment.html:97
msgid "Related finds"
msgstr "Mobilier associé"
-#: models_treatments.py:508
+#: models_treatments.py:744
msgid "Is upstream"
msgstr "Est en amont"
-#: models_treatments.py:520
+#: models_treatments.py:758
msgid "Treatment request types"
msgstr "Types de demande de traitement"
-#: models_treatments.py:543
+#: models_treatments.py:781
msgctxt "key for text search"
msgid "name"
msgstr "nom"
-#: models_treatments.py:547
+#: models_treatments.py:785
msgctxt "key for text search"
msgid "reference"
msgstr "reference"
-#: models_treatments.py:563
+#: models_treatments.py:801
msgctxt "key for text search"
msgid "in-charge"
msgstr "responsable"
-#: models_treatments.py:567
+#: models_treatments.py:805
msgctxt "key for text search"
msgid "applicant"
msgstr "demandeur"
-#: models_treatments.py:571
+#: models_treatments.py:809
msgctxt "key for text search"
msgid "applicant-organisation"
msgstr "demandeur-organisation"
-#: models_treatments.py:584
+#: models_treatments.py:822
msgid "Internal reference"
msgstr "Référence interne"
-#: models_treatments.py:593
+#: models_treatments.py:831
msgid "Person in charge"
msgstr "Personne responsable"
-#: models_treatments.py:619
+#: models_treatments.py:861
msgid "Treatment requests"
msgstr "Demandes de traitement"
+#: models_treatments.py:924
+msgid "Add associated treatment"
+msgstr "Ajouter un traitement associé"
+
+#: templates/ishtar/blocks/window_find_nav.html:9
+msgid "Baskets"
+msgstr "Paniers"
+
#: templates/ishtar/forms/qa_find_basket.html:22
msgid "New"
msgstr "Nouveau"
@@ -1524,49 +1766,56 @@ msgstr "Nouveau"
msgid "Add"
msgstr "Ajout"
-#: templates/ishtar/forms/qa_find_treatment.html:31
+#: templates/ishtar/forms/qa_find_treatment.html:37
msgid "Associate a treatment"
msgstr "Associer un traitement"
-#: templates/ishtar/sheet_basefind.html:6
+#: templates/ishtar/forms/qa_findbasket_duplicate.html:6
+msgid ""
+"Items of the basket will be attached to the new basket but not the shares."
+msgstr ""
+"Les éléments du panier vont être rattachés au nouveau panier mais pas les "
+"partages."
+
+#: templates/ishtar/sheet_basefind.html:10
msgid "Internal ID"
msgstr "ID interne"
-#: templates/ishtar/sheet_basefind.html:21
+#: templates/ishtar/sheet_basefind.html:25
msgid "Discovery date"
msgstr "Date de découverte"
-#: templates/ishtar/sheet_basefind.html:24
+#: templates/ishtar/sheet_basefind.html:28
msgid "Discovery year"
msgstr "Date de découverte"
-#: templates/ishtar/sheet_basefind.html:27
+#: templates/ishtar/sheet_basefind.html:31
msgid "Discovery date (TPQ)"
msgstr "Date de découverte (TPQ)"
-#: templates/ishtar/sheet_basefind.html:52
+#: templates/ishtar/sheet_basefind.html:56
msgid "X:"
msgstr "X :"
-#: templates/ishtar/sheet_basefind.html:53
-#: templates/ishtar/sheet_basefind.html:55
#: templates/ishtar/sheet_basefind.html:57
+#: templates/ishtar/sheet_basefind.html:59
+#: templates/ishtar/sheet_basefind.html:61
msgid "error:"
msgstr "erreur :"
-#: templates/ishtar/sheet_basefind.html:54
+#: templates/ishtar/sheet_basefind.html:58
msgid "Y:"
msgstr "Y :"
-#: templates/ishtar/sheet_basefind.html:56
+#: templates/ishtar/sheet_basefind.html:60
msgid "Z:"
msgstr "Z :"
-#: templates/ishtar/sheet_basefind.html:60
+#: templates/ishtar/sheet_basefind.html:64
msgid "SRID"
msgstr "SRID"
-#: templates/ishtar/sheet_basefind.html:75
+#: templates/ishtar/sheet_basefind.html:79
msgid "Last modified by"
msgstr "Modifié en dernier par"
@@ -1578,65 +1827,86 @@ msgstr ""
"Cette fiche a un traitement aval associé, elle concerne une vieille version "
"de ce mobilier."
-#: templates/ishtar/sheet_find.html:29
-msgid "Associated base finds"
-msgstr "Mobilier d'origine associé"
+#: templates/ishtar/sheet_find.html:23
+msgid "Image / Base find"
+msgstr "Image / Mobilier d'origine"
-#: templates/ishtar/sheet_find.html:53
+#: templates/ishtar/sheet_find.html:30
+msgid "Identification / Description / Dimensions"
+msgstr "Identification / Description / Dimensions"
+
+#: templates/ishtar/sheet_find.html:38
+#, fuzzy
+msgid "Datings / Preservation"
+msgstr "Datations / Conservation"
+
+#: templates/ishtar/sheet_find.html:47
+msgid "Warehouse / Treatments"
+msgstr "Lieu de conservation / Traitements"
+
+#: templates/ishtar/sheet_find.html:64
+msgid "Custom fields"
+msgstr "Champs personnalisés"
+
+#: templates/ishtar/sheet_find.html:123
msgid "Administrative index"
msgstr "Index administratif"
-#: templates/ishtar/sheet_find.html:95
+#: templates/ishtar/sheet_find.html:166
msgid "Checked"
msgstr "Vérifié"
-#: templates/ishtar/sheet_find.html:160
-msgid "Warehouse"
-msgstr "Lieu de conservation"
+#: templates/ishtar/sheet_find.html:233
+msgid "Warehouse - reference container"
+msgstr "Lieu de conservation - Contenant de référence"
+
+#: templates/ishtar/sheet_find.html:243
+msgid "Warehouse - current container"
+msgstr "Lieu de conservation - Contenant actuel"
-#: templates/ishtar/sheet_find.html:178 templates/ishtar/sheet_find.html:216
+#: templates/ishtar/sheet_find.html:258 templates/ishtar/sheet_find.html:295
+#: templates/ishtar/sheet_find.html:333
msgid "Year - index"
msgstr "Année - index"
-#: templates/ishtar/sheet_find.html:182 templates/ishtar/sheet_find.html:220
+#: templates/ishtar/sheet_find.html:262 templates/ishtar/sheet_find.html:299
+#: templates/ishtar/sheet_find.html:337
msgid "Related finds (max. 15 displayed)"
msgstr "Mobilier associé (max. 15 affichés)"
-#: templates/ishtar/sheet_find.html:208
+#: templates/ishtar/sheet_find.html:325
msgid "Export as CSV"
msgstr "Export en CSV"
-#: templates/ishtar/sheet_find.html:208 templates/ishtar/sheet_find.html:247
+#: templates/ishtar/sheet_find.html:325 templates/ishtar/sheet_find.html:364
msgid "CSV"
msgstr "CSV"
-#: templates/ishtar/sheet_find.html:252
+#: templates/ishtar/sheet_find.html:371
+#: templates/ishtar/sheet_treatment.html:124
msgid "Associated documents"
msgstr "Documents associés"
-#: templates/ishtar/sheet_findbasket.html:19
+#: templates/ishtar/sheet_findbasket.html:20
msgid "Content"
msgstr "Contenu"
-#: templates/ishtar/sheet_treatment.html:25
+#: templates/ishtar/sheet_treatment.html:41
+#: templates/ishtar/sheet_treatment.html:132
+#: templates/ishtar/sheet_treatmentfile.html:74
+msgid "Administrative acts"
+msgstr "Actes administratifs"
+
+#: templates/ishtar/sheet_treatment.html:63
msgctxt "Treatment"
msgid "Closed"
msgstr "Close"
-#: templates/ishtar/sheet_treatment.html:27
+#: templates/ishtar/sheet_treatment.html:65
msgctxt "Treatment"
msgid "Active"
msgstr "Actif"
-#: templates/ishtar/sheet_treatment.html:66
-msgid "Related operations"
-msgstr "Opérations associées"
-
-#: templates/ishtar/sheet_treatment.html:77
-#: templates/ishtar/sheet_treatmentfile.html:73
-msgid "Administrative acts"
-msgstr "Actes administratifs"
-
#: templates/ishtar/sheet_treatmentfile.html:24
msgctxt "Treatment request"
msgid "Closed"
@@ -1647,86 +1917,142 @@ msgctxt "Treatment request"
msgid "Active"
msgstr "Active"
-#: views.py:132
+#: templates/ishtar/wizard/wizard_findbasket_deletion.html:8
+msgid "This basket is attached to treatments requests:"
+msgstr "Ce panier est attaché à des demandes de traitements :"
+
+#: templates/ishtar/wizard/wizard_findbasket_deletion.html:12
+msgid "Are you sure you want to delete this basket?"
+msgstr "Êtes vous sûr de vouloir supprimer ce panier ?"
+
+#: templates/ishtar/wizard/wizard_findbasket_deletion.html:16
+msgid "Items inside the basket (these items will not be deleted):"
+msgstr ""
+"Éléments à l'intérieur du panier (ces éléments ne seront pas effacés) :"
+
+#: templates/ishtar/wizard/wizard_findbasket_deletion.html:23
+msgid "Basket informations:"
+msgstr "Informations sur le panier :"
+
+#: templates/ishtar/wizard/wizard_simplefind.html:6
+msgid ""
+"This find is related to many base finds. To edit field related to base finds "
+"edit the corresponding find between theses:"
+msgstr ""
+"Ce mobilier est associé à plusieurs mobiliers d'origine. Pour modifier les "
+"champs associés aux mobiliers d'origines, modifiez le mobilier correspondant "
+"parmi ceux-ci :"
+
+#: templates/ishtar/wizard/wizard_treatement_deletion.html:8
+msgid "Are you sure you want to delete this treatment?"
+msgstr "Êtes-vous sûr de vouloir supprimer ce traitement ? "
+
+#: templates/ishtar/wizard/wizard_treatement_deletion.html:10
+msgid ""
+"The following finds will be deleted and restored to a previous version."
+msgstr ""
+"Le mobilier suivant sera supprimé et restauré à une version précédente."
+
+#: templates/ishtar/wizard/wizard_treatement_deletion.html:16
+msgid ""
+"All changes made to the associated finds since this treatment record will be "
+"lost!"
+msgstr ""
+"Toutes les modifications sur le mobilier associé réalisées depuis "
+"l'enregistrement de ce traitement seront perdues !"
+
+#: templates/ishtar/wizard/wizard_treatement_deletion.html:21
+msgid "Treatment informations:"
+msgstr "Informations sur le traitement :"
+
+#: views.py:175
msgid "Basket modify"
msgstr "Modification de panier"
-#: views.py:173
+#: views.py:198
+msgid "Basket deletion"
+msgstr "Suppression du panier"
+
+#: views.py:229
msgid "New find"
msgstr "Ajouter un mobilier"
-#: views.py:209
+#: views.py:281
msgid "Find modification"
msgstr "Modifier un mobilier"
-#: views.py:238
+#: views.py:316
msgid "Find deletion"
msgstr "Supprimer un mobilier"
-#: views.py:251
+#: views.py:329
msgid "New basket"
msgstr "Ajouter un panier"
-#: views.py:280
+#: views.py:358
msgid "Manage items in basket"
msgstr "Gérer les éléments dans un panier"
-#: views.py:389
-msgid "Delete basket"
-msgstr "Supprimer un panier"
-
-#: views.py:441
+#: views.py:484 views.py:497 views.py:510
msgid "New treatment"
msgstr "Ajouter un traitement"
-#: views.py:449
+#: views.py:518
msgid "Treatment modification"
msgstr "Modifier un traitement"
-#: views.py:466
+#: views.py:609
msgid "Treatment deletion"
msgstr "Supprimer un traitement"
-#: views.py:473
+#: views.py:616
msgid "Treatment: search administrative act"
msgstr "Traitement : rechercher un acte administratif"
-#: views.py:482
+#: views.py:625
msgid "Treatment: new administrative act"
msgstr "Traitement : ajouter un acte administratif"
-#: views.py:492
+#: views.py:635
msgid "Treatment: administrative act modification"
msgstr "Traitement : modifier un acte administratif"
-#: views.py:501
+#: views.py:644
msgid "Treatment: administrative act deletion"
msgstr "Traitement : supprimer un acte administratif"
-#: views.py:534
+#: views.py:691
msgid "New treatment request"
msgstr "Ajouter une demande de traitement"
-#: views.py:541
+#: views.py:700
msgid "Treatment request modification"
msgstr "Modifier une demande de traitement"
-#: views.py:557
+#: views.py:716
msgid "Treatment request deletion"
msgstr "Supprimer une demande de traitement"
-#: views.py:564
+#: views.py:723
msgid "Treatment request: search administrative act"
msgstr "Demande de traitement : rechercher un acte administratif"
-#: views.py:574
+#: views.py:734
msgid "Treatment request: new administrative act"
msgstr "Demande de traitement : ajouter un acte administratif"
-#: views.py:584
+#: views.py:744
msgid "Treatment request: administrative act modification"
msgstr "Demande de traitement : modifier un acte administratif"
-#: views.py:593
+#: views.py:753
msgid "Treatment request: administrative act deletion"
msgstr "Demande de traitement : supprimer un acte administratif"
+
+#: wizards.py:394
+msgid ""
+"The new basket: \"{}\" have been created with the resulting items. This "
+"search have been pinned."
+msgstr ""
+"Le nouveau panier « {} » a été créé avec les éléments résultants. Cette "
+"recherche a été épinglée."
diff --git a/translations/fr/archaeological_operations.po b/translations/fr/archaeological_operations.po
index 5d4bd0631..266eede4d 100644
--- a/translations/fr/archaeological_operations.po
+++ b/translations/fr/archaeological_operations.po
@@ -11,28 +11,28 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Transfer-Encoding: 8bit\n"
"Content-Type: text/plain; charset=UTF-8\n"
-"PO-Revision-Date: 2018-11-12 09:43+0000\n"
+"PO-Revision-Date: 2018-12-11 06:13+0000\n"
"Last-Translator: Étienne Loks <etienne.loks@iggdrasil.net>\n"
"Language-Team: \n"
"Language: fr\n"
"Plural-Forms: nplurals=2; plural=n>1;\n"
"X-Generator: Zanata 4.6.2\n"
-#: admin.py:91 models.py:244 models.py:836
+#: admin.py:91 models.py:263 models.py:880
msgid "Point"
msgstr "Point"
-#: admin.py:93 models.py:245 models.py:837
+#: admin.py:93 models.py:264 models.py:881
msgid "Multi polygon"
msgstr "Polygones multi-parties"
-#: forms.py:64 forms.py:1061 forms.py:1077 forms.py:1083 models.py:1931
+#: forms.py:64 forms.py:1068 forms.py:1084 forms.py:1090 models.py:2014
#: templates/ishtar/blocks/window_tables/parcels.html:9
-#: templates/ishtar/sheet_operation.html:250
+#: templates/ishtar/sheet_operation.html:257
msgid "Parcels"
msgstr "Parcelles"
-#: forms.py:67 forms.py:200 forms.py:1036 models.py:1915
+#: forms.py:67 forms.py:200 forms.py:1043 models.py:1998
#: templates/ishtar/blocks/window_tables/parcels.html:6
#: templates/ishtar/dashboards/dashboard_operation.html:432
#: templates/ishtar/dashboards/dashboard_operation.html:446
@@ -41,22 +41,22 @@ msgstr "Parcelles"
msgid "Town"
msgstr "Commune"
-#: forms.py:69 forms.py:480 forms.py:763 forms.py:1400 models.py:734
-#: models.py:1489 models.py:1696 models.py:1913
+#: forms.py:69 forms.py:480 forms.py:768 forms.py:1426 models.py:774
+#: models.py:1562 models.py:1769 models.py:1996
#: templates/ishtar/blocks/window_tables/parcels.html:7
msgid "Year"
msgstr "Année"
-#: forms.py:72 models.py:1916
+#: forms.py:72 models.py:1999
#: templates/ishtar/blocks/window_tables/parcels.html:8
msgid "Section"
msgstr "Section"
-#: forms.py:75 models.py:1918
+#: forms.py:75 models.py:2001
msgid "Parcel number"
msgstr "Numéro de parcelle"
-#: forms.py:77 models.py:1920 models.py:1939 models.py:2000
+#: forms.py:77 models.py:2003 models.py:2022 models.py:2083
msgid "Public domain"
msgstr "Domaine public"
@@ -92,8 +92,8 @@ msgstr "Il y a des parcelles identiques."
msgid "Relation type"
msgstr "Type de relation"
-#: forms.py:373 forms.py:1254 ishtar_menu.py:32 models.py:842 models.py:1394
-#: models.py:1405 models.py:1491 models.py:1678 models.py:1912
+#: forms.py:373 forms.py:1261 ishtar_menu.py:32 models.py:886 models.py:1466
+#: models.py:1477 models.py:1564 models.py:1751 models.py:1995
#: templates/ishtar/sheet_operation.html:4 wizards.py:320 wizards.py:331
msgid "Operation"
msgstr "Opération (OA)"
@@ -102,7 +102,7 @@ msgstr "Opération (OA)"
msgid ":"
msgstr ": "
-#: forms.py:404 forms.py:608
+#: forms.py:404 forms.py:612
msgid "You should select an operation."
msgstr "Vous devez sélectionner une opération."
@@ -122,7 +122,7 @@ msgstr "Relations actuelles"
msgid "Deleted relations"
msgstr "Relations supprimées"
-#: forms.py:469 templates/ishtar/sheet_operation.html:169
+#: forms.py:469 templates/ishtar/sheet_operation.html:170
msgid "Relations"
msgstr "Relations"
@@ -130,19 +130,23 @@ msgstr "Relations"
msgid "Operation - 080 - Relations"
msgstr "Opération - 080 - Relations"
-#: forms.py:478 forms.py:1237 forms.py:1396
+#: forms.py:478 forms.py:1244 forms.py:1422
msgid "Full text search"
msgstr "Recherche en texte intégral"
-#: forms.py:481 models.py:735
+#: forms.py:481 models.py:775
msgid "Numeric reference"
msgstr "Identifiant numérique"
-#: forms.py:488 forms.py:1064 forms.py:1412 models.py:1930 models.py:2142
+#: forms.py:487 forms.py:761 models.py:870
+msgid "DRASSM code"
+msgstr "Code DRASSM"
+
+#: forms.py:489 forms.py:1071 forms.py:1438 models.py:2013 models.py:2225
msgid "Parcel"
msgstr "Parcelle"
-#: forms.py:491 forms.py:1415 models.py:1395
+#: forms.py:492 forms.py:1441 models.py:1467
#: templates/ishtar/dashboards/dashboard_operation.html:390
#: templates/ishtar/dashboards/dashboard_operation.html:411
#: templates/ishtar/dashboards/dashboard_operation.html:643
@@ -151,273 +155,273 @@ msgstr "Parcelle"
msgid "Department"
msgstr "Département"
-#: forms.py:492 forms.py:1148 forms.py:1241 forms.py:1325 models.py:213
+#: forms.py:493 forms.py:1155 forms.py:1248 forms.py:1340 models.py:224
#: templates/ishtar/blocks/window_tables/archaeologicalsites.html:7
#: templates/ishtar/sheet_operation.html:29
msgid "Name"
msgstr "Nom"
-#: forms.py:493 forms.py:761 models.py:797
+#: forms.py:494 forms.py:766 models.py:838
msgid "Address / Locality"
msgstr "Adresse / Lieu-dit"
-#: forms.py:494 forms.py:678 forms.py:757 models.py:742
+#: forms.py:495 forms.py:682 forms.py:762 models.py:782
msgid "Operation type"
msgstr "Type d'opération"
-#: forms.py:495
+#: forms.py:496
msgid "Is open?"
msgstr "Est ouvert ?"
-#: forms.py:503 forms.py:793 models.py:727
+#: forms.py:504 forms.py:798 models.py:767
msgid "In charge"
msgstr "Responsable du suivi scientifique"
-#: forms.py:510 models.py:1672
+#: forms.py:511 models.py:1745
msgid "Scientist in charge"
msgstr "Responsable scientifique"
-#: forms.py:512 forms.py:680 forms.py:783 models.py:725
+#: forms.py:513 forms.py:684 forms.py:788 models.py:765
msgid "Operator"
msgstr "Opérateur"
-#: forms.py:521 forms.py:1153 forms.py:1243 forms.py:1330 models.py:217
-#: models.py:744
+#: forms.py:522 forms.py:1160 forms.py:1250 forms.py:1345 models.py:228
+#: models.py:784
#: templates/ishtar/blocks/window_tables/archaeologicalsites.html:9
msgid "Remains"
msgstr "Vestiges"
-#: forms.py:522 forms.py:1131 forms.py:1150 forms.py:1242 forms.py:1327
-#: models.py:215 models.py:750
+#: forms.py:523 forms.py:1138 forms.py:1157 forms.py:1249 forms.py:1342
+#: models.py:226 models.py:790
#: templates/ishtar/blocks/window_tables/archaeologicalsites.html:8
msgid "Periods"
msgstr "Périodes"
-#: forms.py:523
+#: forms.py:524
msgid "Started before"
msgstr "Commencé avant"
-#: forms.py:524
+#: forms.py:525
msgid "Started after"
msgstr "Commencé après"
-#: forms.py:525
+#: forms.py:526
msgid "Ended before"
msgstr "Terminé avant"
-#: forms.py:526
+#: forms.py:527
msgid "Ended after"
msgstr "Terminé après"
-#: forms.py:528
+#: forms.py:529
msgid "Search within relations"
msgstr "Rechercher parmi les relations"
-#: forms.py:529 forms.py:841 forms.py:1245 forms.py:1340 models.py:221
-#: models.py:798
+#: forms.py:530 forms.py:846 forms.py:1252 forms.py:1357 models.py:232
+#: models.py:839
msgid "Comment"
msgstr "Commentaire"
-#: forms.py:530
+#: forms.py:531
msgid "Abstract (full text search)"
msgstr "Résumé (recherche en texte intégral)"
-#: forms.py:532 forms.py:844 models.py:800
+#: forms.py:533 forms.py:849 models.py:841
msgid "Comment about scientific documentation"
msgstr "Commentaire relatif à la documentation scientifique"
-#: forms.py:533 forms.py:846 models.py:815
+#: forms.py:534 forms.py:851 models.py:856
msgid "Record quality"
msgstr "Qualité d'enregistrement"
-#: forms.py:534 forms.py:812 models.py:762
+#: forms.py:535 forms.py:817 models.py:802
msgid "Report processing"
msgstr "Traitement du rapport"
-#: forms.py:536 forms.py:849 models.py:810
+#: forms.py:537 forms.py:854 models.py:851
msgid "Virtual operation"
msgstr "Opération virtuelle"
-#: forms.py:538 forms.py:1188 forms.py:1192 models.py:257
+#: forms.py:539 forms.py:1195 forms.py:1199 models.py:276
msgid "Archaeological site"
msgstr "Entité (EA)"
-#: forms.py:544 forms.py:1419
+#: forms.py:545 forms.py:1445
msgid "Created by"
msgstr "Créé par"
-#: forms.py:550 forms.py:1425
+#: forms.py:551 forms.py:1451
msgid "Modified by"
msgstr "Modifié par"
-#: forms.py:557 forms.py:834 models.py:822
+#: forms.py:558 forms.py:839 models.py:863
msgid "Documentation received"
msgstr "Documentation reçue"
-#: forms.py:559
+#: forms.py:560
msgid "Documentation deadline before"
msgstr "Date limite de versement de la documentation avant"
-#: forms.py:561
+#: forms.py:562
msgid "Documentation deadline after"
msgstr "Date limite de versement de la documentation après"
-#: forms.py:563 forms.py:839 models.py:826
+#: forms.py:564 forms.py:844 models.py:867
msgid "Finds received"
msgstr "Mobilier reçu"
-#: forms.py:565
+#: forms.py:566
msgid "Finds deadline before"
msgstr "Date limite de versement du mobilier avant"
-#: forms.py:567
+#: forms.py:568
msgid "Finds deadline after"
msgstr "Date limite de versement du mobilier après"
-#: forms.py:595 views.py:182
+#: forms.py:599 views.py:183
msgid "Operation search"
msgstr "Rechercher une opération"
-#: forms.py:639
+#: forms.py:643
msgid "Associated file"
msgstr "Dossier associé"
-#: forms.py:643 forms.py:937 models.py:1023 models.py:1404 models.py:1490
-#: models.py:1683 wizards.py:83
+#: forms.py:647 forms.py:944 models.py:1083 models.py:1476 models.py:1563
+#: models.py:1756 wizards.py:83
msgid "Archaeological file"
msgstr "Dossier archéologique"
-#: forms.py:650 forms.py:654 models.py:817
+#: forms.py:654 forms.py:658 models.py:858
msgid "Abstract"
msgstr "Résumé"
-#: forms.py:651
+#: forms.py:655
msgid "Operation - 090 - Abstract"
msgstr "Opération - 090 - Résumé"
-#: forms.py:658
+#: forms.py:662
msgid "months"
msgstr "mois"
-#: forms.py:658
+#: forms.py:662
msgid "years"
msgstr "années"
-#: forms.py:660 models.py:711
+#: forms.py:664 models.py:751
msgid "Creation date"
msgstr "Date de création"
-#: forms.py:661
+#: forms.py:665
msgid "Start of field work"
msgstr "Début du travail de terrain"
-#: forms.py:663
+#: forms.py:667
msgid "All"
msgstr "Tout"
-#: forms.py:664
+#: forms.py:668
msgid "Preventive"
msgstr "Préventif"
-#: forms.py:665
+#: forms.py:669
msgid "Research"
msgstr "Programmé"
-#: forms.py:669
+#: forms.py:673
msgid "Slicing"
msgstr "Découpage"
-#: forms.py:672
+#: forms.py:676
msgid "Department detail"
msgstr "Détail par département"
-#: forms.py:674
+#: forms.py:678
msgid "Date get from"
msgstr "Date obtenue depuis"
-#: forms.py:676
+#: forms.py:680
msgid "Preventive/Research"
msgstr "Préventif/Programmé"
-#: forms.py:682
+#: forms.py:686
msgid "Date after"
msgstr "Date après"
-#: forms.py:683
+#: forms.py:687
msgid "Date before"
msgstr "Date avant"
-#: forms.py:684
+#: forms.py:688
msgid "With reports"
msgstr "Avec un rapport"
-#: forms.py:685
+#: forms.py:689
msgid "With finds"
msgstr "Avec du mobilier"
-#: forms.py:737 forms.py:1317 forms.py:1466
+#: forms.py:741 forms.py:1331 forms.py:1492
#: templates/ishtar/sheet_administrativeact.html:23
#: templates/ishtar/sheet_operation.html:12 templates/ishtar/sheet_site.html:33
msgid "General"
msgstr "Général"
-#: forms.py:738
+#: forms.py:742
msgid "Operation - 010 - General"
msgstr "Opération - 010 - Général"
-#: forms.py:759 models.py:796
+#: forms.py:764 models.py:837
msgid "Generic name"
msgstr "Nom générique"
-#: forms.py:768 models.py:764
+#: forms.py:773 models.py:804
msgid "Old code"
msgstr "Ancien code"
-#: forms.py:771
+#: forms.py:776
msgid "Head scientist"
msgstr "Responsable scientifique"
-#: forms.py:790 models.py:795
+#: forms.py:795 models.py:836
msgid "Operator reference"
msgstr "Référence de l'opérateur"
-#: forms.py:804
+#: forms.py:809
msgid "Total surface (m2)"
msgstr "Surface totale (m2)"
-#: forms.py:807 models.py:57 models.py:714 models.py:2144
+#: forms.py:812 models.py:57 models.py:754 models.py:2227
msgid "Start date"
msgstr "Date de début"
-#: forms.py:808 models.py:716
+#: forms.py:813 models.py:756
msgid "Excavation end date"
msgstr "Date de fin de chantier"
-#: forms.py:810 models.py:717
+#: forms.py:815 models.py:757
msgid "Report delivery date"
msgstr "Date de livraison du rapport"
-#: forms.py:831 models.py:819
+#: forms.py:836 models.py:860
msgid "Deadline for submission of the documentation"
msgstr "Date limite de versement de la documentation"
-#: forms.py:836 models.py:824
+#: forms.py:841 models.py:865
msgid "Deadline for submission of the finds"
msgstr "Date limite de versement du mobilier"
-#: forms.py:888
+#: forms.py:895
msgid ""
"If you want to set an excavation end date you have to provide a start date."
msgstr ""
"Avant de renseigner la date de fin de chantier, il est nécessaire de "
"renseigner une date de début."
-#: forms.py:893
+#: forms.py:900
msgid "The excavation end date cannot be before the start date."
msgstr ""
"La date de fin de chantier ne peut être antérieure à la date de début."
-#: forms.py:923
+#: forms.py:930
#, python-format
msgid ""
"Operation code already exists for year: %(year)d - use a value bigger than "
@@ -426,248 +430,256 @@ msgstr ""
"Ce code d'opération existe déjà pour l'année %(year)d - utilisez une valeur "
"plus grande que %(last_val)d"
-#: forms.py:927
+#: forms.py:934
msgid "Bad operation code"
msgstr "Mauvais code d'opération"
-#: forms.py:933 models.py:1038
+#: forms.py:940 models.py:1098
msgid "Operation code"
msgstr "Code de l'opération"
-#: forms.py:968 templates/ishtar/sheet_operation.html:149
+#: forms.py:975 templates/ishtar/sheet_operation.html:150
msgid "Court-ordered seizure"
msgstr "Saisie judiciaire"
-#: forms.py:969
+#: forms.py:976
msgid "Operation - 015 - Court-ordered seizure"
msgstr "Opération - 015 - Saisie judiciaire"
-#: forms.py:973 models.py:829
+#: forms.py:980 models.py:873
msgid "Seizure name"
msgstr "Nom de la saisie"
-#: forms.py:976 models.py:830
+#: forms.py:983 models.py:874
msgid "Official report number"
msgstr "Numéro de procès-verbal"
-#: forms.py:979 models.py:832
+#: forms.py:986 models.py:876
msgid "Name of the protagonist"
msgstr "Nom du protagoniste"
-#: forms.py:984 forms.py:991 models.py:731
+#: forms.py:991 forms.py:998 forms.py:1356 models.py:243 models.py:771
msgid "Collaborators"
msgstr "Collaborateurs"
-#: forms.py:985
+#: forms.py:992
msgid "Operation - 020 - Collaborators"
msgstr "Opération - 020 - Collaborateurs"
-#: forms.py:1000
+#: forms.py:1007
msgid "Preventive informations - excavation"
msgstr "Information archéologie préventive - fouille"
-#: forms.py:1001
+#: forms.py:1008
msgid "Operation - 033 - Preventive - Excavation"
msgstr "Opération - 033 - Préventif - Fouille"
-#: forms.py:1004 models.py:748
+#: forms.py:1011 models.py:788
#: templates/ishtar/dashboards/dashboard_operation.html:701
msgid "Cost (euros)"
msgstr "Coût (euros)"
-#: forms.py:1005 models.py:753
+#: forms.py:1012 models.py:793
msgid "Scheduled man-days"
msgstr "Jours-hommes prévus"
-#: forms.py:1007 models.py:756
+#: forms.py:1014 models.py:796
msgid "Optional man-days"
msgstr "Jours-hommes optionnels"
-#: forms.py:1009 models.py:759
+#: forms.py:1016 models.py:799
msgid "Effective man-days"
msgstr "Jours-hommes effectifs"
-#: forms.py:1019
+#: forms.py:1026
msgid "Preventive informations - diagnostic"
msgstr "Information archéologie préventive - diagnostic"
-#: forms.py:1020
+#: forms.py:1027
msgid "Operation - 037 - Preventive - Diagnostic"
msgstr "Opération - 037 - Préventif - Diagnostic"
-#: forms.py:1025 models.py:779
+#: forms.py:1032 models.py:819
msgid "Prescription on zoning"
msgstr "Prescription sur zonage"
-#: forms.py:1027 models.py:782
+#: forms.py:1034 models.py:822
msgid "Prescription on large area"
msgstr "Prescription sur une vaste surface"
-#: forms.py:1030 models.py:784
+#: forms.py:1037 models.py:824
msgid "Prescription on geoarchaeological context"
msgstr "Prescription sur un contexte géoarchéologique"
-#: forms.py:1034 forms.py:1050 forms.py:1055 forms.py:1359 models.py:128
-#: models.py:219 models.py:506 models.py:746 models.py:1706
+#: forms.py:1041 forms.py:1057 forms.py:1062 forms.py:1381 models.py:131
+#: models.py:230 models.py:541 models.py:786 models.py:1779
msgid "Towns"
msgstr "Communes"
-#: forms.py:1051
+#: forms.py:1058
msgid "Operation - 040 - Towns"
msgstr "Opération - 040 - Communes"
-#: forms.py:1056
+#: forms.py:1063
msgid "Operation - 040 - Towns (2)"
msgstr "Opération - 040 - Communes (2)"
-#: forms.py:1078
+#: forms.py:1085
msgid "Operation - 050 - Parcels"
msgstr "Opération - 050 - Parcelles"
-#: forms.py:1085
+#: forms.py:1092
msgid "Operation - 050 - Parcels (2)"
msgstr "Opération - 050 - Parcelles (2)"
-#: forms.py:1115 models.py:47
+#: forms.py:1122 models.py:47
msgid "Remain types"
msgstr "Types de vestige"
-#: forms.py:1116
+#: forms.py:1123
msgid "Operation - 060 - Remains"
msgstr "Opération - 060 - Vestiges"
-#: forms.py:1122 models.py:46
+#: forms.py:1129 models.py:46
msgid "Remain type"
msgstr "Type de vestige"
-#: forms.py:1132
+#: forms.py:1139
msgid "Operation - 070 - Periods"
msgstr "Opération - 070 - Périodes"
-#: forms.py:1138 templates/ishtar/sheet_operation.html:273
-#: templates/ishtar/sheet_operation.html:310
+#: forms.py:1145 templates/ishtar/sheet_operation.html:280
+#: templates/ishtar/sheet_operation.html:317
msgid "Period"
msgstr "Période"
-#: forms.py:1147 forms.py:1239 forms.py:1324 models.py:212
+#: forms.py:1154 forms.py:1246 forms.py:1339 models.py:223
msgid "Reference"
msgstr "Référence"
-#: forms.py:1171 forms.py:1353
+#: forms.py:1178 forms.py:1375
msgid "This reference already exists."
msgstr "Cette référence existe déjà."
-#: forms.py:1203 models.py:258 models.py:807
-#: templates/ishtar/sheet_operation.html:194
+#: forms.py:1210 models.py:277 models.py:848
+#: templates/ishtar/sheet_operation.html:195
msgid "Archaeological sites"
msgstr "Entités archéologiques"
-#: forms.py:1205
+#: forms.py:1212
msgid "Operation - 030 - Archaeological sites"
msgstr "Opération - 030 - Sites archéologiques"
-#: forms.py:1210
+#: forms.py:1217
msgid "Associated archaeological sites"
msgstr "Entités archéologiques associées"
-#: forms.py:1216 ishtar_menu.py:36 ishtar_menu.py:66 ishtar_menu.py:113
+#: forms.py:1223 ishtar_menu.py:36 ishtar_menu.py:66 ishtar_menu.py:108
msgid "Search"
msgstr "Recherche"
-#: forms.py:1221
+#: forms.py:1228
msgid "Would you like to close this operation?"
msgstr "Voulez-vous clore cette opération ?"
-#: forms.py:1226
+#: forms.py:1233
msgid "Would you like to delete this operation?"
msgstr "Voulez-vous supprimer cette opération ?"
-#: forms.py:1248 models.py:223
+#: forms.py:1255 models.py:234
msgid "Top operation"
msgstr "Opération chapeau"
-#: forms.py:1260 forms.py:1333 models.py:226
+#: forms.py:1267 forms.py:1348 models.py:237
msgid "National Geographic Institute locality"
msgstr "Lieu-dit IGN"
-#: forms.py:1263 forms.py:1337 models.py:229
+#: forms.py:1270 forms.py:1352 models.py:240
msgid "Cadastral locality"
msgstr "Lieu-dit cadastre"
-#: forms.py:1266 forms.py:1374 models.py:233
+#: forms.py:1274 forms.py:1396 models.py:257
+msgid "AffMar number"
+msgstr "Numéro AffMar"
+
+#: forms.py:1276 forms.py:1398 models.py:259
+msgid "DRASSM number"
+msgstr "Numéro DRASSM"
+
+#: forms.py:1278 forms.py:1400 models.py:248
msgid "Shipwreck name"
msgstr "Nom de l'épave"
-#: forms.py:1269 forms.py:1382 models.py:235
+#: forms.py:1281 forms.py:1408 models.py:250
msgid "Oceanographic service localisation"
msgstr "Localisation SHOM"
-#: forms.py:1272 forms.py:1376 models.py:237
+#: forms.py:1284 forms.py:1402 models.py:252
msgid "Shipwreck code"
msgstr "Code épave"
-#: forms.py:1274 forms.py:1378 models.py:239
+#: forms.py:1286 forms.py:1404 models.py:254
msgid "Sinking date"
msgstr "Date de naufrage"
-#: forms.py:1276 forms.py:1380 models.py:241
+#: forms.py:1288 forms.py:1406 models.py:256
msgid "Discovery area"
msgstr "Zone de découverte"
-#: forms.py:1312
+#: forms.py:1326
msgid "You should select an item."
msgstr "Vous devez sélectionner un élément."
-#: forms.py:1318
+#: forms.py:1332
msgid "Archaeological site - 010 - General"
msgstr "Site archéologique - 010 - Général"
-#: forms.py:1360
+#: forms.py:1382
msgid "Archaeological site - 020 - Towns"
msgstr "Site archéologique - 020 - Villes"
-#: forms.py:1369 templates/ishtar/sheet_site.html:52
+#: forms.py:1391 templates/ishtar/sheet_site.html:53
msgid "Underwater"
msgstr "Sous-marin / subaquatique"
-#: forms.py:1370
+#: forms.py:1392
msgid "Archaeological site - 030 - Underwater"
msgstr "Site archéologique - 030 - Sous-marin / subaquatique"
-#: forms.py:1401 forms.py:1535 models.py:1663
+#: forms.py:1427 forms.py:1561 models.py:1736
msgid "Index"
msgstr "Index"
-#: forms.py:1409 forms.py:1469 models.py:1418 models.py:1657
+#: forms.py:1435 forms.py:1495 models.py:1490 models.py:1730
msgid "Act type"
msgstr "Type d'acte"
-#: forms.py:1410 forms.py:1605
+#: forms.py:1436 forms.py:1631
msgid "Indexed?"
msgstr "Indexé ?"
-#: forms.py:1416 forms.py:1474 models.py:1697
+#: forms.py:1442 forms.py:1500 models.py:1770
#: templates/ishtar/blocks/window_tables/administrativacts.html:9
msgid "Object"
msgstr "Objet"
-#: forms.py:1446 views.py:412
+#: forms.py:1472 views.py:413
msgid "Administrative act search"
msgstr "Rechercher un acte administratif"
-#: forms.py:1461 forms.py:1563 forms.py:1630
+#: forms.py:1487 forms.py:1589 forms.py:1656
msgid "You should select an administrative act."
msgstr "Vous devez sélectionner un acte administratif."
-#: forms.py:1477 models.py:1694
+#: forms.py:1503 models.py:1767
msgid "Signature date"
msgstr "Date de signature"
-#: forms.py:1489
+#: forms.py:1515
msgid "Operation - Administrative act - General"
msgstr "Opération - Acte administratif - Général"
-#: forms.py:1523
+#: forms.py:1549
#, python-format
msgid ""
"This index already exists for year: %(year)d - use a value bigger than "
@@ -676,40 +688,40 @@ msgstr ""
"Cet index existe déjà pour l'année : %(year)d, utilisez une valeur plus "
"grande que %(last_val)d"
-#: forms.py:1527
+#: forms.py:1553
msgid "Bad index"
msgstr "Mauvais index"
-#: forms.py:1540
+#: forms.py:1566
msgid "Would you like to delete this administrative act?"
msgstr "Voulez-vous supprimer cet acte administratif ?"
-#: forms.py:1545
+#: forms.py:1571
msgid "Template"
msgstr "Patron"
-#: forms.py:1569 forms.py:1573
+#: forms.py:1595 forms.py:1599
msgid "This document is not intended for this type of act."
msgstr "Ce document n'est pas destiné à ce type d'acte."
-#: forms.py:1591
+#: forms.py:1617
msgid "Doc generation"
msgstr "Génération de document"
-#: forms.py:1593
+#: forms.py:1619
msgid "Generate the associated doc?"
msgstr "Générer le document associé ?"
-#: forms.py:1614 ishtar_menu.py:101 views.py:465
+#: forms.py:1640 ishtar_menu.py:96 views.py:466
msgctxt "admin act register"
msgid "Register"
msgstr "Registre"
-#: ishtar_menu.py:41 ishtar_menu.py:72 ishtar_menu.py:118
+#: ishtar_menu.py:41 ishtar_menu.py:72 ishtar_menu.py:113
msgid "Creation"
msgstr "Ajout"
-#: ishtar_menu.py:46 ishtar_menu.py:77 ishtar_menu.py:123
+#: ishtar_menu.py:46 ishtar_menu.py:77 ishtar_menu.py:118
msgid "Modification"
msgstr "Modification"
@@ -717,42 +729,38 @@ msgstr "Modification"
msgid "Closing"
msgstr "Clôture"
-#: ishtar_menu.py:55 ishtar_menu.py:82 ishtar_menu.py:128
+#: ishtar_menu.py:55 ishtar_menu.py:82 ishtar_menu.py:123
msgid "Deletion"
msgstr "Suppression"
-#: ishtar_menu.py:61 models.py:1713
+#: ishtar_menu.py:61 models.py:1786
#: templates/ishtar/sheet_administrativeact.html:4
msgid "Administrative act"
msgstr "Acte administratif"
-#: ishtar_menu.py:87 models.py:249 models.py:802
-msgid "Documents"
-msgstr "Documents"
-
-#: ishtar_menu.py:95
+#: ishtar_menu.py:90
msgid "Administrative Act"
msgstr "Acte administratif"
-#: ishtar_menu.py:135
+#: ishtar_menu.py:130
msgid "Dashboard"
msgstr "Tableau de bord"
-#: ishtar_menu.py:139
+#: ishtar_menu.py:134
msgid "General informations"
msgstr "Informations générales"
-#: ishtar_menu.py:143 models.py:843
+#: ishtar_menu.py:138 models.py:887
#: templates/ishtar/dashboards/dashboard_operation.html:8
-#: templates/ishtar/sheet_site.html:65
+#: templates/ishtar/sheet_site.html:68
msgid "Operations"
msgstr "Opérations"
-#: models.py:56 models.py:76 models.py:94 models.py:2622
+#: models.py:56 models.py:76 models.py:94 models.py:2705
msgid "Order"
msgstr "Ordre"
-#: models.py:58 models.py:2145
+#: models.py:58 models.py:2228
msgid "End date"
msgstr "Date de fin"
@@ -784,667 +792,694 @@ msgstr "Type de qualité d'enregistrement"
msgid "Types of record quality"
msgstr "Types de qualité d'enregistrement"
-#: models.py:135
+#: models.py:138
msgctxt "key for text search"
msgid "reference"
msgstr "reference"
-#: models.py:139 models.py:569
+#: models.py:142 models.py:605
msgctxt "key for text search"
msgid "name"
msgstr "nom"
-#: models.py:143 models.py:601 tests.py:1625
+#: models.py:146 models.py:637 tests.py:1625
msgctxt "key for text search"
msgid "period"
msgstr "periode"
-#: models.py:147 models.py:597 tests.py:1656
+#: models.py:150 models.py:633 tests.py:1656
msgctxt "key for text search"
msgid "remain"
msgstr "vestige"
-#: models.py:151 models.py:557 tests.py:1633
+#: models.py:154 models.py:593 tests.py:1633
msgctxt "key for text search"
msgid "town"
msgstr "commune"
-#: models.py:155 models.py:625
+#: models.py:158 models.py:661
msgctxt "key for text search"
msgid "comment"
msgstr "commentaire"
-#: models.py:159
+#: models.py:162
msgctxt "key for text search"
msgid "locality-ngi"
msgstr "lieu-dit-ign"
-#: models.py:163
+#: models.py:166
msgctxt "key for text search"
msgid "locality-cadastral"
msgstr "lieu-dit-cadastre"
-#: models.py:167
+#: models.py:170
msgctxt "key for text search"
msgid "shipwreck-name"
msgstr "nom-epave"
-#: models.py:172
+#: models.py:175
msgctxt "key for text search"
msgid "oceanographic-service-localisation"
msgstr "localisation-shom"
-#: models.py:176
+#: models.py:179
msgctxt "key for text search"
msgid "shipwreck-code"
msgstr "code-epave"
-#: models.py:180
+#: models.py:183
msgctxt "key for text search"
msgid "sinking-date"
msgstr "date-naufrage"
-#: models.py:184
+#: models.py:187
msgctxt "key for text search"
msgid "discovery-area"
msgstr "zone-decouverte"
-#: models.py:188 models.py:203
+#: models.py:191 models.py:214
msgctxt "key for text search"
msgid "operation"
msgstr "operation"
-#: models.py:192
+#: models.py:195
msgctxt "key for text search"
msgid "top-operation"
msgstr "operation-chapeau"
-#: models.py:251 models.py:804 models.py:1926
+#: models.py:199
+msgctxt "key for text search"
+msgid "numero-drassm"
+msgstr "numero-drassm"
+
+#: models.py:203
+msgctxt "key for text search"
+msgid "numero-affmar"
+msgstr "numero-affmar"
+
+#: models.py:268 models.py:843
+msgid "Documents"
+msgstr "Documents"
+
+#: models.py:270 models.py:845 models.py:2009
msgid "Cached name"
msgstr "Nom en cache"
-#: models.py:280
+#: models.py:299
msgid "SITE"
msgstr "SITE"
-#: models.py:345
+#: models.py:380
msgid "Unknown"
msgstr "Inconnu"
-#: models.py:348
+#: models.py:383
msgid "Virtual operation of site: {}"
msgstr "Opération virtuelle du site : {}"
-#: models.py:488
+#: models.py:523
msgid "Associated file (label)"
msgstr "Dossier associé (nom)"
-#: models.py:489
+#: models.py:524
msgid "Operator name"
msgstr "Nom de l'opérateur"
-#: models.py:490
+#: models.py:525
msgid "Scientist (full name)"
msgstr "Responsable scientifique (nom complet)"
-#: models.py:491
+#: models.py:526
msgid "Associated file (external ID)"
msgstr "Dossier associé (identifiant)"
-#: models.py:492
+#: models.py:527
msgid "Scientist (title)"
msgstr "Responsable scientifique (titre)"
-#: models.py:493
+#: models.py:528
msgid "Scientist (surname)"
msgstr "Responsable scientifique (nom)"
-#: models.py:494
+#: models.py:529
msgid "Scientist (name)"
msgstr "Scientifique (nom)"
-#: models.py:495
+#: models.py:530
msgid "Scientist - Organization (name)"
msgstr "Scientifique - Organisation (nom)"
-#: models.py:496
+#: models.py:531
msgid "In charge (title)"
msgstr "Responsable du suivi scientifique (titre)"
-#: models.py:497
+#: models.py:532
msgid "In charge (surname)"
msgstr "Responsable du suivi scientifique (prénom)"
-#: models.py:498
+#: models.py:533
msgid "In charge (name)"
msgstr "Responsable du suivi scientifique (nom)"
-#: models.py:499
+#: models.py:534
msgid "In charge - Organization (name)"
msgstr "Responsable du suivi scientifique - Organisation (nom)"
-#: models.py:504
+#: models.py:539
msgid "Archaeological sites (reference)"
msgstr "Entités archéologiques (référence)"
-#: models.py:545 models.py:1502 tests.py:1628 tests.py:1673
+#: models.py:581 models.py:1575 tests.py:1628 tests.py:1673
msgctxt "key for text search"
msgid "year"
msgstr "annee"
-#: models.py:549
+#: models.py:585
msgctxt "key for text search"
msgid "operation-code"
msgstr "code-operation"
-#: models.py:553 models.py:1514
+#: models.py:589 models.py:1587
msgctxt "key for text search"
msgid "patriarche"
msgstr "patriarche"
-#: models.py:561 models.py:1534
+#: models.py:597 models.py:1607
msgctxt "key for text search"
msgid "parcel"
msgstr "parcelle"
-#: models.py:565
+#: models.py:601
msgctxt "key for text search"
msgid "department"
msgstr "departement"
-#: models.py:573
+#: models.py:609
msgctxt "key for text search"
msgid "address"
msgstr "adresse"
-#: models.py:577 models.py:1518
+#: models.py:613 models.py:1591
msgctxt "key for text search"
msgid "type"
msgstr "type"
-#: models.py:581 tests.py:1661
+#: models.py:617 tests.py:1661
msgctxt "key for text search"
msgid "is-open"
msgstr "est-ouvert"
-#: models.py:585
+#: models.py:621
msgctxt "key for text search"
msgid "in-charge"
msgstr "responsable-suivi"
-#: models.py:589
+#: models.py:625
msgctxt "key for text search"
msgid "scientist"
msgstr "scientifique"
-#: models.py:593
+#: models.py:629
msgctxt "key for text search"
msgid "operator"
msgstr "operateur"
-#: models.py:605
+#: models.py:641
msgctxt "key for text search"
msgid "start-before"
msgstr "commence-avant"
-#: models.py:609
+#: models.py:645
msgctxt "key for text search"
msgid "start-after"
msgstr "commence-apres"
-#: models.py:613
+#: models.py:649
msgctxt "key for text search"
msgid "end-before"
msgstr "fini-apres"
-#: models.py:617
+#: models.py:653
msgctxt "key for text search"
msgid "end-after"
msgstr "fini-avant"
-#: models.py:621
+#: models.py:657
msgctxt "key for text search"
msgid "relation-types"
msgstr "type-relation"
-#: models.py:629
+#: models.py:665
msgctxt "key for text search"
msgid "abstract"
msgstr "resume"
-#: models.py:634
+#: models.py:670
msgctxt "key for text search"
msgid "scientific-documentation-comment"
msgstr "commentaire-documentation-scientifique"
-#: models.py:638
+#: models.py:674
msgctxt "key for text search"
msgid "record-quality"
msgstr "qualite-enregistrement"
-#: models.py:643
+#: models.py:679
msgctxt "key for text search"
msgid "report-processing"
msgstr "traitement-rapport"
-#: models.py:648
+#: models.py:684
msgctxt "key for text search"
msgid "virtual-operation"
msgstr "operation-virtuelle"
-#: models.py:653 models.py:696
+#: models.py:689 models.py:736
msgctxt "key for text search"
msgid "site"
msgstr "site"
-#: models.py:657 models.py:1552
+#: models.py:693 models.py:1625
msgctxt "key for text search"
msgid "created-by"
msgstr "cree-par"
-#: models.py:661 models.py:1556
+#: models.py:697 models.py:1629
msgctxt "key for text search"
msgid "modified-by"
msgstr "modifie-par"
-#: models.py:665
+#: models.py:701
msgctxt "key for text search"
msgid "documentation-received"
msgstr "documentation-recue"
-#: models.py:669
+#: models.py:705
msgctxt "key for text search"
msgid "documentation-deadline-before"
msgstr "documentation-date-limite-avant"
-#: models.py:673
+#: models.py:709
msgctxt "key for text search"
msgid "documentation-deadline-after"
msgstr "documentation-date-limite-après"
-#: models.py:677
+#: models.py:713
msgctxt "key for text search"
msgid "finds-received"
msgstr "mobilier-recu"
-#: models.py:681
+#: models.py:717
msgctxt "key for text search"
msgid "finds-deadline-before"
msgstr "mobilier-date-limite-avant"
-#: models.py:685
+#: models.py:721
msgctxt "key for text search"
msgid "finds-deadline-after"
msgstr "mobilier-date-limite-apres"
-#: models.py:698
+#: models.py:725
+msgctxt "key for text search"
+msgid "code-drassm"
+msgstr "code-drassm"
+
+#: models.py:738
msgctxt "key for text search"
msgid "file"
msgstr "dossier"
-#: models.py:713 templates/ishtar/sheet_operation.html:60
+#: models.py:753 templates/ishtar/sheet_operation.html:61
msgid "Closing date"
msgstr "Date de clôture"
-#: models.py:720
+#: models.py:760
msgid "In charge scientist"
msgstr "Responsable du suivi scientifique"
-#: models.py:739 models.py:1908
+#: models.py:779 models.py:1991
msgid "File"
msgstr "Dossier"
-#: models.py:743
+#: models.py:783
msgid "Surface (m2)"
msgstr "Surface (m2)"
-#: models.py:812
+#: models.py:853
msgid ""
"If checked, it means that this operation have not been officialy registered."
msgstr ""
"Si coché, cela signifie que cette opération n'a pas été officiellement "
"enregistrée."
-#: models.py:891
+#: models.py:935
msgid "OPE"
msgstr "OPE"
-#: models.py:988
+#: models.py:1032
msgid "Intercommunal"
msgstr "Intercommunal"
-#: models.py:1024
+#: models.py:1078
+msgid "Add context record"
+msgstr "Ajouter une unité d'enregistrement"
+
+#: models.py:1079
+msgid "context record"
+msgstr "UE"
+
+#: models.py:1084
msgid "Code patriarche"
msgstr "Code patriarche"
-#: models.py:1066
+#: models.py:1126
msgid "This operation code already exists for this year"
msgstr "Ce code d'opération existe déjà pour cette année."
-#: models.py:1111
+#: models.py:1183
msgid "Number of parcels"
msgstr "Nombre de parcelles"
-#: models.py:1121
+#: models.py:1193
msgid "Number of administrative acts"
msgstr "Nombre d'actes administratifs"
-#: models.py:1129
+#: models.py:1201
msgid "Number of indexed administrative acts"
msgstr "Nombre d'actes administratifs indexés"
-#: models.py:1137
+#: models.py:1209
msgid "Number of context records"
msgstr "Nombre d'Unités d'Enregistrement"
-#: models.py:1173
+#: models.py:1245
msgid "Number of finds"
msgstr "Nombre d'éléments de mobilier"
-#: models.py:1218
+#: models.py:1290
msgid "No type"
msgstr "Pas de type"
-#: models.py:1249
+#: models.py:1321
msgid "Number of sources"
msgstr "Nombre de documents"
-#: models.py:1287 templates/ishtar/dashboards/dashboard_operation.html:309
+#: models.py:1359 templates/ishtar/dashboards/dashboard_operation.html:309
#: templates/ishtar/dashboards/dashboard_operation.html:575
#: templates/ishtar/dashboards/dashboard_operation.html:611
msgid "Mean"
msgstr "Moyenne"
-#: models.py:1349
+#: models.py:1421
msgid "Operation relation type"
msgstr "Type de relation entre opérations"
-#: models.py:1350
+#: models.py:1422
msgid "Operation relation types"
msgstr "Types de relation entre opérations"
-#: models.py:1363
+#: models.py:1435
msgid "Operation record relation"
msgstr "Relation entre opérations"
-#: models.py:1364
+#: models.py:1436
msgid "Operation record relations"
msgstr "Relations entre opérations"
-#: models.py:1406 models.py:1688
+#: models.py:1478 models.py:1761
msgid "Treatment request"
msgstr "Demande de traitement"
-#: models.py:1407 models.py:1693
+#: models.py:1479 models.py:1766
msgid "Treatment"
msgstr "Traitement"
-#: models.py:1409
+#: models.py:1481
msgid "Intended to"
msgstr "Destiné à"
-#: models.py:1411
+#: models.py:1483
msgid "Code"
msgstr "Code"
-#: models.py:1414
+#: models.py:1486
msgid "Associated template"
msgstr "Patron associé"
-#: models.py:1415
+#: models.py:1487
msgid "Indexed"
msgstr "Indexé"
-#: models.py:1419
+#: models.py:1491
msgid "Act types"
msgstr "Types d'acte"
-#: models.py:1489 models.py:1734
+#: models.py:1562 models.py:1807
#: templates/ishtar/blocks/window_tables/administrativacts.html:6
#: templates/ishtar/blocks/window_tables/archaeologicalsites.html:6
msgid "Ref."
msgstr "Réf."
-#: models.py:1506
+#: models.py:1579
msgctxt "key for text search"
msgid "index"
msgstr "index"
-#: models.py:1510
+#: models.py:1583
msgctxt "key for text search"
msgid "other-ref"
msgstr "autre-ref"
-#: models.py:1522
+#: models.py:1595
msgctxt "key for text search"
msgid "indexed"
msgstr "indexe"
-#: models.py:1526
+#: models.py:1599
msgctxt "key for text search"
msgid "operation-town"
msgstr "operation-commune"
-#: models.py:1530
+#: models.py:1603
msgctxt "key for text search"
msgid "file-town"
msgstr "dossier-commune"
-#: models.py:1540
+#: models.py:1613
msgctxt "key for text search"
msgid "operation-department"
msgstr "operation-departement"
-#: models.py:1544
+#: models.py:1617
msgctxt "key for text search"
msgid "file-department"
msgstr "dossier-departement"
-#: models.py:1548
+#: models.py:1621
msgctxt "key for text search"
msgid "object"
msgstr "objet"
-#: models.py:1560
+#: models.py:1633
msgctxt "key for text search"
msgid "signature-before"
msgstr "signature-avant"
-#: models.py:1564
+#: models.py:1637
msgctxt "key for text search"
msgid "signature-after"
msgstr "signature-apres"
-#: models.py:1568
+#: models.py:1641
msgctxt "key for text search"
msgid "file-name"
msgstr "dossier-nom"
-#: models.py:1572
+#: models.py:1645
msgctxt "key for text search"
msgid "general-contractor"
msgstr "amenageur"
-#: models.py:1577
+#: models.py:1650
msgctxt "key for text search"
msgid "general-contractor-organization"
msgstr "amenageur-organisation"
-#: models.py:1582
+#: models.py:1655
msgctxt "key for text search"
msgid "file-reference"
msgstr "dossier-reference"
-#: models.py:1586
+#: models.py:1659
msgctxt "key for text search"
msgid "file-year"
msgstr "dossier-annee"
-#: models.py:1590
+#: models.py:1663
msgctxt "key for text search"
msgid "file-other-reference"
msgstr "dossier-autre-reference"
-#: models.py:1594
+#: models.py:1667
msgctxt "key for text search"
msgid "file-in-charge"
msgstr "dossier-responsable"
-#: models.py:1598
+#: models.py:1671
msgctxt "key for text search"
msgid "file-permit-reference"
msgstr "dossier-ref-permis"
-#: models.py:1602
+#: models.py:1675
msgctxt "key for text search"
msgid "treatment-name"
msgstr "traitement-nom"
-#: models.py:1606
+#: models.py:1679
msgctxt "key for text search"
msgid "treatment-reference"
msgstr "traitement-reference"
-#: models.py:1610
+#: models.py:1683
msgctxt "key for text search"
msgid "treatment-year"
msgstr "traitement-annee"
-#: models.py:1614
+#: models.py:1687
msgctxt "key for text search"
msgid "treatment-index"
msgstr "traitement-index"
-#: models.py:1618
+#: models.py:1691
msgctxt "key for text search"
msgid "treatment-type"
msgstr "traitement-type"
-#: models.py:1622
+#: models.py:1695
msgctxt "key for text search"
msgid "treatment-file-name"
msgstr "dossier-traitement-nom"
-#: models.py:1626
+#: models.py:1699
msgctxt "key for text search"
msgid "treatment-file-reference"
msgstr "dossier-traitement-reference"
-#: models.py:1630
+#: models.py:1703
msgctxt "key for text search"
msgid "treatment-file-year"
msgstr "dossier-traitement-annee"
-#: models.py:1634
+#: models.py:1707
msgctxt "key for text search"
msgid "treatment-file-index"
msgstr "dossier-traitement-index"
-#: models.py:1638
+#: models.py:1711
msgctxt "key for text search"
msgid "treatment-file-type"
msgstr "dossier-traitement-type"
-#: models.py:1661
+#: models.py:1734
msgid "Person in charge of the operation"
msgstr "Responsable d'opération"
-#: models.py:1667
+#: models.py:1740
msgid "Archaeological preventive operator"
msgstr "Opérateur d'archéologie préventive"
-#: models.py:1675
+#: models.py:1748
msgid "Signatory"
msgstr "Signataire"
-#: models.py:1703
+#: models.py:1776
msgid "Departments"
msgstr "Départements"
-#: models.py:1704
+#: models.py:1777
msgid "Cached values get from associated departments"
msgstr "Valeur en cache des départements associés"
-#: models.py:1707
+#: models.py:1780
msgid "Cached values get from associated towns"
msgstr "Valeur en cache des communes associées"
-#: models.py:1714 templates/ishtar/sheet_operation.html:202
-#: templates/ishtar/sheet_operation.html:244
+#: models.py:1787 templates/ishtar/sheet_operation.html:205
+#: templates/ishtar/sheet_operation.html:251
msgid "Administrative acts"
msgstr "Actes administratifs"
-#: models.py:1837
+#: models.py:1920
msgid "This index already exists for this year"
msgstr "Cet index existe déjà pour cette année."
-#: models.py:1921
+#: models.py:2004
msgid "External ID"
msgstr "Identifiant"
-#: models.py:1924
+#: models.py:2007
msgid "External ID is set automatically"
msgstr "L'identifiant est attribué automatiquement"
-#: models.py:1925
+#: models.py:2008
msgid "Address - Locality"
msgstr "Adresse - Lieu-dit"
-#: models.py:2140
+#: models.py:2223
msgid "Owner"
msgstr "Propriétaire"
-#: models.py:2148
+#: models.py:2231
msgid "Parcel owner"
msgstr "Propriétaire de parcelle"
-#: models.py:2149
+#: models.py:2232
msgid "Parcel owners"
msgstr "Propriétaires de parcelle"
-#: models.py:2183
+#: models.py:2266
msgid "Recorded"
msgstr "Enregistré"
-#: models.py:2184
+#: models.py:2267
msgid "Effective"
msgstr "Effectif"
-#: models.py:2185
+#: models.py:2268
msgid "Active"
msgstr "Actif"
-#: models.py:2186
+#: models.py:2269
msgid "Field completed"
msgstr "Terrain achevé"
-#: models.py:2187
+#: models.py:2270
msgid "Associated report"
msgstr "Rapport associé"
-#: models.py:2188
+#: models.py:2271
msgid "Closed"
msgstr "Clos"
-#: models.py:2189
+#: models.py:2272
msgid "Documented and closed"
msgstr "Documenté et clos"
-#: models.py:2623
+#: models.py:2706
msgid "Is preventive"
msgstr "Préventif"
-#: models.py:2626
+#: models.py:2709
msgid "Operation type old"
msgstr "Type d'opération - ancien"
-#: models.py:2627
+#: models.py:2710
msgid "Operation types old"
msgstr "Types d'opération - ancien"
#: templates/ishtar/blocks/window_tables/administrativacts.html:7
-#: templates/ishtar/sheet_operation.html:263
-#: templates/ishtar/sheet_operation.html:327
+#: templates/ishtar/sheet_operation.html:270
+#: templates/ishtar/sheet_operation.html:334
msgid "Type"
msgstr "Type"
@@ -1488,12 +1523,12 @@ msgstr "État"
#: templates/ishtar/dashboards/dashboard_operation.html:432
#: templates/ishtar/dashboards/dashboard_operation.html:463
#: templates/ishtar/dashboards/dashboard_operation.html:687
-#: templates/ishtar/sheet_operation.html:263
-#: templates/ishtar/sheet_operation.html:273
-#: templates/ishtar/sheet_operation.html:290
-#: templates/ishtar/sheet_operation.html:300
-#: templates/ishtar/sheet_operation.html:310
-#: templates/ishtar/sheet_operation.html:327
+#: templates/ishtar/sheet_operation.html:270
+#: templates/ishtar/sheet_operation.html:280
+#: templates/ishtar/sheet_operation.html:297
+#: templates/ishtar/sheet_operation.html:307
+#: templates/ishtar/sheet_operation.html:317
+#: templates/ishtar/sheet_operation.html:334
msgid "Number"
msgstr "Nombre"
@@ -1519,7 +1554,7 @@ msgstr "par types"
#: templates/ishtar/dashboards/dashboard_operation.html:479
#: templates/ishtar/dashboards/dashboard_operation.html:499
#: templates/ishtar/dashboards/dashboard_operation.html:623
-#: templates/ishtar/sheet_operation.html:52
+#: templates/ishtar/sheet_operation.html:53
msgid "State"
msgstr "État"
@@ -1684,7 +1719,7 @@ msgid "area by organization by realisation year"
msgstr "surface par organisation et par année de réalisation"
#: templates/ishtar/dashboards/dashboard_operation.html:670
-#: templates/ishtar/sheet_operation.html:77
+#: templates/ishtar/sheet_operation.html:78
msgid "Cost"
msgstr "Coût"
@@ -1697,7 +1732,7 @@ msgid "main towns by cost"
msgstr "communes principales par coût"
#: templates/ishtar/sheet_administrativeact.html:40
-#: templates/ishtar/sheet_operation.html:69
+#: templates/ishtar/sheet_operation.html:70
msgid "Surface"
msgstr "Surface"
@@ -1705,103 +1740,103 @@ msgstr "Surface"
msgid "Address"
msgstr "Adresse"
-#: templates/ishtar/sheet_operation.html:37
+#: templates/ishtar/sheet_operation.html:38
msgid "Begining date"
msgstr "Date de début"
-#: templates/ishtar/sheet_operation.html:54
+#: templates/ishtar/sheet_operation.html:55
msgid "Active file"
msgstr "Dossier actif"
-#: templates/ishtar/sheet_operation.html:55
+#: templates/ishtar/sheet_operation.html:56
msgid "Closed operation"
msgstr "Opération close"
-#: templates/ishtar/sheet_operation.html:62
+#: templates/ishtar/sheet_operation.html:63
msgid "by"
msgstr "par"
-#: templates/ishtar/sheet_operation.html:85
+#: templates/ishtar/sheet_operation.html:86
msgid "Duration"
msgstr "Durée"
-#: templates/ishtar/sheet_operation.html:87
+#: templates/ishtar/sheet_operation.html:88
msgid "days"
msgstr "jours"
-#: templates/ishtar/sheet_operation.html:129
+#: templates/ishtar/sheet_operation.html:130
msgid "Sheet"
msgstr "Fiche"
-#: templates/ishtar/sheet_operation.html:138
+#: templates/ishtar/sheet_operation.html:139
msgid "This operation is virtual."
msgstr "Cette opération est virtuelle."
-#: templates/ishtar/sheet_operation.html:144
+#: templates/ishtar/sheet_operation.html:145
msgid "Patriarche OA code not yet recorded!"
msgstr "Code d'opération Patriarche non renseigné !"
-#: templates/ishtar/sheet_operation.html:159
-#: templates/ishtar/sheet_site.html:43
+#: templates/ishtar/sheet_operation.html:160
+#: templates/ishtar/sheet_site.html:44
msgid "Localisation"
msgstr "Localisation"
-#: templates/ishtar/sheet_operation.html:198
+#: templates/ishtar/sheet_operation.html:200
msgid "Associated parcels"
msgstr "Parcelles associées"
-#: templates/ishtar/sheet_operation.html:206
+#: templates/ishtar/sheet_operation.html:209
msgid "Document from this operation"
msgstr "Documents de cette opération"
-#: templates/ishtar/sheet_operation.html:212
-#: templates/ishtar/sheet_operation.html:255
+#: templates/ishtar/sheet_operation.html:216
+#: templates/ishtar/sheet_operation.html:262
msgid "Context records"
msgstr "Unités d'Enregistrement"
-#: templates/ishtar/sheet_operation.html:217
+#: templates/ishtar/sheet_operation.html:221
msgid "Context record relations"
msgstr "Relations entre Unités d'Enregistrement"
-#: templates/ishtar/sheet_operation.html:222
+#: templates/ishtar/sheet_operation.html:226
msgid "Documents from associated context records"
msgstr "Documents des Unités d'Enregistrement associées"
-#: templates/ishtar/sheet_operation.html:227
-#: templates/ishtar/sheet_operation.html:282
-#: templates/ishtar/sheet_site.html:70
+#: templates/ishtar/sheet_operation.html:232
+#: templates/ishtar/sheet_operation.html:289
+#: templates/ishtar/sheet_site.html:73
msgid "Finds"
msgstr "Mobilier"
-#: templates/ishtar/sheet_operation.html:232
+#: templates/ishtar/sheet_operation.html:237
msgid "Documents from associated finds"
msgstr "Documents du mobilier associé"
-#: templates/ishtar/sheet_operation.html:237
+#: templates/ishtar/sheet_operation.html:243
msgid "Associated containers"
msgstr "Contenants associés"
-#: templates/ishtar/sheet_operation.html:241
+#: templates/ishtar/sheet_operation.html:248
msgid "Statistics"
msgstr "Statistiques"
-#: templates/ishtar/sheet_operation.html:242
+#: templates/ishtar/sheet_operation.html:249
msgid "These numbers are updated hourly"
msgstr "Ces chiffres sont mis à jour toutes les heures"
-#: templates/ishtar/sheet_operation.html:290
+#: templates/ishtar/sheet_operation.html:297
msgid "Material type"
msgstr "Type de matériau"
-#: templates/ishtar/sheet_operation.html:300
+#: templates/ishtar/sheet_operation.html:307
msgid "Object type"
msgstr "Type d'objet"
-#: templates/ishtar/sheet_operation.html:319
+#: templates/ishtar/sheet_operation.html:326
msgid "Sources"
msgstr "Documents"
-#: templates/ishtar/sheet_operation.html:337
+#: templates/ishtar/sheet_operation.html:344
msgid "Finds by context records"
msgstr "Mobilier par Unités d'Enregistrement"
@@ -1824,44 +1859,44 @@ msgstr ""
"Le(s) erreur(s) suivante(s) ont été rencontrées lors de l'analyse du fichier "
"source :"
-#: views.py:244
+#: views.py:245
msgid "New operation"
msgstr "Ajouter une opération"
-#: views.py:293
+#: views.py:294
msgid "Operation modification"
msgstr "Modifier une opération"
-#: views.py:304
+#: views.py:305
msgid "You don't have sufficient permissions to do this action."
msgstr ""
"Vous n'avez pas les permissions suffisantes pour effectuer cette action."
-#: views.py:329
+#: views.py:330
msgid "Operation closing"
msgstr "Clôturer une opération"
-#: views.py:340
+#: views.py:341
msgid "Operation deletion"
msgstr "Supprimer une opération"
-#: views.py:406
+#: views.py:407
msgid "Site deletion"
msgstr "Suppression du site"
-#: views.py:425
+#: views.py:426
msgid "Operation: new administrative act"
msgstr "Opération : ajouter un acte administratif"
-#: views.py:435
+#: views.py:436
msgid "Operation: administrative act modification"
msgstr "Opération : modification d'un acte administratif"
-#: views.py:459
+#: views.py:460
msgid "Operation: administrative act deletion"
msgstr "Opération : supprimer un acte administratif"
-#: views.py:552
+#: views.py:530
msgid ""
"Syntax error on the source template \"{}\" - contact your administrator and "
"ask him to check the syntax of this document."
diff --git a/translations/fr/archaeological_warehouse.po b/translations/fr/archaeological_warehouse.po
index 6b2c7ae8e..1f4e35014 100644
--- a/translations/fr/archaeological_warehouse.po
+++ b/translations/fr/archaeological_warehouse.po
@@ -11,322 +11,322 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Transfer-Encoding: 8bit\n"
"Content-Type: text/plain; charset=UTF-8\n"
-"PO-Revision-Date: 2018-11-12 10:09+0000\n"
+"PO-Revision-Date: 2018-12-04 01:07+0000\n"
"Last-Translator: Étienne Loks <etienne.loks@iggdrasil.net>\n"
"Language-Team: \n"
"Language: fr\n"
"Plural-Forms: nplurals=2; plural=n>1;\n"
"X-Generator: Zanata 4.6.2\n"
-#: forms.py:41 forms.py:113 ishtar_menu.py:40 models.py:94 models.py:258
+#: forms.py:42 forms.py:114 ishtar_menu.py:32 models.py:95 models.py:259
#: templates/ishtar/sheet_warehouse.html:4
msgid "Warehouse"
msgstr "Lieu de conservation"
-#: forms.py:50 forms.py:55 models.py:622
+#: forms.py:51 forms.py:56 models.py:638
msgid "Division"
msgstr "Division"
-#: forms.py:57 models.py:286
+#: forms.py:58 models.py:287
msgid "Order"
msgstr "Ordre"
-#: forms.py:71
+#: forms.py:72
msgid "There are identical divisions."
msgstr "Il y a des divisions identiques"
-#: forms.py:76 models.py:83
+#: forms.py:77 models.py:84
msgid "Divisions"
msgstr "Divisions"
-#: forms.py:77
+#: forms.py:78
msgid "Warehouse - 020 - Divisions"
msgstr "Lieu de conservation - 020 - Divisions"
-#: forms.py:85 forms.py:254
+#: forms.py:86 forms.py:255
msgid "Full text search"
msgstr "Recherche en texte intégral"
-#: forms.py:88 forms.py:119 models.py:75 models.py:255
+#: forms.py:89 forms.py:120 models.py:76 models.py:256
msgid "Name"
msgstr "Nom"
-#: forms.py:89 forms.py:121 models.py:39 models.py:77
+#: forms.py:90 forms.py:122 models.py:40 models.py:78
msgid "Warehouse type"
msgstr "Type de lieu de conservation"
-#: forms.py:101 views.py:108
+#: forms.py:102 views.py:120
msgid "Warehouse search"
msgstr "Rechercher un lieu de conservation"
-#: forms.py:114
+#: forms.py:115
msgid "Warehouse - 010 - General"
msgstr "Lieu de conservation - 010 - Général"
-#: forms.py:124 models.py:80
+#: forms.py:125 models.py:81
msgid "Person in charge"
msgstr "Responsable"
-#: forms.py:130 forms.py:198 models.py:81 models.py:381
+#: forms.py:131 forms.py:199 models.py:82 models.py:383
msgid "Comment"
msgstr "Commentaire"
-#: forms.py:132
+#: forms.py:133
msgid "Address"
msgstr "Adresse"
-#: forms.py:134
+#: forms.py:135
msgid "Address complement"
msgstr "Complément d'adresse"
-#: forms.py:136
+#: forms.py:137
msgid "Postal code"
msgstr "Code postal"
-#: forms.py:138
+#: forms.py:139
msgid "Town"
msgstr "Commune"
-#: forms.py:139
+#: forms.py:140
msgid "Country"
msgstr "Pays"
-#: forms.py:141
+#: forms.py:142
msgid "Phone"
msgstr "Téléphone"
-#: forms.py:142
+#: forms.py:143
msgid "Mobile phone"
msgstr "Téléphone mobile"
-#: forms.py:167 forms.py:168
+#: forms.py:168 forms.py:169
msgid "Would you like to delete this warehouse?"
msgstr "Voulez-vous supprimer ce lieu de conservation?"
-#: forms.py:172 models.py:395 models.py:619
+#: forms.py:173 models.py:397 models.py:635
#: templates/ishtar/sheet_container.html:4
msgid "Container"
msgstr "Contenant"
-#: forms.py:173
+#: forms.py:174
msgid "Container - 010 - General"
msgstr "Contenant - 010 - Général"
-#: forms.py:179 forms.py:261 models.py:301
+#: forms.py:180 forms.py:262 models.py:302
msgid "Ref."
msgstr "Réf."
-#: forms.py:180 models.py:389
+#: forms.py:181 models.py:391
msgid "Old reference"
msgstr "Ancienne référence"
-#: forms.py:182 forms.py:260 models.py:304 models.py:379
+#: forms.py:183 forms.py:261 models.py:306 models.py:381
msgid "Container type"
msgstr "Type de contenant"
-#: forms.py:184 forms.py:258
+#: forms.py:185 forms.py:259
msgid "Current location (warehouse)"
msgstr "Localisation actuelle (lieu de conservation)"
-#: forms.py:190 forms.py:259 models.py:376
+#: forms.py:191 forms.py:260 models.py:378
msgid "Responsible warehouse"
msgstr "Lieu de conservation responsable"
-#: forms.py:196
+#: forms.py:197
msgid "Image"
msgstr "Image"
-#: forms.py:223
+#: forms.py:224
msgid "ID"
msgstr "Identifiant"
-#: forms.py:245
+#: forms.py:246
msgid "This ID already exists for this warehouse."
msgstr "Cet identifiant existe déjà pour ce lieu de conservation."
-#: forms.py:272 forms.py:278 views.py:150
+#: forms.py:273 forms.py:279 views.py:162
msgid "Container search"
msgstr "Rechercher un contenant"
-#: forms.py:274 forms.py:280
+#: forms.py:275 forms.py:281
msgid "You should select a container."
msgstr "Vous devez sélectionner un contenant."
-#: forms.py:275
+#: forms.py:276
msgid "Add a new container"
msgstr "Ajouter un nouveau contenant"
-#: forms.py:285 ishtar_menu.py:36 views.py:103
+#: forms.py:286 views.py:115
msgid "Packaging"
msgstr "Conditionnement"
-#: forms.py:291
+#: forms.py:292
msgid "Packager"
msgstr "Personne assurant le conditionnement"
-#: forms.py:297
+#: forms.py:298
msgid "Date"
msgstr "Date"
-#: forms.py:301
+#: forms.py:304
msgid "Packaged finds"
msgstr "Mobilier conditionné"
-#: forms.py:305
+#: forms.py:308
msgid "Container - 020 - Localisation"
msgstr "Contenant - 020 - Localisation"
-#: forms.py:307 models.py:382
+#: forms.py:310 models.py:384
msgid "Localisation"
msgstr "Localisation"
-#: forms.py:331 forms.py:332
+#: forms.py:334 forms.py:335
msgid "Would you like to delete this container?"
msgstr "Voulez-vous supprimer ce contenant ?"
-#: ishtar_menu.py:32
-msgid "Treatment"
-msgstr "Traitement"
-
-#: ishtar_menu.py:44 ishtar_menu.py:59
+#: ishtar_menu.py:36 ishtar_menu.py:51
msgid "Search"
msgstr "Recherche"
-#: ishtar_menu.py:47 ishtar_menu.py:63
+#: ishtar_menu.py:39 ishtar_menu.py:55
msgid "Creation"
msgstr "Ajout"
-#: ishtar_menu.py:50 ishtar_menu.py:67
+#: ishtar_menu.py:42 ishtar_menu.py:59
msgid "Modification"
msgstr "Modification"
-#: ishtar_menu.py:53 ishtar_menu.py:71
+#: ishtar_menu.py:45 ishtar_menu.py:63
msgid "Deletion"
msgstr "Suppression"
-#: ishtar_menu.py:57 models.py:396 templates/ishtar/sheet_warehouse.html:42
+#: ishtar_menu.py:49 models.py:398 templates/ishtar/sheet_warehouse.html:42
#: templates/ishtar/sheet_warehouse.html:87
msgid "Containers"
msgstr "Contenants"
-#: models.py:40
+#: models.py:41
msgid "Warehouse types"
msgstr "Types de lieu de conservation"
-#: models.py:60
+#: models.py:61
msgctxt "key for text search"
msgid "name"
msgstr "nom"
-#: models.py:64 models.py:356
+#: models.py:65 models.py:358
msgctxt "key for text search"
msgid "type"
msgstr "type"
-#: models.py:87
+#: models.py:88
msgid "Documents"
msgstr "Documents"
-#: models.py:89 models.py:390
+#: models.py:90 models.py:392
msgid "External ID"
msgstr "Identifiant"
-#: models.py:91 models.py:392
+#: models.py:92 models.py:394
msgid "External ID is set automatically"
msgstr "L'identifiant est attribué automatiquement"
-#: models.py:95
+#: models.py:96
msgid "Warehouses"
msgstr "Lieux de conservation"
-#: models.py:257
+#: models.py:258
msgid "Description"
msgstr "Description"
-#: models.py:262 models.py:263
+#: models.py:263 models.py:264
msgid "Collection"
msgstr "Collection"
-#: models.py:272
+#: models.py:273
msgid "Warehouse division type"
msgstr "Type de division de lieu de conservation"
-#: models.py:273
+#: models.py:274
msgid "Warehouse division types"
msgstr "Types de division de lieu de conservation"
-#: models.py:297
+#: models.py:298
msgid "Length (mm)"
msgstr "Longueur (mm)"
-#: models.py:298
+#: models.py:299
msgid "Width (mm)"
msgstr "Largeur (mm)"
-#: models.py:299
+#: models.py:300
msgid "Height (mm)"
msgstr "Hauteur (mm)"
-#: models.py:300
+#: models.py:301
msgid "Volume (l)"
msgstr "Volume (l)"
-#: models.py:305
+#: models.py:307
msgid "Container types"
msgstr "Types de contenant"
-#: models.py:339
+#: models.py:341
msgid "Location - index"
msgstr "Localisation - index"
-#: models.py:340
+#: models.py:342
msgid "Precise localisation"
msgstr "Localisation précise"
-#: models.py:341
+#: models.py:343
msgid "Type"
msgstr "Type"
-#: models.py:348
+#: models.py:350
msgctxt "key for text search"
msgid "location"
msgstr "localisation"
-#: models.py:352
+#: models.py:354
msgctxt "key for text search"
msgid "responsible-warehouse"
msgstr "lieu-de-conservation-responsable"
-#: models.py:360
+#: models.py:362
msgctxt "key for text search"
msgid "reference"
msgstr "reference"
-#: models.py:373
+#: models.py:375
msgid "Location (warehouse)"
msgstr "Localisation (lieu de conservation)"
-#: models.py:380
+#: models.py:382
msgid "Container ref."
msgstr "Réf. du contenant"
-#: models.py:384
+#: models.py:386
msgid "Cached location"
msgstr "Localisation - en cache"
-#: models.py:386
+#: models.py:388
msgid "Cached division"
msgstr "Division mise en cache"
-#: models.py:623
+#: models.py:584
+msgid "Add treatment"
+msgstr "Ajouter un traitement"
+
+#: models.py:639
msgid "Reference"
msgstr "Référence"
-#: models.py:626
+#: models.py:642
msgid "Container localisation"
msgstr "Localisation de contenant"
-#: models.py:627
+#: models.py:643
msgid "Container localisations"
msgstr "Localisations de contenant"
@@ -391,26 +391,26 @@ msgstr ""
"Des contenants localisés sont associés à ce lieu de conservation. Vous ne "
"pouvez pas modifier les divisions."
-#: views.py:120
+#: views.py:132
msgid "Warehouse creation"
msgstr "Ajouter un lieu de conservation"
-#: views.py:129
+#: views.py:141
msgid "Warehouse modification"
msgstr "Modifier un lieu de conservation"
-#: views.py:145
+#: views.py:157
msgid "Warehouse deletion"
msgstr "Supprimer un lieu de conservation"
-#: views.py:161
+#: views.py:173
msgid "Container creation"
msgstr "Ajouter un contenant"
-#: views.py:170
+#: views.py:182
msgid "Container modification"
msgstr "Modifier un contenant"
-#: views.py:185
+#: views.py:197
msgid "Container deletion"
msgstr "Supprimer un contenant"
diff --git a/translations/fr/ishtar_common.po b/translations/fr/ishtar_common.po
index 0c15c6cf7..11b5f6aa2 100644
--- a/translations/fr/ishtar_common.po
+++ b/translations/fr/ishtar_common.po
@@ -12,7 +12,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Transfer-Encoding: 8bit\n"
"Content-Type: text/plain; charset=UTF-8\n"
-"PO-Revision-Date: 2018-11-12 10:08+0000\n"
+"PO-Revision-Date: 2018-12-04 01:09+0000\n"
"Last-Translator: Étienne Loks <etienne.loks@iggdrasil.net>\n"
"Language-Team: \n"
"Language: fr\n"
@@ -43,12 +43,12 @@ msgstr "Seul l'unicode est géré - convertissez votre fichier d'abord"
msgid "Export selected as CSV file"
msgstr "Exporter la sélection en fichier CSV"
-#: admin.py:207 models.py:1686 templates/navbar.html:31
+#: admin.py:207 models.py:1703 templates/navbar.html:31
msgid "Profile"
msgstr "Profil"
#: admin.py:208 forms_common.py:782 forms_common.py:801 forms_common.py:802
-#: models.py:3039
+#: models.py:3063
msgid "Profiles"
msgstr "Profils"
@@ -70,7 +70,7 @@ msgstr "%d élément(s) mis à jour."
msgid "These parents are missing: {}"
msgstr "Ces parents sont manquants : {}"
-#: admin.py:386 admin.py:405 models.py:883 models.py:4141
+#: admin.py:386 admin.py:405 models.py:905 models.py:4214
msgid "Parent"
msgstr "Parent"
@@ -78,11 +78,11 @@ msgstr "Parent"
msgid "Center"
msgstr "Centre"
-#: admin.py:395 models.py:4003
+#: admin.py:395 models.py:4076
msgid "Limit"
msgstr "Limite"
-#: admin.py:398 models.py:4013
+#: admin.py:398 models.py:4086
msgid "Town children"
msgstr "Communes enfants"
@@ -131,16 +131,16 @@ msgstr "Afficher les éléments sélectionnés"
msgid "Hide selected"
msgstr "Cacher les éléments sélectionnés"
-#: admin.py:931 models.py:2080
+#: admin.py:931 models.py:2098
msgid "Form"
msgstr "Formulaire"
-#: admin.py:933 models.py:2105 models_imports.py:127
+#: admin.py:933 models.py:2123 models_imports.py:127
#: templates/ishtar/dashboards/dashboard_main.html:39
msgid "Users"
msgstr "Utilisateurs"
-#: admin.py:953 models.py:2180
+#: admin.py:953 models.py:2202
msgid "Field"
msgstr "Champ"
@@ -239,7 +239,7 @@ msgstr ""
msgid "Too many cols (%(user_col)d) when maximum is %(ref_col)d"
msgstr "Trop de colonnes (%(user_col)d). Le maximum est %(ref_col)d"
-#: data_importer.py:730 views.py:1177
+#: data_importer.py:730 views.py:1200
msgid "No data provided"
msgstr "Aucune donnée fournie"
@@ -272,7 +272,7 @@ msgstr ""
"L'élément {} avec les valeurs {} n'existe pas dans la base de données. Créez-"
"le d'abord ou corrigez votre fichier source."
-#: data_importer.py:1236 views.py:1255 views.py:1265
+#: data_importer.py:1236 views.py:1278 views.py:1288
msgid "Not imported"
msgstr "Non importé"
@@ -339,7 +339,7 @@ msgstr "\"%(value)s\" n'est pas dans %(values)s"
msgid "Enter a valid name consisting of letters, spaces and hyphens."
msgstr "Entrez un nom correct composé de lettres, espaces et tirets."
-#: forms.py:96 forms_common.py:808 views.py:1968
+#: forms.py:96 forms_common.py:808 views.py:2017
msgid "Confirm"
msgstr "Confirmer"
@@ -347,36 +347,44 @@ msgstr "Confirmer"
msgid "Are you sure you want to delete?"
msgstr "Êtes-vous sûr de vouloir supprimer ?"
-#: forms.py:379
+#: forms.py:410
msgid "There are identical items."
msgstr "Il y a des éléments identiques."
-#: forms.py:535
+#: forms.py:566
msgid "Last modified by"
msgstr "Modifié en dernier par"
-#: forms.py:541
+#: forms.py:572
msgid "Modified since"
msgstr "Modifié depuis"
-#: forms.py:565 forms.py:566
+#: forms.py:596 forms.py:597
msgid "Closing date"
msgstr "Date de clôture"
-#: forms.py:578 forms_common.py:1272
+#: forms.py:609 forms_common.py:1272
msgid "You should select an item."
msgstr "Vous devez sélectionner un élément."
-#: forms.py:579
+#: forms.py:610
msgid "Add a new item"
msgstr "Ajouter un nouvel élément"
-#: forms.py:769 models.py:2434
+#: forms.py:757
+msgid " - append to existing"
+msgstr " - ajouter à l'existant"
+
+#: forms.py:760
+msgid " - replace"
+msgstr " - remplacer"
+
+#: forms.py:803 models.py:2457
msgid "Template"
msgstr "Patron"
#: forms_common.py:54 forms_common.py:72 forms_common.py:317
-#: forms_common.py:556 models.py:2568 models.py:4020
+#: forms_common.py:556 models.py:2591 models.py:4093
#: templates/blocks/JQueryAdvancedTown.html:19
msgid "Town"
msgstr "Commune"
@@ -398,8 +406,8 @@ msgstr ""
"<p class='example'>Par exemple tapez « saint denis 93 » pour obtenir la "
"commune Saint-Denis dans le département français de Seine-Saint-Denis.</p>"
-#: forms_common.py:81 forms_common.py:1293 ishtar_menu.py:48 models.py:2952
-#: models.py:3204 models.py:3332 models.py:3495
+#: forms_common.py:81 forms_common.py:1293 ishtar_menu.py:48 models.py:2976
+#: models.py:3228 models.py:3357 models.py:3561
#: templates/ishtar/sheet_person.html:4
msgid "Person"
msgstr "Personne"
@@ -455,17 +463,17 @@ msgid "all users"
msgstr "tous les utilisateurs"
#: forms_common.py:305 forms_common.py:475 forms_common.py:609
-#: ishtar_menu.py:76 models.py:2773 models.py:2890 models.py:3292
+#: ishtar_menu.py:76 models.py:2796 models.py:2914 models.py:3317
#: templates/ishtar/sheet_organization.html:4
msgid "Organization"
msgstr "Organisation"
#: forms_common.py:308 forms_common.py:351 forms_common.py:470
#: forms_common.py:526 forms_common.py:604 forms_common.py:790
-#: forms_common.py:823 models.py:1056 models.py:1080 models.py:1879
-#: models.py:2079 models.py:2430 models.py:2765 models.py:2936 models.py:3192
-#: models.py:3999 models.py:4262 models_imports.py:98 models_imports.py:123
-#: models_imports.py:445 models_imports.py:537 models_imports.py:827
+#: forms_common.py:823 models.py:1078 models.py:1102 models.py:1897
+#: models.py:2097 models.py:2453 models.py:2788 models.py:2960 models.py:3216
+#: models.py:4072 models.py:4337 models_imports.py:98 models_imports.py:123
+#: models_imports.py:445 models_imports.py:537 models_imports.py:828
#: templates/ishtar/import_step_by_step.html:102
#: templates/ishtar/import_step_by_step.html:270
#: templates/ishtar/import_table.html:27
@@ -473,40 +481,40 @@ msgstr "Organisation"
msgid "Name"
msgstr "Nom"
-#: forms_common.py:309 models.py:2721 models_imports.py:630
+#: forms_common.py:309 models.py:2744 models_imports.py:630
#: models_imports.py:631
msgid "Organization type"
msgstr "Type d'organisation"
-#: forms_common.py:311 forms_common.py:550 models.py:2563
+#: forms_common.py:311 forms_common.py:550 models.py:2586
#: templates/ishtar/blocks/sheet_address_section.html:4
msgid "Address"
msgstr "Adresse"
-#: forms_common.py:313 forms_common.py:553 models.py:2564
+#: forms_common.py:313 forms_common.py:553 models.py:2587
msgid "Address complement"
msgstr "Complément d'adresse"
-#: forms_common.py:315 forms_common.py:554 models.py:2566
+#: forms_common.py:315 forms_common.py:554 models.py:2589
msgid "Postal code"
msgstr "Code postal"
-#: forms_common.py:318 forms_common.py:557 models.py:2569
+#: forms_common.py:318 forms_common.py:557 models.py:2592
msgid "Country"
msgstr "Pays"
#: forms_common.py:320 forms_common.py:472 forms_common.py:530
-#: forms_common.py:606 forms_common.py:731 models.py:2596
+#: forms_common.py:606 forms_common.py:731 models.py:2619
msgid "Email"
msgstr "Courriel"
-#: forms_common.py:321 forms_common.py:533 models.py:2581
+#: forms_common.py:321 forms_common.py:533 models.py:2604
#: templates/ishtar/sheet_person.html:27
#: templates/ishtar/wizard/wizard_person.html:33
msgid "Phone"
msgstr "Téléphone"
-#: forms_common.py:322 forms_common.py:542 models.py:2593
+#: forms_common.py:322 forms_common.py:542 models.py:2616
#: templates/ishtar/sheet_person.html:45
#: templates/ishtar/wizard/wizard_person.html:54
msgid "Mobile phone"
@@ -518,8 +526,8 @@ msgid "Full text search"
msgstr "Recherche en texte intégral"
#: forms_common.py:352 forms_common.py:473 forms_common.py:607
-#: forms_common.py:788 models.py:1089 models.py:2767 models.py:3738
-#: models_imports.py:680 templates/ishtar/blocks/window_image_detail.html:24
+#: forms_common.py:788 models.py:1111 models.py:2790 models.py:3804
+#: models_imports.py:681 templates/ishtar/blocks/window_image_detail.html:24
#: templates/ishtar/blocks/window_tables/documents.html:8
#: templates/ishtar/import_table.html:28
#: templates/ishtar/sheet_organization.html:25
@@ -542,7 +550,7 @@ msgstr "Fusionner tous les éléments dans"
msgid "Organization to merge"
msgstr "Organisation à fusionner"
-#: forms_common.py:471 forms_common.py:524 forms_common.py:605 models.py:2934
+#: forms_common.py:471 forms_common.py:524 forms_common.py:605 models.py:2958
#: templates/ishtar/sheet_organization.html:24
msgid "Surname"
msgstr "Prénom"
@@ -559,25 +567,25 @@ msgstr "Personne à fusionner"
msgid "Identity"
msgstr "Identité"
-#: forms_common.py:521 forms_common.py:1095 forms_common.py:1217 models.py:2928
-#: models.py:2930 models.py:3729 models_imports.py:632
+#: forms_common.py:521 forms_common.py:1095 forms_common.py:1217 models.py:2952
+#: models.py:2954 models.py:3795 models_imports.py:633
#: templates/ishtar/blocks/window_tables/documents.html:7
msgid "Title"
msgstr "Titre"
-#: forms_common.py:522 models.py:2932
+#: forms_common.py:522 models.py:2956
msgid "Salutation"
msgstr "Formule d'appel"
-#: forms_common.py:528 models.py:2938
+#: forms_common.py:528 models.py:2962
msgid "Raw name"
msgstr "Nom brut"
-#: forms_common.py:531 models.py:2582
+#: forms_common.py:531 models.py:2605
msgid "Phone description"
msgstr "Type de téléphone"
-#: forms_common.py:534 models.py:2584 models.py:2586
+#: forms_common.py:534 models.py:2607 models.py:2609
msgid "Phone description 2"
msgstr "Type de téléphone 2"
@@ -585,11 +593,11 @@ msgstr "Type de téléphone 2"
msgid "Phone 2"
msgstr "Téléphone 2"
-#: forms_common.py:538 models.py:2590
+#: forms_common.py:538 models.py:2613
msgid "Phone description 3"
msgstr "Type de téléphone 3"
-#: forms_common.py:540 models.py:2588
+#: forms_common.py:540 models.py:2611
msgid "Phone 3"
msgstr "Téléphone 3"
@@ -597,23 +605,23 @@ msgstr "Téléphone 3"
msgid "Current organization"
msgstr "Organisation actuelle"
-#: forms_common.py:559 models.py:2571
+#: forms_common.py:559 models.py:2594
msgid "Other address: address"
msgstr "Autre adresse : adresse"
-#: forms_common.py:562 models.py:2574
+#: forms_common.py:562 models.py:2597
msgid "Other address: address complement"
msgstr "Autre adresse : complément d'adresse"
-#: forms_common.py:564 models.py:2575
+#: forms_common.py:564 models.py:2598
msgid "Other address: postal code"
msgstr "Autre adresse : code postal"
-#: forms_common.py:566 models.py:2577
+#: forms_common.py:566 models.py:2600
msgid "Other address: town"
msgstr "Autre adresse : ville"
-#: forms_common.py:568 models.py:2579
+#: forms_common.py:568 models.py:2602
msgid "Other address: country"
msgstr "Autre adresse : pays"
@@ -621,7 +629,7 @@ msgstr "Autre adresse : pays"
msgid "Already has an account"
msgstr "A déjà un compte"
-#: forms_common.py:603 models.py:3293
+#: forms_common.py:603 models.py:3318
msgid "Username"
msgstr "Nom d'utilisateur"
@@ -629,7 +637,8 @@ msgstr "Nom d'utilisateur"
msgid "Account search"
msgstr "Rechercher un compte"
-#: forms_common.py:669 forms_common.py:709 forms_common.py:713 models.py:2829
+#: forms_common.py:669 forms_common.py:709 forms_common.py:713 models.py:2853
+#: models_imports.py:632
msgid "Person type"
msgstr "Type de personne"
@@ -637,7 +646,7 @@ msgstr "Type de personne"
msgid "Account"
msgstr "Compte"
-#: forms_common.py:734 wizards.py:1639
+#: forms_common.py:734 wizards.py:1651
msgid "New password"
msgstr "Nouveau mot de passe"
@@ -657,7 +666,7 @@ msgstr "Vous devez fournir un mot de passe correct."
msgid "This username already exists."
msgstr "Ce nom d'utilisateur existe déjà."
-#: forms_common.py:789 models.py:3195 models.py:4148
+#: forms_common.py:789 models.py:3219 models.py:4221
msgid "Areas"
msgstr "Zones"
@@ -665,11 +674,11 @@ msgstr "Zones"
msgid "Send the new password by email?"
msgstr "Envoyer le nouveau mot de passe par courriel ?"
-#: forms_common.py:821 models.py:3197 views.py:968
+#: forms_common.py:821 models.py:3221 views.py:991
msgid "Current profile"
msgstr "Profil actuel"
-#: forms_common.py:824 models.py:3175 models.py:3194
+#: forms_common.py:824 models.py:3199 models.py:3218
msgid "Profile type"
msgstr "Type de profil"
@@ -698,8 +707,8 @@ msgstr "Un profil avec un nom identique existe"
msgid " (duplicate)"
msgstr "(copie)"
-#: forms_common.py:932 forms_common.py:946 forms_common.py:947 models.py:4021
-#: models.py:4136
+#: forms_common.py:932 forms_common.py:946 forms_common.py:947 models.py:4094
+#: models.py:4209
msgid "Towns"
msgstr "Communes"
@@ -728,19 +737,19 @@ msgstr "Documentation"
msgid "Document - General"
msgstr "Document - Général"
-#: forms_common.py:1098 forms_common.py:1218 models.py:3543
-#: models_imports.py:633
+#: forms_common.py:1098 forms_common.py:1218 models.py:3609
+#: models_imports.py:634
msgid "Source type"
msgstr "Type de document"
#: forms_common.py:1101 forms_common.py:1152 forms_common.py:1333
-#: forms_common.py:1334 models.py:3504 models.py:3612 models.py:3748
+#: forms_common.py:1334 models.py:3570 models.py:3678 models.py:3814
#: templates/ishtar/blocks/window_image_detail.html:9
#: templates/ishtar/blocks/window_tables/documents.html:9
msgid "Authors"
msgstr "Auteurs"
-#: forms_common.py:1105 models.py:3754
+#: forms_common.py:1105 models.py:3820
msgid "Numerical ressource (web address)"
msgstr "Ressource numérique (adresse web)"
@@ -753,7 +762,7 @@ msgctxt "Not directory"
msgid "File"
msgstr "Fichier"
-#: forms_common.py:1113 forms_common.py:1219 models.py:4138
+#: forms_common.py:1113 forms_common.py:1219 models.py:4211
msgid "Reference"
msgstr "Référence"
@@ -761,38 +770,38 @@ msgstr "Référence"
msgid "Internal reference"
msgstr "Référence interne"
-#: forms_common.py:1118 models.py:3756
+#: forms_common.py:1118 models.py:3822
#: templates/ishtar/blocks/window_image_detail.html:150
msgid "Receipt date"
msgstr "Date de réception"
-#: forms_common.py:1120 models.py:3758 models_imports.py:859
+#: forms_common.py:1120 models.py:3824 models_imports.py:860
#: templates/ishtar/blocks/window_image_detail.html:54
msgid "Creation date"
msgstr "Date de création"
-#: forms_common.py:1123 models.py:3761
+#: forms_common.py:1123 models.py:3827
#: templates/ishtar/blocks/window_image_detail.html:160
msgid "Receipt date in documentation"
msgstr "Date de réception en documentation"
-#: forms_common.py:1125 forms_common.py:1222 models.py:473 models.py:2942
-#: models.py:3421 models.py:3764 models_imports.py:483
+#: forms_common.py:1125 forms_common.py:1222 models.py:496 models.py:2966
+#: models.py:3446 models.py:3830 models_imports.py:483
#: templates/ishtar/blocks/window_image_detail.html:170
msgid "Comment"
msgstr "Commentaire"
-#: forms_common.py:1127 forms_common.py:1221 models.py:1884 models.py:3763
+#: forms_common.py:1127 forms_common.py:1221 models.py:1902 models.py:3829
#: models_imports.py:125 models_imports.py:372 models_imports.py:446
msgid "Description"
msgstr "Description"
-#: forms_common.py:1130 models.py:3765
+#: forms_common.py:1130 models.py:3831
#: templates/ishtar/blocks/window_image_detail.html:182
msgid "Additional information"
msgstr "Information supplémentaire"
-#: forms_common.py:1132 forms_common.py:1225 models.py:3767
+#: forms_common.py:1132 forms_common.py:1225 models.py:3833
#: templates/ishtar/blocks/window_image_detail.html:108
msgid "Has a duplicate"
msgstr "Existe en doublon"
@@ -821,15 +830,15 @@ msgstr "Éléments reliés"
#: forms_common.py:1173
msgid "You should at least fill one of this field: title, url, image or file."
msgstr ""
-"Vous devez au minimum remplir un de ces champs : titres, url, image ou "
-"fichier"
+"Vous devez au minimum remplir un de ces champs : titre, url, image ou "
+"fichier."
#: forms_common.py:1179
-msgid "A document have to attached at least to one item"
-msgstr "Un document doit être rattaché au minimum à un élément"
+msgid "A document has to be attached at least to one item"
+msgstr "Un document doit être attaché au moins à un élément"
#: forms_common.py:1214 forms_common.py:1286 forms_common.py:1321
-#: models.py:3503 templates/ishtar/wizard/wizard_person_deletion.html:139
+#: models.py:3569 templates/ishtar/wizard/wizard_person_deletion.html:139
msgid "Author"
msgstr "Auteur"
@@ -857,7 +866,7 @@ msgstr "Recherche document"
msgid "Would you like to delete this documentation?"
msgstr "Voulez-vous supprimer ce document ?"
-#: forms_common.py:1294 models.py:3468 models.py:3497 models_imports.py:634
+#: forms_common.py:1294 models.py:3534 models.py:3563 models_imports.py:635
msgid "Author type"
msgstr "Type d'auteur"
@@ -869,11 +878,11 @@ msgstr "Sélection d'auteur"
msgid "There are identical authors."
msgstr "Il y a des auteurs identiques."
-#: forms_common.py:1339 models.py:1683
+#: forms_common.py:1339 models.py:1700
msgid "Query"
msgstr "Requête"
-#: forms_common.py:1344 models.py:1687
+#: forms_common.py:1344 models.py:1704
msgid "Is an alert"
msgstr "Est une alerte"
@@ -913,7 +922,7 @@ msgstr "Ajout/modification"
msgid "Deletion"
msgstr "Suppression"
-#: ishtar_menu.py:40 models.py:2209 views.py:992
+#: ishtar_menu.py:40 models.py:2231 views.py:1015
msgid "Global variables"
msgstr "Variables globales"
@@ -933,7 +942,7 @@ msgid "Creation"
msgstr "Ajout"
#: ishtar_menu.py:59 ishtar_menu.py:89 ishtar_menu.py:139
-#: templates/ishtar/forms/qa_base.html:29
+#: templates/ishtar/forms/qa_base.html:28
#: templates/ishtar/forms/qa_form.html:16
msgid "Modification"
msgstr "Modification"
@@ -946,19 +955,19 @@ msgstr "Fusion automatique"
msgid "Manual merge"
msgstr "Fusion manuelle"
-#: ishtar_menu.py:110 models_imports.py:882
+#: ishtar_menu.py:110 models_imports.py:883
msgid "Imports"
msgstr "Imports"
-#: ishtar_menu.py:113 views.py:1000
+#: ishtar_menu.py:113 views.py:1023
msgid "New import"
msgstr "Nouvel import"
-#: ishtar_menu.py:117 views.py:1019
+#: ishtar_menu.py:117 views.py:1042
msgid "Current imports"
msgstr "Imports en cours"
-#: ishtar_menu.py:121 views.py:1468
+#: ishtar_menu.py:121 views.py:1491
msgid "Old imports"
msgstr "Anciens imports"
@@ -970,24 +979,24 @@ msgstr "Documentation / Images"
msgid "Not a valid item."
msgstr "Élément invalide."
-#: models.py:211
+#: models.py:212
msgid "A selected item is not a valid item."
msgstr "Un élément sélectionné n'est pas valide."
-#: models.py:222
+#: models.py:224
msgid "This item already exists."
msgstr "Cet élément existe déjà."
-#: models.py:465 models.py:1682 models.py:2191 models.py:2528 models.py:2544
-#: models.py:3420 models_imports.py:368
+#: models.py:488 models.py:1699 models.py:2213 models.py:2551 models.py:2567
+#: models.py:3445 models_imports.py:368
msgid "Label"
msgstr "Dénomination"
-#: models.py:467
+#: models.py:490
msgid "Textual ID"
msgstr "Identifiant textuel"
-#: models.py:470
+#: models.py:493
msgid ""
"The slug is the standardized version of the name. It contains only lowercase "
"letters, numbers and hyphens. Each slug must be unique."
@@ -996,12 +1005,12 @@ msgstr ""
"lettres en minuscule, des nombres et des tirets (-). Chaque \"slug\" doit "
"être unique dans la typologie."
-#: models.py:474 models.py:2081 models.py:2437 models.py:3425
+#: models.py:497 models.py:2099 models.py:2460 models.py:3450
#: models_imports.py:139 models_imports.py:542
msgid "Available"
msgstr "Disponible"
-#: models.py:898 models.py:1083 models_imports.py:563
+#: models.py:920 models.py:1105 models_imports.py:563
#: templates/ishtar/formset_import_match.html:21
#: templates/ishtar/import_step_by_step.html:171
#: templates/ishtar/import_step_by_step.html:199
@@ -1010,56 +1019,56 @@ msgstr "Disponible"
msgid "Key"
msgstr "Clé"
-#: models.py:904
+#: models.py:926
msgid "Specific key to an import"
msgstr "Clé spécifique à un import"
-#: models.py:1043
+#: models.py:1065
msgid "Generated relation image (SVG)"
msgstr "Image des relations (SVG généré)"
-#: models.py:1057 models.py:1091 models.py:1604 models.py:2193 models.py:3465
-#: models.py:4165 models.py:4247
+#: models.py:1079 models.py:1113 models.py:1621 models.py:2215 models.py:3531
+#: models.py:4238 models.py:4320
msgid "Order"
msgstr "Ordre"
-#: models.py:1060
+#: models.py:1082
msgid "Json data - Menu"
msgstr "Données JSON - Menu"
-#: models.py:1061
+#: models.py:1083
msgid "Json data - Menus"
msgstr "Données JSON - Menus"
-#: models.py:1069
+#: models.py:1091
msgid "Text"
msgstr "Texte"
-#: models.py:1070
+#: models.py:1092
msgid "Long text"
msgstr "Texte long"
-#: models.py:1071 models_imports.py:676
+#: models.py:1093 models_imports.py:677
msgid "Integer"
msgstr "Entier"
-#: models.py:1072
+#: models.py:1094
msgid "Boolean"
msgstr "Booléen"
-#: models.py:1073 models_imports.py:677
+#: models.py:1095 models_imports.py:678
msgid "Float"
msgstr "Nombre à virgule"
-#: models.py:1074 models_imports.py:679
+#: models.py:1096 models_imports.py:680
msgid "Date"
msgstr "Date"
-#: models.py:1075
+#: models.py:1097
msgid "Choices"
msgstr "Choix"
-#: models.py:1084
+#: models.py:1106
msgid ""
"Value of the key in the JSON schema. For hierarchical key use \"__\" to "
"explain it. For instance for the key 'my_subkey' with data such as {'my_key':"
@@ -1070,200 +1079,200 @@ msgstr ""
"{'ma_clef': {'ma_sousclef': 'valeur'}}, sa valeur sera atteinte avec : "
"ma_clef__ma_sousclef."
-#: models.py:1088
+#: models.py:1110
msgid "Display"
msgstr "Afficher"
-#: models.py:1092
+#: models.py:1114
msgid "Use in search indexes"
msgstr "Utiliser dans les index de recherche"
-#: models.py:1099
+#: models.py:1121
msgid "Json data - Field"
msgstr "Donnée JSON - Champ"
-#: models.py:1100
+#: models.py:1122
msgid "Json data - Fields"
msgstr "Donnée JSON - Champs"
-#: models.py:1111
+#: models.py:1133
msgid "Content types of the field and of the menu do not match"
msgstr "Les types de contenu du champ et du menu ne correspondent pas"
-#: models.py:1171
+#: models.py:1193
msgid "Search vector"
msgstr "Vecteur de recherche"
-#: models.py:1172
+#: models.py:1194
msgid "Auto filled at save"
msgstr "Auto-rempli à la sauvegarde"
-#: models.py:1392
+#: models.py:1409
msgid "Add document/image"
msgstr "Ajouter un document / une image"
-#: models.py:1394
+#: models.py:1411
msgid "doc./image"
msgstr "doc./image"
-#: models.py:1413
+#: models.py:1430
msgid "Last editor"
msgstr "Dernier éditeur"
-#: models.py:1416
+#: models.py:1433
msgid "Creator"
msgstr "Créateur"
-#: models.py:1597
+#: models.py:1614
msgid "Above"
msgstr "Au-dessus"
-#: models.py:1598
+#: models.py:1615
msgid "Bellow"
msgstr "En dessous"
-#: models.py:1599
+#: models.py:1616
msgid "Equal"
msgstr "Égal"
-#: models.py:1605
+#: models.py:1622
msgid "Symmetrical"
msgstr "Symétrique"
-#: models.py:1606
+#: models.py:1623
msgid "Tiny label"
msgstr "Dénomination courte"
-#: models.py:1609
+#: models.py:1626
msgid "Inverse relation"
msgstr "Relation inverse"
-#: models.py:1612
+#: models.py:1629
msgid "Logical relation"
msgstr "Relation logique"
-#: models.py:1622
+#: models.py:1639
msgid "Cannot have symmetrical and an inverse_relation"
msgstr "Ne peut pas être symétrique et avoir une relation inverse"
-#: models.py:1685
+#: models.py:1702
msgid "Content type"
msgstr "Type de contenu"
-#: models.py:1690
+#: models.py:1707
msgid "Search query"
msgstr "Requête de recherche"
-#: models.py:1691
+#: models.py:1708
msgid "Search queries"
msgstr "Requêtes de recherche"
-#: models.py:1855
+#: models.py:1873
msgid "Euro"
msgstr "Euro"
-#: models.py:1856
+#: models.py:1874
msgid "US dollar"
msgstr "Dollar US"
-#: models.py:1857 views.py:742 views.py:803
+#: models.py:1875 views.py:765 views.py:826
msgid "Operations"
msgstr "Opérations"
-#: models.py:1858 views.py:744 views.py:807
+#: models.py:1876 views.py:767 views.py:830
msgid "Context records"
msgstr "Unités d'Enregistrement"
-#: models.py:1859
+#: models.py:1877
msgid "Site"
msgstr "Site"
-#: models.py:1859
+#: models.py:1877
msgid "Archaeological entity"
msgstr "Entité (EA)"
-#: models.py:1863
+#: models.py:1881
msgid "Site search"
msgstr "Rechercher un site"
-#: models.py:1864
+#: models.py:1882
msgid "New site"
msgstr "Ajouter un site"
-#: models.py:1865
+#: models.py:1883
msgid "Site modification"
msgstr "Modifier un site"
-#: models.py:1866
+#: models.py:1884
msgid "Site deletion"
msgstr "Supprimer un site"
-#: models.py:1869
+#: models.py:1887
msgid "Archaeological entity search"
msgstr "Rechercher une entité archéologique"
-#: models.py:1870
+#: models.py:1888
msgid "New archaeological entity"
msgstr "Nouvelle entité archéologique"
-#: models.py:1871
+#: models.py:1889
msgid "Archaeological entity modification"
msgstr "Modifier une entité archéologique"
-#: models.py:1872
+#: models.py:1890
msgid "Archaeological entity deletion"
msgstr "Supprimer une entité archéologique"
-#: models.py:1880 models.py:2431 models_imports.py:124
+#: models.py:1898 models.py:2454 models_imports.py:124
msgid "Slug"
msgstr "Identifiant texte"
-#: models.py:1881
+#: models.py:1899
msgid "Current active"
msgstr "Actuellement utilisé"
-#: models.py:1883
+#: models.py:1901
msgid "Activate experimental feature"
msgstr "Activer les fonctionnalités expérimentales"
-#: models.py:1886
+#: models.py:1904
msgid "Alternate configuration"
msgstr "Configuration alternative"
-#: models.py:1888
+#: models.py:1906
msgid "Choose an alternate configuration for label, index management"
msgstr ""
-"Choisir une configuration alternative pour les libellés, gestion des indexes"
+"Choisir une configuration alternative pour les libellés, gestion des index"
-#: models.py:1892
+#: models.py:1910
msgid "Files module"
msgstr "Module Dossiers"
-#: models.py:1894
+#: models.py:1912
msgid "Archaeological site module"
msgstr "Module Site archéologique"
-#: models.py:1896
+#: models.py:1914
msgid "Archaeological site type"
msgstr "Type de site archéologique"
-#: models.py:1900
+#: models.py:1918
msgid "Context records module"
msgstr "Module Unités d'Enregistrement"
-#: models.py:1902
+#: models.py:1920
msgid "Finds module"
msgstr "Module Mobilier"
-#: models.py:1903
+#: models.py:1921
msgid "Need context records module"
msgstr "Nécessite le module Unités d'Enregistrement"
-#: models.py:1905
+#: models.py:1923
msgid "Find index is based on"
msgstr "Index mobilier basé sur"
-#: models.py:1907
+#: models.py:1925
msgid ""
"To prevent irrelevant indexes, change this parameter only if there is no "
"find in the database"
@@ -1271,35 +1280,35 @@ msgstr ""
"Pour éviter des index non pertinents, ne changer ce paramètre que s'il n'y a "
"pas encore de mobilier dans cette base de données"
-#: models.py:1910
+#: models.py:1928
msgid "Warehouses module"
msgstr "Module Lieu de conservation"
-#: models.py:1911
+#: models.py:1929
msgid "Need finds module"
msgstr "Nécessite le module mobilier"
-#: models.py:1912
+#: models.py:1930
msgid "Preservation module"
msgstr "Module de conservation"
-#: models.py:1914
+#: models.py:1932
msgid "Mapping module"
msgstr "Module cartographique"
-#: models.py:1915
+#: models.py:1933
msgid "Underwater module"
msgstr "Module sous-marin / subaquatique"
-#: models.py:1917
+#: models.py:1935
msgid "Parcel are mandatory for context records"
msgstr "Parcelles cadastrales obligatoires pour les Unités d'Enregistrement"
-#: models.py:1919
+#: models.py:1937
msgid "Home page"
msgstr "Page d'accueil"
-#: models.py:1920
+#: models.py:1938
#, python-brace-format
msgid ""
"Homepage of Ishtar - if not defined a default homepage will appear. Use the "
@@ -1309,23 +1318,23 @@ msgstr ""
"défaut apparaît. Utiliser la syntaxe Markdown. {random_image} peut être "
"utilisé pour afficher une image au hasard."
-#: models.py:1924
+#: models.py:1942
msgid "Main operation code prefix"
msgstr "Préfixe principal pour le code opération"
-#: models.py:1928
+#: models.py:1946
msgid "Default operation code prefix"
msgstr "Préfixe par défaut pour le code opération"
-#: models.py:1932
+#: models.py:1950
msgid "Operation region code"
msgstr "Code région des opérations"
-#: models.py:1936
+#: models.py:1954
msgid "File external id"
msgstr "Identifiant de fichier"
-#: models.py:1938
+#: models.py:1956
msgid ""
"Formula to manage file external ID. Change this with care. With incorrect "
"formula, the application might be unusable and import of external data can "
@@ -1335,11 +1344,11 @@ msgstr ""
" Une formule incorrecte peut rendre l'application inutilisable et l'import "
"de données externes peut alors être destructif."
-#: models.py:1943
+#: models.py:1961
msgid "Parcel external id"
msgstr "Identifiant de parcelle"
-#: models.py:1946
+#: models.py:1964
msgid ""
"Formula to manage parcel external ID. Change this with care. With incorrect "
"formula, the application might be unusable and import of external data can "
@@ -1349,11 +1358,11 @@ msgstr ""
"précaution. Une formule incorrecte peut rendre l'application inutilisable et "
"l'import de données externes peut alors être destructif."
-#: models.py:1951
+#: models.py:1969
msgid "Context record external id"
msgstr "Identifiant d'unité d'enregistrement"
-#: models.py:1953
+#: models.py:1971
msgid ""
"Formula to manage context record external ID. Change this with care. With "
"incorrect formula, the application might be unusable and import of external "
@@ -1363,11 +1372,11 @@ msgstr ""
"avec précaution. Une formule incorrecte peut rendre l'application "
"inutilisable et l'import de données externes peut alors être destructif."
-#: models.py:1958
+#: models.py:1976
msgid "Base find external id"
msgstr "Identifiant de mobilier d'origine"
-#: models.py:1960
+#: models.py:1978
msgid ""
"Formula to manage base find external ID. Change this with care. With "
"incorrect formula, the application might be unusable and import of external "
@@ -1377,11 +1386,11 @@ msgstr ""
"précaution. Une formule incorrecte peut rendre l'application inutilisable et "
"l'import de données externes peut alors être destructif."
-#: models.py:1965
+#: models.py:1983
msgid "Find external id"
msgstr "Identifiant de mobilier"
-#: models.py:1967
+#: models.py:1985
msgid ""
"Formula to manage find external ID. Change this with care. With incorrect "
"formula, the application might be unusable and import of external data can "
@@ -1391,11 +1400,11 @@ msgstr ""
" Une formule incorrecte peut rendre l'application inutilisable et l'import "
"de données externes peut alors être destructif."
-#: models.py:1972
+#: models.py:1990
msgid "Container external id"
msgstr "ID du contenant"
-#: models.py:1974
+#: models.py:1992
msgid ""
"Formula to manage container external ID. Change this with care. With "
"incorrect formula, the application might be unusable and import of external "
@@ -1405,11 +1414,11 @@ msgstr ""
"précaution. Une formule incorrecte peut rendre l'application inutilisable et "
"l'import de données externes peut alors être destructif."
-#: models.py:1979
+#: models.py:1997
msgid "Warehouse external id"
msgstr "Identifiant du lieu de conservation"
-#: models.py:1981
+#: models.py:1999
msgid ""
"Formula to manage warehouse external ID. Change this with care. With "
"incorrect formula, the application might be unusable and import of external "
@@ -1419,11 +1428,11 @@ msgstr ""
"avec précaution. Une formule incorrecte peut rendre l'application "
"inutilisable et l'import de données externes peut alors être destructif."
-#: models.py:1986
+#: models.py:2004
msgid "Raw name for person"
msgstr "Nom brut pour une personne"
-#: models.py:1988
+#: models.py:2006
msgid ""
"Formula to manage person raw_name. Change this with care. With incorrect "
"formula, the application might be unusable and import of external data can "
@@ -1433,27 +1442,27 @@ msgstr ""
"Une formule incorrecte peut rendre l'application inutilisable et l'import de "
"données externes peut alors être destructif."
-#: models.py:1992
+#: models.py:2010
msgid "Use auto index for finds"
-msgstr "Utiliser les indexes automatique pour le mobilier"
+msgstr "Utiliser les index automatiques pour le mobilier"
-#: models.py:1994
+#: models.py:2012
msgid "Currency"
msgstr "Devise"
-#: models.py:1998
+#: models.py:2016
msgid "Ishtar site profile"
msgstr "Profil d'instance Ishtar"
-#: models.py:1999
+#: models.py:2017
msgid "Ishtar site profiles"
msgstr "Profils d'instance Ishtar"
-#: models.py:2083
+#: models.py:2101
msgid "Enable this form"
msgstr "Activer ce formulaire"
-#: models.py:2084
+#: models.py:2102
msgid ""
"Disable with caution: disabling a form with mandatory fields may lead to "
"database errors."
@@ -1461,11 +1470,11 @@ msgstr ""
"Désactiver avec précaution : désactiver un formulaire avec des champs "
"obligatoires peut entraîner des erreurs dans la base de données."
-#: models.py:2087
+#: models.py:2105
msgid "Apply to all"
msgstr "S'applique à tous"
-#: models.py:2088
+#: models.py:2106
msgid ""
"Apply this form to all users. If set to True, selecting user and user type "
"is useless."
@@ -1473,48 +1482,48 @@ msgstr ""
"Activer ce formulaire pour tous les utilisateurs. Si mis à Vrai, "
"sélectionner des utilisateurs ou des types d'utilisateurs est inutile."
-#: models.py:2094
+#: models.py:2112
msgid "Custom form"
msgstr "Formulaire personnalisé"
-#: models.py:2095
+#: models.py:2113
msgid "Custom forms"
msgstr "Formulaires personnalisés"
-#: models.py:2111
+#: models.py:2129
msgid "User types"
msgstr "Types d'utilisateur"
-#: models.py:2183
+#: models.py:2205
msgid "Excluded field"
msgstr "Champ exclus"
-#: models.py:2184
+#: models.py:2206
msgid "Excluded fields"
msgstr "Champs exclus"
-#: models.py:2194 templates/blocks/form_flex_snippet.html:18
+#: models.py:2216 templates/blocks/form_flex_snippet.html:18
#: templates/blocks/table_form_snippet.html:9
msgid "Help"
msgstr "Aide"
-#: models.py:2197
+#: models.py:2219
msgid "Custom form - Json data field"
msgstr "Formulaire personnalisé - Champ de donnée Json"
-#: models.py:2198
+#: models.py:2220
msgid "Custom form - Json data fields"
msgstr "Formulaire personnalisé - Champs de donnée Json"
-#: models.py:2202
+#: models.py:2224
msgid "Variable name"
msgstr "Nom de la variable"
-#: models.py:2203
+#: models.py:2225
msgid "Description of the variable"
msgstr "Description de la variable"
-#: models.py:2205 models_imports.py:564
+#: models.py:2227 models_imports.py:564
#: templates/ishtar/formset_import_match.html:22
#: templates/ishtar/import_step_by_step.html:172
#: templates/ishtar/import_step_by_step.html:200
@@ -1522,545 +1531,549 @@ msgstr "Description de la variable"
msgid "Value"
msgstr "Valeur"
-#: models.py:2208
+#: models.py:2230
msgid "Global variable"
msgstr "Variable globale"
-#: models.py:2335 models.py:2365
+#: models.py:2358 models.py:2388
msgid "Total"
msgstr "Total"
-#: models.py:2342 models.py:2529 models.py:2545
+#: models.py:2365 models.py:2552 models.py:2568
#: templates/ishtar/dashboards/dashboard_main_detail.html:211
#: templates/ishtar/dashboards/dashboard_main_detail_users.html:5
#: templates/ishtar/sheet_person.html:30
msgid "Number"
msgstr "Nombre"
-#: models.py:2429
+#: models.py:2452
msgid "Administrative Act"
msgstr "Acte administratif"
-#: models.py:2436
+#: models.py:2459
msgid "Associated object"
msgstr "Objet associé"
-#: models.py:2441
+#: models.py:2464
msgid "Document template"
msgstr "Patron de document"
-#: models.py:2442
+#: models.py:2465
msgid "Document templates"
msgstr "Patrons de document"
-#: models.py:2533 models.py:2546 models.py:4285 models_imports.py:853
+#: models.py:2556 models.py:2569 models.py:4360 models_imports.py:854
msgid "State"
msgstr "État"
-#: models.py:2551 models.py:4007 templates/blocks/JQueryAdvancedTown.html:12
+#: models.py:2574 models.py:4080 templates/blocks/JQueryAdvancedTown.html:12
msgid "Department"
msgstr "Département"
-#: models.py:2552
+#: models.py:2575
msgid "Departments"
msgstr "Départements"
-#: models.py:2592
+#: models.py:2615
msgid "Raw phone"
msgstr "Téléphone brut"
-#: models.py:2598
+#: models.py:2621
msgid "Alternative address is prefered"
msgstr "L'adresse alternative est préférée"
-#: models.py:2637
+#: models.py:2660
msgid "Tel: "
msgstr "Tél :"
-#: models.py:2641
+#: models.py:2664
msgid "Mobile: "
msgstr "Mobile :"
-#: models.py:2645
+#: models.py:2668
msgid "Email: "
msgstr "Courriel :"
-#: models.py:2650
+#: models.py:2673
msgid "Merge key"
msgstr "Clé de fusion"
-#: models.py:2722
+#: models.py:2745
msgid "Organization types"
msgstr "Types d'organisation"
-#: models.py:2749 models.py:2896 models.py:3303
+#: models.py:2772 models.py:2920 models.py:3328
msgctxt "key for text search"
msgid "name"
msgstr "nom"
-#: models.py:2753 models.py:2908 models.py:3315 models.py:3639
+#: models.py:2776 models.py:2932 models.py:3340 models.py:3705
msgctxt "key for text search"
msgid "type"
msgstr "type"
-#: models.py:2768 models.py:2947 models.py:3498 models.py:4015
+#: models.py:2791 models.py:2971 models.py:3564 models.py:4088
msgid "Cached name"
msgstr "Nom en cache"
-#: models.py:2774
+#: models.py:2797
msgid "Organizations"
msgstr "Organisations"
-#: models.py:2804
+#: models.py:2828
msgid "unknown organization"
msgstr "organisation inconnue"
-#: models.py:2830
+#: models.py:2854
msgid "Person types"
msgstr "Types de personne"
-#: models.py:2843 models_imports.py:670
+#: models.py:2867 models_imports.py:671
msgid "Title type"
msgstr "Type de titre"
-#: models.py:2844
+#: models.py:2868
msgid "Title types"
msgstr "Types de titre"
-#: models.py:2868
+#: models.py:2892
msgid "Mr"
msgstr "M."
-#: models.py:2869
+#: models.py:2893
msgid "Miss"
msgstr "Mlle"
-#: models.py:2870
+#: models.py:2894
msgid "Mr and Mrs"
msgstr "M. et Mme"
-#: models.py:2871
+#: models.py:2895
msgid "Mrs"
msgstr "Mme"
-#: models.py:2872
+#: models.py:2896
msgid "Doctor"
msgstr "Dr."
-#: models.py:2900 models.py:3307
+#: models.py:2924 models.py:3332
msgctxt "key for text search"
msgid "surname"
msgstr "prenom"
-#: models.py:2904 models.py:3311
+#: models.py:2928 models.py:3336
msgctxt "key for text search"
msgid "email"
msgstr "courriel"
-#: models.py:2912 models.py:3319
+#: models.py:2936 models.py:3344
msgctxt "key for text search"
msgid "organization"
msgstr "organisation"
-#: models.py:2916
+#: models.py:2940
msgctxt "key for text search"
msgid "has-account"
msgstr "a-un-compte"
-#: models.py:2940
+#: models.py:2964
msgid "Contact type"
msgstr "Type de contact"
-#: models.py:2943 models.py:3033
+#: models.py:2967 models.py:3057
msgid "Types"
msgstr "Types"
-#: models.py:2946
+#: models.py:2970
msgid "Is attached to"
msgstr "Est rattaché à"
-#: models.py:2953
+#: models.py:2977
msgid "Persons"
msgstr "Personnes"
-#: models.py:3171
+#: models.py:3195
msgid "Groups"
msgstr "Groupes"
-#: models.py:3176
+#: models.py:3200
msgid "Profile types"
msgstr "Types de profil"
-#: models.py:3187
+#: models.py:3211
msgid "Profile type summary"
msgstr "Résumé du type de profil"
-#: models.py:3188
+#: models.py:3212
msgid "Profile types summary"
msgstr "Résumés des types de profil"
-#: models.py:3199
+#: models.py:3223
msgid "Show field number"
msgstr "Afficher les numéros des champs"
-#: models.py:3200
+#: models.py:3224
msgid "Automatically pin"
msgstr "Épingler automatiquement"
-#: models.py:3201
+#: models.py:3225
msgid "Display pin menu"
msgstr "Montrer le menu d'épinglage"
-#: models.py:3207
+#: models.py:3231
msgid "User profile"
msgstr "Profil d'utilisateur"
-#: models.py:3208
+#: models.py:3232
msgid "User profiles"
msgstr "Profils d'utilisateurs"
-#: models.py:3243
+#: models.py:3267 models.py:3522
msgid " - duplicate"
-msgstr "- copie"
+msgstr " - copie"
-#: models.py:3299
+#: models.py:3324
msgctxt "key for text search"
msgid "username"
msgstr "nom-utilisateur"
-#: models.py:3335
+#: models.py:3360
msgid "Advanced shortcut menu"
msgstr "Menu de raccourci (avancé)"
-#: models.py:3338
+#: models.py:3363
msgid "Ishtar user"
msgstr "Utilisateur d'Ishtar"
-#: models.py:3339
+#: models.py:3364
msgid "Ishtar users"
msgstr "Utilisateurs d'Ishtar"
-#: models.py:3424
+#: models.py:3449
msgid "Owner"
msgstr "Propriétaire"
-#: models.py:3427
-msgid "Shared with"
-msgstr "Partagé avec"
+#: models.py:3452
+msgid "Shared (read) with"
+msgstr "Partagé (lecture) avec"
-#: models.py:3469
+#: models.py:3456
+msgid "Shared (read/edit) with"
+msgstr "Partagé (lecture/édition) avec"
+
+#: models.py:3535
msgid "Author types"
msgstr "Types d'auteur"
-#: models.py:3544
+#: models.py:3610
msgid "Source types"
msgstr "Types de document"
-#: models.py:3554 models_imports.py:669
+#: models.py:3620 models_imports.py:670
msgid "Support type"
msgstr "Type de support"
-#: models.py:3555
+#: models.py:3621
msgid "Support types"
msgstr "Types de support"
-#: models.py:3564
+#: models.py:3630
msgid "Format type"
msgstr "Type de format"
-#: models.py:3565
+#: models.py:3631
msgid "Format types"
msgstr "Types de format"
-#: models.py:3574
+#: models.py:3640
msgid "URL"
msgstr "URL"
-#: models.py:3577
+#: models.py:3643
msgid "License type"
msgstr "Type de licence"
-#: models.py:3578
+#: models.py:3644
msgid "License types"
msgstr "Types de licence"
-#: models.py:3631
+#: models.py:3697
msgctxt "key for text search"
msgid "author"
msgstr "auteur"
-#: models.py:3635
+#: models.py:3701
msgctxt "key for text search"
msgid "title"
msgstr "titre"
-#: models.py:3643
+#: models.py:3709
msgctxt "key for text search"
msgid "reference"
msgstr "reference"
-#: models.py:3647
+#: models.py:3713
msgctxt "key for text search"
msgid "internal-reference"
msgstr "reference-interne"
-#: models.py:3651
+#: models.py:3717
msgctxt "key for text search"
msgid "description"
msgstr "description"
-#: models.py:3655
+#: models.py:3721
msgctxt "key for text search"
msgid "comment"
msgstr "commentaire"
-#: models.py:3659
+#: models.py:3725
msgctxt "key for text search"
msgid "additional-information"
msgstr "informations-supplementaires"
-#: models.py:3663
+#: models.py:3729
msgctxt "key for text search"
msgid "has-duplicate"
msgstr "existe-en-doublon"
-#: models.py:3667 models.py:3714
+#: models.py:3733 models.py:3780
msgctxt "key for text search"
msgid "operation"
msgstr "operation"
-#: models.py:3671 models.py:3717
+#: models.py:3737 models.py:3783
msgctxt "key for text search"
msgid "context-record"
msgstr "ue"
-#: models.py:3675 models.py:3719
+#: models.py:3741 models.py:3785
msgctxt "key for text search"
msgid "find"
msgstr "mobilier"
-#: models.py:3679 models.py:3718
+#: models.py:3745 models.py:3784
msgctxt "key for text search"
msgid "file"
msgstr "dossier"
-#: models.py:3683 models.py:3720
+#: models.py:3749 models.py:3786
msgctxt "key for text search"
msgid "site"
msgstr "site"
-#: models.py:3687 models.py:3721
+#: models.py:3753 models.py:3787
msgctxt "key for text search"
msgid "warehouse"
msgstr "depot"
-#: models.py:3723
+#: models.py:3789
msgctxt "key for text search"
msgid "treatment"
msgstr "traitement"
-#: models.py:3726
+#: models.py:3792
msgctxt "key for text search"
msgid "treatment-file"
msgstr "dossier-traitement"
-#: models.py:3732
+#: models.py:3798
msgid "Index"
msgstr "Index"
-#: models.py:3734
+#: models.py:3800
msgid "External ID"
msgstr "Identifiant"
-#: models.py:3735 templates/ishtar/blocks/window_image_detail.html:34
+#: models.py:3801 templates/ishtar/blocks/window_image_detail.html:34
msgid "Ref."
msgstr "Réf."
-#: models.py:3736 templates/ishtar/blocks/window_image_detail.html:44
+#: models.py:3802 templates/ishtar/blocks/window_image_detail.html:44
msgid "Internal ref."
msgstr "Réf. interne"
-#: models.py:3740
+#: models.py:3806
msgid "License"
msgstr "Licence"
-#: models.py:3742 templates/ishtar/blocks/window_image_detail.html:78
+#: models.py:3808 templates/ishtar/blocks/window_image_detail.html:78
msgid "Support"
msgstr "Support"
-#: models.py:3744 models_imports.py:635
+#: models.py:3810 models_imports.py:636
#: templates/ishtar/blocks/window_image_detail.html:88
msgid "Format"
msgstr "Format"
-#: models.py:3746 templates/ishtar/blocks/window_image_detail.html:98
+#: models.py:3812 templates/ishtar/blocks/window_image_detail.html:98
msgid "Scale"
msgstr "Échelle"
-#: models.py:3750
+#: models.py:3816
msgid "Authors (raw)"
msgstr "Auteurs (brut)"
-#: models.py:3762 templates/ishtar/blocks/window_image_detail.html:118
+#: models.py:3828 templates/ishtar/blocks/window_image_detail.html:118
msgid "Number of items"
msgstr "Nombre d'éléments"
-#: models.py:3769
+#: models.py:3835
msgid "Symbolic links"
msgstr "Liens symboliques"
-#: models.py:3772
+#: models.py:3838
msgid "Related"
msgstr "Lié"
-#: models.py:3773
+#: models.py:3839
msgid "Cached value - do not edit"
msgstr "Valeur en cache - ne pas éditer"
-#: models.py:3776 templates/ishtar/sheet_document.html:4
+#: models.py:3842 templates/ishtar/sheet_document.html:4
msgid "Document"
msgstr "Document"
-#: models.py:3777 templates/ishtar/sheet_person.html:113
+#: models.py:3843 templates/ishtar/sheet_person.html:113
msgid "Documents"
msgstr "Documents"
-#: models.py:3781
+#: models.py:3847
msgid "Can view all Documents"
msgstr "Peut voir tous les Documents"
-#: models.py:3783
+#: models.py:3849
msgid "Can view own Document"
msgstr "Peut voir ses propres Documents"
-#: models.py:3785
+#: models.py:3851
msgid "Can add own Document"
msgstr "Peut ajouter son propre Document"
-#: models.py:3787
+#: models.py:3853
msgid "Can change own Document"
-msgstr "Peut modifier ses propres documents"
+msgstr "Peut modifier ses propres Documents"
-#: models.py:3789
+#: models.py:3855
msgid "Can delete own Document"
msgstr "Peut supprimer ses propres Documents"
-#: models.py:4000
+#: models.py:4073
msgid "Surface (m2)"
msgstr "Surface (m2)"
-#: models.py:4001
+#: models.py:4074
msgid "Localisation"
msgstr "Localisation"
-#: models.py:4009
+#: models.py:4082
msgid "Year of creation"
msgstr "Année de création"
-#: models.py:4010
+#: models.py:4083
msgid ""
"Filling this field is relevant to distinguish old towns from new towns."
msgstr ""
"Remplir ce champ est nécessaire pour distinguer les anciennes communes des "
"nouvelles communes."
-#: models.py:4142
+#: models.py:4215
msgid "Only four level of parent are managed."
msgstr "Seulement quatre niveaux de parents sont gérés."
-#: models.py:4147
+#: models.py:4220
msgid "Area"
msgstr "Zone"
-#: models.py:4166
+#: models.py:4239
msgid "Is preventive"
msgstr "Est du préventif"
-#: models.py:4167
+#: models.py:4240
msgid "Is judiciary"
msgstr "Est judiciaire"
-#: models.py:4170 models_imports.py:636
+#: models.py:4243 models_imports.py:637
msgid "Operation type"
msgstr "Type d'opération"
-#: models.py:4171
+#: models.py:4244
msgid "Operation types"
msgstr "Types d'opération"
-#: models.py:4210
+#: models.py:4283
msgid "Judiciary"
msgstr "Judiciaire"
-#: models.py:4212
+#: models.py:4285
msgid "Preventive"
msgstr "Préventif"
-#: models.py:4214
+#: models.py:4287
msgid "Research"
msgstr "Programmé"
-#: models.py:4249
+#: models.py:4322
msgid "Authority name"
msgstr "Registre"
-#: models.py:4250
+#: models.py:4323
msgid "Authority SRID"
msgstr "SRID"
-#: models.py:4253 models_imports.py:668
+#: models.py:4326 models_imports.py:669
msgid "Spatial reference system"
msgstr "Système de référence spatiale"
-#: models.py:4254
+#: models.py:4327
msgid "Spatial reference systems"
msgstr "Systèmes de référence spatiale"
-#: models.py:4261
+#: models.py:4336
msgid "Filename"
msgstr "Nom de fichier"
-#: models.py:4266
+#: models.py:4341
msgid "Administration script"
msgstr "Script d'administration"
-#: models.py:4267
+#: models.py:4342
msgid "Administration scripts"
msgstr "Scripts d'administration"
-#: models.py:4274
+#: models.py:4349
msgid "Scheduled"
msgstr "Planifié"
-#: models.py:4275
+#: models.py:4350
msgid "In progress"
msgstr "En cours"
-#: models.py:4276 models_imports.py:792
+#: models.py:4351 models_imports.py:793
msgid "Finished with errors"
msgstr "Terminé avec des erreurs"
-#: models.py:4277 models_imports.py:793
+#: models.py:4352 models_imports.py:794
msgid "Finished"
msgstr "Terminé"
-#: models.py:4290
+#: models.py:4365
msgid "Result"
msgstr "Résultat"
-#: models.py:4293
+#: models.py:4368
msgid "Administration task"
msgstr "Tâche d'administration"
-#: models.py:4294
+#: models.py:4369
msgid "Administration tasks"
msgstr "Tâches d'administration"
-#: models.py:4298
+#: models.py:4373
msgid "Unknown"
msgstr "Inconnu"
-#: models.py:4313
+#: models.py:4388
msgid ""
"ISHTAR_SCRIPT_DIR is not set in your local_settings. Contact your "
"administrator."
@@ -2068,7 +2081,7 @@ msgstr ""
"ISHTAR_SCRIPT_DIR n'est pas défini dans votre fichier local_settings. "
"Contactez l'administrateur."
-#: models.py:4322
+#: models.py:4397
msgid ""
"Your ISHTAR_SCRIPT_DIR is containing dots \"..\". As it can refer to "
"relative paths, it can be a security issue and this is not allowed. Only put "
@@ -2079,11 +2092,11 @@ msgstr ""
"problème de sécurité et cela n'est pas permis. Seul un chemin complet est "
"permis."
-#: models.py:4333
+#: models.py:4408
msgid "Your ISHTAR_SCRIPT_DIR: \"{}\" is not a valid directory."
msgstr "ISHTAR_SCRIPT_DIR: « {} » n'est pas un répertoire valable."
-#: models.py:4349
+#: models.py:4424
msgid ""
"Script \"{}\" is not available in your script directory. Check your "
"configuration."
@@ -2116,8 +2129,8 @@ msgid "Leave blank for no restrictions"
msgstr "Laissez vide pour aucune restriction"
#: models_imports.py:136
-msgid "Is template"
-msgstr "Est un patron"
+msgid "Can be exported"
+msgstr "Peut être exporté"
#: models_imports.py:137
msgid "Unicity keys (separator \";\")"
@@ -2228,11 +2241,11 @@ msgstr "Importeur - Cible"
msgid "Importer - Targets"
msgstr "Importeur - Cibles"
-#: models_imports.py:525 views_item.py:847
+#: models_imports.py:525 views_item.py:346 views_item.py:950
msgid "True"
msgstr "Oui"
-#: models_imports.py:526 views_item.py:849
+#: models_imports.py:526 views_item.py:952
msgid "False"
msgstr "Non"
@@ -2264,329 +2277,329 @@ msgstr "Importeur - Clé de rapprochement"
msgid "Importer - Targets keys"
msgstr "Importeur - Clés de rapprochement"
-#: models_imports.py:637
+#: models_imports.py:638
msgid "Period"
msgstr "Période"
-#: models_imports.py:638
+#: models_imports.py:639
msgid "Report state"
msgstr "État de rapport"
-#: models_imports.py:639
+#: models_imports.py:640
msgid "Remain type"
msgstr "Type de vestige"
-#: models_imports.py:640
+#: models_imports.py:641
msgid "Unit"
msgstr "Unité"
-#: models_imports.py:642
+#: models_imports.py:643
msgid "Activity type"
msgstr "Type d'activité"
-#: models_imports.py:644
+#: models_imports.py:645
msgid "Documentation type"
msgstr "Type de documentation"
-#: models_imports.py:645
+#: models_imports.py:646
msgid "Material"
msgstr "Matériau"
-#: models_imports.py:647
+#: models_imports.py:648
msgid "Conservatory state"
msgstr "État de conservation"
-#: models_imports.py:648
+#: models_imports.py:649
msgid "Container type"
msgstr "Type de contenant"
-#: models_imports.py:650
+#: models_imports.py:651
msgid "Warehouse division"
msgstr "Division de lieu de conservation"
-#: models_imports.py:651
+#: models_imports.py:652
msgid "Warehouse type"
msgstr "Type de lieu de conservation"
-#: models_imports.py:652
+#: models_imports.py:653
msgid "Treatment type"
msgstr "Type de traitement"
-#: models_imports.py:654
+#: models_imports.py:655
msgid "Treatment emergency type"
msgstr "Type d'urgence de traitement"
-#: models_imports.py:655
+#: models_imports.py:656
msgid "Object type"
msgstr "Type d'objet"
-#: models_imports.py:656
+#: models_imports.py:657
msgid "Integrity type"
msgstr "Type d'intégrité"
-#: models_imports.py:658
+#: models_imports.py:659
msgid "Remarkability type"
msgstr "Type de remarquabilité"
-#: models_imports.py:659
+#: models_imports.py:660
msgid "Alteration type"
msgstr "Type d'altération"
-#: models_imports.py:661
+#: models_imports.py:662
msgid "Alteration cause type"
msgstr "Type de cause d'altération"
-#: models_imports.py:662
+#: models_imports.py:663
msgid "Batch type"
msgstr "Type de lot"
-#: models_imports.py:663
+#: models_imports.py:664
msgid "Checked type"
msgstr "Type de vérification"
-#: models_imports.py:665
+#: models_imports.py:666
msgid "Identification type"
msgstr "Type d'identification"
-#: models_imports.py:667
+#: models_imports.py:668
msgid "Context record relation type"
msgstr "Type de relations entre Unités d'Enregistrement"
-#: models_imports.py:678
+#: models_imports.py:679
msgid "String"
msgstr "Chaîne de caractères"
-#: models_imports.py:681
+#: models_imports.py:682
#: templates/ishtar/dashboards/dashboard_main_detail.html:196
msgid "Year"
msgstr "Année"
-#: models_imports.py:682
+#: models_imports.py:683
msgid "INSEE code"
msgstr "Code INSEE"
-#: models_imports.py:683
+#: models_imports.py:684
msgid "String to boolean"
msgstr "Chaîne de caractères vers booléen"
-#: models_imports.py:684
+#: models_imports.py:685
msgctxt "filesystem"
msgid "File"
msgstr "Fichier"
-#: models_imports.py:685
+#: models_imports.py:686
msgid "Unknow type"
msgstr "Type inconnu"
-#: models_imports.py:702
+#: models_imports.py:703
msgid "4 digit year. e.g.: \"2015\""
msgstr "Année sur 4 chiffres. Exemple : « 2015 »"
-#: models_imports.py:703
+#: models_imports.py:704
msgid "4 digit year/month/day. e.g.: \"2015/02/04\""
msgstr "Année sur 4 chiffres/mois/jour. Exemple : « 2015/02/04 »"
-#: models_imports.py:704
+#: models_imports.py:705
msgid "Day/month/4 digit year. e.g.: \"04/02/2015\""
msgstr "Jour/mois/année sur 4 chiffres. Exemple : « 04/02/2015 »"
-#: models_imports.py:720
+#: models_imports.py:721
msgid "Options"
msgstr "Options"
-#: models_imports.py:722
+#: models_imports.py:723
msgid "Split character(s)"
msgstr "Caractère(s) de séparation"
-#: models_imports.py:727
+#: models_imports.py:728
msgid "Importer - Formater type"
msgstr "Importeur - Type de mise en forme"
-#: models_imports.py:728
+#: models_imports.py:729
msgid "Importer - Formater types"
msgstr "Importeur - Types de mise en forme"
-#: models_imports.py:784
+#: models_imports.py:785
#: templates/ishtar/dashboards/dashboard_main_detail.html:132
msgid "Created"
msgstr "Créé"
-#: models_imports.py:785
+#: models_imports.py:786
msgid "Analyse in progress"
msgstr "Analyse en cours"
-#: models_imports.py:786
+#: models_imports.py:787
msgid "Analysed"
msgstr "Analysé"
-#: models_imports.py:787
+#: models_imports.py:788
msgid "Check modified in queue"
msgstr "Vérification des modifications dans la file"
-#: models_imports.py:788
+#: models_imports.py:789
msgid "Import in queue"
msgstr "Import en file d'attente"
-#: models_imports.py:789
+#: models_imports.py:790
msgid "Check modified in progress"
msgstr "Vérification des modifications en cours"
-#: models_imports.py:790
+#: models_imports.py:791
msgid "Import in progress"
msgstr "Import en cours"
-#: models_imports.py:791
+#: models_imports.py:792
msgid "Partially imported"
msgstr "Importé partiellement"
-#: models_imports.py:794
+#: models_imports.py:795
msgid "Archived"
msgstr "Archivé"
-#: models_imports.py:830
+#: models_imports.py:831
msgid "Imported file"
msgstr "Fichier importé"
-#: models_imports.py:832
+#: models_imports.py:833
msgid "Associated images (zip file)"
msgstr "Images associées (fichier zip)"
-#: models_imports.py:836
+#: models_imports.py:837
msgid "If a group is selected, target key saved in this group will be used."
msgstr ""
"Si un groupe est sélectionné, les clés de rapprochement enregistrées dans ce "
"groupe sont utilisées."
-#: models_imports.py:839
+#: models_imports.py:840
msgid "Encoding"
msgstr "Codage"
-#: models_imports.py:842
+#: models_imports.py:843
msgid "Skip lines"
msgstr "Nombre de lignes d'entête"
-#: models_imports.py:843
+#: models_imports.py:844
msgid "Number of header lines in your file (can be 0)."
msgstr "Nombre de ligne d'entête dans votre fichier (peut être égal à zéro)"
-#: models_imports.py:844
+#: models_imports.py:845
msgid "Error file"
msgstr "Fichier erreur"
-#: models_imports.py:847
+#: models_imports.py:848
msgid "Result file"
msgstr "Fichier résultant"
-#: models_imports.py:850
+#: models_imports.py:851
msgid "Match file"
msgstr "Fichier de correspondance"
-#: models_imports.py:856
+#: models_imports.py:857
msgid "Conservative import"
msgstr "Import conservateur"
-#: models_imports.py:857
+#: models_imports.py:858
msgid "If set to true, do not overload existing values."
msgstr "Si coché, ne surchargera pas les valeurs existantes."
-#: models_imports.py:860
+#: models_imports.py:861
msgid "End date"
msgstr "Date de fin"
-#: models_imports.py:863
+#: models_imports.py:864
msgid "Remaining seconds"
msgstr "Secondes restantes"
-#: models_imports.py:865
+#: models_imports.py:866
msgid "Current line"
msgstr "Ligne actuelle"
-#: models_imports.py:867
+#: models_imports.py:868
msgid "Number of line"
msgstr "Nombre de lignes"
-#: models_imports.py:870
+#: models_imports.py:871
msgid "Imported line numbers"
msgstr "Numéros des lignes importées"
-#: models_imports.py:873
+#: models_imports.py:874
msgid "Changed have been checked"
msgstr "Les changements ont été vérifiés"
-#: models_imports.py:876
+#: models_imports.py:877
msgid "Changed line numbers"
msgstr "Numéro des lignes modifiées"
-#: models_imports.py:881
+#: models_imports.py:882
msgid "Import"
msgstr "Import"
-#: models_imports.py:970
+#: models_imports.py:971
msgid "Analyse"
msgstr "Analyser"
-#: models_imports.py:972 models_imports.py:981
+#: models_imports.py:973 models_imports.py:982
msgid "Re-analyse"
msgstr "Analyser de nouveau "
-#: models_imports.py:973
+#: models_imports.py:974
msgid "Launch import"
msgstr "Lancer l'import"
-#: models_imports.py:976
+#: models_imports.py:977
msgid "Step by step import"
msgstr "Import pas à pas"
-#: models_imports.py:977 models_imports.py:986
+#: models_imports.py:978 models_imports.py:987
msgid "Re-check for changes"
msgstr "Re-vérifier les changements"
-#: models_imports.py:979 models_imports.py:988
+#: models_imports.py:980 models_imports.py:989
msgid "Check for changes"
msgstr "Vérifier les changements"
-#: models_imports.py:982
+#: models_imports.py:983
msgid "Re-import"
msgstr "Ré-importer"
-#: models_imports.py:985
+#: models_imports.py:986
msgid "Step by step re-import"
msgstr "Ré-import pas à pas"
-#: models_imports.py:989
+#: models_imports.py:990
msgid "Archive"
msgstr "Archiver"
-#: models_imports.py:991
+#: models_imports.py:992
msgid "Unarchive"
msgstr "Désarchiver"
-#: models_imports.py:992 templates/ishtar/form_delete.html:11 views.py:1847
-#: widgets.py:371 widgets.py:403
+#: models_imports.py:993 templates/ishtar/form_delete.html:11 views.py:1896
+#: widgets.py:379 widgets.py:411
msgid "Delete"
msgstr "Supprimer"
-#: models_imports.py:1042
+#: models_imports.py:1043
msgid "Error in the CSV file."
msgstr "Erreur dans le fichier CSV."
-#: models_imports.py:1070
+#: models_imports.py:1071
msgid "Modification check {} added to the queue"
msgstr "Vérification des changements {} ajoutée à la file d'attente"
-#: models_imports.py:1140
+#: models_imports.py:1141
msgid "Import {} added to the queue"
msgstr "Import {} ajouté à la file d'attente"
-#: models_imports.py:1158
+#: models_imports.py:1159
msgid "Error on imported file: {}"
msgstr "Erreur sur le fichier d'import : {}"
-#: models_imports.py:1193
+#: models_imports.py:1194
msgid "Import {} finished with errors"
msgstr "Import {} fini avec des erreurs"
-#: models_imports.py:1202
+#: models_imports.py:1203
msgid "Import {} finished with no errors"
msgstr "Import {} fini avec aucune erreur"
@@ -2638,12 +2651,12 @@ msgid "View on site"
msgstr "Voir sur le site"
#: templates/admin/change_form.html:24 templates/admin/change_form.html:27
-#: views.py:1231 views.py:1236
+#: views.py:1254 views.py:1259
msgid "Previous"
msgstr "Précédent"
#: templates/admin/change_form.html:32 templates/admin/change_form.html:35
-#: views.py:1239 views.py:1242
+#: views.py:1262 views.py:1265
msgid "Next"
msgstr "Suivant"
@@ -2679,49 +2692,53 @@ msgid " items added."
msgstr "Éléments ajoutés."
#: templates/base.html:47
+msgid "Select only one item."
+msgstr "Sélectionnez seulement un seul élément."
+
+#: templates/base.html:48
msgid "yes"
msgstr "oui"
-#: templates/base.html:48
+#: templates/base.html:49
msgid "no"
msgstr "non"
-#: templates/base.html:49
+#: templates/base.html:50
msgid "Autorefresh start. The form is disabled."
msgstr "Rafraîchissement automatique activé. Le formulaire est désactivé."
-#: templates/base.html:50
+#: templates/base.html:51
msgid "Autorefresh end. The form is re-enabled."
msgstr "Rafraîchissement automatique désactivé. Le formulaire est ré-activé."
-#: templates/base.html:81
+#: templates/base.html:82
msgid "Current items"
msgstr "Éléments courants"
-#: templates/base.html:83 templates/ishtar/forms/qa_base.html:34
+#: templates/base.html:84 templates/ishtar/forms/qa_base.html:33
#: templates/ishtar/forms/qa_form.html:21 templates/ishtar/manage_basket.html:4
#: templates/welcome.html:11 templates/welcome.html:12
-#: templates/welcome.html:13 templates/welcome.html:14 wizards.py:423
+#: templates/welcome.html:13 templates/welcome.html:14 wizards.py:435
msgid ":"
msgstr " :"
-#: templates/base.html:96
+#: templates/base.html:97
msgid "Sheets"
msgstr "Fiches"
-#: templates/base.html:146
+#: templates/base.html:158
msgid "Processing..."
msgstr "En traitement..."
-#: templates/base.html:148
+#: templates/base.html:160
msgid "This can be long."
msgstr "Cela peut être long."
-#: templates/base.html:150
+#: templates/base.html:162
msgid "Time to take a coffee?"
msgstr "Il est peut-être temps de prendre un café ?"
-#: templates/base.html:152
+#: templates/base.html:164
msgid "Time to take another coffee?"
msgstr "Pourquoi pas un autre café ?"
@@ -2731,7 +2748,8 @@ msgid "Expand table"
msgstr "Agrandir le tableau"
#: templates/blocks/DataTables.html:53 templates/blocks/JQueryJqGrid.html:26
-#: templates/ishtar/blocks/window_nav.html:59
+#: templates/ishtar/blocks/window_nav.html:62
+#: templates/ishtar/blocks/window_nav.html:68
#: templates/ishtar/blocks/window_tables/dynamic_documents.html:45
msgid "Export"
msgstr "Exporter"
@@ -2911,8 +2929,8 @@ msgstr ""
#: templates/ishtar/blocks/modify_toolbar.html:1
#: templates/ishtar/blocks/window_image.html:11
-#: templates/ishtar/blocks/window_nav.html:47
-#: templates/ishtar/forms/qa_base.html:57
+#: templates/ishtar/blocks/window_nav.html:49
+#: templates/ishtar/forms/qa_base.html:56
#: templates/ishtar/organization_form.html:37
#: templates/ishtar/organization_person_form.html:32
#: templates/ishtar/person_form.html:43
@@ -2937,13 +2955,17 @@ msgstr "ID interne"
msgid "Data"
msgstr "Données"
+#: templates/ishtar/blocks/sheet_json.html:9
+msgid "No data"
+msgstr "Pas de données"
+
#: templates/ishtar/blocks/window_image_detail.html:64
msgid "Licenses"
msgstr "Licences"
#: templates/ishtar/blocks/window_image_detail.html:111
#: templates/ishtar/import_delete.html:20 templatetags/window_field.py:17
-#: views_item.py:486 wizards.py:393
+#: views_item.py:548 wizards.py:405
msgid "Yes"
msgstr "Oui"
@@ -2956,6 +2978,11 @@ msgstr "Fichier"
msgid "Web"
msgstr "Internet"
+#: templates/ishtar/blocks/window_image_detail.html:193
+#: templates/ishtar/blocks/window_tables/documents.html:10
+msgid "Related to"
+msgstr "Associé à"
+
#: templates/ishtar/blocks/window_nav.html:17
msgid ""
"Are you sure to restore to this version? All changes made since this version "
@@ -2977,26 +3004,22 @@ msgstr "Épingler"
msgid "Item pined in your shortcut menu."
msgstr "Cet élément a été épinglé dans votre menu de raccourcis."
-#: templates/ishtar/blocks/window_nav.html:43
+#: templates/ishtar/blocks/window_nav.html:45
msgid "Actions"
msgstr "Actions"
-#: templates/ishtar/blocks/window_nav.html:61
+#: templates/ishtar/blocks/window_nav.html:73
msgid "Export as OpenOffice.org file"
msgstr "Exporter en fichier OpenOffice.org"
-#: templates/ishtar/blocks/window_nav.html:64
+#: templates/ishtar/blocks/window_nav.html:77
msgid "Export as PDF file"
msgstr "Exporter en fichier PDF"
-#: templates/ishtar/blocks/window_nav.html:72
+#: templates/ishtar/blocks/window_nav.html:92
msgid "Relation between items are not historized."
msgstr "Les relations entre éléments ne sont pas historisées."
-#: templates/ishtar/blocks/window_tables/documents.html:10
-msgid "Related to"
-msgstr "Associé à"
-
#: templates/ishtar/blocks/window_tables/documents.html:11
#: templates/ishtar/blocks/window_tables/documents.html:19
msgid "Link"
@@ -3085,12 +3108,12 @@ msgstr "Mois"
msgid "User type"
msgstr "Type d'utilisateur"
-#: templates/ishtar/form.html:20 templates/ishtar/forms/document.html:24
+#: templates/ishtar/form.html:23 templates/ishtar/forms/document.html:24
#: templates/ishtar/wizard/default_wizard.html:43
msgid "Search and select an item in the table"
msgstr "Rechercher et sélectionner un élément dans le tableau"
-#: templates/ishtar/form.html:26 templates/ishtar/forms/document.html:30
+#: templates/ishtar/form.html:29 templates/ishtar/forms/document.html:30
#: templates/ishtar/forms/search_query.html:77 templates/ishtar/formset.html:8
#: templates/ishtar/formset_import_match.html:51
#: templates/ishtar/import_list.html:30 templates/ishtar/merge.html:30
@@ -3103,12 +3126,12 @@ msgstr "Valider"
msgid "Are you sure you want to delete: "
msgstr "Êtes-vous sûr de vouloir supprimer :"
-#: templates/ishtar/forms/qa_base.html:25
+#: templates/ishtar/forms/qa_base.html:24
#: templates/ishtar/forms/qa_form.html:12
msgid "Modified items"
msgstr "Éléments modifiés"
-#: templates/ishtar/forms/qa_base.html:62
+#: templates/ishtar/forms/qa_base.html:61
#: templates/ishtar/import_step_by_step.html:126
#: templates/ishtar/import_step_by_step.html:305
#: templates/ishtar/organization_form.html:40
@@ -3192,7 +3215,7 @@ msgstr "Ligne"
msgid "Go"
msgstr "Aller"
-#: templates/ishtar/import_step_by_step.html:63 views.py:1081
+#: templates/ishtar/import_step_by_step.html:63 views.py:1104
msgid "Import step by step"
msgstr "Import pas à pas"
@@ -3457,12 +3480,12 @@ msgstr "Aménageur des dossiers"
msgid "Responsible for planning service of archaeological files"
msgstr "Responsable pour le service instructeur des dossiers"
-#: templates/ishtar/wizard/confirm_wizard.html:12
+#: templates/ishtar/wizard/confirm_wizard.html:14
#: templates/ishtar/wizard/wizard_done_summary.html:6
msgid "You have entered the following informations:"
msgstr "Vous avez entré les informations suivantes :"
-#: templates/ishtar/wizard/confirm_wizard.html:50
+#: templates/ishtar/wizard/confirm_wizard.html:56
msgid "Would you like to save them?"
msgstr "Voulez-vous sauvegarder ces informations ?"
@@ -3775,15 +3798,15 @@ msgstr "Épingler la recherche actuelle"
msgid "Bookmarks"
msgstr "Marque-pages"
-#: templatetags/window_field.py:22 wizards.py:395
+#: templatetags/window_field.py:22 wizards.py:407
msgid "No"
msgstr "Non"
-#: templatetags/window_tables.py:88 widgets.py:1065
+#: templatetags/window_tables.py:88 widgets.py:1102
msgid "No results"
msgstr "Pas de résultats"
-#: templatetags/window_tables.py:89 widgets.py:1066
+#: templatetags/window_tables.py:89 widgets.py:1103
msgid "Loading..."
msgstr "Chargement..."
@@ -3792,15 +3815,15 @@ msgid "You don't have sufficient permissions to do this action."
msgstr ""
"Vous n'avez pas les permissions suffisantes pour effectuer cette action."
-#: utils.py:338
+#: utils.py:344
msgid " (...)"
msgstr " (...)"
-#: utils.py:418
+#: utils.py:424
msgid "Information"
msgstr "Information"
-#: utils.py:419
+#: utils.py:425
msgid "Load another random image?"
msgstr "Charger une autre image au hasard ?"
@@ -3869,116 +3892,125 @@ msgstr "Demande de traitement"
msgid "Treatment"
msgstr "Traitement"
-#: views.py:724 views_item.py:103
+#: views.py:747 views_item.py:117
msgid "Operation not permitted."
msgstr "Opération non permise."
-#: views.py:741 views.py:799
+#: views.py:764 views.py:822
msgid "Archaeological files"
msgstr "Dossiers"
-#: views.py:746 views.py:810
+#: views.py:769 views.py:833
msgid "Finds"
msgstr "Mobilier"
-#: views.py:748 views.py:815
+#: views.py:771 views.py:838
msgid "Treatment requests"
msgstr "Demandes de traitement"
-#: views.py:749 views.py:821
+#: views.py:772 views.py:844
msgid "Treatments"
msgstr "Traitements"
-#: views.py:1423
+#: views.py:1446
msgid "Col. "
msgstr "Col."
-#: views.py:1429 views.py:1441
+#: views.py:1452 views.py:1464
msgid "* empty *"
msgstr "* vide *"
-#: views.py:1482
+#: views.py:1505
msgid "Link unmatched items"
msgstr "Associer les éléments non rapprochés"
-#: views.py:1503
+#: views.py:1526
msgid "Delete import"
msgstr "Supprimer un import"
-#: views.py:1542
+#: views.py:1565
msgid "Merge persons"
msgstr "Fusionner des personnes"
-#: views.py:1566
+#: views.py:1589
msgid "Select the main person"
msgstr "Choisir la personne principale"
-#: views.py:1575
+#: views.py:1598
msgid "Merge organization"
msgstr "Fusionner des organisations"
-#: views.py:1585
+#: views.py:1608
msgid "Select the main organization"
msgstr "Sélectionner l'organisation principale"
-#: views.py:1625 views.py:1641
+#: views.py:1648 views.py:1664
msgid "Corporation manager"
msgstr "Représentant de la personne morale"
-#: views.py:1662
+#: views.py:1685
msgid "Document: search"
msgstr "Document : recherche"
-#: views.py:1677
+#: views.py:1700
msgid "Document creation"
msgstr "Document : création"
-#: views.py:1710
+#: views.py:1733
msgid "Document modification"
msgstr "Document : modification"
-#: views.py:1740
+#: views.py:1763
msgid "Document deletion"
msgstr "Document : suppression"
-#: views.py:1823
+#: views.py:1872
msgid "Delete bookmark"
msgstr "Supprimer le marque page"
-#: views.py:1846
+#: views.py:1895
msgid "Bookmark - Delete"
msgstr "Marque page - Suppression"
-#: views_item.py:105
+#: views_item.py:119
#, python-format
msgid "New %s"
msgstr "Nouveau %s"
+#: views_item.py:570
+msgctxt "key for text search"
+msgid "today"
+msgstr "aujourdhui"
+
#: widgets.py:174
msgid "The character \" is not accepted."
msgstr "Le caractère \" n'est pas accepté"
-#: widgets.py:517
+#: widgets.py:555
msgid "{} is not a valid key for {}"
msgstr "{} n’est pas une valeur valide pour {}"
-#: widgets.py:618 widgets.py:752 widgets.py:867
+#: widgets.py:656 widgets.py:790 widgets.py:905
msgid "Search..."
msgstr "Recherche..."
-#: widgets.py:687
+#: widgets.py:725
msgid "Previous value:"
msgstr "Valeur précédente :"
-#: widgets.py:1067
+#: widgets.py:1104
msgid "Remove"
msgstr "Enlever"
-#: wizards.py:431
+#: wizards.py:171
+msgid "Permission error: you cannot do this action."
+msgstr "Erreur de permission : vous ne pouvez pas faire cette action."
+
+#: wizards.py:443
msgid "Deleted"
msgstr "Supprimé"
-#: wizards.py:1757
+#: wizards.py:1769
#, python-format
msgid "[%(app_name)s] Account creation/modification"
msgstr "[%(app_name)s] Création/modification du compte"
diff --git a/version.py b/version.py
index 8885edb48..4f00a9ce2 100644
--- a/version.py
+++ b/version.py
@@ -1,5 +1,5 @@
-# 2.1.dev.17
-VERSION = (2, 1, 'dev', 17)
+# 2.1.dev.19
+VERSION = (2, 1, 'dev', 19)
def get_version():