diff options
author | Étienne Loks <etienne.loks@iggdrasil.net> | 2021-07-29 19:02:32 +0200 |
---|---|---|
committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2021-11-16 17:04:41 +0100 |
commit | 12fd2be76304653e91fc17390e18e73b6015abb1 (patch) | |
tree | 4c907874e3641083d0175ae785dfc23f4c99e666 | |
parent | 4b7bee9c426b99de56d496f20d0de604d62af899 (diff) | |
download | Ishtar-12fd2be76304653e91fc17390e18e73b6015abb1.tar.bz2 Ishtar-12fd2be76304653e91fc17390e18e73b6015abb1.zip |
Preventive file: work on inlines - 3
-rw-r--r-- | archaeological_files/admin.py | 43 | ||||
-rw-r--r-- | archaeological_files/forms.py | 79 | ||||
-rw-r--r-- | archaeological_files/migrations/0106_auto_20210729_1616.py (renamed from archaeological_files/migrations/0106_auto_20210726_1230.py) | 12 | ||||
-rw-r--r-- | archaeological_files/models.py | 129 | ||||
-rw-r--r-- | archaeological_files/views.py | 2 | ||||
-rw-r--r-- | ishtar_common/static/js/ishtar.js | 1 | ||||
-rw-r--r-- | ishtar_common/templates/blocks/bs_formset_snippet.html | 6 |
7 files changed, 203 insertions, 69 deletions
diff --git a/archaeological_files/admin.py b/archaeological_files/admin.py index 629a0031d..a2834c498 100644 --- a/archaeological_files/admin.py +++ b/archaeological_files/admin.py @@ -22,8 +22,13 @@ from ajax_select import make_ajax_form from django.conf import settings from ishtar_common.apps import admin_site -from ishtar_common.admin import HistorizedObjectAdmin, GeneralTypeAdmin, \ - export_as_csv_action, serialize_type_action, ImportActionAdmin +from ishtar_common.admin import ( + HistorizedObjectAdmin, + GeneralTypeAdmin, + export_as_csv_action, + serialize_type_action, + ImportActionAdmin, +) from . import models @@ -66,7 +71,8 @@ admin_site.register(models.File, FileAdmin) general_models = [ - models.FileType, models.PermitType, models.Job, + models.FileType, + models.PermitType, models.GenericEquipmentServiceType, ] if settings.COUNTRY == "fr": @@ -75,8 +81,26 @@ for model in general_models: admin_site.register(model, GeneralTypeAdmin) +class JobAdmin(GeneralTypeAdmin): + list_filter = ("available", "permanent_contract") + LIST_DISPLAY = [ + "label", + "permanent_contract", + "order", + "ground_daily_cost", + "daily_cost", + "default_daily_need_on_ground", + "default_daily_need", + "child", + "available", + ] + + +admin_site.register(models.Job, JobAdmin) + + class EquipmentServiceTypeAdmin(GeneralTypeAdmin): - list_filter = ("available", 'generic_equipment_type') + list_filter = ("available", "generic_equipment_type") admin_site.register(models.EquipmentServiceType, EquipmentServiceTypeAdmin) @@ -88,8 +112,15 @@ class EquipmentServiceCostAdmin(ImportActionAdmin): "service_provider", ) list_filter = ("available",) - list_display = ["equipment_service_type", "specificity", "parent", - "unitary_cost", "unit", "flat_rate", "available"] + list_display = [ + "equipment_service_type", + "specificity", + "parent", + "unitary_cost", + "unit", + "flat_rate", + "available", + ] actions = [export_as_csv_action(), serialize_type_action] model = models.EquipmentServiceCost diff --git a/archaeological_files/forms.py b/archaeological_files/forms.py index 4918fdaaa..77d19ce2f 100644 --- a/archaeological_files/forms.py +++ b/archaeological_files/forms.py @@ -624,10 +624,19 @@ INLINE_JOB_FIELDS = [ "days_worked", ] JOB_WIDGETS = { - "man_by_day_planned": forms.NumberInput(attrs={"class": "w-50 form-planned"}), - "days_planned": forms.NumberInput(attrs={"class": "w-50 form-planned"}), - "man_by_day_worked": forms.NumberInput(attrs={"class": "w-50 form-worked"}), - "days_worked": forms.NumberInput(attrs={"class": "w-50 form-worked"}), + "job": forms.Select(attrs={"bs_col_width": "col-lg-6 col-12"}), + "man_by_day_planned": forms.NumberInput( + attrs={"class": "w-50 form-planned", "bs_col_width": "col-2"} + ), + "days_planned": forms.NumberInput( + attrs={"class": "w-50 form-planned", "bs_col_width": "col-2"} + ), + "man_by_day_worked": forms.NumberInput( + attrs={"class": "w-50 form-worked", "bs_col_width": "col-2"} + ), + "days_worked": forms.NumberInput( + attrs={"class": "w-50 form-worked", "bs_col_width": "col-2"} + ), } JOB_LABELS = { @@ -653,7 +662,30 @@ class PreventiveFileForm(forms.ModelForm): return super().save(commit=commit) -class PreventiveFileJobForm(PreventiveFileForm): +class PreventiveFileGenJobForm(PreventiveFileForm): + def __init__(self, *args, **kwargs): + super(PreventiveFileGenJobForm, self).__init__(*args, **kwargs) + current_value = None + if hasattr(self.instance, "job") and self.instance.job: + current_value = self.instance.job + self.fields["job"].choices = models.Job.get_choices(current_value) + + def save(self, commit=True): + item = super().save(commit=True) + child = item.job.child + if not item or not child: + return + if not self._meta.model.objects.filter(file_id=item.file_id, job=child).count(): + self._meta.model.objects.create( + file_id=item.file_id, + job=child, + man_by_day_planned=item.man_by_day_planned, + days_planned=item.days_planned, + ) + return item + + +class PreventiveFileJobForm(PreventiveFileGenJobForm): class Meta: model = models.PreventiveFileJob fields = ["job"] + INLINE_JOB_FIELDS @@ -675,7 +707,7 @@ PreventiveFileJobFormSet.form_slug = "preventive-030-post-excavation" PreventiveFileJobFormSet.dynamic_add = True -class PreventiveFileGroundJobForm(PreventiveFileForm): +class PreventiveFileGroundJobForm(PreventiveFileGenJobForm): class Meta: model = models.PreventiveFileGroundJob fields = ["job"] + INLINE_JOB_FIELDS @@ -715,12 +747,20 @@ INLINE_COST_FIELDS = [ ] COST_WIDGETS = { - "quantity_by_day_planned": forms.NumberInput(attrs={"class": "w-50 form-planned"}), - "days_planned": forms.NumberInput(attrs={"class": "w-50 form-planned unit-form"}), - "quantity_by_day_worked": forms.NumberInput(attrs={"class": "w-50 form-worked"}), - "days_worked": forms.NumberInput(attrs={"class": "w-50 form-worked unit-form"}), + "quantity_by_day_planned": forms.NumberInput( + attrs={"class": "w-50 form-planned", "bs_col_width": "col-2"} + ), + "days_planned": forms.NumberInput( + attrs={"class": "w-50 form-planned unit-form", "bs_col_width": "col-2"} + ), + "quantity_by_day_worked": forms.NumberInput( + attrs={"class": "w-50 form-worked", "bs_col_width": "col-2"} + ), + "days_worked": forms.NumberInput( + attrs={"class": "w-50 form-worked unit-form", "bs_col_width": "col-2"} + ), "equipment_service_cost": forms.Select( - attrs={"class": "form-cost", "bs_col_width": "col-12"} + attrs={"class": "form-cost", "bs_col_width": "col-lg-6 col-12"} ), } @@ -744,10 +784,13 @@ class PreventiveFileEquipmentServiceForm(PreventiveFileForm): self.unities = {} unit_dict = dict(models.ES_UNITS) - choices = [("", "--")] + choices = [("", "-" * 9)] costs = list(q.all()) - if self.instance and self.instance.equipment_service_cost_id \ - and self.instance.equipment_service_cost not in costs: + if ( + self.instance + and self.instance.equipment_service_cost_id + and self.instance.equipment_service_cost not in costs + ): costs.append(self.instance.equipment_service_cost) self.flat_rates = [] for cost in costs: @@ -767,10 +810,12 @@ class PreventiveFileEquipmentServiceForm(PreventiveFileForm): return for child in item.equipment_service_cost.equipment_service_type.children.all(): if not self._meta.model.objects.filter( - file_id=item.file_id, equipment_service_cost=child).count(): + file_id=item.file_id, equipment_service_cost=child + ).count(): self._meta.model.objects.create( - file_id=item.file_id, equipment_service_cost=child, - quantity_by_day_planned=0 + file_id=item.file_id, + equipment_service_cost=child, + quantity_by_day_planned=0, ) return item diff --git a/archaeological_files/migrations/0106_auto_20210726_1230.py b/archaeological_files/migrations/0106_auto_20210729_1616.py index 5f3163cf9..3891b5d30 100644 --- a/archaeological_files/migrations/0106_auto_20210726_1230.py +++ b/archaeological_files/migrations/0106_auto_20210729_1616.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Generated by Django 1.11.28 on 2021-07-26 12:30 +# Generated by Django 1.11.28 on 2021-07-29 16:16 from __future__ import unicode_literals import django.core.validators @@ -79,16 +79,16 @@ class Migration(migrations.Migration): ('available', models.BooleanField(default=True, verbose_name='Available')), ('ground_daily_cost', models.FloatField(blank=True, null=True, verbose_name='Ground daily cost')), ('daily_cost', models.FloatField(blank=True, null=True, verbose_name='Daily cost')), - ('permanent_contract', models.NullBooleanField(verbose_name='Is a permanent contract')), - ('default_daily_need_on_ground', models.FloatField(default=0, verbose_name='Default daily number needed on the ground')), - ('default_daily_need', models.FloatField(default=0, verbose_name='Default daily number needed')), + ('permanent_contract', models.NullBooleanField(verbose_name='Permanent contract')), + ('default_daily_need_on_ground', models.FloatField(default=0, verbose_name='Def. daily number on ground')), + ('default_daily_need', models.FloatField(default=0, verbose_name='Def. daily number')), ('order', models.IntegerField(default=10, verbose_name='Order')), - ('parents', models.ManyToManyField(blank=True, help_text='Auto-add this job when a parent is added', related_name='_job_parents_+', to='archaeological_files.Job', verbose_name='Parents')), + ('child', models.ForeignKey(blank=True, help_text='Auto-add this job when a parent is added', null=True, on_delete=django.db.models.deletion.CASCADE, to='archaeological_files.Job', verbose_name='Child')), ], options={ 'verbose_name': 'Job', 'verbose_name_plural': 'Jobs', - 'ordering': ('order', 'label'), + 'ordering': ('order', '-permanent_contract', 'label'), }, bases=(ishtar_common.models_common.Cached, models.Model), ), diff --git a/archaeological_files/models.py b/archaeological_files/models.py index ab84be8cb..5129189cf 100644 --- a/archaeological_files/models.py +++ b/archaeological_files/models.py @@ -72,23 +72,60 @@ class Job(GeneralType): ground_daily_cost = models.FloatField(_("Ground daily cost"), blank=True, null=True) daily_cost = models.FloatField(_("Daily cost"), blank=True, null=True) permanent_contract = models.NullBooleanField( - _("Is a permanent contract"), blank=True, null=True) + _("Permanent contract"), blank=True, null=True + ) default_daily_need_on_ground = models.FloatField( - _("Default daily number needed on the ground"), default=0) - default_daily_need = models.FloatField( - _("Default daily number needed"), default=0) + _("Def. daily number on ground"), default=0 + ) + default_daily_need = models.FloatField(_("Def. daily number"), default=0) order = models.IntegerField(_("Order"), default=10) - parents = models.ManyToManyField( + child = models.ForeignKey( "self", blank=True, - verbose_name=_("Parents"), - help_text=_("Auto-add this job when a parent is added") + null=True, + verbose_name=_("Child"), + help_text=_("Auto-add this job when a parent is added"), + related_name="parents", ) class Meta: verbose_name = _("Job") verbose_name_plural = _("Jobs") - ordering = ("order", "label",) + ordering = ( + "order", + "-permanent_contract", + "label", + ) + + def __str__(self): + lbl = self.label + if not self.permanent_contract: + lbl += " ({})".format(_("fixed-term contract")) + return lbl + + @classmethod + def get_choices(cls, current_value): + q = cls.objects.filter( + available=True, + parents__isnull=True, + ) + permanent = [(j.pk, str(j)) for j in q.filter(permanent_contract=True).all()] + fixed_term = [(j.pk, str(j)) for j in q.filter(permanent_contract=False).all()] + if current_value: + if current_value.permanent_contract: + permanent.append((current_value.pk, str(current_value))) + else: + fixed_term.append((current_value.pk, str(current_value))) + return [("", "-" * 9)] + [ + ( + _("Permanent contract"), + permanent, + ), + ( + _("Fixed-term contract"), + fixed_term, + ), + ] class GenericEquipmentServiceType(GeneralType): @@ -97,18 +134,25 @@ class GenericEquipmentServiceType(GeneralType): class Meta: verbose_name = _("Generic equipment type") verbose_name_plural = _("Generic equipment types") - ordering = ("order", "label",) + ordering = ( + "order", + "label", + ) class EquipmentServiceType(GeneralType): generic_equipment_type = models.ForeignKey( - GenericEquipmentServiceType, verbose_name=_("Generic type")) + GenericEquipmentServiceType, verbose_name=_("Generic type") + ) order = models.IntegerField(_("Order"), default=10) class Meta: verbose_name = _("Equipment/service type") verbose_name_plural = _("Equipment/service types") - ordering = ("order", "label",) + ordering = ( + "order", + "label", + ) ES_UNITS = ( @@ -118,10 +162,13 @@ ES_UNITS = ( ("L", _("linear meter")), ) +DCT_ES_UNITS = dict(ES_UNITS) + class EquipmentServiceCost(models.Model): equipment_service_type = models.ForeignKey( - EquipmentServiceType, verbose_name=_("Equipment/Service")) + EquipmentServiceType, verbose_name=_("Equipment/Service") + ) slug = models.SlugField( _("Textual ID"), unique=True, @@ -133,13 +180,16 @@ class EquipmentServiceCost(models.Model): ), ) service_provider = models.CharField( - _("Service provider"), max_length=200, blank=True, default="") + _("Service provider"), max_length=200, blank=True, default="" + ) flat_rate = models.BooleanField(_("Flat rate"), default=False) unitary_cost = models.FloatField(_("Unitary cost"), blank=True, null=True) - unit = models.CharField(_("Unit"), max_length=1, choices=ES_UNITS, - blank=True, null=True) - specificity = models.CharField(_("Specificity"), blank=True, - max_length=200, default="") + unit = models.CharField( + _("Unit"), max_length=1, choices=ES_UNITS, blank=True, null=True + ) + specificity = models.CharField( + _("Specificity"), blank=True, max_length=200, default="" + ) order = models.IntegerField(_("Order"), default=10) available = models.BooleanField(_("Available"), default=True) parent = models.ForeignKey( @@ -149,13 +199,16 @@ class EquipmentServiceCost(models.Model): on_delete=models.CASCADE, verbose_name=_("Parent"), help_text=_("Auto-add this cost when a parent is added"), - related_name="children" + related_name="children", ) class Meta: verbose_name = _("Equipment/service cost") verbose_name_plural = _("Equipment/service costs") - ordering = ("order", "equipment_service_type__label",) + ordering = ( + "order", + "equipment_service_type__label", + ) def __str__(self): lbl = "" @@ -166,6 +219,10 @@ class EquipmentServiceCost(models.Model): lbl += " - " + self.specificity if self.service_provider: lbl += f" ({self.service_provider})" + if self.flat_rate: + lbl += " - " + str(_("Flat rate")) + if self.unit and self.unit in DCT_ES_UNITS: + lbl += " - " + str(DCT_ES_UNITS[self.unit]) return lbl @@ -544,14 +601,16 @@ class File( # <-- research archaeology # --> preventive detail - study_period = models.CharField(_("Study period"), max_length=200, - default="", blank=True) + study_period = models.CharField( + _("Study period"), max_length=200, default="", blank=True + ) start_date = models.DateField(_("Start date"), blank=True, null=True) end_date = models.DateField(_("End date"), blank=True, null=True) ground_start_date = models.DateField(_("Ground start date"), blank=True, null=True) ground_end_date = models.DateField(_("Ground end date"), blank=True, null=True) - execution_report_date = models.DateField(_("Execution report date"), blank=True, - null=True) + execution_report_date = models.DateField( + _("Execution report date"), blank=True, null=True + ) linear_meter = models.IntegerField(_("Linear meter"), blank=True, null=True) # <-- preventive detail @@ -1178,13 +1237,13 @@ class FileDashboard: class ManDays(models.Model): man_by_day_planned = models.FloatField( - _("Man by day - planned"), null=True, blank=True) - days_planned = models.FloatField( - _("Days - planned"), null=True, blank=True) + _("Man by day - planned"), null=True, blank=True + ) + days_planned = models.FloatField(_("Days - planned"), null=True, blank=True) man_by_day_worked = models.FloatField( - _("Man by day - worked"), null=True, blank=True) - days_worked = models.FloatField( - _("Days - worked"), null=True, blank=True) + _("Man by day - worked"), null=True, blank=True + ) + days_worked = models.FloatField(_("Days - worked"), null=True, blank=True) class Meta: abstract = True @@ -1220,13 +1279,13 @@ class PreventiveFileJob(ManDays): class TechDays(models.Model): quantity_by_day_planned = models.FloatField( - _("Quantity by day - planned"), null=True, blank=True) - days_planned = models.FloatField( - _("Days - planned"), null=True, blank=True) + _("Quantity by day - planned"), null=True, blank=True + ) + days_planned = models.FloatField(_("Days - planned"), null=True, blank=True) quantity_by_day_worked = models.FloatField( - _("Quantity by day - worked"), null=True, blank=True) - days_worked = models.FloatField( - _("Days - worked"), null=True, blank=True) + _("Quantity by day - worked"), null=True, blank=True + ) + days_worked = models.FloatField(_("Days - worked"), null=True, blank=True) class Meta: abstract = True diff --git a/archaeological_files/views.py b/archaeological_files/views.py index 805921016..4cf3ce390 100644 --- a/archaeological_files/views.py +++ b/archaeological_files/views.py @@ -438,7 +438,7 @@ class PreventiveEditView(IshtarMixin, LoginRequiredMixin, MixFormFormsetUpdateVi return inlines def get_success_url(self): - return reverse("file_modification") + "?open_item={}".format(self.object.pk) + return reverse("file-edit-preventive", args=[self.object.pk]) def get_form_kwargs(self): kwargs = super(PreventiveEditView, self).get_form_kwargs() diff --git a/ishtar_common/static/js/ishtar.js b/ishtar_common/static/js/ishtar.js index 3fa293deb..0fa058cca 100644 --- a/ishtar_common/static/js/ishtar.js +++ b/ishtar_common/static/js/ishtar.js @@ -1890,7 +1890,6 @@ var inline_register_add_button = function(slug){ let form_regex_var = slug + '(\\d){1}-'; let form_regex = new RegExp(form_regex_var, 'g'); inline_form_num++; - console.log(new_form); new_form.innerHTML = new_form.innerHTML.replace( form_regex, slug + `-${inline_form_num}-`); inline_container.insertBefore(new_form, inline_div_add_button); diff --git a/ishtar_common/templates/blocks/bs_formset_snippet.html b/ishtar_common/templates/blocks/bs_formset_snippet.html index 3a7e537d3..cfc9bb37b 100644 --- a/ishtar_common/templates/blocks/bs_formset_snippet.html +++ b/ishtar_common/templates/blocks/bs_formset_snippet.html @@ -19,9 +19,9 @@ {% csrf_token %} {% for field in form.visible_fields %} - {% with bs_col_width='col-3' %} - {% include "blocks/bs_field_snippet.html" %} - {% endwith %} + {% ifequal field.name "DELETE" %}{% with bs_col_width='col-2' %}{% include "blocks/bs_field_snippet.html" %}{% endwith %} + {% else %}{% with bs_col_width='col-3' %}{% include "blocks/bs_field_snippet.html" %}{% endwith %} + {% endifequal %} {% endfor %} {% if form.extra_render %} |