mirror of
https://github.com/Sosokker/Inventory-Management-System.git
synced 2025-12-18 23:24:05 +01:00
Modify transfer log system
This commit is contained in:
parent
fee98a27cb
commit
921d43c8a1
@ -1,5 +1,5 @@
|
||||
from django.contrib import admin
|
||||
from inventory.models import Warehouse, Inventory, Item
|
||||
from inventory.models import Warehouse, Inventory, Item, Category
|
||||
|
||||
@admin.register(Warehouse)
|
||||
class WarehouseAdmin(admin.ModelAdmin):
|
||||
@ -11,4 +11,8 @@ class InventoryAdmin(admin.ModelAdmin):
|
||||
|
||||
@admin.register(Item)
|
||||
class ItemAdmin(admin.ModelAdmin):
|
||||
list_display = ('name', 'description', 'category', 'weight', 'quantity', 'inventory')
|
||||
list_display = ('name', 'description', 'category', 'weight', 'quantity', 'inventory')
|
||||
|
||||
@admin.register(Category)
|
||||
class CatergoryAdmin(admin.ModelAdmin):
|
||||
list_display = ('name',)
|
||||
@ -3,7 +3,4 @@ from django.apps import AppConfig
|
||||
|
||||
class InventoryConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'inventory'
|
||||
|
||||
def ready(self):
|
||||
import inventory.signals
|
||||
name = 'inventory'
|
||||
@ -0,0 +1,39 @@
|
||||
# Generated by Django 4.2.7 on 2023-11-18 21:22
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0002_alter_inventory_options'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Category',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=255)),
|
||||
],
|
||||
options={
|
||||
'verbose_name_plural': 'Categories',
|
||||
},
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='inventory',
|
||||
name='current_stock',
|
||||
field=models.IntegerField(default=0),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='inventory',
|
||||
name='min_stock',
|
||||
field=models.IntegerField(default=0),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='item',
|
||||
name='category',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='inventory.category'),
|
||||
),
|
||||
]
|
||||
19
inventory/migrations/0004_alter_item_category.py
Normal file
19
inventory/migrations/0004_alter_item_category.py
Normal file
@ -0,0 +1,19 @@
|
||||
# Generated by Django 4.2.7 on 2023-11-18 21:23
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0003_category_alter_inventory_current_stock_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='item',
|
||||
name='category',
|
||||
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='inventory.category'),
|
||||
),
|
||||
]
|
||||
@ -0,0 +1,24 @@
|
||||
# Generated by Django 4.2.7 on 2023-11-18 21:48
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0004_alter_item_category'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='item',
|
||||
name='previous_inventory',
|
||||
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='previous_inventory', to='inventory.inventory'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='item',
|
||||
name='description',
|
||||
field=models.TextField(null=True),
|
||||
),
|
||||
]
|
||||
17
inventory/migrations/0006_remove_item_previous_inventory.py
Normal file
17
inventory/migrations/0006_remove_item_previous_inventory.py
Normal file
@ -0,0 +1,17 @@
|
||||
# Generated by Django 4.2.7 on 2023-11-18 22:23
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0005_item_previous_inventory_alter_item_description'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='item',
|
||||
name='previous_inventory',
|
||||
),
|
||||
]
|
||||
@ -1,5 +1,5 @@
|
||||
from django.db import models
|
||||
|
||||
from django.apps import apps
|
||||
|
||||
class Warehouse(models.Model):
|
||||
"""
|
||||
@ -58,11 +58,25 @@ class Inventory(models.Model):
|
||||
class Meta:
|
||||
verbose_name_plural = 'Inventories'
|
||||
|
||||
class Category(models.Model):
|
||||
"""
|
||||
Catergory of the item
|
||||
|
||||
:param name: Name of the catergory
|
||||
"""
|
||||
name = models.CharField(max_length=255)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.name}"
|
||||
|
||||
class Meta:
|
||||
verbose_name_plural = 'Categories'
|
||||
|
||||
class Item(models.Model):
|
||||
"""
|
||||
Item such as food, drink, furnoture etc.
|
||||
|
||||
:param previous_inventory: Previous inventory that the item belongs to, If null, it means the item is new or never move
|
||||
:param inventory: Inventory that the item belongs to
|
||||
:param name: Name of the item
|
||||
:param description: Description of the item
|
||||
@ -71,11 +85,38 @@ class Item(models.Model):
|
||||
:param quantity: Quantity of the item
|
||||
"""
|
||||
inventory = models.ForeignKey(Inventory, on_delete=models.CASCADE)
|
||||
category = models.ForeignKey(Category, on_delete=models.DO_NOTHING, null=True)
|
||||
name = models.CharField(max_length=255)
|
||||
description = models.TextField()
|
||||
category = models.CharField(max_length=255)
|
||||
description = models.TextField(null=True)
|
||||
weight = models.DecimalField(max_digits=10, decimal_places=3)
|
||||
quantity = models.IntegerField()
|
||||
|
||||
__previous_inventory = None
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
try:
|
||||
self.__previous_inventory = self.inventory
|
||||
except:
|
||||
self.__previous_inventory = None
|
||||
|
||||
def save(self, force_insert=False, force_update=False, *args, **kwargs):
|
||||
if self.__previous_inventory == None:
|
||||
super().save(force_insert, force_update, *args, **kwargs)
|
||||
Inventory.objects.filter(id=self.inventory.id).update(current_stock=self.inventory.current_stock + self.quantity)
|
||||
return
|
||||
|
||||
if self.inventory != self.__previous_inventory:
|
||||
Inventory.objects.filter(id=self.__previous_inventory.id).update(current_stock=self.__previous_inventory.current_stock - self.quantity)
|
||||
Inventory.objects.filter(id=self.inventory.id).update(current_stock=self.inventory.current_stock + self.quantity)
|
||||
apps.get_model('transaction', 'Transfer').objects.create(
|
||||
from_warehouse=self.__previous_inventory.warehouse,
|
||||
to_warehouse=self.inventory.warehouse,
|
||||
item=self,
|
||||
quantity=self.quantity,
|
||||
)
|
||||
super().save(force_insert, force_update, *args, **kwargs)
|
||||
self.__previous_inventory = self.inventory
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.name} - {self.quantity}"
|
||||
@ -1,41 +0,0 @@
|
||||
from django.db.models.signals import post_save, pre_save
|
||||
from django.dispatch import receiver
|
||||
from inventory.models import Item
|
||||
from transaction.models import Transfer
|
||||
|
||||
|
||||
@receiver(pre_save, sender=Item)
|
||||
def handle_item_move(sender, instance, **kwargs):
|
||||
"""
|
||||
Signal to handle moving an Item to a new Inventory.
|
||||
"""
|
||||
if instance.pk:
|
||||
old_item = Item.objects.get(pk=instance.pk)
|
||||
if old_item.inventory != instance.inventory:
|
||||
old_item.inventory.current_stock -= old_item.quantity
|
||||
old_item.inventory.save()
|
||||
|
||||
@receiver(post_save, sender=Item)
|
||||
def update_inventory_current_stock(sender, instance, **kwargs):
|
||||
"""
|
||||
Signal to update current_stock of related Inventory when an Item is created or assigned to a new Inventory.
|
||||
"""
|
||||
if kwargs.get('created', False) or instance.pk:
|
||||
instance.inventory.current_stock += instance.quantity
|
||||
instance.inventory.save()
|
||||
|
||||
|
||||
@receiver(post_save, sender=Item)
|
||||
def create_transfer_instance(sender, instance, **kwargs):
|
||||
"""
|
||||
Signal to create a Transfer instance when an Item is transferred between warehouses.
|
||||
"""
|
||||
# If the item is being created or updated
|
||||
if kwargs.get('created', False) or instance.pk:
|
||||
if instance.pk and instance.inventory.warehouse != instance.inventory.old_warehouse:
|
||||
Transfer.objects.create(
|
||||
from_warehouse=instance.inventory.old_warehouse,
|
||||
to_warehouse=instance.inventory.warehouse,
|
||||
item=instance,
|
||||
quantity=instance.quantity,
|
||||
)
|
||||
@ -20,4 +20,4 @@ class OrderAdmin(admin.ModelAdmin):
|
||||
|
||||
@admin.register(Transfer)
|
||||
class TransferAdmin(admin.ModelAdmin):
|
||||
list_display = ('from_warehouse', 'to_warehouse', 'item', 'from_date_timestamp', 'to_date_timestamp', 'quantity')
|
||||
list_display = ('from_warehouse', 'to_warehouse', 'item', 'update_time', 'quantity')
|
||||
@ -0,0 +1,26 @@
|
||||
# Generated by Django 4.2.7 on 2023-11-18 21:57
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('transaction', '0002_alter_supply_options_alter_order_order_date_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='transfer',
|
||||
name='from_date_timestamp',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='transfer',
|
||||
name='to_date_timestamp',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='transfer',
|
||||
name='update_time',
|
||||
field=models.DateTimeField(auto_now=True),
|
||||
),
|
||||
]
|
||||
@ -87,8 +87,7 @@ class Transfer(models.Model):
|
||||
to_warehouse = models.ForeignKey(Warehouse, related_name='transfer_to', on_delete=models.CASCADE)
|
||||
item = models.ForeignKey(Item, on_delete=models.CASCADE)
|
||||
quantity = models.IntegerField()
|
||||
from_date_timestamp = models.DateTimeField()
|
||||
to_date_timestamp = models.DateTimeField()
|
||||
update_time = models.DateTimeField(auto_now=True)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.from_warehouse.name} - {self.to_warehouse.name} - {self.item.name} - {self.quantity}"
|
||||
Loading…
Reference in New Issue
Block a user