feat: lots of changes
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
from rest_framework.permissions import BasePermission
|
||||
from config.api.v1.mixins import CRUDPermissionsMixin
|
||||
|
||||
|
||||
class ProductPermissions(CRUDPermissionsMixin, BasePermission):
|
||||
view_permission_codes = ("shop.view_product",)
|
||||
create_permission_codes = ("shop.add_product",)
|
||||
destroy_permission_codes = ("shop.delete_product",)
|
||||
update_permission_codes = ("shop.change_product",)
|
||||
|
||||
|
||||
class ProductPricePermissions(CRUDPermissionsMixin, BasePermission):
|
||||
view_permission_codes = ("shop.view_productprice",)
|
||||
create_permission_codes = ("shop.add_productprice",)
|
||||
destroy_permission_codes = ("shop.delete_productprice",)
|
||||
update_permission_codes = ("shop.change_productprice",)
|
||||
@@ -1,4 +1,4 @@
|
||||
# Generated by Django 5.0.3 on 2024-03-24 22:50
|
||||
# Generated by Django 5.0.3 on 2024-04-24 14:00
|
||||
|
||||
import django.db.models.deletion
|
||||
import django.utils.timezone
|
||||
@@ -139,7 +139,12 @@ class Migration(migrations.Migration):
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("uuid", models.UUIDField(default=uuid.uuid4, verbose_name="UUID")),
|
||||
(
|
||||
"uuid",
|
||||
models.UUIDField(
|
||||
db_index=True, default=uuid.uuid4, verbose_name="UUID"
|
||||
),
|
||||
),
|
||||
(
|
||||
"creation_date",
|
||||
models.DateTimeField(
|
||||
@@ -346,6 +351,14 @@ class Migration(migrations.Migration):
|
||||
verbose_name="Producto",
|
||||
),
|
||||
),
|
||||
(
|
||||
"tax",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.PROTECT,
|
||||
to="shop.tax",
|
||||
verbose_name="Impuesto aplicable",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "Precio de producto",
|
||||
|
||||
+29
-12
@@ -7,11 +7,6 @@ from django.utils.text import gettext_lazy as _
|
||||
|
||||
|
||||
class Product(models.Model):
|
||||
class UnitChoices(models.TextChoices):
|
||||
UNIT = "UNIT", _("Unidad")
|
||||
WEIGHT_KG = "KG", _("kg")
|
||||
VOLUME_LITER = "L", _("L")
|
||||
|
||||
name = models.CharField(
|
||||
max_length=96,
|
||||
blank=False,
|
||||
@@ -30,12 +25,8 @@ class Product(models.Model):
|
||||
default=Decimal("0"),
|
||||
verbose_name=_("Stock"),
|
||||
)
|
||||
unit = models.CharField(
|
||||
max_length=6,
|
||||
choices=UnitChoices.choices,
|
||||
default=UnitChoices.UNIT,
|
||||
verbose_name=_("Unidad de medida"),
|
||||
)
|
||||
is_digital_asset = models.BooleanField(default=False)
|
||||
url = models.URLField(blank=True, verbose_name=_('URL de descarga'))
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
@@ -56,9 +47,19 @@ class ProductPrice(models.Model):
|
||||
verbose_name=_("Producto"),
|
||||
related_name="prices",
|
||||
)
|
||||
tax = models.ForeignKey(
|
||||
"shop.Tax",
|
||||
on_delete=models.PROTECT,
|
||||
verbose_name=_("Impuesto aplicable"),
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.price}"
|
||||
return f"{self.price} - {self.tax.code}"
|
||||
|
||||
@property
|
||||
def price_with_tax(self):
|
||||
tax_value = self.price * (self.tax.value / 100)
|
||||
return round(self.price + tax_value, 2)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("Precio de producto")
|
||||
@@ -170,7 +171,23 @@ class OrderLine(models.Model):
|
||||
|
||||
|
||||
class Order(models.Model):
|
||||
class Statuses(models.TextChoices):
|
||||
STATUS_PENDING = "PEN", _("Pendiente de pago")
|
||||
STATUS_PAID = "PAI", _("Pagado")
|
||||
STATUS_READY = "RDY", _("Preparado")
|
||||
STATUS_TO_BE_SENT = "TBS", _("Listo para ser enviado")
|
||||
STATUS_SENT = "SNT", _("Enviado")
|
||||
STATUS_DELIVERED = "DLV", _("Entregado")
|
||||
STATUS_FINISHED = "FIN", _("Finalizado")
|
||||
STATUS_CANCELED = "CAN", _("Cancelado")
|
||||
STATUS_RETURNED = "RTN", _("Devuelto")
|
||||
|
||||
uuid = models.UUIDField(default=uuid4, verbose_name=_("UUID"), db_index=True)
|
||||
|
||||
status = models.CharField(
|
||||
max_length=3, default=Statuses.STATUS_PENDING, verbose_name=_("Estado")
|
||||
)
|
||||
|
||||
creation_date = models.DateTimeField(
|
||||
auto_now_add=True, verbose_name=_("Fecha de creación")
|
||||
)
|
||||
|
||||
@@ -29,9 +29,15 @@ class ShopModelsTest(TestCase):
|
||||
unit=Product.UnitChoices.UNIT,
|
||||
)
|
||||
|
||||
ProductPrice.objects.create(product=self.potatoes, price=Decimal("0.80"))
|
||||
ProductPrice.objects.create(product=self.gasoline, price=Decimal("1.15"))
|
||||
ProductPrice.objects.create(product=self.usb_c, price=Decimal("9.95"))
|
||||
ProductPrice.objects.create(
|
||||
product=self.potatoes, price=Decimal("0.80"), tax=self.tax
|
||||
)
|
||||
ProductPrice.objects.create(
|
||||
product=self.gasoline, price=Decimal("1.15"), tax=self.tax
|
||||
)
|
||||
ProductPrice.objects.create(
|
||||
product=self.usb_c, price=Decimal("9.95"), tax=self.tax
|
||||
)
|
||||
|
||||
def test_create_order(self):
|
||||
self.customer = Customer.objects.create(
|
||||
@@ -57,19 +63,16 @@ class ShopModelsTest(TestCase):
|
||||
l1 = create_order_line_for_product(
|
||||
self.potatoes,
|
||||
quantity=Decimal("1.5"),
|
||||
tax=self.tax,
|
||||
order=order,
|
||||
)
|
||||
l2 = create_order_line_for_product(
|
||||
self.gasoline,
|
||||
quantity=Decimal("40"),
|
||||
tax=self.tax,
|
||||
order=order,
|
||||
)
|
||||
l3 = create_order_line_for_product(
|
||||
self.usb_c,
|
||||
quantity=Decimal("1.00"),
|
||||
tax=self.tax,
|
||||
order=order,
|
||||
)
|
||||
order.calculate_total_from_lines()
|
||||
|
||||
+7
-8
@@ -5,20 +5,19 @@ from shop.models import OrderLine, Tax, Product, Order, Customer
|
||||
from django.db.models import QuerySet
|
||||
|
||||
|
||||
def create_order_line_for_product(
|
||||
product: Product, quantity: Decimal, tax: Tax, order: Order
|
||||
):
|
||||
price = product.prices.last().price
|
||||
base_total = round(price * quantity, 2)
|
||||
taxes = round(base_total * (tax.value / Decimal("100")), 2)
|
||||
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=price.price,
|
||||
base_total=base_total,
|
||||
tax_value=tax.value,
|
||||
tax_value=tax_value,
|
||||
taxes=taxes,
|
||||
total=base_total + taxes,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user