95 lines
3.8 KiB
Python
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)
|