summaryrefslogtreecommitdiff
path: root/archaeological_finds
diff options
context:
space:
mode:
Diffstat (limited to 'archaeological_finds')
-rw-r--r--archaeological_finds/forms.py66
-rw-r--r--archaeological_finds/forms_treatments.py16
-rw-r--r--archaeological_finds/ishtar_menu.py7
-rw-r--r--archaeological_finds/models_finds.py10
-rw-r--r--archaeological_finds/models_treatments.py48
-rw-r--r--archaeological_finds/urls.py3
-rw-r--r--archaeological_finds/views.py13
-rw-r--r--archaeological_finds/wizards.py67
8 files changed, 214 insertions, 16 deletions
diff --git a/archaeological_finds/forms.py b/archaeological_finds/forms.py
index 970b35f92..b95ac90c6 100644
--- a/archaeological_finds/forms.py
+++ b/archaeological_finds/forms.py
@@ -44,7 +44,7 @@ from archaeological_finds.forms_treatments import TreatmentSelect, \
AdministrativeActTreatmentFileFormSelection, \
AdministrativeActTreatmentFileModifForm, \
DashboardForm as DashboardTreatmentForm, N1TreatmentForm,\
- DashboardTreatmentFileForm, QAFindTreatmentForm
+ DashboardTreatmentFileForm, QAFindTreatmentForm, OneNTreatmentForm
from archaeological_operations.models import Period, ArchaeologicalSite, \
RelationType as OpeRelationType
from archaeological_operations.widgets import OAWidget
@@ -84,7 +84,8 @@ __all__ = [
'SelectFindBasketForm', 'DeleteFindBasketForm', 'FindBasketAddItemForm',
'QAFindFormSingle', 'QAFindFormMulti', 'QAFindBasketForm',
'QAFindTreatmentForm',
- 'N1TreatmentForm', 'ResultingFindForm'
+ 'N1TreatmentForm', 'OneNTreatmentForm', 'ResultingFindForm',
+ 'ResultingFindsForm', 'SingleUpstreamFindFormSelection'
]
logger = logging.getLogger(__name__)
@@ -379,8 +380,8 @@ class SimpleFindForm(BaseFindForm):
class ResultingFindForm(CustomForm, ManageOldType):
file_upload = True
form_label = _("Resulting find")
- form_admin_name = _(u"Treatment n-1 - 030 - General")
- form_slug = "treatmentn1-030-general"
+ form_admin_name = _(u"Treatment n-1 - 030 - Resulting find")
+ form_slug = "treatmentn1-030-resulting-find"
associated_models = {
'resulting_material_type': models.MaterialType,
@@ -472,6 +473,50 @@ class ResultingFindForm(CustomForm, ManageOldType):
]
+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"
@@ -1065,7 +1110,7 @@ class FindDeletionForm(FinalForm):
class UpstreamFindFormSelection(PkWizardSearch, FindFormSelection):
- form_label = _(u"Upstream find")
+ form_label = _(u"Upstream finds")
current_model = models.Find
pk_key = 'resulting_pk'
@@ -1084,6 +1129,17 @@ class UpstreamFindFormSelection(PkWizardSearch, 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
diff --git a/archaeological_finds/forms_treatments.py b/archaeological_finds/forms_treatments.py
index 99a685825..be53dd418 100644
--- a/archaeological_finds/forms_treatments.py
+++ b/archaeological_finds/forms_treatments.py
@@ -80,7 +80,7 @@ class TreatmentFormSelection(forms.Form):
class BaseTreatmentForm(CustomForm, ManageOldType):
- form_label = _(u"Base treatment")
+ form_label = _(u"Treatment")
form_admin_name = _(u"Treatment - 020 - General")
form_slug = "treatment-020-general"
base_models = ['treatment_type']
@@ -231,7 +231,6 @@ class BaseTreatmentForm(CustomForm, ManageOldType):
class N1TreatmentForm(BaseTreatmentForm):
- form_label = _(u"Base treatment")
form_admin_name = _(u"Treatment n-1 - 020 - General")
form_slug = "treatmentn1-020-general"
@@ -244,6 +243,19 @@ class N1TreatmentForm(BaseTreatmentForm):
]
+class OneNTreatmentForm(BaseTreatmentForm):
+ form_admin_name = _(u"Treatment 1-n - 020 - General")
+ form_slug = "treatment1n-020-general"
+
+ TYPES = [
+ FieldType('treatment_state', models.TreatmentState),
+ FieldType(
+ 'treatment_type', models.TreatmentType, is_multiple=True,
+ extra_args={'dct': {'upstream_is_many': False,
+ 'downstream_is_many': True}})
+ ]
+
+
class TreatmentModifyForm(BaseTreatmentForm):
index = forms.IntegerField(_(u"Index"))
id = forms.IntegerField(' ', widget=forms.HiddenInput, required=False)
diff --git a/archaeological_finds/ishtar_menu.py b/archaeological_finds/ishtar_menu.py
index cd7ed19b7..2f37f4c4b 100644
--- a/archaeological_finds/ishtar_menu.py
+++ b/archaeological_finds/ishtar_menu.py
@@ -167,6 +167,13 @@ MENU_SECTIONS = [
u"- creation"),
model=models.Treatment,
access_controls=['change_find', 'change_own_find']),
+ MenuItem(
+ 'treatment_creation_1n',
+ _(u"Treatment "
+ u"1 <i class='fa fa-arrows-h' aria-hidden='true'></i> n "
+ u"- creation"),
+ model=models.Treatment,
+ access_controls=['change_find', 'change_own_find']),
MenuItem('treatment_modification',
_(u"Modification"),
model=models.Treatment,
diff --git a/archaeological_finds/models_finds.py b/archaeological_finds/models_finds.py
index 1fb4f6132..e856cb8ca 100644
--- a/archaeological_finds/models_finds.py
+++ b/archaeological_finds/models_finds.py
@@ -1348,7 +1348,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)
@@ -1366,9 +1366,11 @@ 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():
+ dating.pk = None
+ dating.save()
+ new.datings.add(dating)
else:
for val in getattr(self, field).all():
getattr(new, field).add(val)
diff --git a/archaeological_finds/models_treatments.py b/archaeological_finds/models_treatments.py
index d92c98235..68935f142 100644
--- a/archaeological_finds/models_treatments.py
+++ b/archaeological_finds/models_treatments.py
@@ -29,6 +29,7 @@ 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, \
@@ -72,7 +73,8 @@ class Treatment(DashboardFormItem, ValueGetter, BaseHistorizedItem,
"person__cached_label": _(u"Responsible"),
}
# extra keys than can be passed to save method
- EXTRA_SAVED_KEYS = ('items', 'user', 'resulting_find', 'upstream_items')
+ EXTRA_SAVED_KEYS = ('items', 'user', 'resulting_find', 'upstream_items',
+ 'resulting_finds', 'upstream_item')
# alternative names of fields for searches
ALT_NAMES = {
@@ -293,7 +295,10 @@ class Treatment(DashboardFormItem, ValueGetter, BaseHistorizedItem,
if q.count():
self.index = q.all().aggregate(Max('index'))['index__max'] + 1
- def _create_resulting_find(self, resulting_find, upstream_items):
+ def _create_n_1_resulting_find(self, resulting_find, upstream_items):
+ """
+ Manage creation of n<->1 treatment
+ """
m2m = {}
base_fields = [f.name for f in Find._meta.get_fields()]
for k in resulting_find.keys():
@@ -363,15 +368,45 @@ class Treatment(DashboardFormItem, ValueGetter, BaseHistorizedItem,
new_find.skip_history_when_saving = True
new_find.save()
+ def _create_1_n_resulting_find(self, resulting_finds, upstream_item, user):
+ """
+ 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)
+
+ upstream_item.downstream_treatment = self
+ upstream_item.skip_history_when_saving = True
+ upstream_item.save()
+
+ 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, resulting_find = [], None, [], None
- upstream_items = []
+ upstream_items, upstream_item, resulting_finds = [], None, None
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:
@@ -386,7 +421,12 @@ class Treatment(DashboardFormItem, ValueGetter, BaseHistorizedItem,
upstream_items = upstream_items.items.all()
if upstream_items and resulting_find:
- self._create_resulting_find(resulting_find, upstream_items)
+ self._create_n_1_resulting_find(resulting_find, upstream_items)
+ return
+
+ if upstream_item and resulting_finds:
+ self._create_1_n_resulting_find(resulting_finds, upstream_item,
+ self.history_modifier)
return
tps = list(self.treatment_types.all())
diff --git a/archaeological_finds/urls.py b/archaeological_finds/urls.py
index b9f4d8b6c..6e9f59b8c 100644
--- a/archaeological_finds/urls.py
+++ b/archaeological_finds/urls.py
@@ -106,6 +106,9 @@ urlpatterns = [
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'])(
diff --git a/archaeological_finds/views.py b/archaeological_finds/views.py
index ceb00d432..29f0f75af 100644
--- a/archaeological_finds/views.py
+++ b/archaeological_finds/views.py
@@ -476,6 +476,19 @@ treatment_creation_n1_wizard = TreatmentN1Wizard.as_view(
label=_(u"New treatment"),
url_name='treatment_creation_n1',)
+treatment_1n_wizard_steps = [
+ ('selecfind-treatment_creation_1n', SingleUpstreamFindFormSelection),
+ ('file-treatment_creation_1n', TreatmentFormFileChoice),
+ ('basetreatment-treatment_creation_1n', OneNTreatmentForm),
+ ('resultingfinds-treatment_creation_1n', ResultingFindsForm),
+ ('final-treatment_creation_1n', FinalForm)
+]
+
+treatment_creation_1n_wizard = Treatment1NWizard.as_view(
+ treatment_1n_wizard_steps,
+ label=_(u"New treatment"),
+ url_name='treatment_creation_1n',)
+
treatment_modification_wizard = TreatmentModificationWizard.as_view(
[('selec-treatment_modification', TreatmentFormSelection),
('file-treatment_modification', TreatmentFormFileChoice),
diff --git a/archaeological_finds/wizards.py b/archaeological_finds/wizards.py
index 3c25258a6..bd16a55de 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
@@ -316,6 +317,70 @@ class TreatmentN1Wizard(TreatmentBase):
return dct
+class Treatment1NWizard(TreatmentBase):
+ saved_args = {"upstream_item": None, "resulting_finds": None}
+ 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, form_list):
+ """
+ Get items concerned by the treatment
+ """
+ dct = super(Treatment1NWizard, self).get_extra_model(dct, 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):
model = models.Treatment
fields = ['label', 'other_reference', 'year', 'index',