I'm trying to learn Django by building an inventory management system, here's my final models.py.
I'm looking for feedback!
from django.core.exceptions import ValidationError
from django.urls import reverse
from django.db import models
from core.models import Department
from accounts.models import User
class Item(models.Model):
description = models.CharField(
max_length=250,
db_index=True,
verbose_name='Description'
)
quantity_in_stock = models.PositiveSmallIntegerField(
default=0,
blank=True,
verbose_name='Quantity In Stock'
)
class Meta:
db_table = 'items'
verbose_name = 'Item'
verbose_name_plural = 'Items'
def __str__(self):
return self.description
def get_absolute_url(self):
return reverse('item-details', args=[self.id])
def increase_stock_quantity(self, amount):
self.quantity_in_stock += amount
self.save()
def decrease_stock_quantity(self, amount):
if amount > self.quantity_in_stock:
raise ValueError('The Amount is Larger Than the Quantity in Stock')
self.quantity_in_stock -= amount
self.save()
class PurchaseEntry(models.Model):
item = models.ForeignKey(
Item,
on_delete=models.CASCADE,
verbose_name='Item'
)
unit_price = models.PositiveIntegerField(
blank=True,
null=True,
verbose_name='Unit Price'
)
purchased_quantity = models.PositiveSmallIntegerField(
default=1,
verbose_name='Purchased Quantity'
)
purchase_date = models.DateField(
blank=True,
null=True,
verbose_name='Purchase Date'
)
supplier = models.CharField(
max_length=250,
verbose_name='Supplier'
)
entry_number = models.PositiveIntegerField(
blank=True,
null=True,
verbose_name='Entry Number'
)
entry_date = models.DateField(
verbose_name='Entry Date'
)
class Meta:
db_table = 'purchase_entries'
ordering = ['-entry_date']
verbose_name = 'Purchase Entry'
verbose_name_plural = 'Purchase Entries'
def __str__(self):
return f'{self.entry_date} - {self.item.description}'
def save(self, *args, **kwargs):
self.item.increase_stock_quantity(self.purchased_quantity)
super(PurchaseEntry, self).save(*args, **kwargs)
def get_total_price(self):
return self.unit_price * self.purchased_quantity
class IssuedItem(models.Model):
item = models.ForeignKey(
Item,
on_delete=models.PROTECT,
related_name='issued_items',
verbose_name='Item'
)
recipient_employee = models.ForeignKey(
User,
on_delete=models.PROTECT,
related_name='issued_items',
verbose_name='Recipient Employee'
)
recipient_department = models.ForeignKey(
Department,
on_delete=models.PROTECT,
related_name='issued_items',
verbose_name='Recipient Department'
)
issue_quantity = models.PositiveSmallIntegerField(
default=1,
verbose_name='Issue Quantity'
)
issue_reason = models.CharField(
max_length=250,
verbose_name='Issue Reason'
)
issue_date = models.DateField(
verbose_name='Issue Date'
)
exit_number = models.PositiveIntegerField(
blank=True,
null=True,
verbose_name='Exit Number'
)
notes = models.TextField(
default='',
verbose_name='Notes'
)
class Meta:
db_table = 'issued_items'
verbose_name = 'Issued Item'
verbose_name_plural = 'Issued Items'
def __str__(self):
return f'{self.issuance_date} - {self.item.description} - {self.recipient}'
def save(self, *args, **kwargs):
if self.issued_quantity > self.item.quantity_in_stock:
raise ValidationError('Issued Quantity Exceeds Available Quantity')
self.item.decrease_stock_quantity(self.issued_quantity)
super(IssuedItem, self).save(*args, **kwargs)
class ReturnedItem(models.Model):
item = models.ForeignKey(
Item,
on_delete=models.PROTECT,
related_name='returned_items',
verbose_name='Item'
)
return_reason = models.TextField(
verbose_name='Reason for Return'
)
return_quantity = models.PositiveSmallIntegerField(
default=1,
verbose_name='Return Quantity'
)
return_date = models.DateField(
blank=True,
null=True,
verbose_name='Return Date'
)
class Meta:
db_table = 'returned_items'
verbose_name = 'Returned Item'
verbose_name_plural = 'Returned Items'
def __str__(self):
return f'{self.item.description} - {self.return_date} - {self.quantity_returned} - {self.return_reason}'