Compare commits
11 Commits
d1c4acc7ae
...
4162e2c1cc
| Author | SHA1 | Date | |
|---|---|---|---|
| 4162e2c1cc | |||
| 8d01620fa8 | |||
| f8b8bab474 | |||
| 53d1415b18 | |||
| 6ff9119086 | |||
| 24e000b423 | |||
| c69ebe5f7c | |||
| c3a2da607d | |||
| f8c4cc7428 | |||
| abc060ab25 | |||
| 36eb41a18a |
@@ -17,21 +17,25 @@ class InvitationPurchaseProvisioner
|
|||||||
private const PAYMENT_METHOD = 'invitation';
|
private const PAYMENT_METHOD = 'invitation';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var list<array{sector: string, row: int, seats: int, type: string}>
|
* @var list<array{sector: string, row: int, first_seat: int, last_seat: int, type: string}>
|
||||||
*/
|
*/
|
||||||
private const ALLOCATIONS = [
|
private const ALLOCATIONS = [
|
||||||
['sector' => 'A', 'row' => 1, 'seats' => 16, 'type' => 'NORMAL'],
|
['sector' => 'A', 'row' => 1, 'first_seat' => 1, 'last_seat' => 16, 'type' => 'NORMAL'],
|
||||||
['sector' => 'A', 'row' => 3, 'seats' => 14, 'type' => 'NORMAL'],
|
['sector' => 'A', 'row' => 3, 'first_seat' => 1, 'last_seat' => 14, 'type' => 'NORMAL'],
|
||||||
['sector' => 'C', 'row' => 1, 'seats' => 16, 'type' => 'VIP + LUNCH'],
|
['sector' => 'C', 'row' => 1, 'first_seat' => 1, 'last_seat' => 16, 'type' => 'VIP + LUNCH'],
|
||||||
|
['sector' => 'C', 'row' => 3, 'first_seat' => 6, 'last_seat' => 7, 'type' => 'NORMAL'],
|
||||||
];
|
];
|
||||||
|
|
||||||
public function provision(): void
|
/**
|
||||||
|
* @param list<array{sector: string, row: int, first_seat: int, last_seat: int, type: string}>|null $allocations
|
||||||
|
*/
|
||||||
|
public function provision(?array $allocations = null): void
|
||||||
{
|
{
|
||||||
if (! $this->prerequisitesExist()) {
|
if (! $this->prerequisitesExist()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DB::transaction(function (): void {
|
DB::transaction(function () use ($allocations): void {
|
||||||
$now = now();
|
$now = now();
|
||||||
$userId = $this->userId($now);
|
$userId = $this->userId($now);
|
||||||
$purchaseId = $this->purchaseId($userId, $now);
|
$purchaseId = $this->purchaseId($userId, $now);
|
||||||
@@ -44,8 +48,8 @@ class InvitationPurchaseProvisioner
|
|||||||
throw new RuntimeException('No se encontró el catálogo de entradas del desfile.');
|
throw new RuntimeException('No se encontró el catálogo de entradas del desfile.');
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (self::ALLOCATIONS as $allocation) {
|
foreach ($allocations ?? self::ALLOCATIONS as $allocation) {
|
||||||
foreach (range(1, $allocation['seats']) as $seat) {
|
foreach (range($allocation['first_seat'], $allocation['last_seat']) as $seat) {
|
||||||
$variant = $this->variant(
|
$variant = $this->variant(
|
||||||
(int) $catalogItem->id,
|
(int) $catalogItem->id,
|
||||||
$allocation['sector'],
|
$allocation['sector'],
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ class SaleModificationResource extends JsonResource
|
|||||||
'attribute' => $this->attribute,
|
'attribute' => $this->attribute,
|
||||||
'old_value' => $this->old_value,
|
'old_value' => $this->old_value,
|
||||||
'new_value' => $this->new_value,
|
'new_value' => $this->new_value,
|
||||||
|
'changed_at' => $this->changed_at->utc()->toIso8601String(),
|
||||||
'date' => $this->changed_at->format('Y-m-d'),
|
'date' => $this->changed_at->format('Y-m-d'),
|
||||||
'time' => $this->changed_at->format('H:i:s'),
|
'time' => $this->changed_at->format('H:i:s'),
|
||||||
'actor_type' => $this->actor_type->value,
|
'actor_type' => $this->actor_type->value,
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use App\Domains\Desfile\Services\InvitationPurchaseProvisioner;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
app(InvitationPurchaseProvisioner::class)->provision([
|
||||||
|
[
|
||||||
|
'sector' => 'C',
|
||||||
|
'row' => 3,
|
||||||
|
'first_seat' => 6,
|
||||||
|
'last_seat' => 7,
|
||||||
|
'type' => 'NORMAL',
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
// Intentionally irreversible: issued invitation tickets may already be used.
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -288,19 +288,19 @@ class DesfilePuraTendenciaSeederTest extends TestCase
|
|||||||
|
|
||||||
$items = DB::table('compra_items')->where('compra_id', $purchase->id);
|
$items = DB::table('compra_items')->where('compra_id', $purchase->id);
|
||||||
|
|
||||||
$this->assertSame(46, (clone $items)->count());
|
$this->assertSame(48, (clone $items)->count());
|
||||||
$this->assertSame(46, (clone $items)
|
$this->assertSame(48, (clone $items)
|
||||||
->where('precio_unitario', 0)
|
->where('precio_unitario', 0)
|
||||||
->where('discount_total', 0)
|
->where('discount_total', 0)
|
||||||
->where('tax_total', 0)
|
->where('tax_total', 0)
|
||||||
->where('total', 0)
|
->where('total', 0)
|
||||||
->count());
|
->count());
|
||||||
$this->assertSame(46, DB::table('tickets')
|
$this->assertSame(48, DB::table('tickets')
|
||||||
->where('source_purchase_id', $purchase->id)
|
->where('source_purchase_id', $purchase->id)
|
||||||
->where('user_id', $user->id)
|
->where('user_id', $user->id)
|
||||||
->where('source_catalog_item_id', $catalogItemId)
|
->where('source_catalog_item_id', $catalogItemId)
|
||||||
->count());
|
->count());
|
||||||
$this->assertSame(46, DB::table('stock_reservations')
|
$this->assertSame(48, DB::table('stock_reservations')
|
||||||
->where('purchase_id', $purchase->id)
|
->where('purchase_id', $purchase->id)
|
||||||
->where('status', 'committed')
|
->where('status', 'committed')
|
||||||
->count());
|
->count());
|
||||||
@@ -309,6 +309,7 @@ class DesfilePuraTendenciaSeederTest extends TestCase
|
|||||||
['sector' => 'A', 'fila' => '1', 'tipo' => 'NORMAL', 'count' => 16],
|
['sector' => 'A', 'fila' => '1', 'tipo' => 'NORMAL', 'count' => 16],
|
||||||
['sector' => 'A', 'fila' => '3', 'tipo' => 'NORMAL', 'count' => 14],
|
['sector' => 'A', 'fila' => '3', 'tipo' => 'NORMAL', 'count' => 14],
|
||||||
['sector' => 'C', 'fila' => '1', 'tipo' => 'VIP + LUNCH', 'count' => 16],
|
['sector' => 'C', 'fila' => '1', 'tipo' => 'VIP + LUNCH', 'count' => 16],
|
||||||
|
['sector' => 'C', 'fila' => '3', 'tipo' => 'NORMAL', 'count' => 2, 'seats' => ['6', '7']],
|
||||||
] as $allocation) {
|
] as $allocation) {
|
||||||
$allocatedVariants = DB::table('variantes')
|
$allocatedVariants = DB::table('variantes')
|
||||||
->where('catalog_item_id', $catalogItemId)
|
->where('catalog_item_id', $catalogItemId)
|
||||||
@@ -326,6 +327,20 @@ class DesfilePuraTendenciaSeederTest extends TestCase
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->assertSame($allocation['count'], $allocatedVariants->count());
|
$this->assertSame($allocation['count'], $allocatedVariants->count());
|
||||||
|
|
||||||
|
if (isset($allocation['seats'])) {
|
||||||
|
$seatValues = DB::table('variant_values')
|
||||||
|
->join('item_attributes', 'item_attributes.id', '=', 'variant_values.item_attribute_id')
|
||||||
|
->join('attribute', 'attribute.id', '=', 'item_attributes.attribute_id')
|
||||||
|
->whereIn('variant_values.variant_id', (clone $allocatedVariants)->pluck('id'))
|
||||||
|
->where('attribute.codigo', 'asiento')
|
||||||
|
->pluck('variant_values.value')
|
||||||
|
->sort()
|
||||||
|
->values()
|
||||||
|
->all();
|
||||||
|
|
||||||
|
$this->assertSame($allocation['seats'], $seatValues);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
33
tests/Unit/Sale/SaleModificationResourceTest.php
Normal file
33
tests/Unit/Sale/SaleModificationResourceTest.php
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\Unit\Sale;
|
||||||
|
|
||||||
|
use App\Domains\Logging\Models\ValueChange;
|
||||||
|
use App\Domains\Sale\Resources\AdminApp\SaleModificationResource;
|
||||||
|
use Carbon\CarbonImmutable;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
class SaleModificationResourceTest extends TestCase
|
||||||
|
{
|
||||||
|
public function test_it_serializes_the_change_instant_as_utc_iso_8601(): void
|
||||||
|
{
|
||||||
|
$modification = (new ValueChange)->forceFill([
|
||||||
|
'id' => 1,
|
||||||
|
'trackable_id' => 33,
|
||||||
|
'attribute' => 'status',
|
||||||
|
'old_value' => 'pending_payment',
|
||||||
|
'new_value' => 'cancelled',
|
||||||
|
'changed_at' => CarbonImmutable::parse('2026-08-24 17:53:00', 'UTC'),
|
||||||
|
'actor_type' => 'system',
|
||||||
|
]);
|
||||||
|
$modification->setRelation('trackable', null);
|
||||||
|
$modification->setRelation('user', null);
|
||||||
|
|
||||||
|
$data = (new SaleModificationResource($modification))->resolve(Request::create('/'));
|
||||||
|
|
||||||
|
$this->assertSame('2026-08-24T17:53:00+00:00', $data['changed_at']);
|
||||||
|
$this->assertSame('2026-08-24', $data['date']);
|
||||||
|
$this->assertSame('17:53:00', $data['time']);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user