feat(event): support ticket refund configuration in event endpoints
This commit is contained in:
@@ -33,6 +33,16 @@ class UpdateEventRequest extends FormRequest
|
||||
'contact.whatsapp_url' => ['nullable', 'url', 'max:2048'],
|
||||
'contact.instagram_url' => ['nullable', 'url', 'max:2048'],
|
||||
'contact.facebook_url' => ['nullable', 'url', 'max:2048'],
|
||||
'allow_ticket_refund' => ['sometimes', 'boolean'],
|
||||
'allow_ticket_total_refund' => ['sometimes', 'boolean'],
|
||||
'allow_ticket_partial_refund' => ['sometimes', 'boolean'],
|
||||
'ticket_partial_refund_percentage' => [
|
||||
'sometimes',
|
||||
'numeric',
|
||||
'decimal:0,2',
|
||||
'min:0',
|
||||
'max:99.99',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
@@ -49,6 +59,41 @@ class UpdateEventRequest extends FormRequest
|
||||
'The social media field is required.'
|
||||
);
|
||||
}
|
||||
|
||||
if (! array_key_exists('allow_ticket_refund', $input)) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ([
|
||||
'allow_ticket_total_refund',
|
||||
'allow_ticket_partial_refund',
|
||||
'ticket_partial_refund_percentage',
|
||||
] as $field) {
|
||||
if (! array_key_exists($field, $input)) {
|
||||
$validator->errors()->add($field, 'El campo es obligatorio.');
|
||||
}
|
||||
}
|
||||
|
||||
$totalEnabled = $this->boolean('allow_ticket_total_refund');
|
||||
$partialEnabled = $this->boolean('allow_ticket_partial_refund');
|
||||
|
||||
$refundEnabled = $this->boolean('allow_ticket_refund');
|
||||
|
||||
if ($refundEnabled && ! $totalEnabled && ! $partialEnabled) {
|
||||
$validator->errors()->add(
|
||||
'allow_ticket_refund',
|
||||
'Seleccioná al menos un tipo de reembolso.'
|
||||
);
|
||||
}
|
||||
|
||||
if ($refundEnabled
|
||||
&& $partialEnabled
|
||||
&& (float) ($input['ticket_partial_refund_percentage'] ?? 0) <= 0) {
|
||||
$validator->errors()->add(
|
||||
'ticket_partial_refund_percentage',
|
||||
'Ingresá un porcentaje mayor que cero para el reembolso parcial.'
|
||||
);
|
||||
}
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
@@ -18,6 +18,10 @@ class EventResource extends JsonResource
|
||||
'id' => $this->id,
|
||||
'title' => $this->event_title,
|
||||
'location' => $this->event_location,
|
||||
'allow_ticket_refund' => $this->allow_ticket_refund,
|
||||
'allow_ticket_total_refund' => $this->allow_ticket_total_refund,
|
||||
'allow_ticket_partial_refund' => $this->allow_ticket_partial_refund,
|
||||
'ticket_partial_refund_percentage' => $this->ticket_partial_refund_percentage,
|
||||
'dates' => EventDateResource::collection($this->eventDates),
|
||||
'social_media' => $this->socialMedia->map(fn ($item): array => [
|
||||
'code' => $item->code,
|
||||
|
||||
@@ -34,6 +34,12 @@ class EventService
|
||||
$tenant->update([
|
||||
'event_title' => $data['title'],
|
||||
'event_location' => $data['location'],
|
||||
...array_intersect_key($data, array_flip([
|
||||
'allow_ticket_refund',
|
||||
'allow_ticket_total_refund',
|
||||
'allow_ticket_partial_refund',
|
||||
'ticket_partial_refund_percentage',
|
||||
])),
|
||||
]);
|
||||
|
||||
if (array_key_exists('social_media', $data)) {
|
||||
|
||||
@@ -51,6 +51,10 @@ class AdminAppEventControllerTest extends TestCase
|
||||
->assertOk()
|
||||
->assertJsonPath('data.title', 'Festival Acme')
|
||||
->assertJsonPath('data.location', 'Predio Ferial, Rosario')
|
||||
->assertJsonPath('data.allow_ticket_refund', true)
|
||||
->assertJsonPath('data.allow_ticket_total_refund', true)
|
||||
->assertJsonPath('data.allow_ticket_partial_refund', true)
|
||||
->assertJsonPath('data.ticket_partial_refund_percentage', '25.50')
|
||||
->assertJsonCount(0, 'data.dates')
|
||||
->assertJsonPath('data.contact.whatsapp_url', 'https://wa.me/5493415550101')
|
||||
->assertJsonPath('data.contact.instagram_url', 'https://instagram.com/acme')
|
||||
@@ -62,6 +66,10 @@ class AdminAppEventControllerTest extends TestCase
|
||||
'event_title' => 'Festival Acme',
|
||||
'event_location' => 'Predio Ferial, Rosario',
|
||||
'event_date_text' => null,
|
||||
'allow_ticket_refund' => true,
|
||||
'allow_ticket_total_refund' => true,
|
||||
'allow_ticket_partial_refund' => true,
|
||||
'ticket_partial_refund_percentage' => 25.50,
|
||||
]);
|
||||
$this->assertDatabaseCount('event_dates', 0);
|
||||
$this->assertDatabaseHas('tenant_social_media', [
|
||||
@@ -71,6 +79,56 @@ class AdminAppEventControllerTest extends TestCase
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_disabling_refunds_preserves_the_configured_types_and_percentage(): void
|
||||
{
|
||||
$tenant = $this->createTenant('acme');
|
||||
$tenant->update([
|
||||
'allow_ticket_refund' => true,
|
||||
'allow_ticket_total_refund' => true,
|
||||
'allow_ticket_partial_refund' => true,
|
||||
'ticket_partial_refund_percentage' => 35.50,
|
||||
]);
|
||||
Sanctum::actingAs($this->createAdminAppUser($tenant));
|
||||
|
||||
$payload = $this->eventPayload();
|
||||
$payload['allow_ticket_refund'] = false;
|
||||
$payload['ticket_partial_refund_percentage'] = 35.50;
|
||||
|
||||
$this->putJson('/api/v1/adminapp/tenant/event', $payload)
|
||||
->assertOk()
|
||||
->assertJsonPath('data.allow_ticket_refund', false)
|
||||
->assertJsonPath('data.allow_ticket_total_refund', true)
|
||||
->assertJsonPath('data.allow_ticket_partial_refund', true)
|
||||
->assertJsonPath('data.ticket_partial_refund_percentage', '35.50');
|
||||
|
||||
$tenant->refresh();
|
||||
$this->assertFalse($tenant->allow_refund());
|
||||
$this->assertTrue($tenant->allow_ticket_total_refund);
|
||||
$this->assertTrue($tenant->allow_ticket_partial_refund);
|
||||
$this->assertSame('35.50', $tenant->ticket_partial_refund_percentage);
|
||||
}
|
||||
|
||||
public function test_enabled_refunds_require_a_type_and_a_valid_partial_percentage(): void
|
||||
{
|
||||
$tenant = $this->createTenant('acme');
|
||||
Sanctum::actingAs($this->createAdminAppUser($tenant));
|
||||
|
||||
$payload = $this->eventPayload();
|
||||
$payload['allow_ticket_total_refund'] = false;
|
||||
$payload['allow_ticket_partial_refund'] = false;
|
||||
|
||||
$this->putJson('/api/v1/adminapp/tenant/event', $payload)
|
||||
->assertUnprocessable()
|
||||
->assertJsonValidationErrors('allow_ticket_refund');
|
||||
|
||||
$payload['allow_ticket_partial_refund'] = true;
|
||||
$payload['ticket_partial_refund_percentage'] = 0;
|
||||
|
||||
$this->putJson('/api/v1/adminapp/tenant/event', $payload)
|
||||
->assertUnprocessable()
|
||||
->assertJsonValidationErrors('ticket_partial_refund_percentage');
|
||||
}
|
||||
|
||||
public function test_an_adminapp_user_can_read_only_its_tenant_active_event(): void
|
||||
{
|
||||
$tenant = $this->createTenant('acme');
|
||||
@@ -375,6 +433,10 @@ class AdminAppEventControllerTest extends TestCase
|
||||
return [
|
||||
'title' => 'Festival Acme',
|
||||
'location' => 'Predio Ferial, Rosario',
|
||||
'allow_ticket_refund' => true,
|
||||
'allow_ticket_total_refund' => true,
|
||||
'allow_ticket_partial_refund' => true,
|
||||
'ticket_partial_refund_percentage' => 25.50,
|
||||
'contact' => [
|
||||
'whatsapp_url' => 'https://wa.me/5493415550101',
|
||||
'instagram_url' => 'https://instagram.com/acme',
|
||||
|
||||
Reference in New Issue
Block a user