Migrate to global currency system in commerce app
Removed per-product currency in favor of a global site currency managed via SiteConfiguration. Updated models, views, templates, and Stripe integration to use the global currency. Added migration, management command for migration, and API endpoint for currency info. Improved permissions and filtering for orders, reviews, and carts. Expanded supported currencies in configuration.
This commit is contained in:
@@ -71,7 +71,7 @@ class Product(models.Model):
|
||||
|
||||
# -- CENA --
|
||||
price = models.DecimalField(max_digits=10, decimal_places=2, help_text="Net price (without VAT)")
|
||||
currency = models.CharField(max_length=3, default="CZK")
|
||||
# Currency is now global from SiteConfiguration, not per-product
|
||||
|
||||
# VAT rate - configured by business owner in configuration app!!!
|
||||
vat_rate = models.ForeignKey(
|
||||
@@ -127,7 +127,8 @@ class Product(models.Model):
|
||||
return self.price * vat_rate.rate_decimal
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.name} ({self.get_price_with_vat()} {self.currency.upper()} inkl. MwSt)"
|
||||
config = SiteConfiguration.get_solo()
|
||||
return f"{self.name} ({self.get_price_with_vat()} {config.currency} inkl. MwSt)"
|
||||
|
||||
#obrázek pro produkty
|
||||
class ProductImage(models.Model):
|
||||
@@ -164,7 +165,8 @@ class Order(models.Model):
|
||||
|
||||
# Stored order grand total; recalculated on save
|
||||
total_price = models.DecimalField(max_digits=10, decimal_places=2, default=Decimal('0.00'))
|
||||
currency = models.CharField(max_length=10, default="CZK")
|
||||
# Currency - captured from site configuration at creation time, never changes
|
||||
currency = models.CharField(max_length=10, default="", help_text="Order currency - captured from site configuration at order creation and never changes")
|
||||
|
||||
# fakturační údaje (zkopírované z user profilu při objednávce)
|
||||
user = models.ForeignKey(
|
||||
@@ -257,13 +259,25 @@ class Order(models.Model):
|
||||
# Validate order has items
|
||||
if self.pk and not self.items.exists():
|
||||
raise ValidationError("Order must have at least one item.")
|
||||
|
||||
def get_currency(self):
|
||||
\"\"\"Get order currency - falls back to site configuration if not set\"\"\"
|
||||
if self.currency:
|
||||
return self.currency
|
||||
config = SiteConfiguration.get_solo()
|
||||
return config.currency
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
# Keep total_price always in sync with items and discount
|
||||
self.total_price = self.calculate_total_price()
|
||||
|
||||
is_new = self.pk is None
|
||||
|
||||
is_new = self.pk is None
|
||||
|
||||
# CRITICAL: Set currency from site configuration ONLY at creation time
|
||||
# Once set, currency should NEVER change to maintain order integrity
|
||||
if is_new and not self.currency:
|
||||
config = SiteConfiguration.get_solo()
|
||||
self.currency = config.currency
|
||||
|
||||
# Keep total_price always in sync with items and discount
|
||||
self.total_price = self.calculate_total_price()
|
||||
if self.user and is_new:
|
||||
self.import_data_from_user()
|
||||
|
||||
@@ -274,6 +288,15 @@ class Order(models.Model):
|
||||
from .tasks import notify_order_successfuly_created
|
||||
notify_order_successfuly_created.delay(order=self, user=self.user)
|
||||
|
||||
def cancel_order(self):
|
||||
"""Cancel the order if possible"""
|
||||
if self.status == self.OrderStatus.CREATED:
|
||||
self.status = self.OrderStatus.CANCELLED
|
||||
self.save()
|
||||
#TODO: udělat ještě kontrolu jestli už nebyla odeslána zásilka a pokud bude už zaplacena tak se uděla refundace a pokud nebude zaplacena tak se zruší brána.
|
||||
else:
|
||||
raise ValidationError("Only orders in 'created' status can be cancelled.")
|
||||
|
||||
|
||||
# ------------------ DOPRAVCI A ZPŮSOBY DOPRAVY ------------------
|
||||
|
||||
@@ -480,7 +503,7 @@ class DiscountCode(models.Model):
|
||||
)
|
||||
|
||||
# nebo fixní částka
|
||||
amount = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True, help_text="Fixní sleva v CZK")
|
||||
amount = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True, help_text=\"Fixed discount amount in site currency\")
|
||||
|
||||
valid_from = models.DateTimeField(default=timezone.now)
|
||||
valid_to = models.DateTimeField(null=True, blank=True)
|
||||
|
||||
Reference in New Issue
Block a user