feat: enhance purchase detail handling to support cart items and improve resource structure

This commit is contained in:
2026-07-08 15:50:40 -03:00
parent 73bf285bad
commit ca4fea6bcd
4 changed files with 313 additions and 13 deletions

View File

@@ -2,8 +2,11 @@
namespace App\Domains\Purchase\Resources;
use App\Domains\Cart\Models\CartItem;
use App\Domains\Purchase\Models\PurchaseItem;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Support\Collection;
/**
* @mixin \App\Domains\Purchase\Models\Purchase
@@ -15,20 +18,18 @@ class PurchaseResource extends JsonResource
*/
public function toArray(Request $request): array
{
$items = $this->resource->relationLoaded('items')
? $this->resource->getRelation('items')
: collect();
[$items, $itemsSource] = $this->resolveItems();
$subtotal = $items->isNotEmpty()
? $items->reduce(
fn (float $carry, $item): float => $carry + ((float) $item->precio_unitario * $item->cantidad),
fn (float $carry, PurchaseItem|CartItem $item): float => $carry + $this->resolveItemSubtotal($item),
0.0,
)
: (float) ($this->total ?? 0);
$total = $items->isNotEmpty()
? $items->reduce(
fn (float $carry, $item): float => $carry + (float) $item->total,
fn (float $carry, PurchaseItem|CartItem $item): float => $carry + $this->resolveItemTotal($item),
0.0,
)
: (float) ($this->total ?? 0);
@@ -38,18 +39,66 @@ class PurchaseResource extends JsonResource
'cart_id' => $this->cart_id,
'tenant_codigo' => $this->tenant_codigo,
'user_id' => $this->user_id,
'created_at' => $this->created_at,
'status' => $this->status,
'payment_method' => $this->payment_method,
'dni' => $this->dni,
'telefono' => $this->telefono,
'nombre_apellido' => $this->nombre_apellido,
'email' => $this->email,
'items_source' => $itemsSource,
'items' => PurchaseItemResource::collection($items),
'subtotal' => $this->formatMoney($subtotal),
'total' => $this->formatMoney($total),
];
}
/**
* @return array{0: Collection<int, PurchaseItem|CartItem>, 1: string|null}
*/
protected function resolveItems(): array
{
if (! $this->resource->relationLoaded('items')) {
return [collect(), null];
}
$purchaseItems = $this->resource->getRelation('items');
if ($purchaseItems->isNotEmpty()) {
return [$purchaseItems, 'purchase'];
}
if (! $this->resource->relationLoaded('cart')) {
return [collect(), null];
}
$cart = $this->resource->getRelation('cart');
if ($cart === null || ! $cart->relationLoaded('items')) {
return [collect(), null];
}
return [$cart->getRelation('items'), 'cart'];
}
protected function resolveItemSubtotal(PurchaseItem|CartItem $item): float
{
if ($item instanceof PurchaseItem) {
return (float) $item->precio_unitario * $item->cantidad;
}
return (float) ($item->variant?->product?->precio ?? 0) * $item->cantidad;
}
protected function resolveItemTotal(PurchaseItem|CartItem $item): float
{
if ($item instanceof PurchaseItem) {
return (float) ($item->total ?? 0);
}
return $this->resolveItemSubtotal($item);
}
protected function formatMoney(float|int|string|null $amount): string
{
return number_format((float) ($amount ?? 0), 2, '.', '');