feat(inventory): add validation for item availability in released reservations

- Implement `check_released_reservations_available` function to verify if items from released reservations are still available for re-sale when attempting to change a returned order's status
- Update `create_sale_on_order_completion` signal to use this check, allowing transitions to positive statuses only if items are available, otherwise blocking with ValidationError
- Wrap Order.save() in transaction.atomic() to ensure ValidationError in signals rolls back the save operation
- Add comprehensive tests for scenarios where items are available or used in other orders
- Update date carousel in order to always center on today's date and remove unnecessary saving logic
- Add test flag to Django Debug Toolbar settings

Closes #123 (assuming related issue)
This commit is contained in:
2025-12-27 02:31:43 +03:00
parent 44d115b356
commit 1654962ba2
5 changed files with 231 additions and 55 deletions

View File

@@ -176,6 +176,7 @@ class Order(models.Model):
return reverse('orders:order-detail', kwargs={'order_number': self.order_number})
def save(self, *args, **kwargs):
from django.db import transaction
# Генерируем уникальный номер заказа при создании (начиная с 100 для 3-значного поиска)
if not self.order_number:
last_order = Order.objects.order_by('-order_number').first()
@@ -184,7 +185,10 @@ class Order(models.Model):
self.order_number = max(last_order.order_number + 1, 100)
else:
self.order_number = 100
super().save(*args, **kwargs)
# Оборачиваем в транзакцию чтобы ValidationError в сигналах откатывал save()
with transaction.atomic():
super().save(*args, **kwargs)
def recalculate_amount_paid(self):
"""

View File

@@ -41,14 +41,9 @@ class DateCarousel {
this.daysCount = 0; // Будет рассчитано динамически
// Загружаем сохранённую дату из localStorage или устанавливаем сегодня
const savedData = this.loadSavedCenterDate();
if (savedData) {
// Восстанавливаем центральную дату как есть
this.centerDate = savedData.centerDate;
} else {
this.centerDate = new Date();
this.centerDate.setHours(0, 0, 0, 0); // Сбрасываем время!
}
// Но для нового поведения всегда устанавливаем сегодняшнюю дату как центральную
this.centerDate = new Date();
this.centerDate.setHours(0, 0, 0, 0); // Сбрасываем время!
}
/**
@@ -276,10 +271,6 @@ class DateCarousel {
console.log(`Selected date: ${formattedDate}, center stays at: ${this.formatDate(this.centerDate)}`);
// ВАЖНО: Сохраняем текущую позицию карусели перед отправкой формы
// чтобы после перезагрузки страницы карусель осталась на том же месте
this.saveCenterDate();
// Автоматическая отправка формы
const form = this.minInput.closest('form');
if (form) {