diff options
| author | Étienne Loks <etienne.loks@iggdrasil.net> | 2019-01-11 16:19:59 +0100 | 
|---|---|---|
| committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2019-01-11 16:19:59 +0100 | 
| commit | 2aa223c0cac8c445e9f3855db66524cfdeae9380 (patch) | |
| tree | 8b9137dd9b68121db86e4e22dfdb7b7016a6f1ad /archaeological_finds/forms.py | |
| parent | 23697dd97eb201dd557272293227ec42a1c95a54 (diff) | |
| parent | daeeeb175835559724c8520f4f5a8dcd5957a469 (diff) | |
| download | Ishtar-2aa223c0cac8c445e9f3855db66524cfdeae9380.tar.bz2 Ishtar-2aa223c0cac8c445e9f3855db66524cfdeae9380.zip | |
Merge branch 'develop'
Diffstat (limited to 'archaeological_finds/forms.py')
| -rw-r--r-- | archaeological_finds/forms.py | 519 | 
1 files changed, 419 insertions, 100 deletions
| 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\ | 
