from django.db import models from django.db.models import Max from vbv_lernwelt.core.models import Country class Product(models.Model): sku = models.CharField(max_length=255, primary_key=True) price = models.IntegerField() # 10_00 = 10.00 CHF name = models.CharField(max_length=255) description = models.CharField(max_length=255) class CheckoutState(models.TextChoices): """ The state of a checkout process transaction. PAID: Datatrans transaction settled/transmitted. ONGOING: Any state that is not final (e.g. initialized, challenge_ongoing, etc.) 1) We use the `autoSettle` feature of DataTrans! -> https://docs.datatrans.ch/docs/after-the-payment -> https://api-reference.datatrans.ch/#tag/v1transactions/operation/status 2) Difference between `settled` and `transmitted`: - https://www.datatrans.ch/en/know-how/faq/#what-does-the-status-transaction-settled-or-settledtransmitted-mean 3) Related code: init_transaction and get_transaction_state in shop/services.py """ ONGOING = "ongoing" PAID = "paid" CANCELED = "canceled" FAILED = "failed" class CheckoutInformation(models.Model): INVOICE_ADDRESS_PRIVATE = "prv" INVOICE_ADDRESS_ORGANISATION = "org" INVOICE_ADDRESS_CHOICES = ( (INVOICE_ADDRESS_PRIVATE, "Private"), (INVOICE_ADDRESS_ORGANISATION, "Organisation"), ) user = models.ForeignKey("core.User", on_delete=models.PROTECT) product_sku = models.CharField(max_length=255) product_name = models.CharField(max_length=255) product_description = models.CharField(max_length=255) product_price = models.IntegerField( help_text="The total price of the product in centimes -> 1000 = 10.00 CHF" ) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) state = models.CharField( max_length=50, choices=CheckoutState.choices, ) invoice_transmitted_at = models.DateTimeField(blank=True, null=True) transaction_id = models.CharField(max_length=255) # end user (required) first_name = models.CharField(max_length=255) last_name = models.CharField(max_length=255) street = models.CharField(max_length=255) street_number = models.CharField(max_length=255) postal_code = models.CharField(max_length=255) city = models.CharField(max_length=255) country = models.ForeignKey( Country, related_name="+", on_delete=models.SET_NULL, null=True, blank=True, ) invoice_address = models.CharField( max_length=3, choices=INVOICE_ADDRESS_CHOICES, default="prv" ) # organisation data (optional) organisation_detail_name = models.CharField(max_length=255, blank=True) organisation_street = models.CharField(max_length=255, blank=True) organisation_street_number = models.CharField(max_length=255, blank=True) organisation_postal_code = models.CharField(max_length=255, blank=True) organisation_city = models.CharField(max_length=255, blank=True) organisation_country = models.ForeignKey( Country, related_name="+", on_delete=models.SET_NULL, null=True, blank=True, ) # webhook metadata webhook_history = models.JSONField(default=list) # is only set by abacus invoice export code abacus_order_id = models.BigIntegerField(unique=True, null=True, blank=True) def set_increment_abacus_order_id(self): if self.abacus_order_id: return self # Get the current maximum abacus_order_id and increment it by 1 current_max = CheckoutInformation.objects.aggregate( max_number=Max("abacus_order_id") )["max_number"] new_abacus_order_id = ( current_max if current_max is not None else 6_000_000_000 ) + 1 self.abacus_order_id = new_abacus_order_id self.save() return self