From 171b6b83f4c9dc7eedc0a883b014ac346f804679 Mon Sep 17 00:00:00 2001 From: stefan Date: Sat, 25 Jan 2025 14:50:48 +0100 Subject: [PATCH] added option to expand sub-storage stocks to display all components from sub_storages this comes in handy for assortment boxes using sub storages for each individual compartment which usually only holds a single stock --- shimatta_kenkyusho/parts/forms.py | 3 ++- .../0013_storage_expand_sub_storage_stocks.py | 18 ++++++++++++++++++ shimatta_kenkyusho/parts/models.py | 9 +++++++++ .../parts/views/storage_views.py | 10 +++++++++- 4 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 shimatta_kenkyusho/parts/migrations/0013_storage_expand_sub_storage_stocks.py diff --git a/shimatta_kenkyusho/parts/forms.py b/shimatta_kenkyusho/parts/forms.py index 44752e6..3c4cd5f 100644 --- a/shimatta_kenkyusho/parts/forms.py +++ b/shimatta_kenkyusho/parts/forms.py @@ -101,7 +101,8 @@ class ChangeStorageForm(forms.Form): foreign_model=get_user_model(), prepend='@') - is_template = forms.BooleanField(label='is_template', required=False) + expand_sub_storage_stocks = forms.BooleanField(label='Expand sub storage Stocks', required=False) + is_template = forms.BooleanField(label='Is template', required=False) class AddSubStorageForm(ChangeStorageForm): template = AutocompleteForeingKeyField(api_search_url='storage-template-list', diff --git a/shimatta_kenkyusho/parts/migrations/0013_storage_expand_sub_storage_stocks.py b/shimatta_kenkyusho/parts/migrations/0013_storage_expand_sub_storage_stocks.py new file mode 100644 index 0000000..8f7edea --- /dev/null +++ b/shimatta_kenkyusho/parts/migrations/0013_storage_expand_sub_storage_stocks.py @@ -0,0 +1,18 @@ +# Generated by Django 5.1.3 on 2025-01-25 13:20 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('parts', '0012_storage_verbose_name'), + ] + + operations = [ + migrations.AddField( + model_name='storage', + name='expand_sub_storage_stocks', + field=models.BooleanField(default=False), + ), + ] diff --git a/shimatta_kenkyusho/parts/models.py b/shimatta_kenkyusho/parts/models.py index f5d4ec4..2f19cf4 100644 --- a/shimatta_kenkyusho/parts/models.py +++ b/shimatta_kenkyusho/parts/models.py @@ -65,6 +65,7 @@ class Storage(models.Model): verbose_name = models.CharField(max_length=100, null=True, blank=True) parent_storage = models.ForeignKey('self', on_delete=models.CASCADE, blank=True, null=True) responsible = models.ForeignKey(get_user_model(), on_delete=models.SET_NULL, blank=True, null=True) + expand_sub_storage_stocks = models.BooleanField(default=False) # allow storages to be templates which can be selected when adding new storages is_template = models.BooleanField(default=False) @@ -106,6 +107,13 @@ class Storage(models.Model): else: return self.storage_set.all() + def get_tree(self): + self.sub_storages = list(self.storage_set.all()) + for storage in self.sub_storages: + self.sub_storages += storage.get_tree() + + return self.sub_storages + def validate_unique(self, exclude=None): if Storage.objects.exclude(id=self.id).filter(name=self.name, parent_storage__isnull=True).exists(): if self.parent_storage is None: @@ -407,5 +415,6 @@ def auto_apply_template_structure(sender, instance, created, **kwargs): Storage.objects.create(name=sub_storage.name, parent_storage=instance, responsible=instance.responsible, + expand_sub_storage_stocks=instance.expand_sub_storage_stocks, is_template=False, template=sub_storage) diff --git a/shimatta_kenkyusho/parts/views/storage_views.py b/shimatta_kenkyusho/parts/views/storage_views.py index 1e1e402..283ce92 100644 --- a/shimatta_kenkyusho/parts/views/storage_views.py +++ b/shimatta_kenkyusho/parts/views/storage_views.py @@ -74,7 +74,13 @@ class StockViewDetail(LoginRequiredMixin, BaseTemplateMixin, DetailView): return crumbs def search_stock_queryset(self, search): - stocks_in_storage = Stock.objects.filter(storage=self.object).order_by(Lower('component__name')) + + if self.object.expand_sub_storage_stocks: + stocks_in_storage = Stock.objects.filter(storage__in=self.object.get_tree()) + else: + stocks_in_storage = Stock.objects.filter(storage=self.object) + + stocks_in_storage = stocks_in_storage.order_by(Lower('component__name')) if search is None or search == '': return stocks_in_storage @@ -139,6 +145,7 @@ class StockViewDetail(LoginRequiredMixin, BaseTemplateMixin, DetailView): verbose_name=f.cleaned_data.get('verbose_name'), parent_storage=self.object, responsible=f.cleaned_data['responsible'], + expand_sub_storage_stocks=f.cleaned_data['expand_sub_storage_stocks'], is_template=f.cleaned_data['is_template'], template=f.cleaned_data.get('template')) except ValidationError as v_err: @@ -154,6 +161,7 @@ class StockViewDetail(LoginRequiredMixin, BaseTemplateMixin, DetailView): self.object.name = f.cleaned_data['storage_name'] self.object.verbose_name = f.cleaned_data.get('verbose_name') self.object.responsible = f.cleaned_data['responsible'] + self.object.expand_sub_storage_stocks = f.cleaned_data['expand_sub_storage_stocks'] self.object.is_template = f.cleaned_data['is_template'] self.object.save() except ValidationError as v_err: