feat: added customer addresses and shipping method
This commit is contained in:
@@ -13,6 +13,8 @@ from shop.models import (
|
||||
Provider,
|
||||
Tag,
|
||||
Tax,
|
||||
ShippingMethod,
|
||||
CustomerAddress,
|
||||
)
|
||||
|
||||
|
||||
@@ -115,3 +117,28 @@ class ProductBatchAdmin(ModelAdmin):
|
||||
"product",
|
||||
"quantity",
|
||||
)
|
||||
|
||||
|
||||
@admin.register(ShippingMethod)
|
||||
class ShippingMethodAdmin(ModelAdmin):
|
||||
list_display = (
|
||||
"id",
|
||||
"name",
|
||||
"description",
|
||||
)
|
||||
|
||||
|
||||
@admin.register(CustomerAddress)
|
||||
class CustomerAddressAdmin(ModelAdmin):
|
||||
list_display = (
|
||||
"id",
|
||||
"user",
|
||||
"vat_id",
|
||||
"address",
|
||||
"address_state",
|
||||
"address_zip",
|
||||
)
|
||||
|
||||
def get_queryset(self, request):
|
||||
qs = super().get_queryset(request)
|
||||
return qs.filter(hidden=False)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Generated by Django 5.1.3 on 2024-12-07 10:15
|
||||
# Generated by Django 5.1.3 on 2024-12-23 12:01
|
||||
|
||||
import django.db.models.deletion
|
||||
import django.utils.timezone
|
||||
@@ -233,6 +233,10 @@ class Migration(migrations.Migration):
|
||||
verbose_name="número de identificación fiscal",
|
||||
),
|
||||
),
|
||||
(
|
||||
"full_name",
|
||||
models.CharField(max_length=128, verbose_name="dirección"),
|
||||
),
|
||||
("address", models.CharField(max_length=128, verbose_name="dirección")),
|
||||
(
|
||||
"address_town",
|
||||
@@ -271,10 +275,20 @@ class Migration(migrations.Migration):
|
||||
verbose_name="tipo de dirección",
|
||||
),
|
||||
),
|
||||
("default", models.BooleanField(default=True)),
|
||||
(
|
||||
"default",
|
||||
models.BooleanField(default=True, verbose_name="por defecto"),
|
||||
),
|
||||
(
|
||||
"hidden",
|
||||
models.BooleanField(
|
||||
db_index=True, default=False, verbose_name="oculto"
|
||||
),
|
||||
),
|
||||
(
|
||||
"user",
|
||||
models.ForeignKey(
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
verbose_name="usuario",
|
||||
@@ -471,6 +485,12 @@ class Migration(migrations.Migration):
|
||||
verbose_name="Slug",
|
||||
),
|
||||
),
|
||||
(
|
||||
"hidden",
|
||||
models.BooleanField(
|
||||
db_index=True, default=False, verbose_name="oculto"
|
||||
),
|
||||
),
|
||||
(
|
||||
"brand",
|
||||
models.ForeignKey(
|
||||
@@ -697,6 +717,47 @@ class Migration(migrations.Migration):
|
||||
"verbose_name_plural": "remesas de productos",
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="ShippingMethod",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("name", models.CharField(max_length=64, verbose_name="nombre")),
|
||||
(
|
||||
"description",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default="",
|
||||
max_length=256,
|
||||
verbose_name="description",
|
||||
),
|
||||
),
|
||||
("url", models.URLField(blank=True, default="", verbose_name="url")),
|
||||
(
|
||||
"enabled",
|
||||
models.BooleanField(default=True, verbose_name="habilitado"),
|
||||
),
|
||||
(
|
||||
"shipping_product",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
to="shop.product",
|
||||
verbose_name="producto de envío",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "método de envío",
|
||||
"verbose_name_plural": "métodos de envío",
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="ProductPrice",
|
||||
fields=[
|
||||
|
||||
+23
-2
@@ -78,6 +78,7 @@ class Product(TimestampedModel):
|
||||
slug = models.SlugField(
|
||||
default="", blank=True, null=True, max_length=128, verbose_name=_("Slug")
|
||||
)
|
||||
hidden = models.BooleanField(default=False, db_index=True, verbose_name=_("oculto"))
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
@@ -414,7 +415,7 @@ class CustomerAddress(models.Model):
|
||||
BILLING = "BILL", _("facturación")
|
||||
SHIPPING = "SHIP", _("envío")
|
||||
|
||||
user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name=_("usuario"))
|
||||
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, verbose_name=_("usuario"))
|
||||
vat_id = models.CharField(
|
||||
max_length=16,
|
||||
blank=True,
|
||||
@@ -422,6 +423,9 @@ class CustomerAddress(models.Model):
|
||||
default="",
|
||||
verbose_name=_("número de identificación fiscal"),
|
||||
)
|
||||
full_name = models.CharField(
|
||||
max_length=128, blank=False, null=False, verbose_name=_("dirección")
|
||||
)
|
||||
address = models.CharField(
|
||||
max_length=128, blank=False, null=False, verbose_name=_("dirección")
|
||||
)
|
||||
@@ -451,8 +455,25 @@ class CustomerAddress(models.Model):
|
||||
default=Types.SHIPPING,
|
||||
verbose_name=_("tipo de dirección"),
|
||||
)
|
||||
default = models.BooleanField(default=True)
|
||||
default = models.BooleanField(default=True, verbose_name=_("por defecto"))
|
||||
hidden = models.BooleanField(default=False, db_index=True, verbose_name=_("oculto"))
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("dirección de cliente")
|
||||
verbose_name_plural = _("direcciones de cliente")
|
||||
|
||||
|
||||
class ShippingMethod(models.Model):
|
||||
name = models.CharField(max_length=64, verbose_name=_("nombre"))
|
||||
description = models.CharField(
|
||||
max_length=256, default="", blank=True, verbose_name=_("description")
|
||||
)
|
||||
url = models.URLField(default="", blank=True, verbose_name=_("url"))
|
||||
shipping_product = models.ForeignKey(
|
||||
"shop.Product", on_delete=models.CASCADE, verbose_name=_("producto de envío")
|
||||
)
|
||||
enabled = models.BooleanField(default=True, verbose_name=_("habilitado"))
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("método de envío")
|
||||
verbose_name_plural = _("métodos de envío")
|
||||
|
||||
+74
-1
@@ -1,6 +1,15 @@
|
||||
from decimal import Decimal
|
||||
|
||||
from shop.models import Order, OrderLine, Product, ProductBatch
|
||||
from shop.models import (
|
||||
Order,
|
||||
OrderLine,
|
||||
Product,
|
||||
ProductBatch,
|
||||
Cart,
|
||||
CustomerAddress,
|
||||
ShippingMethod,
|
||||
ProductPrice,
|
||||
)
|
||||
from django.contrib.auth import get_user_model
|
||||
|
||||
User = get_user_model()
|
||||
@@ -59,3 +68,67 @@ def delete_product_batch(batch: ProductBatch):
|
||||
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,
|
||||
)
|
||||
|
||||
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 / 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 / 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()
|
||||
|
||||
Reference in New Issue
Block a user