from django.db import models from django.core.validators import MinValueValidator class Category(models.Model): name = models.CharField(max_length=100) description = models.TextField(blank=True) created_at = models.DateTimeField(auto_now_add=True) def __str__(self): return self.name class UnitOfMeasure(models.Model): name = models.CharField(max_length=50) abbreviation = models.CharField(max_length=10) def __str__(self): return self.name class Product(models.Model): PRODUCT_TYPES = [ ('raw_material', 'Raw Material'), ('finished_good', 'Finished Good'), ('component', 'Component'), ] code = models.CharField(max_length=50, unique=True) name = models.CharField(max_length=200) description = models.TextField(blank=True) category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True, blank=True) unit_of_measure = models.ForeignKey(UnitOfMeasure, on_delete=models.SET_NULL, null=True) product_type = models.CharField(max_length=20, choices=PRODUCT_TYPES) reorder_level = models.DecimalField(max_digits=10, decimal_places=2, default=0) selling_price = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True) cost_price = models.DecimalField(max_digits=10, decimal_places=2, null=True, 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 f"{self.code} - {self.name}" class Warehouse(models.Model): name = models.CharField(max_length=100) location = models.CharField(max_length=200) is_active = models.BooleanField(default=True) created_at = models.DateTimeField(auto_now_add=True) def __str__(self): return self.name class Inventory(models.Model): product = models.ForeignKey(Product, on_delete=models.CASCADE) warehouse = models.ForeignKey(Warehouse, on_delete=models.CASCADE) quantity = models.DecimalField(max_digits=10, decimal_places=2, default=0) reserved_quantity = models.DecimalField(max_digits=10, decimal_places=2, default=0) updated_at = models.DateTimeField(auto_now=True) class Meta: unique_together = ('product', 'warehouse') @property def available_quantity(self): return self.quantity - self.reserved_quantity class StockMovement(models.Model): MOVEMENT_TYPES = [ ('in', 'Stock In'), ('out', 'Stock Out'), ('adjustment', 'Adjustment'), ('transfer', 'Transfer'), ] product = models.ForeignKey(Product, on_delete=models.CASCADE) warehouse = models.ForeignKey(Warehouse, on_delete=models.CASCADE) movement_type = models.CharField(max_length=20, choices=MOVEMENT_TYPES) quantity = models.DecimalField(max_digits=10, decimal_places=2) reference_number = models.CharField(max_length=100, blank=True) 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)