summaryrefslogtreecommitdiff
path: root/archaeological_warehouse
diff options
context:
space:
mode:
Diffstat (limited to 'archaeological_warehouse')
-rw-r--r--archaeological_warehouse/forms.py123
-rw-r--r--archaeological_warehouse/models.py9
-rw-r--r--archaeological_warehouse/templates/ishtar/forms/qa_container_move.html66
-rw-r--r--archaeological_warehouse/urls.py7
-rw-r--r--archaeological_warehouse/views.py36
5 files changed, 197 insertions, 44 deletions
diff --git a/archaeological_warehouse/forms.py b/archaeological_warehouse/forms.py
index 963042346..f2605ba12 100644
--- a/archaeological_warehouse/forms.py
+++ b/archaeological_warehouse/forms.py
@@ -22,10 +22,11 @@ import datetime
from bootstrap_datepicker.widgets import DateField
from django import forms
-from django.db.models import Max
+from django.db.models import Max, Q
from django.conf import settings
from django.core.validators import validate_slug
from django.forms.formsets import formset_factory
+
from ishtar_common.utils import ugettext_lazy as _
from ishtar_common.models import (
@@ -35,21 +36,23 @@ from ishtar_common.models import (
SpatialReferenceSystem,
Organization,
valid_ids,
- person_type_pks_lazy,
)
from archaeological_operations.models import ArchaeologicalSite
from archaeological_context_records.models import ContextRecord
from archaeological_finds.models import (
- TreatmentType,
+ AlterationType,
+ AlterationCauseType,
+ ConservatoryState,
+ Find,
FindBasket,
+ IntegrityType,
MaterialType,
ObjectType,
- IntegrityType,
RemarkabilityType,
- ConservatoryState,
- AlterationType,
- AlterationCauseType,
TreatmentEmergencyType,
+ Treatment,
+ TreatmentState,
+ TreatmentType,
)
from . import models
@@ -80,6 +83,7 @@ from ishtar_common.forms_common import (
MergeIntoForm,
)
from archaeological_finds.forms import FindMultipleFormSelection, SelectFindBasketForm
+from archaeological_finds.forms_treatments import QABasePackagingForm
def get_warehouse_field(label=_("Warehouse"), required=True):
@@ -719,35 +723,50 @@ class QAContainerFormMulti(QAForm):
PREFIX = "qa"
form_admin_name = _("Container - Quick action - Modify")
form_slug = "container-quickaction-modify"
- base_models = ["qaparent", "qacontainer_type", "qalocation", "qaresponsibility"]
+ base_models = ["qacontainer_type", "qaresponsibility"]
associated_models = {
- "qaparent": models.Container,
"qacontainer_type": models.ContainerType,
- "qalocation": models.Warehouse,
"qaresponsibility": models.Warehouse,
}
MULTI = True
- REPLACE_FIELDS = ["qaparent", "qacontainer_type", "qalocation", "qaresponsibility"]
+ REPLACE_FIELDS = ["qacontainer_type", "qaresponsibility"]
HEADERS = {
- "qalocation": FormHeader(_("Warehouse")),
+ "qaresponsibility": FormHeader(_("Warehouse")),
}
SINGLE_FIELDS = []
qacontainer_type = forms.ChoiceField(
label=_("Container type"), required=False, choices=[]
)
- qalocation = forms.IntegerField(
- label=_("Location"),
+ qaresponsibility = forms.IntegerField(
+ label=_("Responsibility"),
widget=widgets.JQueryAutoComplete(
reverse_lazy("autocomplete-warehouse"), associated_model=models.Warehouse
),
validators=[valid_id(models.Warehouse)],
required=False,
)
- qaresponsibility = forms.IntegerField(
- label=_("Responsibility"),
+
+ TYPES = [
+ FieldType("qacontainer_type", models.ContainerType),
+ ]
+
+ def __init__(self, *args, **kwargs):
+ self.items = kwargs["items"]
+ super().__init__(*args, **kwargs)
+
+ def _get_qaresponsibility(self, value):
+ try:
+ return models.Warehouse.objects.get(pk=value).name
+ except models.Warehouse.DoesNotExist:
+ return ""
+
+
+class QAContainerMoveForm(QABasePackagingForm):
+ qalocation = forms.IntegerField(
+ label=_("Location"),
widget=widgets.JQueryAutoComplete(
reverse_lazy("autocomplete-warehouse"), associated_model=models.Warehouse
),
@@ -765,13 +784,9 @@ class QAContainerFormMulti(QAForm):
required=False,
)
- TYPES = [
- FieldType("qacontainer_type", models.ContainerType),
- ]
-
def __init__(self, *args, **kwargs):
self.items = kwargs["items"]
- super(QAContainerFormMulti, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
locations = {item.location_id for item in self.items}
if len(locations) == 1 and "qalocation" in self.fields:
self.fields["qalocation"].initial = locations.pop()
@@ -782,12 +797,6 @@ class QAContainerFormMulti(QAForm):
except models.Warehouse.DoesNotExist:
return ""
- def _get_qaresponsibility(self, value):
- try:
- return models.Warehouse.objects.get(pk=value).name
- except models.Warehouse.DoesNotExist:
- return ""
-
def _get_qaparent(self, value):
try:
return models.Container.objects.get(pk=value).cached_label
@@ -796,8 +805,6 @@ class QAContainerFormMulti(QAForm):
def clean(self):
new_values = {}
- if self.cleaned_data.get("qacontainer_type", None):
- new_values["container_type_id"] = self.cleaned_data["qacontainer_type"]
if self.cleaned_data.get("qalocation", None):
new_values["location_id"] = self.cleaned_data["qalocation"]
if self.cleaned_data.get("qaparent", None):
@@ -805,8 +812,8 @@ class QAContainerFormMulti(QAForm):
new_tuples = []
for item in self.items:
if (
- new_values.get("parent_id", None)
- and int(new_values["parent_id"]) == item.pk
+ new_values.get("parent_id", None)
+ and int(new_values["parent_id"]) == item.pk
):
raise forms.ValidationError(
_("A container cannot be a parent of himself.")
@@ -846,12 +853,50 @@ class QAContainerFormMulti(QAForm):
return self.cleaned_data
def save(self, items, user):
- super(QAContainerFormMulti, self).save(items, user)
- if self.cleaned_data.get("qaparent", None):
+ location_id = self.cleaned_data.get("qalocation", None)
+ parent_id = self.cleaned_data.get("qaparent", None)
+ for container in self.items:
+ changed = False
+ if parent_id and parent_id != container.parent_id:
+ container.parent_id = parent_id
+ changed = True
+ if location_id and location_id != container.location_id:
+ container.location_id = location_id
+ # remove parent if do not share the same location
+ if not changed and container.parent \
+ and container.parent.location != container.location:
+ container.parent = None
+ changed = True
+ if changed:
+ container.save()
+ if not self.cleaned_data.get("create_treatment", False):
return
- for item in items:
- item = models.Container.objects.get(pk=item.pk)
- # remove parent if do not share the same location
- if item.parent and item.parent.location != item.location:
- item.parent = None
- item.save()
+ treat_type = TreatmentType.objects.get(pk=self.cleaned_data['treatment_type'])
+ treat_state = TreatmentState.get_completed_state()
+
+ try:
+ location = models.Warehouse.objects.get(pk=self.cleaned_data.get("qalocation", None))
+ except models.Warehouse.DoesNotExist:
+ location = None
+
+ for container in self.items:
+ t = Treatment.objects.create(
+ container=container,
+ year=self.cleaned_data['year'],
+ start_date=self.cleaned_data['start_date'],
+ location=location,
+ person_id=self.cleaned_data['person'],
+ organization_id=self.cleaned_data['organization'],
+ history_modifier=user,
+ treatment_state=treat_state
+ )
+ t.treatment_types.add(treat_type)
+ t.save()
+ q = Find.objects.filter(Q(container=container) | Q(container_ref=container))
+ if not q.count():
+ continue
+ for find in q.all():
+ t.finds.add(find)
+ t.save() # force find container history
+
+
diff --git a/archaeological_warehouse/models.py b/archaeological_warehouse/models.py
index 364926173..d501eab1f 100644
--- a/archaeological_warehouse/models.py
+++ b/archaeological_warehouse/models.py
@@ -1106,6 +1106,13 @@ class Container(
target="many",
rights=["change_container", "change_own_container"],
)
+ QA_MOVE = QuickAction(
+ url="container-qa-move",
+ icon_class="fa fa-arrow-right",
+ text=pgettext_lazy("action", "Move"),
+ target="many",
+ rights=["change_container", "change_own_container"],
+ )
QA_LOCK = QuickAction(
url="container-qa-lock",
icon_class="fa fa-lock",
@@ -1113,7 +1120,7 @@ class Container(
target="many",
rights=["change_container", "change_own_container"],
)
- QUICK_ACTIONS = [QA_EDIT, QA_LOCK]
+ QUICK_ACTIONS = [QA_EDIT, QA_MOVE, QA_LOCK]
BASE_QUERY_LOCATION = "container_tree_child__container_parent"
SERIALIZE_CALL = {
diff --git a/archaeological_warehouse/templates/ishtar/forms/qa_container_move.html b/archaeological_warehouse/templates/ishtar/forms/qa_container_move.html
new file mode 100644
index 000000000..69396b7ba
--- /dev/null
+++ b/archaeological_warehouse/templates/ishtar/forms/qa_container_move.html
@@ -0,0 +1,66 @@
+{% extends "ishtar/forms/qa_base.html" %}
+{% load i18n inline_formset table_form %}
+
+{% block main_form %}
+ {% if form.non_field_errors %}
+ <div class="alert alert-danger" role="alert">
+ {{form.non_field_errors}}
+ </div>
+ {% endif %}
+
+ <h4>{% trans "Containers" %}</h4>
+ <ul>{% for item in items %}
+ <li>{{item}}</li>{% endfor %}
+ </ul>
+
+ <h4>{% trans "Move" context "action" %}</h4>
+ {% for hidden in form.hidden_fields %}
+ {{hidden}}
+ {% if hidden.errors %}<div class="invalid-feedback">
+ {{ hidden.errors }}
+ </div>{% endif %}
+ {% endfor %}
+ <div class="form-row">
+ {% with force_large_col=True %}
+ {% with form.qalocation as field %}
+ {% include "blocks/bs_field_snippet.html" %}
+ {% endwith %}
+ {% with form.qaparent as field %}
+ {% include "blocks/bs_field_snippet.html" %}
+ {% endwith %}
+ {% endwith %}
+ </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">
+ <div class="form-row">
+ {% with force_large_col=false %}{% for field in form %}
+ {% if field.name != 'qalocation' and field.name != 'qaparent' and field.name != 'create_treatment' %}
+ {% include "blocks/bs_field_snippet.html" %}
+ {% endif %}
+ {% endfor %}{% endwith %}
+ </div>
+ </div>
+{% endblock %}
+
+{% block js %}
+var update_form_display = function(){
+ if ($("#{{form.create_treatment.auto_id}}:checked").length){
+ $("#new-treatment").show();
+ } else {
+ $("#new-treatment").hide();
+ }
+};
+
+$(document).ready(function(){
+ $("#{{form.create_treatment.auto_id}}").click(update_form_display);
+ update_form_display();
+});
+
+{% endblock %}
+
+
diff --git a/archaeological_warehouse/urls.py b/archaeological_warehouse/urls.py
index 1bf10ff16..a41852b8b 100644
--- a/archaeological_warehouse/urls.py
+++ b/archaeological_warehouse/urls.py
@@ -221,6 +221,13 @@ urlpatterns = [
kwargs={"confirm": True},
),
url(
+ r"^container-qa-move/(?P<pks>[0-9-]+)?/$",
+ check_rights(["change_container", "change_own_container"])(
+ views.QAContainerMoveForm.as_view()
+ ),
+ name="container-qa-move",
+ ),
+ url(
r"^container-qa-lock/(?P<pks>[0-9-]+)?/$",
views.QAContainerLockView.as_view(),
name="container-qa-lock",
diff --git a/archaeological_warehouse/views.py b/archaeological_warehouse/views.py
index 6c1ad6837..0ce6f8763 100644
--- a/archaeological_warehouse/views.py
+++ b/archaeological_warehouse/views.py
@@ -35,14 +35,15 @@ from archaeological_warehouse import forms
from ishtar_common.forms import FinalForm
from ishtar_common.views import (
- QABaseLockView,
- wizard_is_available,
+ IshtarMixin,
merge_action,
ManualMergeMixin,
ManualMergeItemsMixin,
- IshtarMixin,
LoginRequiredMixin,
+ QABaseLockView,
+ QAItemForm,
QAItemEditForm,
+ wizard_is_available,
)
from ishtar_common.views_item import get_item, show_item, new_qa_item, revert_item
from archaeological_finds.views import treatment_add
@@ -59,7 +60,6 @@ from archaeological_warehouse.wizards import (
ContainerDeletionWizard,
)
-
get_container = get_item(
models.Container, "get_container", "container", search_form=forms.ContainerSelect
)
@@ -509,6 +509,34 @@ class QAContainerForm(QAItemEditForm):
return kwargs
+class QAContainerMoveForm(QAItemForm):
+ model = models.Container
+ form_class = forms.QAContainerMoveForm
+ icon = "fa fa-arrow-right"
+ page_name = _("Move")
+ template_name = "ishtar/forms/qa_container_move.html"
+ base_url = "container-qa-move"
+
+ def dispatch(self, request, *args, **kwargs):
+ returned = super().dispatch(request, *args, **kwargs)
+ for item in self.items:
+ if item.is_locked(request.user):
+ return HttpResponseRedirect(reverse("qa-not-available"))
+ return returned
+
+ def get_form_kwargs(self):
+ kwargs = super().get_form_kwargs()
+ # item list is necessary to verify uniqueness rules
+ kwargs["items"] = self.items
+ kwargs["user"] = self.request.user
+ kwargs["prefix"] = "qa-move"
+ return kwargs
+
+ def form_valid(self, form):
+ form.save(self.items, self.request.user)
+ return HttpResponseRedirect(reverse("success"))
+
+
class GenerateStats(IshtarMixin, LoginRequiredMixin, RedirectView):
model = None