commit
This commit is contained in:
@@ -244,3 +244,66 @@ class StockBatchManager:
|
||||
|
||||
batch.is_active = False
|
||||
batch.save(update_fields=['is_active'])
|
||||
|
||||
@staticmethod
|
||||
@transaction.atomic
|
||||
def transfer_product_by_fifo(product, from_warehouse, to_warehouse, quantity):
|
||||
"""
|
||||
Переместить товар с одного склада на другой по FIFO логике.
|
||||
Старые партии перемещаются первыми.
|
||||
|
||||
Args:
|
||||
product: объект Product
|
||||
from_warehouse: объект Warehouse (источник)
|
||||
to_warehouse: объект Warehouse (назначение)
|
||||
quantity: Decimal - количество товара для перемещения
|
||||
|
||||
Returns:
|
||||
list: [(source_batch, qty_transferred, new_batch), ...]
|
||||
список кортежей с исходной партией, количеством и созданной партией
|
||||
|
||||
Raises:
|
||||
ValueError: если недостаточно товара на складе-источнике
|
||||
"""
|
||||
# Получаем партии по FIFO (старые первыми)
|
||||
allocations = StockBatchManager.get_batches_for_fifo(product, from_warehouse)
|
||||
|
||||
result = []
|
||||
remaining = quantity
|
||||
|
||||
for batch in allocations:
|
||||
if remaining <= 0:
|
||||
break
|
||||
|
||||
# Определяем сколько перемещаем из этой партии
|
||||
qty_to_transfer = min(batch.quantity, remaining)
|
||||
|
||||
# Уменьшаем исходную партию
|
||||
batch.quantity -= qty_to_transfer
|
||||
if batch.quantity <= 0:
|
||||
batch.is_active = False
|
||||
batch.save(update_fields=['quantity', 'is_active', 'updated_at'])
|
||||
|
||||
# Создаем новую партию на целевом складе с СОХРАНЕНИЕМ cost_price
|
||||
new_batch = StockBatch.objects.create(
|
||||
product=product,
|
||||
warehouse=to_warehouse,
|
||||
quantity=qty_to_transfer,
|
||||
cost_price=batch.cost_price # ВАЖНО: сохраняем цену!
|
||||
)
|
||||
|
||||
result.append((batch, qty_to_transfer, new_batch))
|
||||
remaining -= qty_to_transfer
|
||||
|
||||
# Проверяем что было достаточно товара
|
||||
if remaining > 0:
|
||||
raise ValueError(
|
||||
f"Недостаточно товара '{product.name}' на складе '{from_warehouse.name}'. "
|
||||
f"Не хватает {remaining} шт из запрашиваемых {quantity} шт"
|
||||
)
|
||||
|
||||
# Обновляем кеш остатков на обоих складах
|
||||
StockBatchManager.refresh_stock_cache(product, from_warehouse)
|
||||
StockBatchManager.refresh_stock_cache(product, to_warehouse)
|
||||
|
||||
return result
|
||||
|
||||
Reference in New Issue
Block a user