我正在尝试创建一个应用程序来保存商店的帐户。每次将发票上载到系统时,必须在另一个名为“产品”的表中创建产品,但如果产品已经存在,则只需更新价格和数量。
每张发票可以有多个产品
-
-
是否有任何方法可以在每张发票上创建产品列表来表示这种关系?。一个供应商可以提供多个产品。
-
有没有一种方法可以在不创建重复项的情况下创建产品表中的记录?。如果一次更新的产品数量与发票中的数量相同,则不必输入新的存货。
例如,要输入的发票包含以下信息:
如果产品A存在,发票必须更新库存中的价格和数量。
到目前为止,我只有:
发票/模型.py
:
from django.db import models
from product.models import Product
from sales.models import PaymentMethod
class Supplyer(models.Model):
"""
Proveedor de servicios o productos
"""
rif = models.CharField(max_length=255)
name = models.CharField(max_length=255)
phone = models.CharField(max_length=255)
email = models.EmailField()
def __str__(self):
return '{} - {}'.format(self.name, self.rif)
class Invoice(models.Model):
"""
Clase que controla las facturas ingresadas al sistema
"""
ref = models.CharField(max_length=255)
supplyer = models.OneToOneField(Supplyer, on_delete=models.CASCADE)
items = models.ManyToManyField(Product)
total = models.DecimalField(max_digits=14, decimal_places=2)
paymnet_method = models.OneToOneField(PaymentMethod, on_delete=models.CASCADE)
date = models.DateField(auto_now_add=True, auto_now=False)
def __str__(self):
return '{} - {} - {}'.format(self.supplyer, self.date, self.ref)
:
from rest_framework.serializers import ModelSerializer
from invoice.models import Supplyer, Invoice
from stock.models import Product
from stock.serializers import ProductSerializer
class SupplyerSerializer(ModelSerializer):
"""
Clase que controla los proveedores de productos o servicios
"""
class Meta:
model = Supplyer
fields = ('rif', 'name', 'phone', 'email')
class InvoiceSerializer(ModelSerializer):
"""
Clase que controla las facturas de proveedores.
Esta clase tiene un metodo crear propio para poder crear productos cuando
se carga la factura, y si el producto ya existe, debe actualizar el costo
del producto en el inventario
"""
# Llamada al serializador de productos
product_serializer = ProductSerializer(many=True)
# Llamada al serializador de proveedores
supplyer_serializer = SupplyerSerializer()
class Meta:
model = Invoice
fields = ('ref', 'supplyer_serializer', 'product_serializer', 'total', 'payment_method', 'date')
def create(self, validated_data):
"""
Este metodo sobre escribe el metodo de crear instancia por defecto del
serializador, esto nos permite crear un producto y actualizar el
precio al momento de cargar la factura al sistema.
self: llamada al metodo
validated_data: Datos validados por el serializador
"""
# lista de productos o servicios en la factura
products_obj = validated_data.pop('items')
# Cargar la factura a la base de datos
invoice = Invoice.objects.create(**validated_data)
# Iterar por la lista de productos de la factura
for product in products_obj:
Product.objects.create(products_obj)
return invoice
def update(self, instance, validated_data):
"""
Este metodo actualiza las facturas y productos asociados a ella
self: llamada al metodo
instance: instancia u objeto a modificar
validated_data: datos validados por el serializador
"""
# Se obtienen los datos de los productos en la factura
products_obj = validated_data.pop('items')
products = (instance.product_serializer).all()
products = list(products)
# Se selecciona la factura y se actualizan los datos
instance.ref = validated_data.get('ref', instance.ref)
instance.supplyer = validated_data.get('supplyer', instance.supplyer)
instance.total = validated_data.get('total', instance.total)
instance.payment_method = validated_data.get('payment_method', instance.payment_method)
# Iterar pro la lista de productos
for product_data in products_obj:
# Dentro del bucle se atualizan los datos de los productos
product = products.pop(0)
product.name = product_data.get('name', product.name)
product.description = product_data.get('description', product.description)
product.price = product_data.get('price', product.price)
product.save()
return instance
股票/模型.py
:
from django.db import models
class Product(models.Model):
name = models.CharField(max_length=255)
description = models.CharField(max_length=255)
price = models.DecimalField(max_digits=12, decimal_places=2)
class Stock(models.Model):
item = models.OneToOneField(Product, on_delete='CACADE')
package = models.CharField(max_length=255)
unity = models.IntegerField()
date = models.DateTimeField(auto_now=True)
value = models.DecimalField(max_digits=12, decimal_places=2)
cost = models.DecimalField(max_digits=12, decimal_places=2)
qty = models.IntegerField()
def __str__(self):
return '{}'.format(self.date)