summaryrefslogtreecommitdiff
path: root/archaeological_finds
diff options
context:
space:
mode:
Diffstat (limited to 'archaeological_finds')
-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
37 files changed, 5424 insertions, 1262 deletions
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