From 830d33763e3ddf9ceee3151c222d1958dae18225 Mon Sep 17 00:00:00 2001
From: Oliver <oliver.henry.walters@gmail.com>
Date: Sat, 14 Apr 2018 20:33:53 +1000
Subject: [PATCH] Fix deletion of part category and stock location

- Category up part updated to parent
- Location of item updated to parent
---
 .../migrations/0012_auto_20180414_1032.py     | 21 +++++++++++++++++++
 InvenTree/part/models.py                      | 17 ++++++++++++---
 .../migrations/0004_auto_20180414_1032.py     | 21 +++++++++++++++++++
 InvenTree/stock/models.py                     | 13 +++++++++++-
 InvenTree/stock/templates/stock/loc_link.html |  2 +-
 5 files changed, 69 insertions(+), 5 deletions(-)
 create mode 100644 InvenTree/part/migrations/0012_auto_20180414_1032.py
 create mode 100644 InvenTree/stock/migrations/0004_auto_20180414_1032.py

diff --git a/InvenTree/part/migrations/0012_auto_20180414_1032.py b/InvenTree/part/migrations/0012_auto_20180414_1032.py
new file mode 100644
index 0000000000..a23e7d502d
--- /dev/null
+++ b/InvenTree/part/migrations/0012_auto_20180414_1032.py
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11 on 2018-04-14 10:32
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('part', '0011_partattachment'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='part',
+            name='category',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='parts', to='part.PartCategory'),
+        ),
+    ]
diff --git a/InvenTree/part/models.py b/InvenTree/part/models.py
index b86f2aedd2..6ca25b6e5d 100644
--- a/InvenTree/part/models.py
+++ b/InvenTree/part/models.py
@@ -8,8 +8,9 @@ from InvenTree.models import InvenTreeTree
 
 import os
 
-#from django.db.models.signals.pre_delete
-#from django.dispatch import receiver
+from django.db.models.signals import pre_delete
+from django.dispatch import receiver
+
 
 class PartCategory(InvenTreeTree):
     """ PartCategory provides hierarchical organization of Part objects.
@@ -19,9 +20,19 @@ class PartCategory(InvenTreeTree):
         verbose_name = "Part Category"
         verbose_name_plural = "Part Categories"
 
+    """
     @property
     def parts(self):
         return self.part_set.all()
+    """
+
+@receiver(pre_delete, sender=PartCategory, dispatch_uid='partcategory_delete_log')
+def before_delete_part_category(sender, instance, using, **kwargs):
+
+    # Update each part in this category to point to the parent category
+    for part in instance.parts.all():
+        part.category = instance.parent
+        part.save()
 
 
 # Function to automatically rename a part image on upload
@@ -63,7 +74,7 @@ class Part(models.Model):
     # Part category - all parts must be assigned to a category
     category = models.ForeignKey(PartCategory, related_name='parts',
                                  null=True, blank=True,
-                                 on_delete=models.SET_NULL)
+                                 on_delete=models.DO_NOTHING)
 
     image = models.ImageField(upload_to=rename_part_image, max_length=255, null=True, blank=True)
 
diff --git a/InvenTree/stock/migrations/0004_auto_20180414_1032.py b/InvenTree/stock/migrations/0004_auto_20180414_1032.py
new file mode 100644
index 0000000000..2fd841dea8
--- /dev/null
+++ b/InvenTree/stock/migrations/0004_auto_20180414_1032.py
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11 on 2018-04-14 10:32
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('stock', '0003_auto_20180413_1230'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='stockitem',
+            name='location',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='items', to='stock.StockLocation'),
+        ),
+    ]
diff --git a/InvenTree/stock/models.py b/InvenTree/stock/models.py
index f89837b7a0..146943e1b0 100644
--- a/InvenTree/stock/models.py
+++ b/InvenTree/stock/models.py
@@ -11,6 +11,8 @@ from InvenTree.models import InvenTreeTree
 
 from datetime import datetime
 
+from django.db.models.signals import pre_delete
+from django.dispatch import receiver
 
 class StockLocation(InvenTreeTree):
     """ Organization tree for StockItem objects
@@ -24,12 +26,21 @@ class StockLocation(InvenTreeTree):
         return stock_list
 
 
+@receiver(pre_delete, sender=StockLocation, dispatch_uid='stocklocation_delete_log')
+def before_delete_stock_location(sender, instance, using, **kwargs):
+
+    # Update each part in the stock location
+    for item in instance.items.all():
+        item.location = instance.parent
+        item.save()
+
 class StockItem(models.Model):
     part = models.ForeignKey(Part, on_delete=models.CASCADE, related_name='locations')
 
     supplier_part = models.ForeignKey(SupplierPart, blank=True, null=True, on_delete=models.SET_NULL)
 
-    location = models.ForeignKey(StockLocation, on_delete=models.CASCADE)
+    location = models.ForeignKey(StockLocation, on_delete=models.DO_NOTHING,
+                                 related_name='items', blank=True, null=True)
 
     quantity = models.PositiveIntegerField(validators=[MinValueValidator(0)])
 
diff --git a/InvenTree/stock/templates/stock/loc_link.html b/InvenTree/stock/templates/stock/loc_link.html
index 9c2db9b9c7..0683f355e1 100644
--- a/InvenTree/stock/templates/stock/loc_link.html
+++ b/InvenTree/stock/templates/stock/loc_link.html
@@ -1,4 +1,4 @@
-<div class="container">
+<div class="navigation">
 <a href="/stock/list/">Stock</a> >
 {% if location %}
 {% for path_item in location.parentpath %}