Merge branch 'refactor/inventory_stock' of https://gitea.quo.ar/tbianchini/shopit-back into refactor/inventory_stock
This commit is contained in:
@@ -64,7 +64,6 @@ class CatalogInventoryService
|
||||
$selection->loadMissing('variants.inventory');
|
||||
|
||||
return $selection->variants
|
||||
->each(fn (Variant $variant) => $variant->setRelation('catalogItem', $selection))
|
||||
->filter(fn (Variant $variant): bool => $variant->isSellable())
|
||||
->unique(fn (Variant $variant): string => $variant->inventory_id === null
|
||||
? 'object:'.spl_object_id($variant->inventory)
|
||||
@@ -154,7 +153,7 @@ class CatalogInventoryService
|
||||
|
||||
if ($operation === 'commit'
|
||||
&& $requirement['tracks_inventory']
|
||||
&& $inventory->availableStock() < 0) {
|
||||
&& $inventory->real_stock - $inventory->entry_reserved_stock < $requiredQuantity) {
|
||||
throw new \InvalidArgumentException('No hay suficiente stock real para confirmar la compra.');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace App\Domains\Commerce\Catalog\Services;
|
||||
|
||||
use App\Shared\Attachable\Models\Attachment;
|
||||
use App\Shared\Attachable\Services\AttachmentService;
|
||||
use App\Domains\Commerce\Catalog\Enums\CatalogItemType;
|
||||
use App\Domains\Commerce\Catalog\Models\Attribute;
|
||||
use App\Domains\Commerce\Catalog\Models\CatalogItem;
|
||||
@@ -9,10 +11,8 @@ use App\Domains\Commerce\Catalog\Models\Category;
|
||||
use App\Domains\Commerce\Catalog\Models\Inventory;
|
||||
use App\Domains\Commerce\Catalog\Models\ItemAttribute;
|
||||
use App\Domains\Commerce\Catalog\Models\Variant;
|
||||
use App\Domains\Core\Tenant\Models\Tenant;
|
||||
use App\Domains\Ticketing\Event\Models\EventDate;
|
||||
use App\Shared\Attachable\Models\Attachment;
|
||||
use App\Shared\Attachable\Services\AttachmentService;
|
||||
use App\Domains\Core\Tenant\Models\Tenant;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
@@ -286,11 +286,9 @@ class CatalogService
|
||||
int $perPage,
|
||||
int $page,
|
||||
): LengthAwarePaginator {
|
||||
$categoryIds = $this->categoryAndDescendantIds($tenant, $category);
|
||||
|
||||
return CatalogItem::query()
|
||||
->forTenantCatalog($tenant)
|
||||
->whereIn('category_id', $categoryIds)
|
||||
->where('category_id', $category->id)
|
||||
->whereAvailable()
|
||||
->with([
|
||||
'attachments',
|
||||
@@ -308,34 +306,6 @@ class CatalogService
|
||||
->paginate(perPage: $perPage, pageName: 'page', page: $page);
|
||||
}
|
||||
|
||||
/** @return array<int, int> */
|
||||
private function categoryAndDescendantIds(Tenant $tenant, Category $category): array
|
||||
{
|
||||
$childrenByParent = Category::query()
|
||||
->where('tenant_code', $tenant->codigo)
|
||||
->get(['id', 'categoria_id'])
|
||||
->groupBy('categoria_id');
|
||||
|
||||
$categoryIds = [];
|
||||
$pendingIds = [$category->id];
|
||||
|
||||
while ($pendingIds !== []) {
|
||||
$categoryId = array_shift($pendingIds);
|
||||
|
||||
if (isset($categoryIds[$categoryId])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$categoryIds[$categoryId] = $categoryId;
|
||||
|
||||
foreach ($childrenByParent->get($categoryId, collect()) as $child) {
|
||||
$pendingIds[] = $child->id;
|
||||
}
|
||||
}
|
||||
|
||||
return array_values($categoryIds);
|
||||
}
|
||||
|
||||
public function delete(CatalogItem $catalogItem): void
|
||||
{
|
||||
DB::transaction(function () use ($catalogItem): void {
|
||||
@@ -370,12 +340,9 @@ class CatalogService
|
||||
|
||||
private function createInventory(int $realStock): Inventory
|
||||
{
|
||||
$inventory = Inventory::query()->create([
|
||||
return Inventory::query()->create([
|
||||
'real_stock' => $realStock,
|
||||
]);
|
||||
$inventory->recordInitialization();
|
||||
|
||||
return $inventory;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -225,7 +225,7 @@ class StockReservationService
|
||||
$inventory = $inventories->get($line->inventory_id)
|
||||
?? throw new \InvalidArgumentException('No se encontró el inventario reservado.');
|
||||
if ($inventory->reserved_stock < $line->quantity
|
||||
|| ($line->tracks_inventory && $inventory->availableStock() < 0)) {
|
||||
|| ($line->tracks_inventory && $inventory->real_stock - $inventory->entry_reserved_stock < $line->quantity)) {
|
||||
throw new \InvalidArgumentException('La reserva de stock no alcanza para confirmar la compra.');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,7 +194,6 @@ class VariantReplacementService
|
||||
'entry_reserved_stock' => $sourceInventory->entry_reserved_stock,
|
||||
'real_stock' => $sourceInventory->real_stock,
|
||||
]);
|
||||
$replacementInventory->recordTransferInitialization();
|
||||
|
||||
if ($activeLines->isNotEmpty()) {
|
||||
StockReservationLine::query()
|
||||
@@ -203,10 +202,7 @@ class VariantReplacementService
|
||||
}
|
||||
EntryReservation::query()->where('inventory_id', $sourceInventory->id)
|
||||
->update(['inventory_id' => $replacementInventory->id]);
|
||||
$sourceInventory->transferCounters([
|
||||
'reserved_stock' => -$sourceInventory->reserved_stock,
|
||||
'entry_reserved_stock' => -$sourceInventory->entry_reserved_stock,
|
||||
]);
|
||||
$sourceInventory->update(['reserved_stock' => 0, 'entry_reserved_stock' => 0]);
|
||||
|
||||
return $replacementInventory;
|
||||
}
|
||||
@@ -240,14 +236,13 @@ class VariantReplacementService
|
||||
throw new \LogicException('El inventario reservado de la variante es inconsistente.');
|
||||
}
|
||||
|
||||
$transferredCounters = [
|
||||
'real_stock' => $sourceInventory->real_stock,
|
||||
'reserved_stock' => $sourceInventory->reserved_stock,
|
||||
'entry_reserved_stock' => $sourceInventory->entry_reserved_stock,
|
||||
'sold_units' => $sourceInventory->sold_units,
|
||||
'refunded_units' => $sourceInventory->refunded_units,
|
||||
];
|
||||
$destinationInventory->transferCounters($transferredCounters);
|
||||
$destinationInventory->update([
|
||||
'real_stock' => $destinationInventory->real_stock + $sourceInventory->real_stock,
|
||||
'reserved_stock' => $destinationInventory->reserved_stock + $sourceInventory->reserved_stock,
|
||||
'entry_reserved_stock' => $destinationInventory->entry_reserved_stock + $sourceInventory->entry_reserved_stock,
|
||||
'sold_units' => $destinationInventory->sold_units + $sourceInventory->sold_units,
|
||||
'refunded_units' => $destinationInventory->refunded_units + $sourceInventory->refunded_units,
|
||||
]);
|
||||
if ($activeLines->isNotEmpty()) {
|
||||
StockReservationLine::query()
|
||||
->whereKey($activeLines->modelKeys())
|
||||
@@ -255,10 +250,13 @@ class VariantReplacementService
|
||||
}
|
||||
EntryReservation::query()->where('inventory_id', $sourceInventory->id)
|
||||
->update(['inventory_id' => $destinationInventory->id]);
|
||||
$sourceInventory->transferCounters(array_map(
|
||||
fn (int $value): int => -$value,
|
||||
$transferredCounters,
|
||||
));
|
||||
$sourceInventory->update([
|
||||
'real_stock' => 0,
|
||||
'reserved_stock' => 0,
|
||||
'entry_reserved_stock' => 0,
|
||||
'sold_units' => 0,
|
||||
'refunded_units' => 0,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @return list<string> */
|
||||
|
||||
Reference in New Issue
Block a user