From dd184265eed2d4f487b6a08b42433bf444cce55d Mon Sep 17 00:00:00 2001 From: Andrey Smakotin Date: Thu, 20 Nov 2025 11:40:08 +0300 Subject: [PATCH] Add default showcase selection per warehouse MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add is_default field to Showcase model with unique constraint per warehouse - Implement Showcase.save() to ensure only one default per warehouse - Add SetDefaultShowcaseView for AJAX-based default selection - Update ShowcaseForm to include is_default checkbox - Add interactive checkbox UI in showcase list with AJAX functionality - Update POS API to return showcase.is_default instead of warehouse.is_default - Update terminal.js to auto-select showcase based on its is_default flag - Add migration for is_default field πŸ€– Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- myproject/inventory/forms_showcase.py | 5 +- .../0004_showcase_is_default_and_more.py | 22 +++ myproject/inventory/models.py | 9 ++ .../templates/inventory/showcase/form.html | 20 ++- .../templates/inventory/showcase/list.html | 148 +++++++++++++++++- myproject/inventory/urls.py | 3 +- myproject/inventory/views/showcase.py | 43 ++++- myproject/pos/static/pos/js/terminal.js | 12 +- myproject/pos/views.py | 6 +- 9 files changed, 253 insertions(+), 15 deletions(-) create mode 100644 myproject/inventory/migrations/0004_showcase_is_default_and_more.py diff --git a/myproject/inventory/forms_showcase.py b/myproject/inventory/forms_showcase.py index d1f0bcf..a96b5b1 100644 --- a/myproject/inventory/forms_showcase.py +++ b/myproject/inventory/forms_showcase.py @@ -12,7 +12,7 @@ class ShowcaseForm(forms.ModelForm): """ class Meta: model = Showcase - fields = ['name', 'warehouse', 'description', 'is_active'] + fields = ['name', 'warehouse', 'description', 'is_active', 'is_default'] widgets = { 'name': forms.TextInput(attrs={ 'class': 'form-control', @@ -25,16 +25,19 @@ class ShowcaseForm(forms.ModelForm): 'placeholder': 'ОписаниС Π²ΠΈΡ‚Ρ€ΠΈΠ½Ρ‹, Π΅Ρ‘ располоТСниС ΠΈΠ»ΠΈ особСнности' }), 'is_active': forms.CheckboxInput(attrs={'class': 'form-check-input'}), + 'is_default': forms.CheckboxInput(attrs={'class': 'form-check-input'}), } labels = { 'name': 'НазваниС Π²ΠΈΡ‚Ρ€ΠΈΠ½Ρ‹', 'warehouse': 'Π‘ΠΊΠ»Π°Π΄', 'description': 'ОписаниС', 'is_active': 'Активна', + 'is_default': 'Π’ΠΈΡ‚Ρ€ΠΈΠ½Π° ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ', } help_texts = { 'warehouse': 'Π‘ΠΊΠ»Π°Π΄, ΠΊ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ привязана Π²ΠΈΡ‚Ρ€ΠΈΠ½Π°', 'is_active': 'НСактивныС Π²ΠΈΡ‚Ρ€ΠΈΠ½Ρ‹ скрыты ΠΈΠ· списка Π²Ρ‹Π±ΠΎΡ€Π°', + 'is_default': 'Π’ΠΈΡ‚Ρ€ΠΈΠ½Π° Π±ΡƒΠ΄Π΅Ρ‚ автоматичСски Π²Ρ‹Π±Ρ€Π°Π½Π° ΠΏΡ€ΠΈ создании Ρ€Π΅Π·Π΅Ρ€Π²Π° Π½Π° этом складС', } def __init__(self, *args, **kwargs): diff --git a/myproject/inventory/migrations/0004_showcase_is_default_and_more.py b/myproject/inventory/migrations/0004_showcase_is_default_and_more.py new file mode 100644 index 0000000..227fb99 --- /dev/null +++ b/myproject/inventory/migrations/0004_showcase_is_default_and_more.py @@ -0,0 +1,22 @@ +# Generated by Django 5.0.10 on 2025-11-20 08:08 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('inventory', '0003_showcase_reservation_showcase_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='showcase', + name='is_default', + field=models.BooleanField(default=False, verbose_name='По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ'), + ), + migrations.AddIndex( + model_name='showcase', + index=models.Index(fields=['is_default'], name='inventory_s_is_defa_bf9a7c_idx'), + ), + ] diff --git a/myproject/inventory/models.py b/myproject/inventory/models.py index a9c03db..794f41a 100644 --- a/myproject/inventory/models.py +++ b/myproject/inventory/models.py @@ -369,6 +369,7 @@ class Showcase(models.Model): related_name='showcases', verbose_name="Π‘ΠΊΠ»Π°Π΄") description = models.TextField(blank=True, null=True, verbose_name="ОписаниС") is_active = models.BooleanField(default=True, verbose_name="Активна") + is_default = models.BooleanField(default=False, verbose_name="По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ") created_at = models.DateTimeField(auto_now_add=True, verbose_name="Π”Π°Ρ‚Π° создания") updated_at = models.DateTimeField(auto_now=True, verbose_name="Π”Π°Ρ‚Π° обновлСния") @@ -379,11 +380,19 @@ class Showcase(models.Model): indexes = [ models.Index(fields=['warehouse']), models.Index(fields=['is_active']), + models.Index(fields=['is_default']), ] def __str__(self): return f"{self.name} ({self.warehouse.name})" + def save(self, *args, **kwargs): + """ΠžΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΠ²Π°Π΅ΠΌ Ρ‡Ρ‚ΠΎ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄Π½Π° Π²ΠΈΡ‚Ρ€ΠΈΠ½Π° ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ склада""" + if self.is_default: + # Π‘Π½ΠΈΠΌΠ°Π΅ΠΌ Ρ„Π»Π°Π³ is_default со всСх Π΄Ρ€ΡƒΠ³ΠΈΡ… Π²ΠΈΡ‚Ρ€ΠΈΠ½ этого склада + Showcase.objects.filter(warehouse=self.warehouse, is_default=True).exclude(pk=self.pk).update(is_default=False) + super().save(*args, **kwargs) + class Reservation(models.Model): """ diff --git a/myproject/inventory/templates/inventory/showcase/form.html b/myproject/inventory/templates/inventory/showcase/form.html index 2c9d8bd..1ff5473 100644 --- a/myproject/inventory/templates/inventory/showcase/form.html +++ b/myproject/inventory/templates/inventory/showcase/form.html @@ -85,7 +85,7 @@ -
+
{{ form.is_active }}
+ +
+
+ {{ form.is_default }} + + {% if form.is_default.help_text %} +
{{ form.is_default.help_text }}
+ {% endif %} +
+ {% if form.is_default.errors %} +
+ {{ form.is_default.errors }} +
+ {% endif %} +
+