diff options
| -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 %}  | 
