Django_Basic_Manufacturing_3/apps/purchasing/models.py
2025-08-22 17:05:22 +07:00

95 lines
3.8 KiB
Python

from django.db import models
class Supplier(models.Model):
code = models.CharField(max_length=50, unique=True)
name = models.CharField(max_length=200)
contact_person = models.CharField(max_length=100, blank=True)
email = models.EmailField(blank=True)
phone = models.CharField(max_length=20, blank=True)
address = models.TextField(blank=True)
tax_id = models.CharField(max_length=50, blank=True)
payment_terms = models.CharField(max_length=100, blank=True)
is_active = models.BooleanField(default=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.name
class PurchaseOrder(models.Model):
STATUS_CHOICES = [
('ordered', 'Ordered'),
('completed', 'Completed'),
('cancelled', 'Cancelled'),
]
po_number = models.CharField(max_length=50, unique=True, blank=True)
supplier = models.ForeignKey(Supplier, on_delete=models.CASCADE)
order_date = models.DateField()
expected_delivery_date = models.DateField(null=True, blank=True)
status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='ordered')
subtotal = models.DecimalField(max_digits=12, decimal_places=2, default=0)
tax_amount = models.DecimalField(max_digits=12, decimal_places=2, default=0)
total_amount = models.DecimalField(max_digits=12, decimal_places=2, default=0)
notes = models.TextField(blank=True)
created_by = models.ForeignKey('accounts.User', on_delete=models.SET_NULL, null=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def save(self, *args, **kwargs):
if not self.po_number:
self.po_number = self.generate_po_number()
super().save(*args, **kwargs)
def generate_po_number(self):
"""Generate a unique purchase order number"""
last_po = PurchaseOrder.objects.order_by('-id').first()
if last_po and last_po.po_number and last_po.po_number.startswith('PO'):
try:
last_number = int(last_po.po_number[2:]) # Remove 'PO' prefix
new_number = last_number + 1
except ValueError:
new_number = 1
else:
new_number = 1
return f'PO{new_number:04d}'
def __str__(self):
return self.po_number
class PurchaseOrderItem(models.Model):
po = models.ForeignKey(PurchaseOrder, on_delete=models.CASCADE, related_name='items')
product = models.ForeignKey('inventory.Product', on_delete=models.CASCADE)
quantity = models.DecimalField(max_digits=10, decimal_places=2)
unit_price = models.DecimalField(max_digits=10, decimal_places=2)
total_price = models.DecimalField(max_digits=12, decimal_places=2)
received_quantity = models.DecimalField(max_digits=10, decimal_places=2, default=0)
def save(self, *args, **kwargs):
self.total_price = self.quantity * self.unit_price
super().save(*args, **kwargs)
class GoodsReceipt(models.Model):
gr_number = models.CharField(max_length=50, unique=True)
po = models.ForeignKey(PurchaseOrder, on_delete=models.CASCADE)
receipt_date = models.DateField()
received_by = models.ForeignKey('accounts.User', on_delete=models.SET_NULL, null=True)
notes = models.TextField(blank=True)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.gr_number
class GoodsReceiptItem(models.Model):
receipt = models.ForeignKey(GoodsReceipt, on_delete=models.CASCADE, related_name='items')
po_item = models.ForeignKey(PurchaseOrderItem, on_delete=models.CASCADE)
received_quantity = models.DecimalField(max_digits=10, decimal_places=2)
notes = models.TextField(blank=True)