feat(variants): enhance disableForSuspension method to manage variant replacements and inventory merging
This commit is contained in:
@@ -56,7 +56,7 @@ class VariantReplacementService
|
||||
|
||||
public function disableForSuspension(EventDate $eventDate): void
|
||||
{
|
||||
Variant::query()
|
||||
$variants = Variant::query()
|
||||
->whereNull('sales_disabled_at')
|
||||
->whereNull('replaced_by_variant_id')
|
||||
->where(function ($query) use ($eventDate): void {
|
||||
@@ -64,7 +64,43 @@ class VariantReplacementService
|
||||
->orWhereHas('eventDates', fn ($eventDates) => $eventDates
|
||||
->where('event_dates.id', $eventDate->getKey()));
|
||||
})
|
||||
->update(['sales_disabled_at' => now()]);
|
||||
->with(['eventDates', 'eventDate', 'definitions', 'allAttachments'])
|
||||
->orderBy('id')
|
||||
->lockForUpdate()
|
||||
->get();
|
||||
|
||||
foreach ($variants as $variant) {
|
||||
$remainingDateIds = $variant->selectedEventDates()
|
||||
->filter(fn (EventDate $date): bool => $date->suspended_at === null
|
||||
&& $date->rescheduled_to_event_date_id === null)
|
||||
->pluck('id')
|
||||
->map(fn ($id): int => (int) $id)
|
||||
->unique()
|
||||
->sort()
|
||||
->values();
|
||||
|
||||
if ($remainingDateIds->isEmpty()) {
|
||||
$variant->update(['sales_disabled_at' => now()]);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$replacement = $this->findEquivalent($variant, $remainingDateIds);
|
||||
if ($replacement === null) {
|
||||
$replacement = $this->cloneWithDates($variant, $remainingDateIds);
|
||||
} else {
|
||||
$this->mergeInventoryInto($variant, $replacement);
|
||||
}
|
||||
|
||||
$variant->update([
|
||||
'replaced_by_variant_id' => $replacement->getKey(),
|
||||
'sales_disabled_at' => now(),
|
||||
]);
|
||||
|
||||
BundleComponent::query()
|
||||
->where('component_variant_id', $variant->getKey())
|
||||
->update(['component_variant_id' => $replacement->getKey()]);
|
||||
}
|
||||
}
|
||||
|
||||
/** @param Collection<int, int> $eventDateIds */
|
||||
@@ -166,6 +202,52 @@ class VariantReplacementService
|
||||
return $replacementInventory;
|
||||
}
|
||||
|
||||
private function mergeInventoryInto(Variant $source, Variant $destination): void
|
||||
{
|
||||
if ($source->inventory_id === $destination->inventory_id) {
|
||||
return;
|
||||
}
|
||||
|
||||
$inventories = Inventory::query()
|
||||
->whereKey([$source->inventory_id, $destination->inventory_id])
|
||||
->orderBy('id')
|
||||
->lockForUpdate()
|
||||
->get()
|
||||
->keyBy('id');
|
||||
$sourceInventory = $inventories->get($source->inventory_id);
|
||||
$destinationInventory = $inventories->get($destination->inventory_id);
|
||||
if ($sourceInventory === null || $destinationInventory === null) {
|
||||
throw new \LogicException('No se encontró el inventario de una variante.');
|
||||
}
|
||||
|
||||
$activeLines = StockReservationLine::query()
|
||||
->where('inventory_id', $source->inventory_id)
|
||||
->whereHas('reservation', fn ($reservation) => $reservation
|
||||
->where('status', StockReservation::STATUS_ACTIVE))
|
||||
->orderBy('id')
|
||||
->lockForUpdate()
|
||||
->get();
|
||||
if ($sourceInventory->reserved_stock !== (int) $activeLines->sum('quantity')) {
|
||||
throw new \LogicException('El inventario reservado de la variante es inconsistente.');
|
||||
}
|
||||
|
||||
$destinationInventory->update([
|
||||
'real_stock' => $destinationInventory->real_stock + $sourceInventory->real_stock,
|
||||
'reserved_stock' => $destinationInventory->reserved_stock + $sourceInventory->reserved_stock,
|
||||
'sold_units' => $destinationInventory->sold_units + $sourceInventory->sold_units,
|
||||
]);
|
||||
if ($activeLines->isNotEmpty()) {
|
||||
StockReservationLine::query()
|
||||
->whereKey($activeLines->modelKeys())
|
||||
->update(['inventory_id' => $destinationInventory->getKey()]);
|
||||
}
|
||||
$sourceInventory->update([
|
||||
'real_stock' => 0,
|
||||
'reserved_stock' => 0,
|
||||
'sold_units' => 0,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @return list<string> */
|
||||
private function definitionSignature(Variant $variant): array
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user