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)