Features: 1) Add support for optional billing_address_uuid and shipping_address_uuid in apply_addresses; 2) Introduce chosen_products parameter in the buy method for customized order creation;

Fixes: 1) Correct type annotations in `buy` and `bulk_add_products` methods for improved type safety;

Extra: 1) Refactor `buy` method for enhanced readability and maintainability; 2) Update usage of `self` to `order` for clarity in dynamic order creation scenarios.
This commit is contained in:
Egor Pavlovich Gorbunov 2025-07-06 23:53:46 +03:00
parent 34f25052e0
commit 1ace97c233

View file

@ -1532,7 +1532,7 @@ class Order(ExportModelOperationsMixin("order"), NiceModel): # type: ignore [mi
raise Http404(_("promocode does not exist")) from dne
return promocode.use(self)
def apply_addresses(self, billing_address_uuid, shipping_address_uuid):
def apply_addresses(self, billing_address_uuid: str | None = None, shipping_address_uuid: str | None = None):
try:
if not any([shipping_address_uuid, billing_address_uuid]):
if self.is_whole_digital:
@ -1561,21 +1561,27 @@ class Order(ExportModelOperationsMixin("order"), NiceModel): # type: ignore [mi
def buy(
self,
force_balance=False,
force_payment=False,
promocode_uuid=None,
billing_address=None,
shipping_address=None,
force_balance: bool = False,
force_payment: bool = False,
promocode_uuid: str | None = None,
billing_address: str | None = None,
shipping_address: str | None = None,
chosen_products: list = None,
) -> Self | Transaction | None:
order = self
if chosen_products:
order = Order.objects.create(status="MOMENTAL", user=self.user)
order.bulk_add_products(chosen_products)
if config.DISABLED_COMMERCE:
raise DisabledCommerceError(_("you can not buy at this moment, please try again in a few minutes"))
if (not force_balance and not force_payment) or (force_balance and force_payment):
raise ValueError(_("invalid force value"))
self.apply_addresses(billing_address, shipping_address)
order.apply_addresses(billing_address, shipping_address)
if self.total_quantity < 1:
if order.total_quantity < 1:
raise ValueError(_("you cannot purchase an empty order!"))
force = None
@ -1586,34 +1592,34 @@ class Order(ExportModelOperationsMixin("order"), NiceModel): # type: ignore [mi
if force_payment:
force = "payment"
amount = self.apply_promocode(promocode_uuid) if promocode_uuid else self.total_price
amount = order.apply_promocode(promocode_uuid) if promocode_uuid else order.total_price
if not self.user:
if not order.user:
raise ValueError(_("you cannot buy an order without a user"))
if not self.user.payments_balance:
if not order.user.payments_balance:
raise ValueError(_("a user without a balance cannot buy with balance"))
match force:
case "balance":
if self.user.payments_balance.amount < amount:
if order.user.payments_balance.amount < amount:
raise NotEnoughMoneyError(_("insufficient funds to complete the order"))
self.status = "CREATED"
self.buy_time = timezone.now()
self.order_products.all().update(status="DELIVERING")
self.save()
return self
order.status = "CREATED"
order.buy_time = timezone.now()
order.order_products.all().update(status="DELIVERING")
order.save()
return order
case "payment":
self.status = "PAYMENT"
self.save()
order.status = "PAYMENT"
order.save()
return Transaction.objects.create(
balance=self.user.payments_balance,
balance=order.user.payments_balance,
amount=amount,
currency=CURRENCY_CODE,
order=self,
order=order,
)
return self
return order
def buy_without_registration(self, products: list, promocode_uuid, **kwargs) -> Transaction | None:
if config.DISABLED_COMMERCE:
@ -1689,7 +1695,7 @@ class Order(ExportModelOperationsMixin("order"), NiceModel): # type: ignore [mi
self.status = "FINISHED"
self.save()
def bulk_add_products(self, products: list):
def bulk_add_products(self, products: list[dict[str, Any]]):
for product in products:
self.add_product(
product.get("uuid"),