diff options
| -rw-r--r-- | archaeological_files/admin.py | 8 | ||||
| -rw-r--r-- | archaeological_files/forms.py | 37 | ||||
| -rw-r--r-- | archaeological_files/migrations/0106_auto_20210708_1044.py (renamed from archaeological_files/migrations/0106_auto_20210622_1456.py) | 128 | ||||
| -rw-r--r-- | archaeological_files/models.py | 62 | 
4 files changed, 176 insertions, 59 deletions
diff --git a/archaeological_files/admin.py b/archaeological_files/admin.py index 3c85fcdcd..9ba3d17d5 100644 --- a/archaeological_files/admin.py +++ b/archaeological_files/admin.py @@ -64,8 +64,14 @@ class FileAdmin(HistorizedObjectAdmin):  admin_site.register(models.File, FileAdmin) -general_models = [models.FileType, models.PermitType] +general_models = [ +    models.FileType, models.PermitType, models.Job, models.GenericEquipmentType, +    models.EquipmentType, models.TechnicalService, +]  if settings.COUNTRY == "fr":      general_models.append(models.SaisineType)  for model in general_models:      admin_site.register(model, GeneralTypeAdmin) + +admin_site.register(models.EquipmentCost) +admin_site.register(models.TechnicalServiceCost) diff --git a/archaeological_files/forms.py b/archaeological_files/forms.py index 1710a5560..8b5b3d00d 100644 --- a/archaeological_files/forms.py +++ b/archaeological_files/forms.py @@ -609,6 +609,7 @@ JOB_LABELS = {      "days_worked": _("Days"),  } +  class PreventiveFileJobForm(forms.ModelForm):      file_id = forms.IntegerField(widget=forms.HiddenInput) @@ -620,16 +621,15 @@ class PreventiveFileJobForm(forms.ModelForm):          labels = JOB_LABELS -  class PreventiveFileJobBaseFormSet(FileBaseFormset):      model = models.PreventiveFileJob  PreventiveFileJobFormSet = formset_factory(      PreventiveFileJobForm, formset=PreventiveFileJobBaseFormSet, can_delete=True) -PreventiveFileJobFormSet.form_label = _("Jobs") -PreventiveFileJobFormSet.form_admin_name = _("Preventive file - 030 - Jobs") -PreventiveFileJobFormSet.form_slug = "preventive-030-jobs" +PreventiveFileJobFormSet.form_label = _("Post-excavation") +PreventiveFileJobFormSet.form_admin_name = _("Preventive file - 030 - Post-excavation") +PreventiveFileJobFormSet.form_slug = "preventive-030-post-excavation"  PreventiveFileJobFormSet.dynamic_add = True @@ -658,15 +658,32 @@ PreventiveFileGroundJobFormSet.form_admin_name = _(  PreventiveFileGroundJobFormSet.form_slug = "preventive-040-ground-jobs"  PreventiveFileGroundJobFormSet.dynamic_add = True +COST_LABELS = { +    "quantity_by_day_planned": _("Quantity"), +    "days_planned": _("Days / weeks / months"), +    "quantity_by_day_worked": _("Quantity"), +    "days_worked": _("Days / weeks / months"), +} + +INLINE_COST_FIELDS = [ +    "quantity_by_day_planned", "days_planned", "quantity_by_day_worked", "days_worked"] + +COST_WIDGETS = { +    "quantity_by_day_planned": forms.NumberInput(attrs={"class": "w-50 form-planned"}), +    "days_planned": forms.NumberInput(attrs={"class": "w-50 form-planned"}), +    "quantity_by_day_worked": forms.NumberInput(attrs={"class": "w-50 form-worked"}), +    "days_worked": forms.NumberInput(attrs={"class": "w-50 form-worked"}) +} +  class PreventiveFileEquipmentForm(forms.ModelForm):      file_id = forms.IntegerField(widget=forms.HiddenInput)      class Meta:          model = models.PreventiveFileEquipmentCost -        fields = ["equipment_cost"] + INLINE_JOB_FIELDS -        widgets = JOB_WIDGETS -        labels = JOB_LABELS +        fields = ["equipment_cost"] + INLINE_COST_FIELDS +        widgets = COST_WIDGETS +        labels = COST_LABELS  class PreventiveFileEquipmentBaseFormSet(FileBaseFormset): @@ -688,9 +705,9 @@ class PreventiveFileTechnicalServiceForm(forms.ModelForm):      class Meta:          model = models.PreventiveFileTechnicalServiceCost -        fields = ["technical_service_cost"] + INLINE_JOB_FIELDS -        widgets = JOB_WIDGETS -        labels = JOB_LABELS +        fields = ["technical_service_cost"] + INLINE_COST_FIELDS +        widgets = COST_WIDGETS +        labels = COST_LABELS  class PreventiveFileTechnicalServiceBaseFormSet(FileBaseFormset): diff --git a/archaeological_files/migrations/0106_auto_20210622_1456.py b/archaeological_files/migrations/0106_auto_20210708_1044.py index 2667a705d..c09f9338f 100644 --- a/archaeological_files/migrations/0106_auto_20210622_1456.py +++ b/archaeological_files/migrations/0106_auto_20210708_1044.py @@ -1,5 +1,5 @@  # -*- coding: utf-8 -*- -# Generated by Django 1.11.28 on 2021-06-22 14:56 +# Generated by Django 1.11.28 on 2021-07-08 10:44  from __future__ import unicode_literals  import django.core.validators @@ -28,6 +28,7 @@ class Migration(migrations.Migration):                  ('wednesday', models.BooleanField(default=True, verbose_name='Wednesday')),                  ('thursday', models.BooleanField(default=True, verbose_name='Thursday')),                  ('friday', models.BooleanField(default=True, verbose_name='Friday')), +                ('order', models.IntegerField(default=10, verbose_name='Order')),              ],              options={                  'verbose_name': 'Equipment cost', @@ -79,6 +80,8 @@ class Migration(migrations.Migration):                  ('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')), +                ('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')),              ],              options={                  'verbose_name': 'Job', @@ -88,7 +91,34 @@ class Migration(migrations.Migration):              bases=(ishtar_common.models_common.Cached, models.Model),          ),          migrations.CreateModel( -            name='ManDays', +            name='PreventiveFileEquipmentCost', +            fields=[ +                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), +                ('quantity_by_day_planned', models.FloatField(blank=True, null=True, verbose_name='Quantity by day - planned')), +                ('days_planned', models.FloatField(blank=True, null=True, verbose_name='Days - planned')), +                ('quantity_by_day_worked', models.FloatField(blank=True, null=True, verbose_name='Quantity by day - worked')), +                ('days_worked', models.FloatField(blank=True, null=True, verbose_name='Days - worked')), +                ('equipment_cost', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='archaeological_files.EquipmentCost')), +            ], +            options={ +                'abstract': False, +            }, +        ), +        migrations.CreateModel( +            name='PreventiveFileGroundJob', +            fields=[ +                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), +                ('man_by_day_planned', models.FloatField(blank=True, null=True, verbose_name='Man by day - planned')), +                ('days_planned', models.FloatField(blank=True, null=True, verbose_name='Days - planned')), +                ('man_by_day_worked', models.FloatField(blank=True, null=True, verbose_name='Man by day - worked')), +                ('days_worked', models.FloatField(blank=True, null=True, verbose_name='Days - worked')), +            ], +            options={ +                'abstract': False, +            }, +        ), +        migrations.CreateModel( +            name='PreventiveFileJob',              fields=[                  ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),                  ('man_by_day_planned', models.FloatField(blank=True, null=True, verbose_name='Man by day - planned')), @@ -96,6 +126,22 @@ class Migration(migrations.Migration):                  ('man_by_day_worked', models.FloatField(blank=True, null=True, verbose_name='Man by day - worked')),                  ('days_worked', models.FloatField(blank=True, null=True, verbose_name='Days - worked')),              ], +            options={ +                'abstract': False, +            }, +        ), +        migrations.CreateModel( +            name='PreventiveFileTechnicalServiceCost', +            fields=[ +                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), +                ('quantity_by_day_planned', models.FloatField(blank=True, null=True, verbose_name='Quantity by day - planned')), +                ('days_planned', models.FloatField(blank=True, null=True, verbose_name='Days - planned')), +                ('quantity_by_day_worked', models.FloatField(blank=True, null=True, verbose_name='Quantity by day - worked')), +                ('days_worked', models.FloatField(blank=True, null=True, verbose_name='Days - worked')), +            ], +            options={ +                'abstract': False, +            },          ),          migrations.CreateModel(              name='TechnicalService', @@ -121,11 +167,13 @@ class Migration(migrations.Migration):                  ('flat_rate', models.BooleanField(default=False, verbose_name='Flat rate')),                  ('unitary_cost', models.FloatField(blank=True, null=True, verbose_name='Unitary cost')),                  ('unit', models.CharField(blank=True, choices=[('D', 'Days'), ('M', 'Linear meter')], max_length=1, null=True, verbose_name='Unit')), +                ('order', models.IntegerField(default=10, verbose_name='Order')), +                ('parents', models.ManyToManyField(blank=True, help_text='Auto-add this cost when a parent is added', related_name='_technicalservicecost_parents_+', to='archaeological_files.TechnicalServiceCost', verbose_name='Parents')),                  ('technical_service', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='archaeological_files.TechnicalService', verbose_name='Technical service')),              ],              options={ -                'verbose_name': 'Equipment cost', -                'verbose_name_plural': 'Equipment costs', +                'verbose_name': 'Technical service cost', +                'verbose_name_plural': 'Technical service costs',              },          ),          migrations.AddField( @@ -198,39 +246,40 @@ class Migration(migrations.Migration):              name='end_date',              field=models.DateField(blank=True, null=True, verbose_name='End date'),          ), -        migrations.CreateModel( -            name='PreventiveFileEquipmentCost', -            fields=[ -                ('mandays_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='archaeological_files.ManDays')), -            ], -            bases=('archaeological_files.mandays',), +        migrations.AddField( +            model_name='preventivefiletechnicalservicecost', +            name='file', +            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='technical_service_costs', to='archaeological_files.File'),          ), -        migrations.CreateModel( -            name='PreventiveFileGroundJob', -            fields=[ -                ('mandays_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='archaeological_files.ManDays')), -                ('file', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='ground_jobs', to='archaeological_files.File')), -                ('job', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='archaeological_files.Job')), -            ], -            bases=('archaeological_files.mandays',), +        migrations.AddField( +            model_name='preventivefiletechnicalservicecost', +            name='technical_service_cost', +            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='archaeological_files.TechnicalServiceCost'),          ), -        migrations.CreateModel( -            name='PreventiveFileJob', -            fields=[ -                ('mandays_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='archaeological_files.ManDays')), -                ('file', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='jobs', to='archaeological_files.File')), -                ('job', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='archaeological_files.Job')), -            ], -            bases=('archaeological_files.mandays',), +        migrations.AddField( +            model_name='preventivefilejob', +            name='file', +            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='jobs', to='archaeological_files.File'),          ), -        migrations.CreateModel( -            name='PreventiveFileTechnicalServiceCost', -            fields=[ -                ('mandays_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='archaeological_files.ManDays')), -                ('file', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='technical_service_costs', to='archaeological_files.File')), -                ('technical_service_cost', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='archaeological_files.TechnicalServiceCost')), -            ], -            bases=('archaeological_files.mandays',), +        migrations.AddField( +            model_name='preventivefilejob', +            name='job', +            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='archaeological_files.Job'), +        ), +        migrations.AddField( +            model_name='preventivefilegroundjob', +            name='file', +            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='ground_jobs', to='archaeological_files.File'), +        ), +        migrations.AddField( +            model_name='preventivefilegroundjob', +            name='job', +            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='archaeological_files.Job'), +        ), +        migrations.AddField( +            model_name='preventivefileequipmentcost', +            name='file', +            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='equipment_costs', to='archaeological_files.File'),          ),          migrations.AddField(              model_name='equipmenttype', @@ -243,13 +292,8 @@ class Migration(migrations.Migration):              field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='archaeological_files.EquipmentType', verbose_name='Equipment'),          ),          migrations.AddField( -            model_name='preventivefileequipmentcost', -            name='equipment_cost', -            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='archaeological_files.EquipmentCost'), -        ), -        migrations.AddField( -            model_name='preventivefileequipmentcost', -            name='file', -            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='equipment_costs', to='archaeological_files.File'), +            model_name='equipmentcost', +            name='parents', +            field=models.ManyToManyField(blank=True, help_text='Auto-add this cost when a parent is added', related_name='_equipmentcost_parents_+', to='archaeological_files.EquipmentCost', verbose_name='Parents'),          ),      ] diff --git a/archaeological_files/models.py b/archaeological_files/models.py index fde527ae1..87abd4083 100644 --- a/archaeological_files/models.py +++ b/archaeological_files/models.py @@ -77,6 +77,13 @@ class Job(GeneralType):          _("Default daily number needed on the ground"), default=0)      default_daily_need = models.FloatField(          _("Default daily number needed"), default=0) +    order = models.IntegerField(_("Order"), default=10) +    parents = models.ManyToManyField( +        "self", +        blank=True, +        verbose_name=_("Parents"), +        help_text=_("Auto-add this job when a parent is added") +    )      class Meta:          verbose_name = _("Job") @@ -113,6 +120,13 @@ class EquipmentCost(models.Model):      wednesday = models.BooleanField(_("Wednesday"), default=True)      thursday = models.BooleanField(_("Thursday"), default=True)      friday = models.BooleanField(_("Friday"), default=True) +    order = models.IntegerField(_("Order"), default=10) +    parents = models.ManyToManyField( +        "self", +        blank=True, +        verbose_name=_("Parents"), +        help_text=_("Auto-add this cost when a parent is added") +    )      class Meta:          verbose_name = _("Equipment cost") @@ -141,10 +155,17 @@ class TechnicalServiceCost(models.Model):      unitary_cost = models.FloatField(_("Unitary cost"), blank=True, null=True)      unit = models.CharField(_("Unit"), max_length=1, choices=TECH_UNITS,                              blank=True, null=True) +    order = models.IntegerField(_("Order"), default=10) +    parents = models.ManyToManyField( +        "self", +        blank=True, +        verbose_name=_("Parents"), +        help_text=_("Auto-add this cost when a parent is added") +    )      class Meta: -        verbose_name = _("Equipment cost") -        verbose_name_plural = _("Equipment costs") +        verbose_name = _("Technical service cost") +        verbose_name_plural = _("Technical service costs")  class FileType(GeneralType): @@ -1164,14 +1185,17 @@ class ManDays(models.Model):      days_worked = models.FloatField(          _("Days - worked"), null=True, blank=True) +    class Meta: +        abstract = True +      @property -    def man_days_planned(self): +    def quantity_planned(self):          if not self.days_planned or not self.man_by_day_planned:              return 0          return self.days_planned * self.man_by_day_planned      @property -    def man_days_worked(self): +    def quantity_worked(self):          if not self.days_worked or not self.man_by_day_worked:              return 0          return self.days_worked * self.man_by_day_worked @@ -1187,11 +1211,37 @@ class PreventiveFileJob(ManDays):      job = models.ForeignKey(Job) -class PreventiveFileEquipmentCost(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_worked = models.FloatField( +        _("Quantity by day - worked"), null=True, blank=True) +    days_worked = models.FloatField( +        _("Days - worked"), null=True, blank=True) + +    class Meta: +        abstract = True + +    @property +    def quantity_planned(self): +        if not self.days_planned or not self.quantity_by_day_planned: +            return 0 +        return self.days_planned * self.quantity_by_day_planned + +    @property +    def quantity_worked(self): +        if not self.days_worked or not self.quantity_by_day_worked: +            return 0 +        return self.days_worked * self.quantity_by_day_worked + + +class PreventiveFileEquipmentCost(TechDays):      file = models.ForeignKey(File, related_name="equipment_costs")      equipment_cost = models.ForeignKey(EquipmentCost) -class PreventiveFileTechnicalServiceCost(ManDays): +class PreventiveFileTechnicalServiceCost(TechDays):      file = models.ForeignKey(File, related_name="technical_service_costs")      technical_service_cost = models.ForeignKey(TechnicalServiceCost)  | 
