diff --git a/InvenTree/company/migrations/0043_company_is_deleted.py b/InvenTree/company/migrations/0043_company_is_deleted.py new file mode 100644 index 0000000000..cf42f7cc6a --- /dev/null +++ b/InvenTree/company/migrations/0043_company_is_deleted.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.12 on 2022-03-29 22:46 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('company', '0042_supplierpricebreak_updated'), + ] + + operations = [ + migrations.AddField( + model_name='company', + name='is_deleted', + field=models.BooleanField(default=False, help_text='Is this company a deleted placeholder?', verbose_name='is deleted'), + ), + ] diff --git a/InvenTree/company/models.py b/InvenTree/company/models.py index f72668f9f0..8058b7e358 100644 --- a/InvenTree/company/models.py +++ b/InvenTree/company/models.py @@ -9,7 +9,7 @@ import os from django.utils.translation import ugettext_lazy as _ from django.core.validators import MinValueValidator -from django.core.exceptions import ValidationError +from django.core.exceptions import ValidationError, PermissionDenied from django.db import models from django.db.models import Sum, Q, UniqueConstraint @@ -147,6 +147,8 @@ class Company(models.Model): is_manufacturer = models.BooleanField(default=False, verbose_name=_('is manufacturer'), help_text=_('Does this company manufacture parts?')) + is_deleted = models.BooleanField(default=False, verbose_name=_('is deleted'), help_text=_('Is this company a deleted placeholder?')) + currency = models.CharField( max_length=3, verbose_name=_('Currency'), @@ -266,6 +268,18 @@ class Company(models.Model): return self.purchase_orders.filter(status__in=PurchaseOrderStatus.FAILED) + def save(self, *args, **kwargs): + """Save the instance, unless it is the magic already deleted object""" + if self.pk and self.is_deleted: + raise PermissionDenied(_('This company is a placeholder and can not be updated')) + return super().save(*args, **kwargs) + + def delete(self, *args, **kwargs): + """Delete the instance, unless it is the magic already deleted object""" + if self.is_deleted: + raise PermissionDenied(_('This company is a placeholder and can not be deleted')) + return super().delete(*args, **kwargs) + class Contact(models.Model): """ A Contact represents a person who works at a particular company. diff --git a/InvenTree/order/migrations/0064_auto_20220329_2246.py b/InvenTree/order/migrations/0064_auto_20220329_2246.py new file mode 100644 index 0000000000..ad0a804d11 --- /dev/null +++ b/InvenTree/order/migrations/0064_auto_20220329_2246.py @@ -0,0 +1,25 @@ +# Generated by Django 3.2.12 on 2022-03-29 22:46 + +from django.db import migrations, models +import order.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('company', '0043_company_is_deleted'), + ('order', '0063_alter_purchaseorderlineitem_unique_together'), + ] + + operations = [ + migrations.AlterField( + model_name='purchaseorder', + name='supplier', + field=models.ForeignKey(help_text='Company from which the items are being ordered', limit_choices_to={'is_supplier': True}, on_delete=models.SET(order.models.get_deleted_company), related_name='purchase_orders', to='company.company', verbose_name='Supplier'), + ), + migrations.AlterField( + model_name='salesorder', + name='customer', + field=models.ForeignKey(help_text='Company to which the items are being sold', limit_choices_to={'is_customer': True}, null=True, on_delete=models.SET(order.models.get_deleted_company), related_name='sales_orders', to='company.company', verbose_name='Customer'), + ), + ] diff --git a/InvenTree/order/models.py b/InvenTree/order/models.py index f08880a882..9225f3faf8 100644 --- a/InvenTree/order/models.py +++ b/InvenTree/order/models.py @@ -92,6 +92,9 @@ def get_next_so_number(): return reference +def get_deleted_company(): + return Company.objects.get_or_create(name='deleted', email='deleted',is_deleted=True)[0] + class Order(ReferenceIndexingMixin): """ Abstract model for an order. @@ -219,7 +222,7 @@ class PurchaseOrder(Order): help_text=_('Purchase order status')) supplier = models.ForeignKey( - Company, on_delete=models.CASCADE, + Company, on_delete=models.SET(get_deleted_company), limit_choices_to={ 'is_supplier': True, }, @@ -567,7 +570,7 @@ class SalesOrder(Order): customer = models.ForeignKey( Company, - on_delete=models.SET_NULL, + on_delete=models.SET(get_deleted_company), null=True, limit_choices_to={'is_customer': True}, related_name='sales_orders',