diff --git a/counter/migrations/0036_productformula.py b/counter/migrations/0036_productformula.py new file mode 100644 index 00000000..abac4bc9 --- /dev/null +++ b/counter/migrations/0036_productformula.py @@ -0,0 +1,43 @@ +# Generated by Django 5.2.8 on 2025-11-26 11:34 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [("counter", "0035_remove_selling_is_validated_and_more")] + + operations = [ + migrations.CreateModel( + name="ProductFormula", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "products", + models.ManyToManyField( + help_text="The products that constitute this formula.", + related_name="formulas", + to="counter.product", + verbose_name="products", + ), + ), + ( + "result", + models.OneToOneField( + help_text="The formula product.", + on_delete=django.db.models.deletion.CASCADE, + to="counter.product", + verbose_name="result product", + ), + ), + ], + ), + ] diff --git a/counter/models.py b/counter/models.py index 996f22e6..0141ff16 100644 --- a/counter/models.py +++ b/counter/models.py @@ -455,6 +455,24 @@ class Product(models.Model): return self.selling_price - self.purchase_price +class ProductFormula(models.Model): + products = models.ManyToManyField( + Product, + related_name="formulas", + verbose_name=_("products"), + help_text=_("The products that constitute this formula."), + ) + result = models.OneToOneField( + Product, + on_delete=models.CASCADE, + verbose_name=_("result product"), + help_text=_("The product got with the formula."), + ) + + def __str__(self): + return self.result.name + + class CounterQuerySet(models.QuerySet): def annotate_has_barman(self, user: User) -> Self: """Annotate the queryset with the `user_is_barman` field.