From 2836cae57302f572bf3993a53fc61d4ffe56f16e Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Thu, 8 Jul 2021 11:43:33 +0200 Subject: Files preventive - update model --- archaeological_files/admin.py | 8 +- archaeological_files/forms.py | 37 ++- .../migrations/0106_auto_20210622_1456.py | 255 ------------------ .../migrations/0106_auto_20210708_1044.py | 299 +++++++++++++++++++++ archaeological_files/models.py | 62 ++++- 5 files changed, 389 insertions(+), 272 deletions(-) delete mode 100644 archaeological_files/migrations/0106_auto_20210622_1456.py create mode 100644 archaeological_files/migrations/0106_auto_20210708_1044.py 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_20210622_1456.py deleted file mode 100644 index 2667a705d..000000000 --- a/archaeological_files/migrations/0106_auto_20210622_1456.py +++ /dev/null @@ -1,255 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.28 on 2021-06-22 14:56 -from __future__ import unicode_literals - -import django.core.validators -from django.db import migrations, models -import django.db.models.deletion -import ishtar_common.models_common -import re - - -class Migration(migrations.Migration): - - dependencies = [ - ('archaeological_files', '0105_auto_20201204_1442'), - ] - - operations = [ - migrations.CreateModel( - name='EquipmentCost', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('service_provider', models.CharField(default='-', max_length=200, verbose_name='Service provider')), - ('flat_rate', models.BooleanField(default=False, verbose_name='Flat rate')), - ('daily_cost', models.FloatField(blank=True, null=True, verbose_name='Daily cost')), - ('monday', models.BooleanField(default=True, verbose_name='Monday')), - ('tuesday', models.BooleanField(default=True, verbose_name='Tuesday')), - ('wednesday', models.BooleanField(default=True, verbose_name='Wednesday')), - ('thursday', models.BooleanField(default=True, verbose_name='Thursday')), - ('friday', models.BooleanField(default=True, verbose_name='Friday')), - ], - options={ - 'verbose_name': 'Equipment cost', - 'verbose_name_plural': 'Equipment costs', - }, - ), - migrations.CreateModel( - name='EquipmentType', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('label', models.TextField(verbose_name='Label')), - ('txt_idx', models.TextField(help_text='The slug is the standardized version of the name. It contains only lowercase letters, numbers and hyphens. Each slug must be unique.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z', 32), "Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens.", 'invalid')], verbose_name='Textual ID')), - ('comment', models.TextField(blank=True, default='', verbose_name='Comment')), - ('available', models.BooleanField(default=True, verbose_name='Available')), - ], - options={ - 'verbose_name': 'Equipment type', - 'verbose_name_plural': 'Equipment types', - 'ordering': ('label',), - }, - bases=(ishtar_common.models_common.Cached, models.Model), - ), - migrations.CreateModel( - name='GenericEquipmentType', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('label', models.TextField(verbose_name='Label')), - ('txt_idx', models.TextField(help_text='The slug is the standardized version of the name. It contains only lowercase letters, numbers and hyphens. Each slug must be unique.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z', 32), "Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens.", 'invalid')], verbose_name='Textual ID')), - ('comment', models.TextField(blank=True, default='', verbose_name='Comment')), - ('available', models.BooleanField(default=True, verbose_name='Available')), - ], - options={ - 'verbose_name': 'Generic equipment type', - 'verbose_name_plural': 'Generic equipment types', - 'ordering': ('label',), - }, - bases=(ishtar_common.models_common.Cached, models.Model), - ), - migrations.CreateModel( - name='Job', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('label', models.TextField(verbose_name='Label')), - ('txt_idx', models.TextField(help_text='The slug is the standardized version of the name. It contains only lowercase letters, numbers and hyphens. Each slug must be unique.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z', 32), "Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens.", 'invalid')], verbose_name='Textual ID')), - ('comment', models.TextField(blank=True, default='', verbose_name='Comment')), - ('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')), - ], - options={ - 'verbose_name': 'Job', - 'verbose_name_plural': 'Jobs', - 'ordering': ('label',), - }, - bases=(ishtar_common.models_common.Cached, models.Model), - ), - migrations.CreateModel( - name='ManDays', - 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')), - ], - ), - migrations.CreateModel( - name='TechnicalService', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('label', models.TextField(verbose_name='Label')), - ('txt_idx', models.TextField(help_text='The slug is the standardized version of the name. It contains only lowercase letters, numbers and hyphens. Each slug must be unique.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z', 32), "Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens.", 'invalid')], verbose_name='Textual ID')), - ('comment', models.TextField(blank=True, default='', verbose_name='Comment')), - ('available', models.BooleanField(default=True, verbose_name='Available')), - ], - options={ - 'verbose_name': 'Technical service', - 'verbose_name_plural': 'Technical services', - 'ordering': ('label',), - }, - bases=(ishtar_common.models_common.Cached, models.Model), - ), - migrations.CreateModel( - name='TechnicalServiceCost', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('service_provider', models.CharField(default='-', max_length=200, verbose_name='Service provider')), - ('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')), - ('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', - }, - ), - migrations.AddField( - model_name='file', - name='execution_report_date', - field=models.DateField(blank=True, null=True, verbose_name='Execution report date'), - ), - migrations.AddField( - model_name='file', - name='ground_end_date', - field=models.DateField(blank=True, null=True, verbose_name='Ground end date'), - ), - migrations.AddField( - model_name='file', - name='ground_start_date', - field=models.DateField(blank=True, null=True, verbose_name='Ground start date'), - ), - migrations.AddField( - model_name='file', - name='linear_meter', - field=models.IntegerField(blank=True, null=True, verbose_name='Linear meter'), - ), - migrations.AddField( - model_name='file', - name='start_date', - field=models.DateField(blank=True, null=True, verbose_name='Start date'), - ), - migrations.AddField( - model_name='file', - name='study_period', - field=models.CharField(blank=True, default='', max_length=200, verbose_name='Study period'), - ), - migrations.AddField( - model_name='historicalfile', - name='execution_report_date', - field=models.DateField(blank=True, null=True, verbose_name='Execution report date'), - ), - migrations.AddField( - model_name='historicalfile', - name='ground_end_date', - field=models.DateField(blank=True, null=True, verbose_name='Ground end date'), - ), - migrations.AddField( - model_name='historicalfile', - name='ground_start_date', - field=models.DateField(blank=True, null=True, verbose_name='Ground start date'), - ), - migrations.AddField( - model_name='historicalfile', - name='linear_meter', - field=models.IntegerField(blank=True, null=True, verbose_name='Linear meter'), - ), - migrations.AddField( - model_name='historicalfile', - name='start_date', - field=models.DateField(blank=True, null=True, verbose_name='Start date'), - ), - migrations.AddField( - model_name='historicalfile', - name='study_period', - field=models.CharField(blank=True, default='', max_length=200, verbose_name='Study period'), - ), - migrations.AlterField( - model_name='file', - name='end_date', - field=models.DateField(blank=True, null=True, verbose_name='End date'), - ), - migrations.AlterField( - model_name='historicalfile', - 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.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.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.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='equipmenttype', - name='generic_equipment_type', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='archaeological_files.GenericEquipmentType', verbose_name='Generic type'), - ), - migrations.AddField( - model_name='equipmentcost', - name='equipment_type', - 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'), - ), - ] diff --git a/archaeological_files/migrations/0106_auto_20210708_1044.py b/archaeological_files/migrations/0106_auto_20210708_1044.py new file mode 100644 index 000000000..c09f9338f --- /dev/null +++ b/archaeological_files/migrations/0106_auto_20210708_1044.py @@ -0,0 +1,299 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.28 on 2021-07-08 10:44 +from __future__ import unicode_literals + +import django.core.validators +from django.db import migrations, models +import django.db.models.deletion +import ishtar_common.models_common +import re + + +class Migration(migrations.Migration): + + dependencies = [ + ('archaeological_files', '0105_auto_20201204_1442'), + ] + + operations = [ + migrations.CreateModel( + name='EquipmentCost', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('service_provider', models.CharField(default='-', max_length=200, verbose_name='Service provider')), + ('flat_rate', models.BooleanField(default=False, verbose_name='Flat rate')), + ('daily_cost', models.FloatField(blank=True, null=True, verbose_name='Daily cost')), + ('monday', models.BooleanField(default=True, verbose_name='Monday')), + ('tuesday', models.BooleanField(default=True, verbose_name='Tuesday')), + ('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', + 'verbose_name_plural': 'Equipment costs', + }, + ), + migrations.CreateModel( + name='EquipmentType', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('label', models.TextField(verbose_name='Label')), + ('txt_idx', models.TextField(help_text='The slug is the standardized version of the name. It contains only lowercase letters, numbers and hyphens. Each slug must be unique.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z', 32), "Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens.", 'invalid')], verbose_name='Textual ID')), + ('comment', models.TextField(blank=True, default='', verbose_name='Comment')), + ('available', models.BooleanField(default=True, verbose_name='Available')), + ], + options={ + 'verbose_name': 'Equipment type', + 'verbose_name_plural': 'Equipment types', + 'ordering': ('label',), + }, + bases=(ishtar_common.models_common.Cached, models.Model), + ), + migrations.CreateModel( + name='GenericEquipmentType', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('label', models.TextField(verbose_name='Label')), + ('txt_idx', models.TextField(help_text='The slug is the standardized version of the name. It contains only lowercase letters, numbers and hyphens. Each slug must be unique.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z', 32), "Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens.", 'invalid')], verbose_name='Textual ID')), + ('comment', models.TextField(blank=True, default='', verbose_name='Comment')), + ('available', models.BooleanField(default=True, verbose_name='Available')), + ], + options={ + 'verbose_name': 'Generic equipment type', + 'verbose_name_plural': 'Generic equipment types', + 'ordering': ('label',), + }, + bases=(ishtar_common.models_common.Cached, models.Model), + ), + migrations.CreateModel( + name='Job', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('label', models.TextField(verbose_name='Label')), + ('txt_idx', models.TextField(help_text='The slug is the standardized version of the name. It contains only lowercase letters, numbers and hyphens. Each slug must be unique.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z', 32), "Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens.", 'invalid')], verbose_name='Textual ID')), + ('comment', models.TextField(blank=True, default='', verbose_name='Comment')), + ('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')), + ('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', + 'verbose_name_plural': 'Jobs', + 'ordering': ('label',), + }, + bases=(ishtar_common.models_common.Cached, models.Model), + ), + migrations.CreateModel( + 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')), + ('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='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', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('label', models.TextField(verbose_name='Label')), + ('txt_idx', models.TextField(help_text='The slug is the standardized version of the name. It contains only lowercase letters, numbers and hyphens. Each slug must be unique.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z', 32), "Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens.", 'invalid')], verbose_name='Textual ID')), + ('comment', models.TextField(blank=True, default='', verbose_name='Comment')), + ('available', models.BooleanField(default=True, verbose_name='Available')), + ], + options={ + 'verbose_name': 'Technical service', + 'verbose_name_plural': 'Technical services', + 'ordering': ('label',), + }, + bases=(ishtar_common.models_common.Cached, models.Model), + ), + migrations.CreateModel( + name='TechnicalServiceCost', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('service_provider', models.CharField(default='-', max_length=200, verbose_name='Service provider')), + ('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': 'Technical service cost', + 'verbose_name_plural': 'Technical service costs', + }, + ), + migrations.AddField( + model_name='file', + name='execution_report_date', + field=models.DateField(blank=True, null=True, verbose_name='Execution report date'), + ), + migrations.AddField( + model_name='file', + name='ground_end_date', + field=models.DateField(blank=True, null=True, verbose_name='Ground end date'), + ), + migrations.AddField( + model_name='file', + name='ground_start_date', + field=models.DateField(blank=True, null=True, verbose_name='Ground start date'), + ), + migrations.AddField( + model_name='file', + name='linear_meter', + field=models.IntegerField(blank=True, null=True, verbose_name='Linear meter'), + ), + migrations.AddField( + model_name='file', + name='start_date', + field=models.DateField(blank=True, null=True, verbose_name='Start date'), + ), + migrations.AddField( + model_name='file', + name='study_period', + field=models.CharField(blank=True, default='', max_length=200, verbose_name='Study period'), + ), + migrations.AddField( + model_name='historicalfile', + name='execution_report_date', + field=models.DateField(blank=True, null=True, verbose_name='Execution report date'), + ), + migrations.AddField( + model_name='historicalfile', + name='ground_end_date', + field=models.DateField(blank=True, null=True, verbose_name='Ground end date'), + ), + migrations.AddField( + model_name='historicalfile', + name='ground_start_date', + field=models.DateField(blank=True, null=True, verbose_name='Ground start date'), + ), + migrations.AddField( + model_name='historicalfile', + name='linear_meter', + field=models.IntegerField(blank=True, null=True, verbose_name='Linear meter'), + ), + migrations.AddField( + model_name='historicalfile', + name='start_date', + field=models.DateField(blank=True, null=True, verbose_name='Start date'), + ), + migrations.AddField( + model_name='historicalfile', + name='study_period', + field=models.CharField(blank=True, default='', max_length=200, verbose_name='Study period'), + ), + migrations.AlterField( + model_name='file', + name='end_date', + field=models.DateField(blank=True, null=True, verbose_name='End date'), + ), + migrations.AlterField( + model_name='historicalfile', + name='end_date', + field=models.DateField(blank=True, null=True, verbose_name='End date'), + ), + 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.AddField( + model_name='preventivefiletechnicalservicecost', + name='technical_service_cost', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='archaeological_files.TechnicalServiceCost'), + ), + 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.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', + name='generic_equipment_type', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='archaeological_files.GenericEquipmentType', verbose_name='Generic type'), + ), + migrations.AddField( + model_name='equipmentcost', + name='equipment_type', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='archaeological_files.EquipmentType', verbose_name='Equipment'), + ), + migrations.AddField( + 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) -- cgit v1.2.3