diff --git a/django/contatti_app/migrations/0001_initial.py b/django/contatti_app/migrations/0001_initial.py index dc86026..4842bf3 100644 --- a/django/contatti_app/migrations/0001_initial.py +++ b/django/contatti_app/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 4.1.7 on 2023-05-12 22:20 +# Generated by Django 4.1.7 on 2023-05-14 13:47 from django.db import migrations, models import django.db.models.deletion @@ -8,8 +8,8 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ("dati_geo_app", "0007_delete_indirizzo"), ("contenttypes", "0002_remove_content_type_name"), + ("dati_geo_app", "0007_delete_indirizzo"), ] operations = [ diff --git a/django/fattura_elettronica_app/admin.py b/django/fattura_elettronica_app/admin.py index d26fe76..cd914ae 100644 --- a/django/fattura_elettronica_app/admin.py +++ b/django/fattura_elettronica_app/admin.py @@ -506,7 +506,7 @@ class TipologiaDocumentaleAdmin(ImportExportModelAdmin): pass -@admin.register(models.DatiEstesiDettaglioFatturabile) +@admin.register(models.OggettoDaFatturare) class DatiEstesiDettaglioFatturabileAdmin(ImportExportModelAdmin): # resource = resources.DatiEstesiDettaglioFatturabileResource # list_per_page = 15 diff --git a/django/fattura_elettronica_app/migrations/0001_initial.py b/django/fattura_elettronica_app/migrations/0001_initial.py index dd59305..92bc83a 100644 --- a/django/fattura_elettronica_app/migrations/0001_initial.py +++ b/django/fattura_elettronica_app/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 4.1.7 on 2023-05-12 22:20 +# Generated by Django 4.1.7 on 2023-05-14 13:48 from django.db import migrations, models import django.db.models.deletion @@ -8,8 +8,8 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ("contenttypes", "0002_remove_content_type_name"), ("dati_geo_app", "0007_delete_indirizzo"), + ("contenttypes", "0002_remove_content_type_name"), ("contatti_app", "0001_initial"), ] @@ -288,39 +288,6 @@ class Migration(migrations.Migration): "verbose_name_plural": "datidocumentali", }, ), - migrations.CreateModel( - name="DatiEstesiDettaglioFatturabile", - fields=[ - ( - "id", - models.AutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("descrizione", models.CharField(max_length=1000, null=True)), - ( - "quantita", - models.DecimalField( - blank=True, decimal_places=4, max_digits=21, null=True - ), - ), - ( - "prezzo_unitario", - models.DecimalField( - blank=True, decimal_places=2, max_digits=21, null=True - ), - ), - ("data_inizio", models.DateField(blank=True, null=True)), - ("data_fine", models.DateField(blank=True, null=True)), - ], - options={ - "verbose_name": "datiestesidettagliofatturabile", - "verbose_name_plural": "datiestesidettagliofatturabile", - }, - ), migrations.CreateModel( name="DatiRitenuta", fields=[ @@ -404,16 +371,6 @@ class Migration(migrations.Migration): to="fattura_elettronica_app.aliquotaiva", ), ), - ( - "dati_estesi", - models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="DettaglioLinee_da_DatiEstesiDettaglioFatturabile_dati_estesi", - to="fattura_elettronica_app.datiestesidettagliofatturabile", - ), - ), ], options={ "verbose_name": "dettagliolinee", @@ -1226,6 +1183,49 @@ class Migration(migrations.Migration): "verbose_name_plural": "riferimentoddtnumerolinea", }, ), + migrations.CreateModel( + name="OggettoDaFatturare", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("descrizione", models.CharField(max_length=1000, null=True)), + ( + "quantita", + models.DecimalField( + blank=True, decimal_places=4, max_digits=21, null=True + ), + ), + ( + "prezzo_unitario", + models.DecimalField( + blank=True, decimal_places=2, max_digits=21, null=True + ), + ), + ("data_inizio", models.DateField(blank=True, null=True)), + ("data_fine", models.DateField(blank=True, null=True)), + ( + "unita_misura", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="DatiEstesiDettaglioFatturabile_da_UnitaMisura_unita_misura", + to="fattura_elettronica_app.unitamisura", + ), + ), + ], + options={ + "verbose_name": "OggettoDaFatturare", + "verbose_name_plural": "OggettoDaFatturare", + }, + ), migrations.AddField( model_name="iscrizionerea", name="socio_unico", @@ -1428,6 +1428,17 @@ class Migration(migrations.Migration): to="fattura_elettronica_app.fatturaelettronica", ), ), + migrations.AddField( + model_name="dettagliolinee", + name="riferimento_oggetto_fattura", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="DettaglioLinee_da_DatiEstesiDettaglioFatturabile_riferimento_oggetto_fattura", + to="fattura_elettronica_app.oggettodafatturare", + ), + ), migrations.AddField( model_name="dettagliolinee", name="sconto_maggiorazione", @@ -1734,17 +1745,6 @@ class Migration(migrations.Migration): "verbose_name_plural": "datifatturecollegate", }, ), - migrations.AddField( - model_name="datiestesidettagliofatturabile", - name="unita_misura", - field=models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="DatiEstesiDettaglioFatturabile_da_UnitaMisura_unita_misura", - to="fattura_elettronica_app.unitamisura", - ), - ), migrations.AddField( model_name="datidocumentali", name="dati_generali", diff --git a/django/fattura_elettronica_app/modello_database.xml b/django/fattura_elettronica_app/modello_database.xml index 3d5c41f..941af92 100644 --- a/django/fattura_elettronica_app/modello_database.xml +++ b/django/fattura_elettronica_app/modello_database.xml @@ -52,7 +52,7 @@ id - +
INTEGER NULL @@ -63,9 +63,9 @@ INTEGERNULL - + INTEGER -NULL +NULL INTEGER @@ -1044,9 +1044,9 @@ INTEGER NULL - + INTEGER -NULL +NULL id @@ -1226,7 +1226,7 @@ id
- +
INTEGER NULL diff --git a/django/fattura_elettronica_app/models.py b/django/fattura_elettronica_app/models.py index 7f76175..6782dd3 100644 --- a/django/fattura_elettronica_app/models.py +++ b/django/fattura_elettronica_app/models.py @@ -655,8 +655,8 @@ class DettaglioLinee(models.Model): riferimento_amministrazione = models.CharField(null=True, max_length=20) tipo_cessione_prestazione = models.ForeignKey('TipoCessionePrestazione', on_delete=models.CASCADE, null=True, blank=True, related_name="DettaglioLinee_da_TipoCessionePrestazione_tipo_cessione_prestazione") - dati_estesi = models.ForeignKey('DatiEstesiDettaglioFatturabile', on_delete=models.CASCADE, null=True, - blank=True, related_name="DettaglioLinee_da_DatiEstesiDettaglioFatturabile_dati_estesi") + riferimento_oggetto_fattura = models.ForeignKey('OggettoDaFatturare', on_delete=models.CASCADE, null=True, + blank=True, related_name="DettaglioLinee_da_DatiEstesiDettaglioFatturabile_riferimento_oggetto_fattura") class altroDatoGestionale(models.Model): @@ -804,13 +804,13 @@ class TipologiaDocumentale(models.Model): descrizione = models.CharField(null=True, max_length=100) -class DatiEstesiDettaglioFatturabile(models.Model): +class OggettoDaFatturare(models.Model): class Meta: - verbose_name = 'datiestesidettagliofatturabile' - verbose_name_plural = 'datiestesidettagliofatturabile' + verbose_name = 'OggettoDaFatturare' + verbose_name_plural = 'OggettoDaFatturare' def __str__(self): - return f"DatiEstesiDettaglioFatturabile (id: {self.id})" + return f"OggettoDaFatturare (id: {self.id})" unita_misura = models.ForeignKey('UnitaMisura', on_delete=models.CASCADE, null=True, blank=True, related_name="DatiEstesiDettaglioFatturabile_da_UnitaMisura_unita_misura") diff --git a/django/fattura_elettronica_app/resources.py b/django/fattura_elettronica_app/resources.py index d124cda..4eea2d1 100644 --- a/django/fattura_elettronica_app/resources.py +++ b/django/fattura_elettronica_app/resources.py @@ -266,4 +266,4 @@ class TipologiaDocumentaleResource(resources.ModelResource): class DatiEstesiDettaglioFatturabileResource(resources.ModelResource): class Meta: - model = models.DatiEstesiDettaglioFatturabile + model = models.OggettoDaFatturare diff --git a/django/fattura_elettronica_app/serializers.py b/django/fattura_elettronica_app/serializers.py index 153ae4f..4dcb8f2 100644 --- a/django/fattura_elettronica_app/serializers.py +++ b/django/fattura_elettronica_app/serializers.py @@ -4,19 +4,6 @@ from . import models # --------------- FINE PREFISSO TEMPLATE --------------- -class ModalitaLavoroSerializer(serializers.ModelSerializer): - class Meta: - model = models.ModalitaLavoro - fields = ('unita_misura_std', 'descrizione') - - -class DettaglioFatturabileSerializer(serializers.ModelSerializer): - class Meta: - model = models.DettaglioFatturabile - fields = ('offerta_riferimento', 'modalita_lavoro', - 'dati_estesi', 'flusso_di_ricavi') - - class FatturaElettronicaSerializer(serializers.ModelSerializer): class Meta: model = models.FatturaElettronica @@ -304,7 +291,7 @@ class DettaglioLineeSerializer(serializers.ModelSerializer): class Meta: model = models.DettaglioLinee fields = ('fattura_elettronica_body', 'numero_linea', 'sconto_maggiorazione', 'aliquota_iva', - 'riferimento_amministrazione', 'tipo_cessione_prestazione', 'dati_estesi') + 'riferimento_amministrazione', 'tipo_cessione_prestazione', 'riferimento_oggetto_fattura') class altroDatoGestionaleSerializer(serializers.ModelSerializer): @@ -377,7 +364,7 @@ class TipologiaDocumentaleSerializer(serializers.ModelSerializer): class DatiEstesiDettaglioFatturabileSerializer(serializers.ModelSerializer): class Meta: - model = models.DatiEstesiDettaglioFatturabile + model = models.OggettoDaFatturare fields = ('unita_misura', 'descrizione', 'quantita', 'prezzo_unitario', 'data_inizio', 'data_fine') diff --git a/django/fattura_elettronica_app/urls.py b/django/fattura_elettronica_app/urls.py index eb76735..1702b90 100644 --- a/django/fattura_elettronica_app/urls.py +++ b/django/fattura_elettronica_app/urls.py @@ -12,7 +12,7 @@ router = routers.DefaultRouter() # --------------- FINE PREFISSO TEMPLATE --------------- router.register(r'modalitalavoro', views.ModalitaLavoro_View) -router.register(r'dettagliofatturabile', views.DettaglioFatturabile_View) +router.register(r'AtomoFatturabile', views.DettaglioFatturabile_View) router.register(r'fatturaelettronica', views.FatturaElettronica_View) router.register(r'regimefiscale', views.RegimeFiscale_View) router.register(r'tipocassa', views.TipoCassa_View) @@ -75,7 +75,7 @@ router.register(r'riferimentoordineacquistonumerolinea', views.RiferimentoOrdineAcquistoNumeroLinea_View) router.register(r'codicidocumentali', views.CodiciDocumentali_View) router.register(r'tipologiadocumentale', views.TipologiaDocumentale_View) -router.register(r'datiestesidettagliofatturabile', +router.register(r'OggettoDaFatturare', views.DatiEstesiDettaglioFatturabile_View) router.register(r'sede', views.Sede_View) router.register(r'fax', views.Fax_View) diff --git a/django/fattura_elettronica_app/views.py b/django/fattura_elettronica_app/views.py index 10cfaf3..ca3c080 100644 --- a/django/fattura_elettronica_app/views.py +++ b/django/fattura_elettronica_app/views.py @@ -31,7 +31,7 @@ class DettaglioFatturabile_View(viewsets.ModelViewSet): # authentication_classes = [BasicAuthentication, SessionAuthentication, TokenAuthentication] # permission_classes = [DjangoModelPermissions] - queryset = models.DettaglioFatturabile.objects.all() + queryset = models.AtomoFatturabile.objects.all() serializer_class = serializers.DettaglioFatturabileSerializer @@ -503,7 +503,7 @@ class DatiEstesiDettaglioFatturabile_View(viewsets.ModelViewSet): # authentication_classes = [BasicAuthentication, SessionAuthentication, TokenAuthentication] # permission_classes = [DjangoModelPermissions] - queryset = models.DatiEstesiDettaglioFatturabile.objects.all() + queryset = models.OggettoDaFatturare.objects.all() serializer_class = serializers.DatiEstesiDettaglioFatturabileSerializer diff --git a/django/business_model_canvas_app/migrations/__init__.py b/django/offerte_app/__init__.py similarity index 100% rename from django/business_model_canvas_app/migrations/__init__.py rename to django/offerte_app/__init__.py diff --git a/django/offerte_app/admin.py b/django/offerte_app/admin.py new file mode 100644 index 0000000..679d68a --- /dev/null +++ b/django/offerte_app/admin.py @@ -0,0 +1,92 @@ +from import_export.admin import ImportExportModelAdmin +from django.contrib import admin +# from django.core.cache import cache +# from django.core.paginator import Paginator +from . import models +from . import resources + + +# # Modified version of a GIST I found in a SO thread +# # cfr. http://masnun.rocks/2017/03/20/django-admin-expensive-count-all-queries/ +# class CachingPaginator(Paginator): +# def _get_count(self): +# if not hasattr(self, "_count"): +# self._count = None +# if self._count is None: +# try: +# key = "adm:{0}:count".format(hash(self.object_list.query.__str__())) +# self._count = cache.get(key, -1) +# if self._count == -1: +# self._count = super().count +# cache.set(key, self._count, 60) +# except: +# self._count = len(self.object_list) +# return self._count +# count = property(_get_count) + +# # Main reusable Admin class for only viewing +# class ViewAdminMixin(admin.ModelAdmin): +# def has_add_permission(self, request): +# return False +# +# def has_change_permission(self, request, obj=None): +# return False +# +# def has_delete_permission(self, request, obj=None): +# return False + +# --------------- FINE PREFISSO TEMPLATE --------------- +@admin.register(models.DestinatarioOfferta) +class DestinatarioOffertaAdmin(ImportExportModelAdmin): + # resource = resources.DestinatarioOffertaResource + # list_per_page = 15 + # paginator = CachingPaginator + # show_full_result_count = False + pass + + +@admin.register(models.GruppoOfferte) +class GruppoOfferteAdmin(ImportExportModelAdmin): + # resource = resources.GruppoOfferteResource + # list_per_page = 15 + # paginator = CachingPaginator + # show_full_result_count = False + pass + + +@admin.register(models.Offerta) +class OffertaAdmin(ImportExportModelAdmin): + # resource = resources.OffertaResource + # list_per_page = 15 + # paginator = CachingPaginator + # show_full_result_count = False + pass + + +@admin.register(models.AgenteOfferta) +class AgenteOffertaAdmin(ImportExportModelAdmin): + # resource = resources.AgenteOffertaResource + # list_per_page = 15 + # paginator = CachingPaginator + # show_full_result_count = False + pass + + +@admin.register(models.ParteEconomicaOfferta) +class ParteEconomicaOffertaAdmin(ImportExportModelAdmin): + # resource = resources.ParteEconomicaOffertaResource + # list_per_page = 15 + # paginator = CachingPaginator + # show_full_result_count = False + pass + + +@admin.register(models.TipologiaOfferta) +class TipologiaOffertaAdmin(ImportExportModelAdmin): + # resource = resources.TipologiaOffertaResource + # list_per_page = 15 + # paginator = CachingPaginator + # show_full_result_count = False + pass + + diff --git a/django/offerte_app/apps.py b/django/offerte_app/apps.py new file mode 100644 index 0000000..709db0d --- /dev/null +++ b/django/offerte_app/apps.py @@ -0,0 +1,12 @@ +import pathlib + +from django.apps import AppConfig + + +class OfferteAppConfig(AppConfig): + name = 'offerte_app' + verbose_name = 'Offerte' + path = pathlib.Path(__file__).parent + + def ready(self): + from . import signals diff --git a/django/offerte_app/consumers.py b/django/offerte_app/consumers.py new file mode 100644 index 0000000..f11bdce --- /dev/null +++ b/django/offerte_app/consumers.py @@ -0,0 +1,17 @@ + +import json +from channels.generic.websocket import WebsocketConsumer +from asgiref.sync import async_to_sync + + +class WsConsumer(WebsocketConsumer): + def connect(self): + self.accept() + print("accept ws connection") + + def disconnect(self, close_code): + print("ws disconnection") + + def receive(self, text_data): + text_data_json = json.loads(text_data) + print("ws receive", text_data_json) diff --git a/django/business_model_canvas_app/migrations/0001_initial.py b/django/offerte_app/migrations/0001_initial.py similarity index 51% rename from django/business_model_canvas_app/migrations/0001_initial.py rename to django/offerte_app/migrations/0001_initial.py index 4b19a5a..8ea0c65 100644 --- a/django/business_model_canvas_app/migrations/0001_initial.py +++ b/django/offerte_app/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 4.1.7 on 2023-05-12 22:46 +# Generated by Django 4.1.7 on 2023-05-14 13:48 from django.db import migrations, models import django.db.models.deletion @@ -7,11 +7,14 @@ import django.db.models.deletion class Migration(migrations.Migration): initial = True - dependencies = [] + dependencies = [ + ("contatti_app", "0001_initial"), + ("fattura_elettronica_app", "0001_initial"), + ] operations = [ migrations.CreateModel( - name="BMCModelloDiBusiness", + name="AgenteOfferta", fields=[ ( "id", @@ -22,15 +25,112 @@ class Migration(migrations.Migration): verbose_name="ID", ), ), + ("codice", models.IntegerField(blank=True, null=True)), + ], + options={ + "verbose_name": "agenteofferta", + "verbose_name_plural": "agenteofferta", + }, + ), + migrations.CreateModel( + name="AtomoFatturabile", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ], + options={ + "verbose_name": "AtomoFatturabile", + "verbose_name_plural": "AtomoFatturabile", + }, + ), + migrations.CreateModel( + name="DestinatarioOfferta", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "destinazione", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="DestinatarioOfferta_da_Sede_destinazione", + to="contatti_app.sede", + ), + ), + ( + "intestatario", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="DestinatarioOfferta_da_contatti_appPersonaContattoAzienda_intestatario", + to="contatti_app.personacontattoazienda", + ), + ), + ], + options={ + "verbose_name": "destinatarioofferta", + "verbose_name_plural": "destinatarioofferta", + }, + ), + migrations.CreateModel( + name="GruppoOfferte", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("anno_1a_rev", models.IntegerField(blank=True, null=True)), + ("numero", models.IntegerField(blank=True, null=True)), ("descrizione", models.CharField(max_length=4096, null=True)), + ( + "agente", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="GruppoOfferte_da_AgenteOfferta_agente", + to="offerte_app.agenteofferta", + ), + ), + ( + "destinatario", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="GruppoOfferte_da_DestinatarioOfferta_destinatario", + to="offerte_app.destinatarioofferta", + ), + ), ], options={ - "verbose_name": "bmcmodellodibusiness", - "verbose_name_plural": "bmcmodellodibusiness", + "verbose_name": "gruppoofferte", + "verbose_name_plural": "gruppoofferte", }, ), migrations.CreateModel( - name="BMCSegmentiDiClientela", + name="Offerta", fields=[ ( "id", @@ -41,25 +141,29 @@ class Migration(migrations.Migration): verbose_name="ID", ), ), - ("settore_cliente", models.IntegerField(blank=True, null=True)), + ("data", models.DateField(blank=True, null=True)), + ("revisione", models.IntegerField(blank=True, null=True)), + ("documento", models.CharField(max_length=128, null=True)), + ("codice_offerta", models.IntegerField(blank=True, null=True)), + ("accettazione", models.DateField(blank=True, null=True)), ( - "modello_di_business", + "gruppo", models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, - related_name="BMCSegmentiDiClientela_da_BMCModelloDiBusiness_modello_di_business", - to="business_model_canvas_app.bmcmodellodibusiness", + related_name="Offerta_da_GruppoOfferte_gruppo", + to="offerte_app.gruppoofferte", ), ), ], options={ - "verbose_name": "bmcsegmentidiclientela", - "verbose_name_plural": "bmcsegmentidiclientela", + "verbose_name": "offerta", + "verbose_name_plural": "offerta", }, ), migrations.CreateModel( - name="BMCRisorsaChiave", + name="TipologiaOfferta", fields=[ ( "id", @@ -70,25 +174,15 @@ class Migration(migrations.Migration): verbose_name="ID", ), ), - ("risorsa_chiave", models.IntegerField(blank=True, null=True)), - ( - "modello_di_business", - models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="BMCRisorsaChiave_da_BMCModelloDiBusiness_modello_di_business", - to="business_model_canvas_app.bmcmodellodibusiness", - ), - ), + ("descrizione", models.CharField(max_length=1024, null=True)), ], options={ - "verbose_name": "bmcrisorsachiave", - "verbose_name_plural": "bmcrisorsachiave", + "verbose_name": "tipologiaofferta", + "verbose_name_plural": "tipologiaofferta", }, ), migrations.CreateModel( - name="BMCRelazioneConCliente", + name="ParteEconomicaOfferta", fields=[ ( "id", @@ -99,25 +193,34 @@ class Migration(migrations.Migration): verbose_name="ID", ), ), - ("relazione_cliente", models.IntegerField(blank=True, null=True)), ( - "modello_di_business", + "dettaglio_economico_offerto", models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, - related_name="BMCRelazioneConCliente_da_BMCModelloDiBusiness_modello_di_business", - to="business_model_canvas_app.bmcmodellodibusiness", + related_name="ParteEconomicaOfferta_da_DettaglioFatturabile_dettaglio_economico_offerto", + to="offerte_app.atomofatturabile", + ), + ), + ( + "revisione", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="ParteEconomicaOfferta_da_Offerta_revisione", + to="offerte_app.offerta", ), ), ], options={ - "verbose_name": "bmcrelazioneconcliente", - "verbose_name_plural": "bmcrelazioneconcliente", + "verbose_name": "parteeconomicaofferta", + "verbose_name_plural": "parteeconomicaofferta", }, ), migrations.CreateModel( - name="BMCPropostaDiValore", + name="ModalitaLavoro", fields=[ ( "id", @@ -128,137 +231,65 @@ class Migration(migrations.Migration): verbose_name="ID", ), ), - ("proposta_di_valore", models.IntegerField(blank=True, null=True)), + ("descrizione", models.IntegerField(blank=True, null=True)), ( - "modello_di_business", + "unita_misura_std", models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, - related_name="BMCPropostaDiValore_da_BMCModelloDiBusiness_modello_di_business", - to="business_model_canvas_app.bmcmodellodibusiness", + related_name="ModalitaLavoro_da_UnitaMisura_unita_misura_std", + to="fattura_elettronica_app.unitamisura", ), ), ], options={ - "verbose_name": "bmcpropostadivalore", - "verbose_name_plural": "bmcpropostadivalore", + "verbose_name": "modalitalavoro", + "verbose_name_plural": "modalitalavoro", }, ), - migrations.CreateModel( - name="BMCPartnerChiave", - fields=[ - ( - "id", - models.AutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("partnership_azienda", models.IntegerField(blank=True, null=True)), - ( - "modello_di_business", - models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="BMCPartnerChiave_da_BMCModelloDiBusiness_modello_di_business", - to="business_model_canvas_app.bmcmodellodibusiness", - ), - ), - ], - options={ - "verbose_name": "bmcpartnerchiave", - "verbose_name_plural": "bmcpartnerchiave", - }, + migrations.AddField( + model_name="gruppoofferte", + name="tipo", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="GruppoOfferte_da_TipologiaOfferta_tipo", + to="offerte_app.tipologiaofferta", + ), ), - migrations.CreateModel( - name="BMCFlussoDiRicavi", - fields=[ - ( - "id", - models.AutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("flusso_di_ricavi", models.IntegerField(blank=True, null=True)), - ( - "modello_di_business", - models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="BMCFlussoDiRicavi_da_BMCModelloDiBusiness_modello_di_business", - to="business_model_canvas_app.bmcmodellodibusiness", - ), - ), - ], - options={ - "verbose_name": "bmcflussodiricavi", - "verbose_name_plural": "bmcflussodiricavi", - }, + migrations.AddField( + model_name="atomofatturabile", + name="modalita_lavoro", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="DettaglioFatturabile_da_ModalitaLavoro_modalita_lavoro", + to="offerte_app.modalitalavoro", + ), ), - migrations.CreateModel( - name="BMCCanaleDiDistribuzione", - fields=[ - ( - "id", - models.AutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("canale", models.IntegerField(blank=True, null=True)), - ( - "modello_di_business", - models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="BMCCanaleDiDistribuzione_da_BMCModelloDiBusiness_modello_di_business", - to="business_model_canvas_app.bmcmodellodibusiness", - ), - ), - ], - options={ - "verbose_name": "bmccanaledidistribuzione", - "verbose_name_plural": "bmccanaledidistribuzione", - }, + migrations.AddField( + model_name="atomofatturabile", + name="offerta_riferimento", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="DettaglioFatturabile_da_Offerta_offerta_riferimento", + to="offerte_app.offerta", + ), ), - migrations.CreateModel( - name="BMCAttivitaChiave", - fields=[ - ( - "id", - models.AutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("attivita_chiave", models.IntegerField(blank=True, null=True)), - ( - "modello_di_business", - models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="BMCAttivitaChiave_da_BMCModelloDiBusiness_modello_di_business", - to="business_model_canvas_app.bmcmodellodibusiness", - ), - ), - ], - options={ - "verbose_name": "bmcattivitachiave", - "verbose_name_plural": "bmcattivitachiave", - }, + migrations.AddField( + model_name="atomofatturabile", + name="riferimento_oggetto_fattura", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="DettaglioFatturabile_da_DatiEstesiDettaglioFatturabile_riferimento_oggetto_fattura", + to="fattura_elettronica_app.oggettodafatturare", + ), ), ] diff --git a/django/offerte_app/migrations/__init__.py b/django/offerte_app/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/django/offerte_app/modello_database.xml b/django/offerte_app/modello_database.xml new file mode 100644 index 0000000..7e81ec3 --- /dev/null +++ b/django/offerte_app/modello_database.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/django/offerte_app/models.py b/django/offerte_app/models.py new file mode 100644 index 0000000..28c3b0b --- /dev/null +++ b/django/offerte_app/models.py @@ -0,0 +1,119 @@ +from django.db import models + +# --------------- FINE PREFISSO TEMPLATE --------------- +class DestinatarioOfferta(models.Model): + class Meta: + verbose_name = 'destinatarioofferta' + verbose_name_plural = 'destinatarioofferta' + + def __str__(self): + return f"DestinatarioOfferta (id: {self.id})" + + destinazione = models.ForeignKey('contatti_app.Sede', on_delete=models.CASCADE, null=True, + blank=True, related_name="DestinatarioOfferta_da_Sede_destinazione") + intestatario = models.ForeignKey('contatti_app.PersonaContattoAzienda', on_delete=models.CASCADE, null=True, + blank=True, related_name="DestinatarioOfferta_da_contatti_appPersonaContattoAzienda_intestatario") + + +class GruppoOfferte(models.Model): + class Meta: + verbose_name = 'gruppoofferte' + verbose_name_plural = 'gruppoofferte' + + def __str__(self): + return f"GruppoOfferte (id: {self.id})" + + destinatario = models.ForeignKey('DestinatarioOfferta', on_delete=models.CASCADE, null=True, + blank=True, related_name="GruppoOfferte_da_DestinatarioOfferta_destinatario") + agente = models.ForeignKey('AgenteOfferta', on_delete=models.CASCADE, null=True, + blank=True, related_name="GruppoOfferte_da_AgenteOfferta_agente") + tipo = models.ForeignKey('TipologiaOfferta', on_delete=models.CASCADE, null=True, + blank=True, related_name="GruppoOfferte_da_TipologiaOfferta_tipo") + anno_1a_rev = models.IntegerField(null=True, blank=True) + numero = models.IntegerField(null=True, blank=True) + descrizione = models.CharField(null=True, max_length=4096) + + +class Offerta(models.Model): + class Meta: + verbose_name = 'offerta' + verbose_name_plural = 'offerta' + + def __str__(self): + return f"Offerta (id: {self.id})" + + gruppo = models.ForeignKey('GruppoOfferte', on_delete=models.CASCADE, + null=True, blank=True, related_name="Offerta_da_GruppoOfferte_gruppo") + data = models.DateField(null=True, blank=True) + revisione = models.IntegerField(null=True, blank=True) + documento = models.CharField(null=True, max_length=128) + codice_offerta = models.IntegerField(null=True, blank=True) + accettazione = models.DateField(null=True, blank=True) + + +class AgenteOfferta(models.Model): + class Meta: + verbose_name = 'agenteofferta' + verbose_name_plural = 'agenteofferta' + + def __str__(self): + return f"AgenteOfferta (id: {self.id})" + + codice = models.IntegerField(null=True, blank=True) + + +class ModalitaLavoro(models.Model): + class Meta: + verbose_name = 'modalitalavoro' + verbose_name_plural = 'modalitalavoro' + + def __str__(self): + return f"ModalitaLavoro (id: {self.id})" + + unita_misura_std = models.ForeignKey('fattura_elettronica_app.UnitaMisura', on_delete=models.CASCADE, null=True, + blank=True, related_name="ModalitaLavoro_da_UnitaMisura_unita_misura_std") + descrizione = models.IntegerField(null=True, blank=True) + + +class AtomoFatturabile(models.Model): + class Meta: + verbose_name = 'AtomoFatturabile' + verbose_name_plural = 'AtomoFatturabile' + + def __str__(self): + return f"AtomoFatturabile (id: {self.id})" + + offerta_riferimento = models.ForeignKey('Offerta', on_delete=models.CASCADE, null=True, + blank=True, related_name="DettaglioFatturabile_da_Offerta_offerta_riferimento") + modalita_lavoro = models.ForeignKey('ModalitaLavoro', on_delete=models.CASCADE, null=True, + blank=True, related_name="DettaglioFatturabile_da_ModalitaLavoro_modalita_lavoro") + riferimento_oggetto_fattura = models.ForeignKey('fattura_elettronica_app.OggettoDaFatturare', on_delete=models.CASCADE, null=True, + blank=True, related_name="DettaglioFatturabile_da_DatiEstesiDettaglioFatturabile_riferimento_oggetto_fattura") + # flusso_di_ricavi = models.ForeignKey('FlussoDiRicavi', on_delete=models.CASCADE, null=True, + # blank=True, related_name="DettaglioFatturabile_da_FlussoDiRicavi_flusso_di_ricavi") + +class ParteEconomicaOfferta(models.Model): + class Meta: + verbose_name = 'parteeconomicaofferta' + verbose_name_plural = 'parteeconomicaofferta' + + def __str__(self): + return f"ParteEconomicaOfferta (id: {self.id})" + + revisione = models.ForeignKey('Offerta', on_delete=models.CASCADE, null=True, + blank=True, related_name="ParteEconomicaOfferta_da_Offerta_revisione") + dettaglio_economico_offerto = models.ForeignKey('AtomoFatturabile', on_delete=models.CASCADE, null=True, + blank=True, related_name="ParteEconomicaOfferta_da_DettaglioFatturabile_dettaglio_economico_offerto") + + +class TipologiaOfferta(models.Model): + class Meta: + verbose_name = 'tipologiaofferta' + verbose_name_plural = 'tipologiaofferta' + + def __str__(self): + return f"TipologiaOfferta (id: {self.id})" + + descrizione = models.CharField(null=True, max_length=1024) + + diff --git a/django/offerte_app/resources.py b/django/offerte_app/resources.py new file mode 100644 index 0000000..65c5248 --- /dev/null +++ b/django/offerte_app/resources.py @@ -0,0 +1,34 @@ +from import_export import resources +from . import models + +# --------------- FINE PREFISSO TEMPLATE --------------- +class DestinatarioOffertaResource(resources.ModelResource): + class Meta: + model = models.DestinatarioOfferta + + +class GruppoOfferteResource(resources.ModelResource): + class Meta: + model = models.GruppoOfferte + + +class OffertaResource(resources.ModelResource): + class Meta: + model = models.Offerta + + +class AgenteOffertaResource(resources.ModelResource): + class Meta: + model = models.AgenteOfferta + + +class ParteEconomicaOffertaResource(resources.ModelResource): + class Meta: + model = models.ParteEconomicaOfferta + + +class TipologiaOffertaResource(resources.ModelResource): + class Meta: + model = models.TipologiaOfferta + + diff --git a/django/offerte_app/serializers.py b/django/offerte_app/serializers.py new file mode 100644 index 0000000..ba9f676 --- /dev/null +++ b/django/offerte_app/serializers.py @@ -0,0 +1,55 @@ +from rest_framework import serializers +from . import models + +# --------------- FINE PREFISSO TEMPLATE --------------- +class DestinatarioOffertaSerializer(serializers.ModelSerializer): + class Meta: + model = models.DestinatarioOfferta + fields = ('destinazione', 'intestatario') + + +class GruppoOfferteSerializer(serializers.ModelSerializer): + class Meta: + model = models.GruppoOfferte + fields = ('destinatario', 'agente', 'tipo', + 'anno_1a_rev', 'numero', 'descrizione') + + +class OffertaSerializer(serializers.ModelSerializer): + class Meta: + model = models.Offerta + fields = ('gruppo', 'data', 'revisione', 'documento', + 'codice_offerta', 'accettazione') + + +class AgenteOffertaSerializer(serializers.ModelSerializer): + class Meta: + model = models.AgenteOfferta + fields = ('codice') + + +class ParteEconomicaOffertaSerializer(serializers.ModelSerializer): + class Meta: + model = models.ParteEconomicaOfferta + fields = ('revisione', 'dettaglio_economico_offerto') + + +class TipologiaOffertaSerializer(serializers.ModelSerializer): + class Meta: + model = models.TipologiaOfferta + fields = ('descrizione') + + +class ModalitaLavoroSerializer(serializers.ModelSerializer): + class Meta: + model = models.ModalitaLavoro + fields = ('unita_misura_std', 'descrizione') + + +class DettaglioFatturabileSerializer(serializers.ModelSerializer): + class Meta: + model = models.AtomoFatturabile + fields = ('offerta_riferimento', 'modalita_lavoro', + 'riferimento_oggetto_fattura')#, 'flusso_di_ricavi') + + diff --git a/django/offerte_app/signals.py b/django/offerte_app/signals.py new file mode 100644 index 0000000..418cbb8 --- /dev/null +++ b/django/offerte_app/signals.py @@ -0,0 +1,8 @@ +from django.db.models.signals import pre_save, post_save, pre_delete, post_delete +from django.dispatch import receiver +from . import models + +# @receiver(pre_save, sender=models.ExampleModel) +# def example_callback(sender, instance, created=False, **kwargs): +# if kwargs['raw'] or created: +# return diff --git a/django/offerte_app/sqldes2django.py b/django/offerte_app/sqldes2django.py new file mode 100755 index 0000000..89b438d --- /dev/null +++ b/django/offerte_app/sqldes2django.py @@ -0,0 +1,480 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +sqldes2django. + +Usage: + sqldes2django.py write [--tgt-dir=] [--unmanaged=] [--models-file=] [--serializers-file=] [--views-file=] [--urls-file=] [--admin-file=] [--resources-file=] [--no-format] [--xml=] + sqldes2django.py (-h | --help) + sqldes2django.py (--version) + + +Options: + --tgt-dir= Directory di output [default: .]. + --xml= Directory di output [default: modello_database.xml]. + --models-file= Nome del file dei modelli [default: /models.py]. + --serializers-file= Nome del file dei serializers [default: /serializers.py]. + --views-file= Nome del file delle views [default: /views.py]. + --urls-file= Nome del file degli url [default: /urls.py]. + --admin-file= Nome del file dell'admin [default: /admin.py]. + --resources-file= Nome del file delle resources [default: /resources.py]. + --no-format Non formattare l'output con autopep8. + --unmanaged= Crea modelli unmanaged (senza migrazioni): supporta pk e fk multiple, setta database= + --version Show version. + -h --help Show this screen. +""" +import xml.etree.ElementTree as ET +from collections import defaultdict +import lark +import os +import sys +import autopep8 +import re +from docopt import docopt +""" +Created on Thu Feb 28 15:28:17 2019 + +@author: guido +""" +# TODO: Validare nomi per uso con Django +# TODO: Trattare le chiavi primarie manuali e le chiavi primarie composite +# TODO: Aggiungere tipi mancanti alla mappa + + +if __name__ == '__main__': + arguments = docopt(__doc__, version='Sqldes2django 0.1') + for arg in arguments: + if isinstance(arguments[arg], str): + arguments[arg] = arguments[arg].replace("", + arguments['--tgt-dir']) + + tgtdir = arguments['--tgt-dir'] + + unmanaged = False + if arguments['--unmanaged']: + unmanaged = True + nome_db = arguments['--unmanaged'] + print(arguments) + + tgtfil = {x: arguments["--" + x + "-file"] + for x in ('models', 'admin', 'serializers', 'views', 'urls', 'resources',)} + + sql_type_grammar = lark.Lark(r""" + %import common.ESCAPED_STRING + %import common.SIGNED_NUMBER + %import common.WS + %import common.CNAME + %ignore WS + + tipo: costruttore | costruttore "(" [arg ("," arg)* ] ")" + ?costruttore: CNAME + ?arg: val | keyword_argument + val: SIGNED_NUMBER | ESCAPED_STRING + keyword_argument: CNAME "=" val""", + parser="lalr", + start="tipo") # TODO: leggere lo standard vero sql + + def tutti_parametri(stringa_orig): + params = sql_type_grammar.parse(stringa_orig) + parametri = params.children[1:] + posizionali = [] + keyword_args = {} + trovato_kw = False + for x in parametri: + if x.data == "val": + assert not trovato_kw, f"Argomento posizionale non può seguire keyword argument in '{stringa_orig}'" + posizionali.append(x.children[0].value) + if x.data == "keyword_argument": + trovato_kw = True + keyword_args[x.children[0].value] = x.children[1].children[0].value + return {"costruttore": params.children[0].value, "posizionali": posizionali, "keyword_args": keyword_args, "stringa": stringa_orig} + + def get_tipo_mappato(parsato): + tipodato = parsato['costruttore'].upper() + return mappa_tipi[tipodato] + + def is_parametrico(parsato): + return len(parsato["posizionali"]) > 0 or len(parsato["keyword_args"]) > 0 + + def get_parametro(parametri, positional=None, keyword=None): + if keyword is not None and keyword in parametri['keyword_args']: + val = parametri['keyword_args'][keyword] + del parametri['keyword_args'][keyword] + return val + if positional is not None: + try: + return parametri['posizionali'][positional] + except IndexError as e: + raise Exception( + f"Richiesti almeno {positional + 1} argomenti posizionali, trovati {len(parametri['posizionali'])} in {parametri['stringa']}") from e + raise Exception("Occorre specificare positional o keyword") + + fine_prefisso_RE = re.compile(r'# +-+ +FINE PREFISSO TEMPLATE +-+') + def leggi_prefisso(nome_modulo): + tmpl_prefisso = [] + with open(tgtfil[nome_modulo]) as fp: + for l in fp.readlines(): + tmpl_prefisso.append(l) + if fine_prefisso_RE.search(l): + break + return ''.join(tmpl_prefisso) + + + multifkimport = "from compositefk.fields import CompositeForeignKey # Installa django-composite-foreignkey" + multipkmodel = """ +class MultiPkModel(models.Model): + class Meta: + abstract = True + def save(self, *args, **kwargs): + raise NotImplementedError("È un MultiPkModel") + # TODO + def __hash__(self): + attributi_chiave_multipla = self._meta.unique_together[0] + parti = [] + for x in attributi_chiave_multipla: + try: + parte = getattr(self, x + '_id') # se oltre che parte di primary è foreign, non vogliamo fetchare tutto l'oggetto + except AttributeError: + parte = getattr(self, x) + parti.append(parte) + return hash(tuple(parti)) + + + +class MultiPkQuerySet(models.QuerySet): + def get(self, *args, **kwargs): + attributi_chiave_multipla = self.model._meta.unique_together[0] + if any(key not in kwargs for key in attributi_chiave_multipla): + raise Exception("È un MultiPkModel. Fornire anche i seguenti keywoard arguments: " + str(set(attributi_chiave_multipla) - set(kwargs.keys()))) + filtro = {k : kwargs[k] for k in attributi_chiave_multipla} + risultati = list(self.filter(**filtro).all()) + if len(risultati) == 1: + return risultati[0] + elif len(risultati) == 0: + raise self.model.DoesNotExist(self.model._meta.object_name + " with " + str(filtro)) + else: + raise Exception("MultiPkQuerySet.get: righe multiple con " + str(filtro)) + + +class MultiPkManager(models.Manager): + def get_queryset(self): + return MultiPkQuerySet(self.model, using=self._db) + """ + + tmpl_models_prefisso = leggi_prefisso('models') + tmpl_models = ''' +{multifkimport} +{multipkmodel} + +{corpo} + ''' + + tmpl_model_class = ''' +class {nometab}({classe_model}):{db_name} + class Meta: + verbose_name = '{nometab_lower}' + verbose_name_plural = '{nometab_lower}' + {is_managed}{unique_together} + def __str__(self): + return f"{nometab} ({chiavi})" + + {righetxt} + ''' + tmpl_riga = '''{nomeriga} = models.{tiporiga}({opzioniriga})''' + tmpl_chiave_fk = '''{nomeriga} = models.ForeignKey('{altratab}', {opzioniriga})''' + + tmpl_admin_prefisso = leggi_prefisso('admin') + tmpl_admin = ''' +{corpo} + ''' + + tmpl_admin_class = ''' +@admin.register(models.{nometab}) +class {nometab}Admin(ImportExportModelAdmin): + # resource = resources.{nometab}Resource + # list_per_page = 15 + # paginator = CachingPaginator + # show_full_result_count = False + pass + ''' + + + tmpl_serializers_prefisso = leggi_prefisso('serializers') + tmpl_serializers = ''' +{corpo} + ''' + + tmpl_serializer_class = ''' +class {nometab}Serializer(serializers.ModelSerializer): + class Meta: + model = models.{nometab} + fields = ('{campi}') + ''' + + tmpl_views_prefisso = leggi_prefisso('views') + tmpl_views = ''' +{corpo} + ''' + + tmpl_view_class = ''' +class {nometab}_View(viewsets.ModelViewSet): + # authentication_classes = [BasicAuthentication, SessionAuthentication, TokenAuthentication] + # permission_classes = [DjangoModelPermissions] + + queryset = models.{nometab}.objects.all() + serializer_class = serializers.{nometab}Serializer + ''' + + tmpl_urls_prefisso = leggi_prefisso('urls') + tmpl_urls = ''' +{urls} + +urlpatterns += router.urls + ''' + + tmpl_url_route = '''router.register(r'{nometaburl}', views.{nometab}_View)''' + tmpl_resources_prefisso = leggi_prefisso('resources') + tmpl_resources = ''' +{corpo} + ''' + + tmpl_resource_class = ''' +class {nometab}Resource(resources.ModelResource): + class Meta: + model = models.{nometab} + ''' + + mappa_tipi = { + 'INTEGER': 'IntegerField', + 'INT': 'IntegerField', + 'NUMERIC': 'DecimalField', + 'DECIMAL': 'DecimalField', + 'SMALLINT': 'SmallIntegerField', + 'FLOAT': 'FloatField', + 'TEXT': 'TextField', + 'VARCHAR': 'CharField', + 'CHAR': 'CharField', + 'MEDIUMTEXT': 'TextField', + 'DATE': 'DateField', + 'TIME': 'TimeField', + 'DATETIME': 'DateTimeField', + 'TIMESTAMP': 'DateTimeField', + 'DECIMAL': 'DecimalField', + 'BIT': 'BooleanField', + 'BINARY': 'BooleanField', + 'JSONB': 'JSONField' + } + + tabelle = list(ET.ElementTree(file=arguments['--xml']) + .findall('.//table')) + tabelle2 = (ET.ElementTree(file=arguments['--xml']) + .findall('.//table')) + + models = [] + admin = [] + serializers = [] + views = [] + urls = [] + resources = [] + nomi_tabelle = [] + any_multiple_fk = False + any_multiple_pk = False + + tabelle_multi_pk = set() + for t in tabelle2: + nome = t.get('name') + chiave = t.findall('.//key/part') + if len(chiave) > 1: + tabelle_multi_pk.add(nome) + any_multiple_pk = True + + renames = {} + is_fk_and_pk = set() + for t in tabelle: + righe = t.findall('.//row') + n_tab = t.get('name') + chiave = t.findall('.//key/part') + + # prima decido i rename + for r in righe: + fk = r.find('relation') + n = r.get('name') + is_simple_fk = fk is not None and fk.get( + 'table') not in tabelle_multi_pk + if is_simple_fk and unmanaged: + # renames[(n_tab, n)] = 'fk_' + n # poi ci pensiamo + renames[(n_tab, n)] = n + else: + renames[(n_tab, n)] = n + if is_simple_fk and n in [x.text for x in chiave]: + is_fk_and_pk.add((n_tab, n)) + + for t in tabelle: + rec_tabella = dict() + rec_serializers = dict() + rec_tabella['nometab'] = t.get('name') + rec_tabella['nometab_lower'] = rec_tabella['nometab'].lower() + n_tab = t.get('name') + rec_tabella['classe_model'] = 'models.Model' + nomi_tabelle.append(rec_tabella['nometab']) + rec_serializers['nometab'] = t.get('name') + rec_tabella['is_managed'] = '' + rec_tabella['db_name'] = '' + rec_tabella['unique_together'] = '' + if unmanaged: + rec_tabella['is_managed'] = f'managed = False\n db_table = "{rec_tabella["nometab"]}"\n ' + rec_tabella['db_name'] = f'\n database = "{nome_db}"' + righe = t.findall('.//row') + chiave = t.findall('.//key/part') + pk_singola = None + righetxt = [] + if len(chiave) == 1: + if not unmanaged: + righe = [r for r in righe if r.get('name') != chiave[0].text] + pk_singola = chiave[0].text + if unmanaged: + rec_tabella['chiavi'] = renames[(n_tab, pk_singola)] + ': {self.' + (renames[(n_tab, pk_singola)]+'_id' if ( + n_tab, pk_singola) in is_fk_and_pk else renames[(n_tab, pk_singola)]) + '}' + else: + rec_tabella['chiavi'] = "id: {self.id}" + elif len(chiave) > 1: + multi_pk = True + rec_tabella['classe_model'] = "MultiPkModel" + nomi = ", ".join(f"'{renames[(n_tab, x.text)]}'" for x in chiave) + rec_tabella['unique_together'] = f"unique_together=[({nomi})]" + if unmanaged: + rec_tabella['chiavi'] = ", ".join(renames[(n_tab, x.text)] + ': {self.' + (renames[(n_tab, x.text)]+'_id' if ( + n_tab, x.text) in is_fk_and_pk else renames[(n_tab, x.text)]) + '}' for x in chiave) + else: + rec_tabella['chiavi'] = "non puoi fare una pk multipla in django" + righetxt.append('objects = MultiPkManager()') + righeserializerstxt = [] + # TODO: implementare eventuali tipi multiparametro e con spazi + + datoparametricoRE = re.compile( + r'(?P[^(]*)\((?P[^)]*)\)') + fk_composite = defaultdict(list) + is_first = True + for r in righe: + rec_riga = dict() + rec_chiave_fk = dict() + rec_chiave_fk['opzioniriga'] = dict() + rec_riga['opzioniriga'] = dict() + comm = r.find('comment') + if comm is not None and 'django_ignore' in comm.text: + continue + riga_nullable = r.get('null', "1") == "1" + if is_first and unmanaged and rec_tabella['nometab'] in tabelle_multi_pk: + if not riga_nullable: + # il primo field diventa chiave primaria fittizia. Attenzione a non usarlo davvero! + righetxt.append("") + righetxt.append( + "# chiave primaria fittizia. Attenzione a non usarla! Fa fede unique_together.") + rec_riga['opzioniriga']['primary_key'] = True + rec_chiave_fk['opzioniriga']['primary_key'] = True + is_first = False + fk = r.find('relation') + is_simple_fk = fk is not None and fk.get( + 'table') not in tabelle_multi_pk + if is_simple_fk: + rec_chiave_fk['nomeriga'] = renames[(n_tab, r.get('name'))] + n_altra_tab = rec_chiave_fk['altratab'] = fk.get('table') + rec_chiave_fk['altracol'] = renames[( + n_altra_tab, fk.get('row'))] + rec_chiave_fk['opzioniriga']['on_delete'] = 'models.CASCADE' + rec_chiave_fk['opzioniriga']['null'] = riga_nullable + rec_chiave_fk['opzioniriga']['blank'] = riga_nullable + if unmanaged: + rec_chiave_fk['opzioniriga']['to_field'] = f"'{rec_chiave_fk['altracol']}'" + rec_chiave_fk['opzioniriga']['db_column'] = f"'{r.get('name')}'" + rec_chiave_fk['opzioniriga']['related_name'] = ( + f""""{rec_tabella['nometab']}_da_{rec_chiave_fk['altratab']}_{rec_chiave_fk['nomeriga']}" """.strip()) + if not rec_chiave_fk['opzioniriga']['null']: + del rec_chiave_fk['opzioniriga']['null'] + del rec_chiave_fk['opzioniriga']['blank'] + rec_chiave_fk['opzioniriga'] = ', '.join( + f'{k}={v}' for k, v in rec_chiave_fk['opzioniriga'].items()) + righetxt.append(tmpl_chiave_fk.format(**rec_chiave_fk)) + else: + rec_riga['opzioniriga']['null'] = riga_nullable + rec_riga['opzioniriga']['blank'] = riga_nullable + if fk is not None: # è composita + tab_target = fk.get('table') + fk_composite[tab_target].append({"campo": r.get('name'), + "campo_tgt": renames[(tab_target, fk.get("row"))], + "nullabile": rec_riga['opzioniriga']['null']}) + rec_riga['nomeriga'] = r.get('name') + orig = tipodato = str(r.find('datatype').text) + parsato = tutti_parametri(tipodato) + #parametrico = datoparametricoRE.match(tipodato) + parametrico = is_parametrico(parsato) + # parametrico = tipo + rec_riga['tiporiga'] = get_tipo_mappato(parsato) + if parametrico: + if rec_riga['tiporiga'] in ('CharField',): + lunghezza = get_parametro( + parsato, positional=0, keyword="max_length") + rec_riga['opzioniriga']['max_length'] = int(lunghezza) + elif rec_riga['tiporiga'] == "DecimalField": + max_digits = get_parametro( + parsato, positional=0, keyword="max_digits") + decimal_places = get_parametro( + parsato, positional=1, keyword="decimal_places") + rec_riga['opzioniriga']['max_digits'] = int(max_digits) + rec_riga['opzioniriga']['decimal_places'] = int( + decimal_places) + arg_avanzati = parsato["keyword_args"] + for x in arg_avanzati: + rec_riga['opzioniriga'][x] = arg_avanzati[x] + elif unmanaged: + if tipodato in ('CHAR', 'VARCHAR'): + rec_riga['opzioniriga']['max_length'] = 1000000 + if r.get('name') == pk_singola: + # chiave singola + rec_riga['opzioniriga']['primary_key'] = True + if not rec_riga['opzioniriga']['null']: + del rec_riga['opzioniriga']['null'] + del rec_riga['opzioniriga']['blank'] + if rec_riga['tiporiga'] in ('CharField', 'TextField') and 'blank' in rec_riga['opzioniriga']: + del rec_riga['opzioniriga']['blank'] + rec_riga['opzioniriga'] = ','.join( + f'{k}={v}' for k, v in rec_riga['opzioniriga'].items()) + righetxt.append(tmpl_riga.format(**rec_riga)) + rec_riga_serializers = dict() + rec_riga_serializers['nomecampo'] = r.get('name') + righeserializerstxt.append(rec_riga_serializers['nomecampo']) + for tgt in fk_composite: + nullabile = any(x['nullabile'] for x in fk_composite[tgt]) + fk_fields = ",\n ".join( + f"'{x['campo_tgt']}': '{x['campo']}'" for x in fk_composite[tgt]) + asd = f"fk_{tgt} = CompositeForeignKey('{tgt}', on_delete=models.CASCADE, null={nullabile}, to_fields=" + "{\n " + fk_fields + "\n })" + righetxt.append(asd) + any_multiple_fk = True + rec_tabella['righetxt'] = '\n '.join(righetxt) + rec_serializers['campi'] = "','".join(righeserializerstxt) + models.append(tmpl_model_class.format(**rec_tabella)) + admin.append(tmpl_admin_class.format(**rec_tabella)) + serializers.append(tmpl_serializer_class.format(**rec_serializers)) + views.append(tmpl_view_class.format(nometab=rec_tabella['nometab'])) + urls.append(tmpl_url_route.format( + nometaburl=rec_tabella['nometab'].lower(), nometab=rec_tabella['nometab'])) + resources.append(tmpl_resource_class.format( + nometab=rec_tabella['nometab'])) + + models = tmpl_models_prefisso + tmpl_models.format(corpo='\n'.join(models), + multipkmodel=multipkmodel if any_multiple_pk else "", + multifkimport=multifkimport if any_multiple_fk else "") + admin = tmpl_admin_prefisso + tmpl_admin.format(corpo='\n'.join(admin)) + serializers = tmpl_serializers_prefisso + tmpl_serializers.format(corpo='\n'.join(serializers)) + views = tmpl_views_prefisso + tmpl_views.format(corpo='\n'.join(views)) + urls = tmpl_urls_prefisso + tmpl_urls.format(urls='\n'.join(urls)) + resources = tmpl_resources_prefisso + tmpl_resources.format(corpo='\n'.join(resources)) + + for tgt_name, tgt_path in tgtfil.items(): + with open(tgt_path, 'w') as f: + print( + f"Writing {tgt_name} to {tgt_path}, autopep8: {not arguments['--no-format']}...") + if arguments['--no-format']: + f.write(globals()[tgt_name]) + else: + f.write(autopep8.fix_code(globals()[tgt_name])) diff --git a/django/offerte_app/tests.py b/django/offerte_app/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/django/offerte_app/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/django/offerte_app/urls.py b/django/offerte_app/urls.py new file mode 100644 index 0000000..20c165d --- /dev/null +++ b/django/offerte_app/urls.py @@ -0,0 +1,18 @@ +from rest_framework import routers +from django.urls import include, path +from . import views + +app_name = "offerte_app" + +urlpatterns = [ + # path('', views.index, name='index'), +] +router = routers.DefaultRouter() + +# --------------- FINE PREFISSO TEMPLATE --------------- +router.register(r'destinatarioofferta', views.DestinatarioOfferta_View) +router.register(r'gruppoofferte', views.GruppoOfferte_View) +router.register(r'offerta', views.Offerta_View) +router.register(r'agenteofferta', views.AgenteOfferta_View) +router.register(r'parteeconomicaofferta', views.ParteEconomicaOfferta_View) +router.register(r'tipologiaofferta', views.TipologiaOfferta_View) diff --git a/django/offerte_app/views.py b/django/offerte_app/views.py new file mode 100644 index 0000000..aff5809 --- /dev/null +++ b/django/offerte_app/views.py @@ -0,0 +1,67 @@ +from copy import deepcopy + +from django.shortcuts import render, redirect +from django.http import JsonResponse, HttpResponse +from django.utils.http import url_has_allowed_host_and_scheme +from django.contrib.auth.forms import AuthenticationForm +from django.contrib.auth import authenticate, login, logout +from rest_framework import viewsets +from rest_framework.authentication import SessionAuthentication, BasicAuthentication +from rest_framework.permissions import DjangoModelPermissions, IsAuthenticated + +from django_auto_prefetching import AutoPrefetchViewSetMixin +from . import models +from . import serializers + +# def index(request): +# return HttpResponse("Hello, %s!" % (request.user.username if request.user.is_authenticated else 'World')) + +# --------------- FINE PREFISSO TEMPLATE --------------- +class DestinatarioOfferta_View(viewsets.ModelViewSet): + # authentication_classes = [BasicAuthentication, SessionAuthentication, TokenAuthentication] + # permission_classes = [DjangoModelPermissions] + + queryset = models.DestinatarioOfferta.objects.all() + serializer_class = serializers.DestinatarioOffertaSerializer + + +class GruppoOfferte_View(viewsets.ModelViewSet): + # authentication_classes = [BasicAuthentication, SessionAuthentication, TokenAuthentication] + # permission_classes = [DjangoModelPermissions] + + queryset = models.GruppoOfferte.objects.all() + serializer_class = serializers.GruppoOfferteSerializer + + +class Offerta_View(viewsets.ModelViewSet): + # authentication_classes = [BasicAuthentication, SessionAuthentication, TokenAuthentication] + # permission_classes = [DjangoModelPermissions] + + queryset = models.Offerta.objects.all() + serializer_class = serializers.OffertaSerializer + + +class AgenteOfferta_View(viewsets.ModelViewSet): + # authentication_classes = [BasicAuthentication, SessionAuthentication, TokenAuthentication] + # permission_classes = [DjangoModelPermissions] + + queryset = models.AgenteOfferta.objects.all() + serializer_class = serializers.AgenteOffertaSerializer + + +class ParteEconomicaOfferta_View(viewsets.ModelViewSet): + # authentication_classes = [BasicAuthentication, SessionAuthentication, TokenAuthentication] + # permission_classes = [DjangoModelPermissions] + + queryset = models.ParteEconomicaOfferta.objects.all() + serializer_class = serializers.ParteEconomicaOffertaSerializer + + +class TipologiaOfferta_View(viewsets.ModelViewSet): + # authentication_classes = [BasicAuthentication, SessionAuthentication, TokenAuthentication] + # permission_classes = [DjangoModelPermissions] + + queryset = models.TipologiaOfferta.objects.all() + serializer_class = serializers.TipologiaOffertaSerializer + + diff --git a/django/sangue_app/admin.py b/django/sangue_app/admin.py index 415f479..fdadb0e 100644 --- a/django/sangue_app/admin.py +++ b/django/sangue_app/admin.py @@ -38,51 +38,6 @@ from . import resources # --------------- FINE PREFISSO TEMPLATE --------------- -@admin.register(models.DestinatarioOfferta) -class DestinatarioOffertaAdmin(ImportExportModelAdmin): - # resource = resources.DestinatarioOffertaResource - # list_per_page = 15 - # paginator = CachingPaginator - # show_full_result_count = False - pass - - -@admin.register(models.GruppoOfferte) -class GruppoOfferteAdmin(ImportExportModelAdmin): - # resource = resources.GruppoOfferteResource - # list_per_page = 15 - # paginator = CachingPaginator - # show_full_result_count = False - pass - - -@admin.register(models.Offerta) -class OffertaAdmin(ImportExportModelAdmin): - # resource = resources.OffertaResource - # list_per_page = 15 - # paginator = CachingPaginator - # show_full_result_count = False - pass - - -@admin.register(models.AgenteOfferta) -class AgenteOffertaAdmin(ImportExportModelAdmin): - # resource = resources.AgenteOffertaResource - # list_per_page = 15 - # paginator = CachingPaginator - # show_full_result_count = False - pass - - -@admin.register(models.ParteEconomicaOfferta) -class ParteEconomicaOffertaAdmin(ImportExportModelAdmin): - # resource = resources.ParteEconomicaOffertaResource - # list_per_page = 15 - # paginator = CachingPaginator - # show_full_result_count = False - pass - - @admin.register(models.Progetto) class ProgettoAdmin(ImportExportModelAdmin): # resource = resources.ProgettoResource @@ -101,15 +56,6 @@ class ValorizzazioneEconomicaProgettoAdmin(ImportExportModelAdmin): pass -@admin.register(models.TipologiaOfferta) -class TipologiaOffertaAdmin(ImportExportModelAdmin): - # resource = resources.TipologiaOffertaResource - # list_per_page = 15 - # paginator = CachingPaginator - # show_full_result_count = False - pass - - @admin.register(models.Repository) class RepositoryAdmin(ImportExportModelAdmin): # resource = resources.RepositoryResource diff --git a/django/sangue_app/migrations/0001_initial.py b/django/sangue_app/migrations/0001_initial.py index 04ccc97..bf3e95f 100644 --- a/django/sangue_app/migrations/0001_initial.py +++ b/django/sangue_app/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 4.1.7 on 2023-05-12 22:20 +# Generated by Django 4.1.7 on 2023-05-14 13:48 from django.db import migrations, models import django.db.models.deletion @@ -8,30 +8,11 @@ class Migration(migrations.Migration): initial = True dependencies = [ + ("offerte_app", "0001_initial"), ("fattura_elettronica_app", "0001_initial"), - ("contatti_app", "0001_initial"), ] operations = [ - migrations.CreateModel( - name="AgenteOfferta", - fields=[ - ( - "id", - models.AutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("codice", models.IntegerField(blank=True, null=True)), - ], - options={ - "verbose_name": "agenteofferta", - "verbose_name_plural": "agenteofferta", - }, - ), migrations.CreateModel( name="ArchivioFiles", fields=[ @@ -109,25 +90,6 @@ class Migration(migrations.Migration): "verbose_name_plural": "attivitadelprogetto", }, ), - migrations.CreateModel( - name="BMCModelloDiBusiness", - fields=[ - ( - "id", - models.AutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("descrizione", models.CharField(max_length=4096, null=True)), - ], - options={ - "verbose_name": "bmcmodellodibusiness", - "verbose_name_plural": "bmcmodellodibusiness", - }, - ), migrations.CreateModel( name="CanaleDiDistribuzione", fields=[ @@ -147,190 +109,6 @@ class Migration(migrations.Migration): "verbose_name_plural": "canaledidistribuzione", }, ), - migrations.CreateModel( - name="DestinatarioOfferta", - fields=[ - ( - "id", - models.AutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ], - options={ - "verbose_name": "destinatarioofferta", - "verbose_name_plural": "destinatarioofferta", - }, - ), - migrations.CreateModel( - name="DettaglioFatturabile", - fields=[ - ( - "id", - models.AutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ( - "dati_estesi", - models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="DettaglioFatturabile_da_DatiEstesiDettaglioFatturabile_dati_estesi", - to="fattura_elettronica_app.datiestesidettagliofatturabile", - ), - ), - ], - options={ - "verbose_name": "dettagliofatturabile", - "verbose_name_plural": "dettagliofatturabile", - }, - ), - migrations.CreateModel( - name="GruppoOfferte", - fields=[ - ( - "id", - models.AutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("anno_1a_rev", models.IntegerField(blank=True, null=True)), - ("numero", models.IntegerField(blank=True, null=True)), - ("descrizione", models.CharField(max_length=4096, null=True)), - ( - "agente", - models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="GruppoOfferte_da_AgenteOfferta_agente", - to="sangue_app.agenteofferta", - ), - ), - ( - "destinatario", - models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="GruppoOfferte_da_DestinatarioOfferta_destinatario", - to="sangue_app.destinatarioofferta", - ), - ), - ], - options={ - "verbose_name": "gruppoofferte", - "verbose_name_plural": "gruppoofferte", - }, - ), - migrations.CreateModel( - name="Indirizzo", - fields=[ - ( - "id", - models.AutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("duf", models.CharField(max_length=256, null=True)), - ("civico", models.CharField(max_length=256, null=True)), - ("altro", models.CharField(max_length=2048, null=True)), - ("cap_id", models.CharField(max_length=5, null=True)), - ("comune_id", models.IntegerField(blank=True, null=True)), - ("dug_id", models.CharField(max_length=40, null=True)), - ], - options={ - "verbose_name": "indirizzo", - "verbose_name_plural": "indirizzo", - }, - ), - migrations.CreateModel( - name="Offerta", - fields=[ - ( - "id", - models.AutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("data", models.DateField(blank=True, null=True)), - ("revisione", models.IntegerField(blank=True, null=True)), - ("documento", models.CharField(max_length=128, null=True)), - ("codice_offerta", models.IntegerField(blank=True, null=True)), - ("accettazione", models.DateField(blank=True, null=True)), - ( - "gruppo", - models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="Offerta_da_GruppoOfferte_gruppo", - to="sangue_app.gruppoofferte", - ), - ), - ], - options={ - "verbose_name": "offerta", - "verbose_name_plural": "offerta", - }, - ), - migrations.CreateModel( - name="PersonaFisica", - fields=[ - ( - "id", - models.AutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("titolo", models.CharField(max_length=10, null=True)), - ("nome", models.CharField(max_length=60, null=True)), - ("cognome", models.CharField(max_length=60, null=True)), - ], - options={ - "verbose_name": "personafisica", - "verbose_name_plural": "personafisica", - }, - ), - migrations.CreateModel( - name="PersonaGiuridica", - fields=[ - ( - "id", - models.AutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("denominazione", models.CharField(max_length=80, null=True)), - ], - options={ - "verbose_name": "personagiuridica", - "verbose_name_plural": "personagiuridica", - }, - ), migrations.CreateModel( name="Progetto", fields=[ @@ -524,25 +302,6 @@ class Migration(migrations.Migration): "verbose_name_plural": "tipoattivita", }, ), - migrations.CreateModel( - name="TipologiaOfferta", - fields=[ - ( - "id", - models.AutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("descrizione", models.CharField(max_length=1024, null=True)), - ], - options={ - "verbose_name": "tipologiaofferta", - "verbose_name_plural": "tipologiaofferta", - }, - ), migrations.CreateModel( name="TipoRelazione", fields=[ @@ -582,7 +341,7 @@ class Migration(migrations.Migration): null=True, on_delete=django.db.models.deletion.CASCADE, related_name="ValorizzazioneEconomicaProgetto_da_DettaglioFatturabile_dato_economico", - to="sangue_app.dettagliofatturabile", + to="offerte_app.atomofatturabile", ), ), ( @@ -630,7 +389,7 @@ class Migration(migrations.Migration): null=True, on_delete=django.db.models.deletion.CASCADE, related_name="ValorizzazioneEconomicaAttivita_da_DettaglioFatturabile_dato_economico", - to="sangue_app.dettagliofatturabile", + to="offerte_app.atomofatturabile", ), ), ], @@ -715,46 +474,6 @@ class Migration(migrations.Migration): "verbose_name_plural": "valoredellattivita", }, ), - migrations.CreateModel( - name="SoggettoFiscale", - fields=[ - ( - "id", - models.AutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("indirizzo_pec", models.IntegerField(blank=True, null=True)), - ("regime_fiscale", models.IntegerField(blank=True, null=True)), - ("codice_fiscale", models.IntegerField(blank=True, null=True)), - ("partita_iva", models.IntegerField(blank=True, null=True)), - ("codice_sdi", models.IntegerField(blank=True, null=True)), - ("sede_legale", models.IntegerField()), - ("stabile_organizzazione", models.IntegerField(blank=True, null=True)), - ("cod_eori", models.CharField(max_length=17, null=True)), - ("nazione", models.IntegerField(blank=True, null=True)), - ("numero_licenza_guida", models.CharField(max_length=20, null=True)), - ("iscrizione_rea", models.IntegerField(blank=True, null=True)), - ("rimosso", models.BooleanField(blank=True, null=True)), - ( - "revisione_principale", - models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="SoggettoFiscale_da_SoggettoFiscale_revisione_principale", - to="sangue_app.soggettofiscale", - ), - ), - ], - options={ - "verbose_name": "soggettofiscale", - "verbose_name_plural": "soggettofiscale", - }, - ), migrations.CreateModel( name="SettoreAzienda", fields=[ @@ -774,7 +493,7 @@ class Migration(migrations.Migration): null=True, on_delete=django.db.models.deletion.CASCADE, related_name="SettoreAzienda_da_SoggettoFiscale_azienda", - to="sangue_app.soggettofiscale", + to="fattura_elettronica_app.soggettofiscale", ), ), ( @@ -803,35 +522,6 @@ class Migration(migrations.Migration): "verbose_name_plural": "settoreazienda", }, ), - migrations.CreateModel( - name="Sede", - fields=[ - ( - "id", - models.AutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("is_legale", models.BooleanField(blank=True, null=True)), - ( - "inquilino", - models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="Sede_da_SoggettoFiscale_inquilino", - to="sangue_app.soggettofiscale", - ), - ), - ], - options={ - "verbose_name": "sede", - "verbose_name_plural": "sede", - }, - ), migrations.CreateModel( name="RisorsaChiave", fields=[ @@ -880,7 +570,7 @@ class Migration(migrations.Migration): null=True, on_delete=django.db.models.deletion.CASCADE, related_name="RelazioneConAzienda_da_SoggettoFiscale_azienda", - to="sangue_app.soggettofiscale", + to="fattura_elettronica_app.soggettofiscale", ), ), ( @@ -909,115 +599,6 @@ class Migration(migrations.Migration): "verbose_name_plural": "relazioneconazienda", }, ), - migrations.CreateModel( - name="ParteEconomicaOfferta", - fields=[ - ( - "id", - models.AutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ( - "dettaglio_economico_offerto", - models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="ParteEconomicaOfferta_da_DettaglioFatturabile_dettaglio_economico_offerto", - to="sangue_app.dettagliofatturabile", - ), - ), - ( - "revisione", - models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="ParteEconomicaOfferta_da_Offerta_revisione", - to="sangue_app.offerta", - ), - ), - ], - options={ - "verbose_name": "parteeconomicaofferta", - "verbose_name_plural": "parteeconomicaofferta", - }, - ), - migrations.CreateModel( - name="ModalitaLavoro", - fields=[ - ( - "id", - models.AutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("descrizione", models.IntegerField(blank=True, null=True)), - ( - "unita_misura_std", - models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="ModalitaLavoro_da_UnitaMisura_unita_misura_std", - to="fattura_elettronica_app.unitamisura", - ), - ), - ], - options={ - "verbose_name": "modalitalavoro", - "verbose_name_plural": "modalitalavoro", - }, - ), - migrations.CreateModel( - name="IscrizioneAlboProfessionale", - fields=[ - ( - "id", - models.AutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("albo_professionale", models.IntegerField(blank=True, null=True)), - ("numero_iscrizione_albo", models.CharField(max_length=60, null=True)), - ("data_iscrizione_albo", models.DateField(blank=True, null=True)), - ( - "persona_fisica", - models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="IscrizioneAlboProfessionale_da_PersonaFisica_persona_fisica", - to="sangue_app.personafisica", - ), - ), - ], - options={ - "verbose_name": "iscrizionealboprofessionale", - "verbose_name_plural": "iscrizionealboprofessionale", - }, - ), - migrations.AddField( - model_name="gruppoofferte", - name="tipo", - field=models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="GruppoOfferte_da_TipologiaOfferta_tipo", - to="sangue_app.tipologiaofferta", - ), - ), migrations.CreateModel( name="FlussoDiRicavi", fields=[ @@ -1047,61 +628,6 @@ class Migration(migrations.Migration): "verbose_name_plural": "flussodiricavi", }, ), - migrations.AddField( - model_name="dettagliofatturabile", - name="flusso_di_ricavi", - field=models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="DettaglioFatturabile_da_FlussoDiRicavi_flusso_di_ricavi", - to="sangue_app.flussodiricavi", - ), - ), - migrations.AddField( - model_name="dettagliofatturabile", - name="modalita_lavoro", - field=models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="DettaglioFatturabile_da_ModalitaLavoro_modalita_lavoro", - to="sangue_app.modalitalavoro", - ), - ), - migrations.AddField( - model_name="dettagliofatturabile", - name="offerta_riferimento", - field=models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="DettaglioFatturabile_da_Offerta_offerta_riferimento", - to="sangue_app.offerta", - ), - ), - migrations.AddField( - model_name="destinatarioofferta", - name="destinazione", - field=models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="DestinatarioOfferta_da_Sede_destinazione", - to="sangue_app.sede", - ), - ), - migrations.AddField( - model_name="destinatarioofferta", - name="intestatario", - field=models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="DestinatarioOfferta_da_contatti_appPersonaContattoAzienda_intestatario", - to="contatti_app.personacontattoazienda", - ), - ), migrations.CreateModel( name="CanaleDistribuzioneIndiretto", fields=[ @@ -1130,310 +656,6 @@ class Migration(migrations.Migration): "verbose_name_plural": "canaledistribuzioneindiretto", }, ), - migrations.CreateModel( - name="BMCSegmentiDiClientela", - fields=[ - ( - "id", - models.AutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ( - "modello_di_business", - models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="BMCSegmentiDiClientela_da_BMCModelloDiBusiness_modello_di_business", - to="sangue_app.bmcmodellodibusiness", - ), - ), - ( - "settore_cliente", - models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="BMCSegmentiDiClientela_da_SettoreAzienda_settore_cliente", - to="sangue_app.settoreazienda", - ), - ), - ], - options={ - "verbose_name": "bmcsegmentidiclientela", - "verbose_name_plural": "bmcsegmentidiclientela", - }, - ), - migrations.CreateModel( - name="BMCRisorsaChiave", - fields=[ - ( - "id", - models.AutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ( - "modello_di_business", - models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="BMCRisorsaChiave_da_BMCModelloDiBusiness_modello_di_business", - to="sangue_app.bmcmodellodibusiness", - ), - ), - ( - "risorsa_chiave", - models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="BMCRisorsaChiave_da_RisorsaChiave_risorsa_chiave", - to="sangue_app.risorsachiave", - ), - ), - ], - options={ - "verbose_name": "bmcrisorsachiave", - "verbose_name_plural": "bmcrisorsachiave", - }, - ), - migrations.CreateModel( - name="BMCRelazioneConCliente", - fields=[ - ( - "id", - models.AutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ( - "modello_di_business", - models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="BMCRelazioneConCliente_da_BMCModelloDiBusiness_modello_di_business", - to="sangue_app.bmcmodellodibusiness", - ), - ), - ( - "relazione_cliente", - models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="BMCRelazioneConCliente_da_RelazioneConAzienda_relazione_cliente", - to="sangue_app.relazioneconazienda", - ), - ), - ], - options={ - "verbose_name": "bmcrelazioneconcliente", - "verbose_name_plural": "bmcrelazioneconcliente", - }, - ), - migrations.CreateModel( - name="BMCPropostaDiValore", - fields=[ - ( - "id", - models.AutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ( - "modello_di_business", - models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="BMCPropostaDiValore_da_BMCModelloDiBusiness_modello_di_business", - to="sangue_app.bmcmodellodibusiness", - ), - ), - ( - "proposta_di_valore", - models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="BMCPropostaDiValore_da_PropostaDiValore_proposta_di_valore", - to="sangue_app.propostadivalore", - ), - ), - ], - options={ - "verbose_name": "bmcpropostadivalore", - "verbose_name_plural": "bmcpropostadivalore", - }, - ), - migrations.CreateModel( - name="BMCPartnerChiave", - fields=[ - ( - "id", - models.AutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ( - "modello_di_business", - models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="BMCPartnerChiave_da_BMCModelloDiBusiness_modello_di_business", - to="sangue_app.bmcmodellodibusiness", - ), - ), - ( - "partnership_azienda", - models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="BMCPartnerChiave_da_RelazioneConAzienda_partnership_azienda", - to="sangue_app.relazioneconazienda", - ), - ), - ], - options={ - "verbose_name": "bmcpartnerchiave", - "verbose_name_plural": "bmcpartnerchiave", - }, - ), - migrations.CreateModel( - name="BMCFlussoDiRicavi", - fields=[ - ( - "id", - models.AutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ( - "flusso_di_ricavi", - models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="BMCFlussoDiRicavi_da_FlussoDiRicavi_flusso_di_ricavi", - to="sangue_app.flussodiricavi", - ), - ), - ( - "modello_di_business", - models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="BMCFlussoDiRicavi_da_BMCModelloDiBusiness_modello_di_business", - to="sangue_app.bmcmodellodibusiness", - ), - ), - ], - options={ - "verbose_name": "bmcflussodiricavi", - "verbose_name_plural": "bmcflussodiricavi", - }, - ), - migrations.CreateModel( - name="BMCCanaleDiDistribuzione", - fields=[ - ( - "id", - models.AutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ( - "canale", - models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="BMCCanaleDiDistribuzione_da_CanaleDiDistribuzione_canale", - to="sangue_app.canaledidistribuzione", - ), - ), - ( - "modello_di_business", - models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="BMCCanaleDiDistribuzione_da_BMCModelloDiBusiness_modello_di_business", - to="sangue_app.bmcmodellodibusiness", - ), - ), - ], - options={ - "verbose_name": "bmccanaledidistribuzione", - "verbose_name_plural": "bmccanaledidistribuzione", - }, - ), - migrations.CreateModel( - name="BMCAttivitaChiave", - fields=[ - ( - "id", - models.AutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ( - "attivita_chiave", - models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="BMCAttivitaChiave_da_Attivita_attivita_chiave", - to="sangue_app.attivita", - ), - ), - ( - "modello_di_business", - models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="BMCAttivitaChiave_da_BMCModelloDiBusiness_modello_di_business", - to="sangue_app.bmcmodellodibusiness", - ), - ), - ], - options={ - "verbose_name": "bmcattivitachiave", - "verbose_name_plural": "bmcattivitachiave", - }, - ), migrations.AddField( model_name="attivitadelprogetto", name="progetto", diff --git a/django/sangue_app/migrations/0002_remove_bmccanaledidistribuzione_canale_and_more.py b/django/sangue_app/migrations/0002_remove_bmccanaledidistribuzione_canale_and_more.py deleted file mode 100644 index b38ee39..0000000 --- a/django/sangue_app/migrations/0002_remove_bmccanaledidistribuzione_canale_and_more.py +++ /dev/null @@ -1,95 +0,0 @@ -# Generated by Django 4.1.7 on 2023-05-12 22:46 - -from django.db import migrations - - -class Migration(migrations.Migration): - dependencies = [ - ("sangue_app", "0001_initial"), - ] - - operations = [ - migrations.RemoveField( - model_name="bmccanaledidistribuzione", - name="canale", - ), - migrations.RemoveField( - model_name="bmccanaledidistribuzione", - name="modello_di_business", - ), - migrations.RemoveField( - model_name="bmcflussodiricavi", - name="flusso_di_ricavi", - ), - migrations.RemoveField( - model_name="bmcflussodiricavi", - name="modello_di_business", - ), - migrations.RemoveField( - model_name="bmcpartnerchiave", - name="modello_di_business", - ), - migrations.RemoveField( - model_name="bmcpartnerchiave", - name="partnership_azienda", - ), - migrations.RemoveField( - model_name="bmcpropostadivalore", - name="modello_di_business", - ), - migrations.RemoveField( - model_name="bmcpropostadivalore", - name="proposta_di_valore", - ), - migrations.RemoveField( - model_name="bmcrelazioneconcliente", - name="modello_di_business", - ), - migrations.RemoveField( - model_name="bmcrelazioneconcliente", - name="relazione_cliente", - ), - migrations.RemoveField( - model_name="bmcrisorsachiave", - name="modello_di_business", - ), - migrations.RemoveField( - model_name="bmcrisorsachiave", - name="risorsa_chiave", - ), - migrations.RemoveField( - model_name="bmcsegmentidiclientela", - name="modello_di_business", - ), - migrations.RemoveField( - model_name="bmcsegmentidiclientela", - name="settore_cliente", - ), - migrations.DeleteModel( - name="BMCAttivitaChiave", - ), - migrations.DeleteModel( - name="BMCCanaleDiDistribuzione", - ), - migrations.DeleteModel( - name="BMCFlussoDiRicavi", - ), - migrations.DeleteModel( - name="BMCModelloDiBusiness", - ), - migrations.DeleteModel( - name="BMCPartnerChiave", - ), - migrations.DeleteModel( - name="BMCPropostaDiValore", - ), - migrations.DeleteModel( - name="BMCRelazioneConCliente", - ), - migrations.DeleteModel( - name="BMCRisorsaChiave", - ), - migrations.DeleteModel( - name="BMCSegmentiDiClientela", - ), - ] diff --git a/django/sangue_app/migrations/0003_delete_indirizzo_and_more.py b/django/sangue_app/migrations/0003_delete_indirizzo_and_more.py deleted file mode 100644 index 968a76d..0000000 --- a/django/sangue_app/migrations/0003_delete_indirizzo_and_more.py +++ /dev/null @@ -1,78 +0,0 @@ -# Generated by Django 4.1.7 on 2023-05-13 14:06 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - dependencies = [ - ("contatti_app", "0001_initial"), - ("fattura_elettronica_app", "0001_initial"), - ("sangue_app", "0002_remove_bmccanaledidistribuzione_canale_and_more"), - ] - - operations = [ - migrations.DeleteModel( - name="Indirizzo", - ), - migrations.RemoveField( - model_name="iscrizionealboprofessionale", - name="persona_fisica", - ), - migrations.DeleteModel( - name="PersonaGiuridica", - ), - migrations.RemoveField( - model_name="sede", - name="inquilino", - ), - migrations.RemoveField( - model_name="soggettofiscale", - name="revisione_principale", - ), - migrations.AlterField( - model_name="destinatarioofferta", - name="destinazione", - field=models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="DestinatarioOfferta_da_Sede_destinazione", - to="contatti_app.sede", - ), - ), - migrations.AlterField( - model_name="relazioneconazienda", - name="azienda", - field=models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="RelazioneConAzienda_da_SoggettoFiscale_azienda", - to="fattura_elettronica_app.soggettofiscale", - ), - ), - migrations.AlterField( - model_name="settoreazienda", - name="azienda", - field=models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="SettoreAzienda_da_SoggettoFiscale_azienda", - to="fattura_elettronica_app.soggettofiscale", - ), - ), - migrations.DeleteModel( - name="IscrizioneAlboProfessionale", - ), - migrations.DeleteModel( - name="PersonaFisica", - ), - migrations.DeleteModel( - name="Sede", - ), - migrations.DeleteModel( - name="SoggettoFiscale", - ), - ] diff --git a/django/sangue_app/modello_database.xml b/django/sangue_app/modello_database.xml index 25c1d97..8e8ce9a 100644 --- a/django/sangue_app/modello_database.xml +++ b/django/sangue_app/modello_database.xml @@ -130,7 +130,7 @@ INTEGER -NULL +NULL id @@ -151,7 +151,7 @@ id
- +
INTEGER NULL @@ -163,7 +163,7 @@ INTEGER NULL - + INTEGER NULL @@ -205,7 +205,7 @@ INTEGER -NULL +NULL INTEGER @@ -631,7 +631,7 @@ INTEGER -NULL +NULL id diff --git a/django/sangue_app/models.py b/django/sangue_app/models.py index b384726..2fc400d 100644 --- a/django/sangue_app/models.py +++ b/django/sangue_app/models.py @@ -4,112 +4,6 @@ from polymorphic.models import PolymorphicModel # --------------- FINE PREFISSO TEMPLATE --------------- -class DestinatarioOfferta(models.Model): - class Meta: - verbose_name = 'destinatarioofferta' - verbose_name_plural = 'destinatarioofferta' - - def __str__(self): - return f"DestinatarioOfferta (id: {self.id})" - - destinazione = models.ForeignKey('contatti_app.Sede', on_delete=models.CASCADE, null=True, - blank=True, related_name="DestinatarioOfferta_da_Sede_destinazione") - intestatario = models.ForeignKey('contatti_app.PersonaContattoAzienda', on_delete=models.CASCADE, null=True, - blank=True, related_name="DestinatarioOfferta_da_contatti_appPersonaContattoAzienda_intestatario") - - -class GruppoOfferte(models.Model): - class Meta: - verbose_name = 'gruppoofferte' - verbose_name_plural = 'gruppoofferte' - - def __str__(self): - return f"GruppoOfferte (id: {self.id})" - - destinatario = models.ForeignKey('DestinatarioOfferta', on_delete=models.CASCADE, null=True, - blank=True, related_name="GruppoOfferte_da_DestinatarioOfferta_destinatario") - agente = models.ForeignKey('AgenteOfferta', on_delete=models.CASCADE, null=True, - blank=True, related_name="GruppoOfferte_da_AgenteOfferta_agente") - tipo = models.ForeignKey('TipologiaOfferta', on_delete=models.CASCADE, null=True, - blank=True, related_name="GruppoOfferte_da_TipologiaOfferta_tipo") - anno_1a_rev = models.IntegerField(null=True, blank=True) - numero = models.IntegerField(null=True, blank=True) - descrizione = models.CharField(null=True, max_length=4096) - - -class Offerta(models.Model): - class Meta: - verbose_name = 'offerta' - verbose_name_plural = 'offerta' - - def __str__(self): - return f"Offerta (id: {self.id})" - - gruppo = models.ForeignKey('GruppoOfferte', on_delete=models.CASCADE, - null=True, blank=True, related_name="Offerta_da_GruppoOfferte_gruppo") - data = models.DateField(null=True, blank=True) - revisione = models.IntegerField(null=True, blank=True) - documento = models.CharField(null=True, max_length=128) - codice_offerta = models.IntegerField(null=True, blank=True) - accettazione = models.DateField(null=True, blank=True) - - -class AgenteOfferta(models.Model): - class Meta: - verbose_name = 'agenteofferta' - verbose_name_plural = 'agenteofferta' - - def __str__(self): - return f"AgenteOfferta (id: {self.id})" - - codice = models.IntegerField(null=True, blank=True) - - -class ParteEconomicaOfferta(models.Model): - class Meta: - verbose_name = 'parteeconomicaofferta' - verbose_name_plural = 'parteeconomicaofferta' - - def __str__(self): - return f"ParteEconomicaOfferta (id: {self.id})" - - revisione = models.ForeignKey('Offerta', on_delete=models.CASCADE, null=True, - blank=True, related_name="ParteEconomicaOfferta_da_Offerta_revisione") - dettaglio_economico_offerto = models.ForeignKey('DettaglioFatturabile', on_delete=models.CASCADE, null=True, - blank=True, related_name="ParteEconomicaOfferta_da_DettaglioFatturabile_dettaglio_economico_offerto") - -class ModalitaLavoro(models.Model): - class Meta: - verbose_name = 'modalitalavoro' - verbose_name_plural = 'modalitalavoro' - - def __str__(self): - return f"ModalitaLavoro (id: {self.id})" - - unita_misura_std = models.ForeignKey('fattura_elettronica_app.UnitaMisura', on_delete=models.CASCADE, null=True, - blank=True, related_name="ModalitaLavoro_da_UnitaMisura_unita_misura_std") - descrizione = models.IntegerField(null=True, blank=True) - - - -class DettaglioFatturabile(models.Model): - class Meta: - verbose_name = 'dettagliofatturabile' - verbose_name_plural = 'dettagliofatturabile' - - def __str__(self): - return f"DettaglioFatturabile (id: {self.id})" - - offerta_riferimento = models.ForeignKey('Offerta', on_delete=models.CASCADE, null=True, - blank=True, related_name="DettaglioFatturabile_da_Offerta_offerta_riferimento") - modalita_lavoro = models.ForeignKey('ModalitaLavoro', on_delete=models.CASCADE, null=True, - blank=True, related_name="DettaglioFatturabile_da_ModalitaLavoro_modalita_lavoro") - dati_estesi = models.ForeignKey('fattura_elettronica_app.DatiEstesiDettaglioFatturabile', on_delete=models.CASCADE, null=True, - blank=True, related_name="DettaglioFatturabile_da_DatiEstesiDettaglioFatturabile_dati_estesi") - flusso_di_ricavi = models.ForeignKey('FlussoDiRicavi', on_delete=models.CASCADE, null=True, - blank=True, related_name="DettaglioFatturabile_da_FlussoDiRicavi_flusso_di_ricavi") - - class Progetto(models.Model): class Meta: verbose_name = 'progetto' @@ -135,22 +29,11 @@ class ValorizzazioneEconomicaProgetto(models.Model): progetto = models.ForeignKey('Progetto', on_delete=models.CASCADE, null=True, blank=True, related_name="ValorizzazioneEconomicaProgetto_da_Progetto_progetto") - dato_economico = models.ForeignKey('DettaglioFatturabile', on_delete=models.CASCADE, null=True, + dato_economico = models.ForeignKey('offerte_app.AtomoFatturabile', on_delete=models.CASCADE, null=True, blank=True, related_name="ValorizzazioneEconomicaProgetto_da_DettaglioFatturabile_dato_economico") fase_target = models.IntegerField(null=True, blank=True) -class TipologiaOfferta(models.Model): - class Meta: - verbose_name = 'tipologiaofferta' - verbose_name_plural = 'tipologiaofferta' - - def __str__(self): - return f"TipologiaOfferta (id: {self.id})" - - descrizione = models.CharField(null=True, max_length=1024) - - class Repository(models.Model): class Meta: verbose_name = 'repository' @@ -401,7 +284,7 @@ class ValorizzazioneEconomicaAttivita(models.Model): attivita_del_progetto = models.ForeignKey('AttivitaDelProgetto', on_delete=models.CASCADE, null=True, blank=True, related_name="ValorizzazioneEconomicaAttivita_da_AttivitaDelProgetto_attivita_del_progetto") - dato_economico = models.ForeignKey('DettaglioFatturabile', on_delete=models.CASCADE, null=True, + dato_economico = models.ForeignKey('offerte_app.AtomoFatturabile', on_delete=models.CASCADE, null=True, blank=True, related_name="ValorizzazioneEconomicaAttivita_da_DettaglioFatturabile_dato_economico") diff --git a/django/sangue_app/resources.py b/django/sangue_app/resources.py index 9ceaa6a..abf26d3 100644 --- a/django/sangue_app/resources.py +++ b/django/sangue_app/resources.py @@ -4,31 +4,6 @@ from . import models # --------------- FINE PREFISSO TEMPLATE --------------- -class DestinatarioOffertaResource(resources.ModelResource): - class Meta: - model = models.DestinatarioOfferta - - -class GruppoOfferteResource(resources.ModelResource): - class Meta: - model = models.GruppoOfferte - - -class OffertaResource(resources.ModelResource): - class Meta: - model = models.Offerta - - -class AgenteOffertaResource(resources.ModelResource): - class Meta: - model = models.AgenteOfferta - - -class ParteEconomicaOffertaResource(resources.ModelResource): - class Meta: - model = models.ParteEconomicaOfferta - - class ProgettoResource(resources.ModelResource): class Meta: model = models.Progetto @@ -39,11 +14,6 @@ class ValorizzazioneEconomicaProgettoResource(resources.ModelResource): model = models.ValorizzazioneEconomicaProgetto -class TipologiaOffertaResource(resources.ModelResource): - class Meta: - model = models.TipologiaOfferta - - class RepositoryResource(resources.ModelResource): class Meta: model = models.Repository diff --git a/django/sangue_app/serializers.py b/django/sangue_app/serializers.py index 8a4a933..89587c1 100644 --- a/django/sangue_app/serializers.py +++ b/django/sangue_app/serializers.py @@ -4,38 +4,6 @@ from . import models # --------------- FINE PREFISSO TEMPLATE --------------- -class DestinatarioOffertaSerializer(serializers.ModelSerializer): - class Meta: - model = models.DestinatarioOfferta - fields = ('destinazione', 'intestatario') - - -class GruppoOfferteSerializer(serializers.ModelSerializer): - class Meta: - model = models.GruppoOfferte - fields = ('destinatario', 'agente', 'tipo', - 'anno_1a_rev', 'numero', 'descrizione') - - -class OffertaSerializer(serializers.ModelSerializer): - class Meta: - model = models.Offerta - fields = ('gruppo', 'data', 'revisione', 'documento', - 'codice_offerta', 'accettazione') - - -class AgenteOffertaSerializer(serializers.ModelSerializer): - class Meta: - model = models.AgenteOfferta - fields = ('codice') - - -class ParteEconomicaOffertaSerializer(serializers.ModelSerializer): - class Meta: - model = models.ParteEconomicaOfferta - fields = ('revisione', 'dettaglio_economico_offerto') - - class ProgettoSerializer(serializers.ModelSerializer): class Meta: model = models.Progetto @@ -48,12 +16,6 @@ class ValorizzazioneEconomicaProgettoSerializer(serializers.ModelSerializer): fields = ('progetto', 'dato_economico', 'fase_target') -class TipologiaOffertaSerializer(serializers.ModelSerializer): - class Meta: - model = models.TipologiaOfferta - fields = ('descrizione') - - class RepositorySerializer(serializers.ModelSerializer): class Meta: model = models.Repository diff --git a/django/sangue_app/urls.py b/django/sangue_app/urls.py index 43e8539..88c3db3 100644 --- a/django/sangue_app/urls.py +++ b/django/sangue_app/urls.py @@ -11,15 +11,9 @@ router = routers.DefaultRouter() # --------------- FINE PREFISSO TEMPLATE --------------- -router.register(r'destinatarioofferta', views.DestinatarioOfferta_View) -router.register(r'gruppoofferte', views.GruppoOfferte_View) -router.register(r'offerta', views.Offerta_View) -router.register(r'agenteofferta', views.AgenteOfferta_View) -router.register(r'parteeconomicaofferta', views.ParteEconomicaOfferta_View) router.register(r'progetto', views.Progetto_View) router.register(r'valorizzazioneeconomicaprogetto', views.ValorizzazioneEconomicaProgetto_View) -router.register(r'tipologiaofferta', views.TipologiaOfferta_View) router.register(r'repository', views.Repository_View) router.register(r'tiporelazione', views.TipoRelazione_View) router.register(r'attivita', views.Attivita_View) diff --git a/django/sangue_app/views.py b/django/sangue_app/views.py index 95673ac..a52b9a7 100644 --- a/django/sangue_app/views.py +++ b/django/sangue_app/views.py @@ -19,46 +19,6 @@ from . import serializers # --------------- FINE PREFISSO TEMPLATE --------------- -class DestinatarioOfferta_View(viewsets.ModelViewSet): - # authentication_classes = [BasicAuthentication, SessionAuthentication, TokenAuthentication] - # permission_classes = [DjangoModelPermissions] - - queryset = models.DestinatarioOfferta.objects.all() - serializer_class = serializers.DestinatarioOffertaSerializer - - -class GruppoOfferte_View(viewsets.ModelViewSet): - # authentication_classes = [BasicAuthentication, SessionAuthentication, TokenAuthentication] - # permission_classes = [DjangoModelPermissions] - - queryset = models.GruppoOfferte.objects.all() - serializer_class = serializers.GruppoOfferteSerializer - - -class Offerta_View(viewsets.ModelViewSet): - # authentication_classes = [BasicAuthentication, SessionAuthentication, TokenAuthentication] - # permission_classes = [DjangoModelPermissions] - - queryset = models.Offerta.objects.all() - serializer_class = serializers.OffertaSerializer - - -class AgenteOfferta_View(viewsets.ModelViewSet): - # authentication_classes = [BasicAuthentication, SessionAuthentication, TokenAuthentication] - # permission_classes = [DjangoModelPermissions] - - queryset = models.AgenteOfferta.objects.all() - serializer_class = serializers.AgenteOffertaSerializer - - -class ParteEconomicaOfferta_View(viewsets.ModelViewSet): - # authentication_classes = [BasicAuthentication, SessionAuthentication, TokenAuthentication] - # permission_classes = [DjangoModelPermissions] - - queryset = models.ParteEconomicaOfferta.objects.all() - serializer_class = serializers.ParteEconomicaOffertaSerializer - - class Progetto_View(viewsets.ModelViewSet): # authentication_classes = [BasicAuthentication, SessionAuthentication, TokenAuthentication] # permission_classes = [DjangoModelPermissions] @@ -75,14 +35,6 @@ class ValorizzazioneEconomicaProgetto_View(viewsets.ModelViewSet): serializer_class = serializers.ValorizzazioneEconomicaProgettoSerializer -class TipologiaOfferta_View(viewsets.ModelViewSet): - # authentication_classes = [BasicAuthentication, SessionAuthentication, TokenAuthentication] - # permission_classes = [DjangoModelPermissions] - - queryset = models.TipologiaOfferta.objects.all() - serializer_class = serializers.TipologiaOffertaSerializer - - class Repository_View(viewsets.ModelViewSet): # authentication_classes = [BasicAuthentication, SessionAuthentication, TokenAuthentication] # permission_classes = [DjangoModelPermissions] diff --git a/django/sangue_django/modello_dati.xml b/django/sangue_django/modello_dati.xml new file mode 100644 index 0000000..68e72c5 --- /dev/null +++ b/django/sangue_django/modello_dati.xml @@ -0,0 +1,2054 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +INTEGER +NULL + + +INTEGER +NULL + +INTEGER +NULL + + +id + +
+ + +INTEGER +NULL + + +INTEGER +NULL + + +INTEGER +NULL + +INTEGER +NULL + + +INTEGER +NULL + +INTEGER +NULL + +VARCHAR(4096) +NULL + +id + +
+ + +INTEGER +NULL + +INTEGER +NULL + + +DATE +NULL + +INTEGER +NULL + +VARCHAR +NULL + +INTEGER +NULL + +DATE +NULL + +id + +
+ + +INTEGER +NULL + +INTEGER +NULL + +persona_ptr + +
+ + +INTEGER +NULL + +INTEGER +NULL + + +INTEGER +NULL + + +id + +Serve solo per fatturazioni trasversali +
+ + +INTEGER +NULL + +INTEGER +NULL + + +INTEGER +NULL + +id + +
+ + +INTEGER +NULL + + +INTEGER +NULL + +INTEGER +NULL + + +INTEGER +NULL + + +id + +
+ + +INTEGER +NULL + +INTEGER +NULL + + +INTEGER +NULL + +VARCHAR(4096) +NULL + +MEDIUMTEXT +NULL + +id + +
+ + +INTEGER +NULL + +INTEGER +NULL + + +INTEGER +NULL + + +INTEGER +NULL + +id + +
+ + +INTEGER +NULL + + +INTEGER +NULL + +persona_ptr + +
+ + +INTEGER +NULL + +VARCHAR(1024) +NULL + +id + +
+ + +INTEGER +NULL + + +VARCHAR(1024) +NULL + +VARCHAR(4096) +NULL + +risorsachiave_ptr + +
+ + +INTEGER +NULL + +VARCHAR(4096) +NULL + +id + +
+ + +INTEGER +NULL + +INTEGER +NULL + + +INTEGER +NULL + + +VARCHAR(4096) +NULL + +id + +
+ + +INTEGER +NULL + + +INTEGER +NULL + + +VARCHAR(4096) +NULL + +id + +
+ + +INTEGER +NULL + +INTEGER +NULL + + +VARCHAR(4096) +NULL + +id + +
+ + +INTEGER +NULL + +VARCHAR(4096) +NULL + +id + +
+ + +INTEGER +NULL + +VARCHAR(4096) +NULL + +id + +
+ + +INTEGER +NULL + +INTEGER +NULL + + +VARCHAR(4096) +NULL + +id + +
+ + +INTEGER +NULL + +id + +
+ + +INTEGER +NULL + +INTEGER +NULL + + +INTEGER +NULL + + +INTEGER +NULL + + +id + +
+ + +INTEGER +NULL + +VARCHAR(4096) +NULL + +id + +
+ + +INTEGER +NULL + +INTEGER +NULL + + +INTEGER +NULL + + +id + +
+ + +INTEGER +NULL + +INTEGER +NULL + + +INTEGER +NULL + + +INTEGER +NULL + + +id + +
+ + +INTEGER +NULL + +INTEGER +NULL + + +INTEGER +NULL + + +id + +
+ + +INTEGER +NULL + +INTEGER +NULL + + +INTEGER +NULL + + +id + +
+ + +INTEGER +NULL + +VARCHAR(4096) +NULL + +id + +produttive, di problem solving, di manutenzione o sviluppo +
+ + +INTEGER +NULL + +INTEGER +NULL + + +INTEGER +NULL + + +id + +
+ + +INTEGER +NULL + +INTEGER +NULL + + +INTEGER +NULL + + +id + +Ricchezza che viene al cliente dal progetto +
+ + +INTEGER +NULL + +INTEGER +NULL + + +INTEGER +NULL + + +id + +
+ + +INTEGER +NULL + +INTEGER +NULL + + +INTEGER +NULL + + +id + +Il M2M serve solo per attività trasversali, sennò qui trovi solo link 1:1 +
+ + +INTEGER +NULL + +INTEGER +NULL + + +INTEGER +NULL + + +id + +Ricchezza che viene a noi dal progetto +
+ + +INTEGER +NULL + +INTEGER +NULL + + +risorsachiave_ptr + +
+ + +INTEGER +NULL + + +VARCHAR(4096) +NULL + +risorsachiave_ptr + +
+ + +INTEGER +NULL + + +VARCHAR(4096) +NULL + +risorsachiave_ptr + +
+ + +INTEGER +NULL + +INTEGER +NULL + + +INTEGER +NULL + + +id + +
+ + +INTEGER +NULL + +INTEGER +NULL + + +INTEGER +NULL + + +id + +Ricchezza che viene al cliente dall'attività +
+ + +INTEGER +NULL + +INTEGER +NULL + + +INTEGER +NULL + + +id + +
+ + +INTEGER +NULL + +INTEGER +NULL + + +INTEGER +NULL + + +id + +
+ + +INTEGER +NULL + + +VARCHAR(1024) +NULL + +VARCHAR(4096) +NULL + +risorsachiave_ptr + +Seafile +
+ + +INTEGER +NULL + +INTEGER +NULL + + +INTEGER +NULL + + +id + +
+ + +INTEGER +NULL + +INTEGER +NULL + + +INTEGER +NULL + + +id + +
+ + +INTEGER +NULL + + +INTEGER +NULL + + +canaledidistribuzione_ptr + +
+ + +INTEGER +NULL + + +INTEGER +NULL + +INTEGER +NULL + + +DATE +'NULL' + +VARCHAR(20) +'NULL' + +INTEGER +NULL + + +DECIMAL(15) +NULL + +DECIMAL(15) +NULL + +VARCHAR(200) +NULL + +INTEGER +NULL + + +bit +NULL + +INTEGER +NULL + + +INTEGER +NULL + + +INTEGER +NULL + + +INTEGER +NULL + + +INTEGER +NULL + + +id + +
+ + +INTEGER +NULL + +CHAR(4) +'NULL' + +VARCHAR(250) +NULL + +id + +
+ + +INTEGER +NULL + +CHAR(4) +'NULL' + +VARCHAR(250) +NULL + +id + +
+ + +INTEGER +NULL + +CHAR(4) +'NULL' + +VARCHAR(250) +NULL + +id + +
+ + +INTEGER +NULL + +CHAR(4) +'NULL' + +VARCHAR(250) +NULL + +id + +
+ + +INTEGER +NULL + +CHAR(4) +'NULL' + +VARCHAR(250) +NULL + +id + +
+ + +INTEGER +NULL + +CHAR(4) +NULL + +VARCHAR(250) +NULL + +id + +
+ + +INTEGER +NULL + + +INTEGER +NULL + +VARCHAR(10) +'NULL' + +VARCHAR +NULL + +id + +
+ + +INTEGER +NULL + +INTEGER +NULL + + +INTEGER +NULL + + +VARCHAR(20) +NULL + +INTEGER +NULL + + +INTEGER +NULL + + +INTEGER +NULL + + +INTEGER +NULL + + +INTEGER +NULL + + +INTEGER +NULL + + +id + +
+ + +INTEGER +NULL + + +INTEGER +NULL + + +INTEGER +NULL + + +INTEGER +NULL + + +INTEGER +NULL + + +INTEGER +NULL + +INTEGER +NULL + +VARCHAR(17) +NULL + +INTEGER +NULL + + +VARCHAR(20) +NULL + +INTEGER +NULL + + +INTEGER +NULL + +INTEGER +NULL + + +bit +NULL + +id + +
+ + +INTEGER +NULL + +VARCHAR(28) +'NULL' + +id + +
+ + +INTEGER +NULL + +CHAR(2) +'NULL' + +VARCHAR(250) +NULL + +id + +
+ + +INTEGER +NULL + +CHAR(5) +'NULL' + +VARCHAR(250) +NULL + +id + +
+ + +INTEGER +NULL + +VARCHAR(7) +'NULL' + +VARCHAR(250) +NULL + +id + +
+ + +INTEGER +NULL + +INTEGER +NULL + + +id + +
+ + +INTEGER +NULL + + +VARCHAR(20) +'NULL' + +VARCHAR(64) +NULL + +datodicontatto_ptr + +
+ + +INTEGER +NULL + + +VARCHAR(30) +'NULL' + +VARCHAR(64) +NULL + +datodicontatto_ptr + +
+ + +INTEGER +NULL + +INTEGER +NULL + + +VARCHAR(60) +NULL + +DATE +NULL + +INTEGER +NULL + + +id + +
+ + +INTEGER +NULL + +INTEGER +NULL + + +VARCHAR(20) +'NULL' + +DECIMAL(15) +NULL + +INTEGER +NULL + + +INTEGER +NULL + + +id + +
+ + +INTEGER +NULL + +CHAR(2) +'NULL' + +VARCHAR(30) +NULL + +id + +
+ + +INTEGER +NULL + +CHAR(2) +'NULL' + +VARCHAR(30) +NULL + +id + +
+ + +INTEGER +NULL + +INTEGER +NULL + + +INTEGER +NULL + + +id + +
+ + +INTEGER +NULL + +CHAR(2) +'NULL' + +VARCHAR(30) +NULL + +id + +
+ + +INTEGER +NULL + + +VARCHAR(10) +NULL + +VARCHAR(60) +NULL + +VARCHAR(60) +NULL + +soggetto_fiscale_ptr + +
+ + +INTEGER +NULL + + +VARCHAR(80) +NULL + + +
+ + +INTEGER +NULL + +VARCHAR(60) +NULL + +INTEGER +NULL + + +id + +
+ + +INTEGER +NULL + +INTEGER +NULL + + +VARCHAR(60) +'NULL' + +VARCHAR(10) +NULL + +VARCHAR(10) +NULL + +VARCHAR(100) +'NULL' + +MEDIUMTEXT +'NULL' + +id + +
+ + +INTEGER +NULL + +INTEGER +NULL + + +INTEGER +NULL + + +DATE +NULL + +INTEGER +NULL + +DATE +NULL + +DECIMAL(15) +NULL + +DECIMAL(15) +NULL + +DATE +NULL + +DECIMAL(15) +NULL + +DATE +NULL + +VARCHAR(60) +NULL + +INTEGER +NULL + +INTEGER +NULL + + +id + +
+ + +INTEGER +NULL + +DATE +'NULL' + +VARCHAR(15) +'NULL' + +id + +
+ + +INTEGER +NULL + + +INTEGER +NULL + + +VARCHAR(20) +'NULL' + +DATE +NULL + +VARCHAR(20) +NULL + +INTEGER +NULL + + +INTEGER +NULL + +id + +DatiOrdineAcquisto, DatiContratto, DatiConvenzione, DatiRicezione +
+ + +INTEGER +NULL + +INTEGER +NULL + + +INTEGER +NULL + + +id + +
+ + +INTEGER +NULL + +INTEGER +NULL + + +INTEGER(3) +NULL + +id + +
+ + +INTEGER +NULL + + +INTEGER +NULL + +VARCHAR(20) +'NULL' + +DATE +'NULL' + +id + +
+ + +INTEGER +NULL + + +INTEGER +NULL + + +INTEGER +NULL + +VARCHAR(80) +NULL + +INTEGER(4) +NULL + +VARCHAR(100) +NULL + +DECIMAL(7) +NULL + +DECIMAL(7) +NULL + +DATETIME +NULL + +DATE +NULL + +INTEGER +NULL + + +DATETIME +NULL + +INTEGER +NULL + + +INTEGER +NULL + + +id + +
+ + +INTEGER +NULL + +CHAR(3) +'NULL' + +VARCHAR(250) +NULL + +id + +
+ + +INTEGER +NULL + +INTEGER +NULL + + +DECIMAL(15) +NULL + +DECIMAL(6) +NULL + +INTEGER +NULL + + +id + +
+ + +INTEGER +NULL + +CHAR(2) +'NULL' + +VARCHAR(20) +NULL + +id + +
+ + +INTEGER +NULL + +DECIMAL(15) +NULL + +id + +
+ + +INTEGER +NULL + +INTEGER +NULL + + +DECIMAL(6) +NULL + +DECIMAL(15) +NULL + +DECIMAL(15) +NULL + +bit +NULL + +VARCHAR(20) +NULL + +INTEGER +NULL + + +id + +
+ + +INTEGER +NULL + +INTEGER +NULL + + +DECIMAL(6) +NULL + +DECIMAL(6) +NULL + +id + +
+ + +INTEGER +NULL + +CHAR(2) +'NULL' + +VARCHAR(20) +NULL + +id + +
+ + +INTEGER +NULL + +DECIMAL(6) +NULL + +INTEGER +NULL + + +VARCHAR(50) +NULL + +id + +
+ + +INTEGER +NULL + +INTEGER +NULL + + +VARCHAR(200) +NULL + +INTEGER +NULL + + +VARCHAR(34) +NULL + +id + +
+ + +INTEGER +NULL + +VARCHAR(50) +'NULL' + +CHAR(5) +NULL + +CHAR(5) +NULL + +VARCHAR(11) +NULL + +id + +
+ + +INTEGER +NULL + + +INTEGER +NULL + + +INTEGER +NULL + +id + +
+ + +INTEGER +NULL + +CHAR(4) +'NULL' + +VARCHAR(50) +NULL + +id + +
+ + +INTEGER +NULL + + +INTEGER +NULL + +INTEGER +NULL + +INTEGER +NULL + + +INTEGER +NULL + + +VARCHAR(20) +NULL + +INTEGER +NULL + + +INTEGER +NULL + + +id + +
+ + +INTEGER +NULL + +INTEGER +NULL + + +VARCHAR(10) +'NULL' + +VARCHAR(60) +NULL + +DECIMAL(21) +NULL + +DATE +NULL + +id + +
+ + +INTEGER +NULL + +CHAR(2) +'NULL' + +VARCHAR(50) +NULL + +id + +
+ + +INTEGER +NULL + +INTEGER +NULL + + +VARCHAR(35) +NULL + +id + +
+ + +INTEGER +NULL + +VARCHAR(35) +'NULL' + +VARCHAR(250) +NULL + +id + +
+ + +INTEGER +NULL + +INTEGER +NULL + + +INTEGER +NULL + + +id + +
+ + +INTEGER +NULL + +VARCHAR(10) +'NULL' + +VARCHAR(40) +NULL + +id + +
+ + +INTEGER +NULL + +CHAR(3) +'NULL' + +VARCHAR(50) +NULL + +id + +
+ + +INTEGER +NULL + +INTEGER +NULL + + +INTEGER +NULL + + +id + +
+ + +INTEGER +NULL + +INTEGER +NULL + + +INTEGER +NULL + + +id + +
+ + +INTEGER +NULL + +VARCHAR(100) +NULL + +VARCHAR(15) +NULL + +VARCHAR(15) +NULL + +id + +
+ + +INTEGER +NULL + +VARCHAR(50) +'NULL' + +VARCHAR(100) +NULL + +id + +
+ + +INTEGER +NULL + + +INTEGER +NULL + +VARCHAR(1000) +NULL + +DECIMAL(21) +NULL + +DECIMAL(21) +NULL + +DATE +NULL + +DATE +NULL + +id + +
+ + +INTEGER +NULL + + +INTEGER +NULL + + +bit +NULL + +indirizzo_ptr + +
+ + +INTEGER +NULL + + +VARCHAR(20) +NULL + +VARCHAR(64) +NULL + +datodicontatto_ptr + +
+ + +INTEGER +NULL + + +email_ptr + +
+ + +VARCHAR(5) +'None' + +codice + +
+ + +INTEGER +None + +VARCHAR(60) +'None' + +VARCHAR(6) +'None' + +VARCHAR(4) +'None' + +VARCHAR(2) +'None' + + +id + +
+ + +INTEGER +None + +INTEGER +None + + +VARCHAR(5) +'None' + + +id + +
+ + +VARCHAR(40) +'None' + +nome + +
+ + +INTEGER +None + +VARCHAR(256) +'None' + +VARCHAR(256) +'None' + +VARCHAR(2048) +'None' + +VARCHAR(5) +'None' + + +INTEGER +None + + +VARCHAR(40) +'None' + + +id + +
+ + +VARCHAR(2) +'None' + +VARCHAR(50) +'None' + +VARCHAR(32) +'None' + + +sigla + +
+ + +VARCHAR(32) +'None' + +nome + +
+ + +INTEGER +NULL + +INTEGER +NULL + + +INTEGER +NULL + + +id + +
+ diff --git a/django/sangue_django/settings.py b/django/sangue_django/settings.py index 18c883c..09847e8 100644 --- a/django/sangue_django/settings.py +++ b/django/sangue_django/settings.py @@ -134,6 +134,7 @@ FIXTURE_DIRS = ( # Application definition INSTALLED_APPS = [ 'sangue_app.apps.SangueAppConfig', + 'offerte_app.apps.OfferteAppConfig', 'business_model_canvas_app.apps.BusinessModelCanvasAppConfig', 'fattura_elettronica_app.apps.FatturaElettronicaAppConfig', 'contatti_app.apps.ContattiAppConfig',