From ac326c135fe3912c17ed4c5bfb6f1495ef1e4dfe Mon Sep 17 00:00:00 2001
From: Oliver Walters <oliver.henry.walters@gmail.com>
Date: Thu, 9 May 2019 23:01:32 +1000
Subject: [PATCH] Auto delete stock items when they are depleted

---
 .../0015_stockitem_delete_on_deplete.py       | 18 +++++
 InvenTree/stock/models.py                     | 67 ++++++++++++-------
 2 files changed, 60 insertions(+), 25 deletions(-)
 create mode 100644 InvenTree/stock/migrations/0015_stockitem_delete_on_deplete.py

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 4a2e8bc358..a5f323268a 100644
--- a/InvenTree/stock/models.py
+++ b/InvenTree/stock/models.py
@@ -284,15 +284,39 @@ class StockItem(models.Model):
             msg += " (from {loc})".format(loc=str(self.location))
 
         self.location = location
-        self.save()
 
         self.addTransactionNote(msg,
                                   user,
                                   notes=notes,
                                   system=True)
 
+        self.save()
+
         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.
@@ -305,15 +329,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.addTransactionNote('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
 
@@ -330,14 +354,12 @@ class StockItem(models.Model):
         if quantity <= 0 or self.infinite:
             return False
 
-        self.quantity += quantity
-
-        self.save()
-
-        self.addTransactionNote('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
 
@@ -354,17 +376,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.addTransactionNote('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