diff --git a/InvenTree/stock/forms.py b/InvenTree/stock/forms.py index c040c58fce..f181a6db88 100644 --- a/InvenTree/stock/forms.py +++ b/InvenTree/stock/forms.py @@ -34,6 +34,7 @@ class CreateStockItemForm(HelperForm): 'location', 'batch', 'quantity', + 'delete_on_deplete', 'status', 'notes', 'URL', @@ -78,6 +79,7 @@ class EditStockItemForm(HelperForm): fields = [ 'supplier_part', 'batch', + 'delete_on_deplete', 'status', 'notes', 'URL', diff --git a/InvenTree/stock/migrations/0015_stockitem_delete_on_deplete.py b/InvenTree/stock/migrations/0015_stockitem_delete_on_deplete.py new file mode 100644 index 0000000000..29631b94d8 --- /dev/null +++ b/InvenTree/stock/migrations/0015_stockitem_delete_on_deplete.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2 on 2019-05-09 12:59 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('stock', '0014_auto_20190508_2332'), + ] + + operations = [ + migrations.AddField( + model_name='stockitem', + name='delete_on_deplete', + field=models.BooleanField(default=True, help_text='Delete this Stock Item when stock is depleted'), + ), + ] diff --git a/InvenTree/stock/models.py b/InvenTree/stock/models.py index f5ecb1be33..67d92c87e7 100644 --- a/InvenTree/stock/models.py +++ b/InvenTree/stock/models.py @@ -93,7 +93,7 @@ class StockItem(models.Model): if add_note: # This StockItem is being saved for the first time - self.add_transaction_note( + self.addTransactionNote( 'Created stock item', None, notes="Created new stock item for part '{p}'".format(p=str(self.part)), @@ -221,6 +221,8 @@ class StockItem(models.Model): review_needed = models.BooleanField(default=False) + delete_on_deplete = models.BooleanField(default=True, help_text='Delete this Stock Item when stock is depleted') + ITEM_OK = 10 ITEM_ATTENTION = 50 ITEM_DAMAGED = 55 @@ -261,7 +263,11 @@ class StockItem(models.Model): def has_tracking_info(self): return self.tracking_info.count() > 0 - def add_transaction_note(self, title, user, notes='', system=True): + def addTransactionNote(self, title, user, notes='', system=True): + """ Generation a stock transaction note for this item. + + Brief automated note detailing a movement or quantity change. + """ track = StockItemTracking.objects.create( item=self, title=title, @@ -290,15 +296,39 @@ class StockItem(models.Model): msg += " (from {loc})".format(loc=str(self.location)) self.location = location + + self.addTransactionNote(msg, + user, + notes=notes, + system=True) + self.save() - self.add_transaction_note(msg, - user, - notes=notes, - system=True) - return True + @transaction.atomic + def updateQuantity(self, quantity): + """ Update stock quantity for this item. + + If the quantity has reached zero, this StockItem will be deleted. + + Returns: + - True if the quantity was saved + - False if the StockItem was deleted + """ + + if quantity < 0: + quantity = 0 + + self.quantity = quantity + + if quantity <= 0 and self.delete_on_deplete: + self.delete() + return False + else: + self.save() + return True + @transaction.atomic def stocktake(self, count, user, notes=''): """ Perform item stocktake. @@ -311,15 +341,15 @@ class StockItem(models.Model): if count < 0 or self.infinite: return False - self.quantity = count self.stocktake_date = datetime.now().date() self.stocktake_user = user - self.save() - self.add_transaction_note('Stocktake - counted {n} items'.format(n=count), - user, - notes=notes, - system=True) + if self.updateQuantity(count): + + self.addTransactionNote('Stocktake - counted {n} items'.format(n=count), + user, + notes=notes, + system=True) return True @@ -336,14 +366,12 @@ class StockItem(models.Model): if quantity <= 0 or self.infinite: return False - self.quantity += quantity - - self.save() - - self.add_transaction_note('Added {n} items to stock'.format(n=quantity), - user, - notes=notes, - system=True) + if self.updateQuantity(self.quantity + quantity): + + self.addTransactionNote('Added {n} items to stock'.format(n=quantity), + user, + notes=notes, + system=True) return True @@ -360,17 +388,12 @@ class StockItem(models.Model): if quantity <= 0 or self.infinite: return False - self.quantity -= quantity + if self.updateQuantity(self.quantity - quantity): - if self.quantity < 0: - self.quantity = 0 - - self.save() - - self.add_transaction_note('Removed {n} items from stock'.format(n=quantity), - user, - notes=notes, - system=True) + self.addTransactionNote('Removed {n} items from stock'.format(n=quantity), + user, + notes=notes, + system=True) return True