From 921d43c8a1108ced406faa85940484db20f5b5c2 Mon Sep 17 00:00:00 2001 From: sosokker Date: Sun, 19 Nov 2023 05:37:29 +0700 Subject: [PATCH] Modify transfer log system --- inventory/admin.py | 8 +++- inventory/apps.py | 5 +- ..._alter_inventory_current_stock_and_more.py | 39 +++++++++++++++ .../migrations/0004_alter_item_category.py | 19 ++++++++ ...evious_inventory_alter_item_description.py | 24 ++++++++++ .../0006_remove_item_previous_inventory.py | 17 +++++++ inventory/models.py | 47 +++++++++++++++++-- inventory/signals.py | 41 ---------------- transaction/admin.py | 2 +- ...e_transfer_from_date_timestamp_and_more.py | 26 ++++++++++ transaction/models.py | 3 +- 11 files changed, 178 insertions(+), 53 deletions(-) create mode 100644 inventory/migrations/0003_category_alter_inventory_current_stock_and_more.py create mode 100644 inventory/migrations/0004_alter_item_category.py create mode 100644 inventory/migrations/0005_item_previous_inventory_alter_item_description.py create mode 100644 inventory/migrations/0006_remove_item_previous_inventory.py delete mode 100644 inventory/signals.py create mode 100644 transaction/migrations/0003_remove_transfer_from_date_timestamp_and_more.py diff --git a/inventory/admin.py b/inventory/admin.py index a6de755..6eb6baf 100644 --- a/inventory/admin.py +++ b/inventory/admin.py @@ -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') \ No newline at end of file + list_display = ('name', 'description', 'category', 'weight', 'quantity', 'inventory') + +@admin.register(Category) +class CatergoryAdmin(admin.ModelAdmin): + list_display = ('name',) \ No newline at end of file diff --git a/inventory/apps.py b/inventory/apps.py index a1cf823..ec78620 100644 --- a/inventory/apps.py +++ b/inventory/apps.py @@ -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' \ No newline at end of file diff --git a/inventory/migrations/0003_category_alter_inventory_current_stock_and_more.py b/inventory/migrations/0003_category_alter_inventory_current_stock_and_more.py new file mode 100644 index 0000000..1c11e71 --- /dev/null +++ b/inventory/migrations/0003_category_alter_inventory_current_stock_and_more.py @@ -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'), + ), + ] diff --git a/inventory/migrations/0004_alter_item_category.py b/inventory/migrations/0004_alter_item_category.py new file mode 100644 index 0000000..45c097b --- /dev/null +++ b/inventory/migrations/0004_alter_item_category.py @@ -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'), + ), + ] diff --git a/inventory/migrations/0005_item_previous_inventory_alter_item_description.py b/inventory/migrations/0005_item_previous_inventory_alter_item_description.py new file mode 100644 index 0000000..925eecf --- /dev/null +++ b/inventory/migrations/0005_item_previous_inventory_alter_item_description.py @@ -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), + ), + ] diff --git a/inventory/migrations/0006_remove_item_previous_inventory.py b/inventory/migrations/0006_remove_item_previous_inventory.py new file mode 100644 index 0000000..9bf3b94 --- /dev/null +++ b/inventory/migrations/0006_remove_item_previous_inventory.py @@ -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', + ), + ] diff --git a/inventory/models.py b/inventory/models.py index efe2a3b..9307df8 100644 --- a/inventory/models.py +++ b/inventory/models.py @@ -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}" \ No newline at end of file diff --git a/inventory/signals.py b/inventory/signals.py deleted file mode 100644 index 48bc5b2..0000000 --- a/inventory/signals.py +++ /dev/null @@ -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, - ) \ No newline at end of file diff --git a/transaction/admin.py b/transaction/admin.py index 2c2b2ca..34deebc 100644 --- a/transaction/admin.py +++ b/transaction/admin.py @@ -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') \ No newline at end of file + list_display = ('from_warehouse', 'to_warehouse', 'item', 'update_time', 'quantity') \ No newline at end of file diff --git a/transaction/migrations/0003_remove_transfer_from_date_timestamp_and_more.py b/transaction/migrations/0003_remove_transfer_from_date_timestamp_and_more.py new file mode 100644 index 0000000..91c1e72 --- /dev/null +++ b/transaction/migrations/0003_remove_transfer_from_date_timestamp_and_more.py @@ -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), + ), + ] diff --git a/transaction/models.py b/transaction/models.py index e2a0e16..36e1283 100644 --- a/transaction/models.py +++ b/transaction/models.py @@ -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}" \ No newline at end of file