from decimal import Decimal from django.contrib.auth import get_user_model from shop.models import ( Cart, CustomerAddress, Order, OrderLine, Product, ProductBatch, ProductPrice, ShippingMethod, ) User = get_user_model() def create_order_line_for_product(product: Product, quantity: Decimal, order: Order): price = product.prices.last() base_total = round(price.price * quantity, 2) tax_value = price.tax.value / Decimal("100") taxes = round(base_total * tax_value, 2) return OrderLine.objects.create( order=order, product=product, quantity=quantity, price=price.price, base_total=base_total, tax_value=tax_value, taxes=taxes, total=base_total + taxes, ) def create_order( customer: User, billing_address: str, billing_city: str, billing_state: str, billing_country: str, billing_zip: str, shipping_address: str = "", shipping_city: str = "", shipping_state: str = "", shipping_country: str = "", shipping_zip: str = "", ) -> Order: order = Order.objects.create( user=customer, billing_address=billing_address, billing_city=billing_city, billing_state=billing_state, billing_country=billing_country, billing_zip=billing_zip, shipping_address=shipping_address, shipping_city=shipping_city, shipping_state=shipping_state, shipping_country=shipping_country, shipping_zip=shipping_zip, ) return order def delete_product_batch(batch: ProductBatch): product = batch.product product.stock = max(product.stock - batch.quantity, 0) product.save() batch.delete() def create_order_from_cart( cart: Cart, billing_address: CustomerAddress, shipping_address: CustomerAddress, shipping_method: ShippingMethod, ): order = Order.objects.create( billing_address=billing_address.address, billing_city=billing_address.address_town, billing_state=billing_address.address_state, billing_country=billing_address.address_country, billing_zip=billing_address.address_zip, shipping_address=shipping_address.address, shipping_city=shipping_address.address_town, shipping_state=shipping_address.address_state, shipping_country=shipping_address.address_country, shipping_zip=shipping_address.address_zip, user=cart.user, ) for item in cart.items.all(): product = item.product price: ProductPrice = product.price base_total = price.price * item.quantity tax_value = price.tax.value taxes = base_total * tax_value / Decimal(100) total = base_total + taxes OrderLine.objects.create( order=order, product=product, quantity=item.quantity, price=price.price, base_total=base_total, tax_value=tax_value, taxes=taxes, total=total, ) order.calculate_total_from_lines() add_shipping_order_line(order, shipping_method) return order def add_shipping_order_line(order, shipping_method): shipping_price: ProductPrice = shipping_method.shipping_product.price shipping_base_total = shipping_price.price shipping_tax_value = shipping_price.tax.value shipping_taxes = shipping_base_total * (shipping_tax_value / Decimal(100)) shipping_total = shipping_base_total + shipping_taxes OrderLine.objects.create( order=order, product=shipping_method.shipping_product, quantity=1, price=shipping_price.price, base_total=shipping_base_total, tax_value=shipping_tax_value, taxes=shipping_taxes, total=shipping_total, ) order.calculate_total_from_lines()