diff --git a/app/Domains/BankAccount/Controllers/BankAccountController.php b/app/Domains/BankAccount/Controllers/BankAccountController.php deleted file mode 100644 index 2f2934a..0000000 --- a/app/Domains/BankAccount/Controllers/BankAccountController.php +++ /dev/null @@ -1,76 +0,0 @@ -bankAccounts()->latest()->get(); - return BankAccountResource::collection($accounts)->response(); - } - - public function store(StoreBankAccountRequest $request, Tenant $tenant): JsonResponse - { - $data = $request->validated(); - $data['tenant_code'] = $tenant->codigo; - - $account = BankAccount::query()->create($data); - - return BankAccountResource::make($account)->response()->setStatusCode(201); - } - - public function show(Tenant $tenant, BankAccount $bankAccount): BankAccountResource - { - abort_if($bankAccount->tenant_code !== $tenant->codigo, 404); - - return BankAccountResource::make($bankAccount); - } - - public function update(UpdateBankAccountRequest $request, Tenant $tenant, BankAccount $bankAccount): BankAccountResource - { - abort_if($bankAccount->tenant_code !== $tenant->codigo, 404); - - $bankAccount->update($request->validated()); - - return BankAccountResource::make($bankAccount); - } - - public function destroy(Tenant $tenant, BankAccount $bankAccount): Response - { - abort_if($bankAccount->tenant_code !== $tenant->codigo, 404); - - $bankAccount->delete(); - - return response()->noContent(); - } - - public function select(Tenant $tenant, BankAccount $bankAccount): TenantResource - { - abort_if($bankAccount->tenant_code !== $tenant->codigo, 400, 'La cuenta bancaria no pertenece a este tenant.'); - - $tenant->selected_bank_account_id = $bankAccount->id; - $tenant->save(); - - return TenantResource::make($tenant->loadMissing(['headerLogo', 'footerLogo'])); - } - - public function selected(Tenant $tenant): JsonResponse - { - $account = $tenant->selectedBankAccount; - - abort_if(!$account, 404, 'No hay ninguna cuenta bancaria seleccionada para este tenant.'); - - return BankAccountResource::make($account)->response(); - } -} diff --git a/app/Domains/BankAccount/Models/BankAccount.php b/app/Domains/BankAccount/Models/BankAccount.php deleted file mode 100644 index 1b48baf..0000000 --- a/app/Domains/BankAccount/Models/BankAccount.php +++ /dev/null @@ -1,29 +0,0 @@ - - */ - public function tenant(): BelongsTo - { - return $this->belongsTo(Tenant::class, 'tenant_code', 'codigo'); - } -} diff --git a/app/Domains/BankAccount/Requests/StoreBankAccountRequest.php b/app/Domains/BankAccount/Requests/StoreBankAccountRequest.php deleted file mode 100644 index d3b2f99..0000000 --- a/app/Domains/BankAccount/Requests/StoreBankAccountRequest.php +++ /dev/null @@ -1,47 +0,0 @@ - - */ - public function rules(): array - { - return [ - 'titular' => ['required', 'string', 'max:255'], - 'entidad' => ['required', 'string', 'max:255'], - 'alias' => ['required', 'string', 'max:255'], - 'cvu' => ['required', 'string', 'max:255'], - ]; - } - - /** - * @return array - */ - public function messages(): array - { - return [ - 'titular.required' => 'El campo titular es obligatorio.', - 'titular.string' => 'El campo titular debe ser una cadena de texto.', - 'titular.max' => 'El campo titular no debe superar los 255 caracteres.', - 'entidad.required' => 'El campo entidad es obligatorio.', - 'entidad.string' => 'El campo entidad debe ser una cadena de texto.', - 'entidad.max' => 'El campo entidad no debe superar los 255 caracteres.', - 'alias.required' => 'El campo alias es obligatorio.', - 'alias.string' => 'El campo alias debe ser una cadena de texto.', - 'alias.max' => 'El campo alias no debe superar los 255 caracteres.', - 'cvu.required' => 'El campo cvu es obligatorio.', - 'cvu.string' => 'El campo cvu debe ser una cadena de texto.', - 'cvu.max' => 'El campo cvu no debe superar los 255 caracteres.', - ]; - } -} diff --git a/app/Domains/BankAccount/Requests/UpdateBankAccountRequest.php b/app/Domains/BankAccount/Requests/UpdateBankAccountRequest.php deleted file mode 100644 index 3c95772..0000000 --- a/app/Domains/BankAccount/Requests/UpdateBankAccountRequest.php +++ /dev/null @@ -1,43 +0,0 @@ - - */ - public function rules(): array - { - return [ - 'titular' => ['sometimes', 'string', 'max:255'], - 'entidad' => ['sometimes', 'string', 'max:255'], - 'alias' => ['sometimes', 'string', 'max:255'], - 'cvu' => ['sometimes', 'string', 'max:255'], - ]; - } - - /** - * @return array - */ - public function messages(): array - { - return [ - 'titular.string' => 'El campo titular debe ser una cadena de texto.', - 'titular.max' => 'El campo titular no debe superar los 255 caracteres.', - 'entidad.string' => 'El campo entidad debe ser una cadena de texto.', - 'entidad.max' => 'El campo entidad no debe superar los 255 caracteres.', - 'alias.string' => 'El campo alias debe ser una cadena de texto.', - 'alias.max' => 'El campo alias no debe superar los 255 caracteres.', - 'cvu.string' => 'El campo cvu debe ser una cadena de texto.', - 'cvu.max' => 'El campo cvu no debe superar los 255 caracteres.', - ]; - } -} diff --git a/app/Domains/BankAccount/Resources/BankAccountResource.php b/app/Domains/BankAccount/Resources/BankAccountResource.php deleted file mode 100644 index 98fb33d..0000000 --- a/app/Domains/BankAccount/Resources/BankAccountResource.php +++ /dev/null @@ -1,27 +0,0 @@ - - */ - public function toArray(Request $request): array - { - return [ - 'id' => $this->id, - 'tenant_code' => $this->tenant_code, - 'titular' => $this->titular, - 'entidad' => $this->entidad, - 'alias' => $this->alias, - 'cvu' => $this->cvu, - ]; - } -} diff --git a/app/Domains/BankAccount/routes/api.php b/app/Domains/BankAccount/routes/api.php deleted file mode 100644 index 173a127..0000000 --- a/app/Domains/BankAccount/routes/api.php +++ /dev/null @@ -1,13 +0,0 @@ -group(function (): void { - Route::middleware('auth:sanctum')->group(function (): void { - Route::get('bank-accounts/selected', [BankAccountController::class, 'selected']); - Route::post('bank-accounts/{bank_account}/select', [BankAccountController::class, 'select']); - Route::apiResource('bank-accounts', BankAccountController::class) - ->parameters(['bank-accounts' => 'bank_account']); - }); -}); diff --git a/app/Domains/Integration/Services/TelepagosIntegrationService.php b/app/Domains/Integration/Services/TelepagosIntegrationService.php index 61c3cb3..27014ee 100644 --- a/app/Domains/Integration/Services/TelepagosIntegrationService.php +++ b/app/Domains/Integration/Services/TelepagosIntegrationService.php @@ -167,6 +167,18 @@ class TelepagosIntegrationService extends BaseIntegrationService ]); } + /** + * Get the account info. + * + * @return array + * @throws Exception + */ + public function getAccountInfo(): array + { + $response = $this->sendRequest('get', '/v2/account/info'); + return $this->handleResponse($response, 'get account info'); + } + /** * Handle the Telepagos API response, logging any failures and throwing Exceptions. * diff --git a/app/Domains/Purchase/Controllers/PurchaseController.php b/app/Domains/Purchase/Controllers/PurchaseController.php index 10aa1be..6a37e85 100644 --- a/app/Domains/Purchase/Controllers/PurchaseController.php +++ b/app/Domains/Purchase/Controllers/PurchaseController.php @@ -61,17 +61,26 @@ class PurchaseController extends Controller ]); if ($method === 'transfer') { - $bankAccount = $tenant->selectedBankAccount; + $telepagosService = new \App\Domains\Integration\Services\TelepagosIntegrationService(); + $telepagosService->forTenant($tenant->codigo); - return response()->json([ - 'payment_method' => 'transfer', - 'transfer_data' => $bankAccount ? [ - 'titular' => $bankAccount->titular, - 'entidad' => $bankAccount->entidad, - 'alias' => $bankAccount->alias, - 'cvu' => $bankAccount->cvu, - ] : null, - ]); + try { + $accountInfo = $telepagosService->getAccountInfo(); + + return response()->json([ + 'payment_method' => 'transfer', + 'transfer_data' => [ + 'titular' => $accountInfo['holder'] ?? null, + 'cvu' => $accountInfo['cvu'] ?? null, + 'alias' => $accountInfo['alias'] ?? null, + 'cuit' => $accountInfo['cuit'] ?? null, + ], + ]); + } catch (\Exception $e) { + return response()->json([ + 'message' => 'Error getting account info: ' . $e->getMessage() + ], 500); + } } if ($method === 'qr') { diff --git a/app/Domains/Tenant/Models/Tenant.php b/app/Domains/Tenant/Models/Tenant.php index 552cb18..030bda0 100644 --- a/app/Domains/Tenant/Models/Tenant.php +++ b/app/Domains/Tenant/Models/Tenant.php @@ -3,7 +3,6 @@ namespace App\Domains\Tenant\Models; use App\Domains\Attachable\Models\Attachment; -use App\Domains\BankAccount\Models\BankAccount; use App\Domains\Catalog\Models\Product; use Illuminate\Database\Eloquent\Attributes\Fillable; use Illuminate\Database\Eloquent\Factories\HasFactory; @@ -49,28 +48,9 @@ class Tenant extends Model return $this->belongsTo(Attachment::class, 'footer_logo_id'); } - /** - * @return HasMany - */ public function productos(): HasMany { return $this->hasMany(Product::class, 'tenant_codigo', 'codigo'); } - - /** - * @return HasMany - */ - public function bankAccounts(): HasMany - { - return $this->hasMany(BankAccount::class, 'tenant_code', 'codigo'); - } - - /** - * @return BelongsTo - */ - public function selectedBankAccount(): BelongsTo - { - return $this->belongsTo(BankAccount::class, 'selected_bank_account_id'); - } } diff --git a/database/migrations/2026_07_06_194803_drop_bank_accounts_table.php b/database/migrations/2026_07_06_194803_drop_bank_accounts_table.php new file mode 100644 index 0000000..9dbcfa2 --- /dev/null +++ b/database/migrations/2026_07_06_194803_drop_bank_accounts_table.php @@ -0,0 +1,44 @@ +dropForeign(['selected_bank_account_id']); + $table->dropColumn('selected_bank_account_id'); + }); + + Schema::dropIfExists('bank_accounts'); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::create('bank_accounts', function (Blueprint $table) { + $table->id(); + $table->string('tenant_code'); + $table->string('titular'); + $table->string('entidad'); + $table->string('alias'); + $table->string('cvu'); + $table->timestamps(); + + $table->foreign('tenant_code')->references('codigo')->on('tenants')->onDelete('cascade'); + }); + + Schema::table('tenants', function (Blueprint $table) { + $table->unsignedBigInteger('selected_bank_account_id')->nullable(); + $table->foreign('selected_bank_account_id')->references('id')->on('bank_accounts')->onDelete('set null'); + }); + } +}; diff --git a/database/seeders/TenantSeeder.php b/database/seeders/TenantSeeder.php index 076bb8d..a0caf67 100644 --- a/database/seeders/TenantSeeder.php +++ b/database/seeders/TenantSeeder.php @@ -85,32 +85,5 @@ class TenantSeeder extends Seeder 'header_logo' => $headerLogo, 'footer_logo' => $footerLogo, ]); - - $bankAccount1 = \App\Domains\BankAccount\Models\BankAccount::query()->create([ - 'tenant_code' => $tenant->codigo, - 'titular' => 'Sonder S.A. (Principal)', - 'entidad' => 'Banco de la Nación Argentina', - 'alias' => 'sonder.indumentaria', - 'cvu' => '0110065420006540987654', - ]); - - \App\Domains\BankAccount\Models\BankAccount::query()->create([ - 'tenant_code' => $tenant->codigo, - 'titular' => 'Sonder S.A. (Secundaria)', - 'entidad' => 'Banco de Galicia y Buenos Aires', - 'alias' => 'sonder.indumentaria.galicia', - 'cvu' => '0070012345678901234567', - ]); - - \App\Domains\BankAccount\Models\BankAccount::query()->create([ - 'tenant_code' => $tenant->codigo, - 'titular' => 'Sonder S.A. (Mercado Pago)', - 'entidad' => 'Mercado Pago', - 'alias' => 'sonder.indumentaria.mp', - 'cvu' => '0000003100012345678901', - ]); - - $tenant->selected_bank_account_id = $bankAccount1->id; - $tenant->save(); } } diff --git a/routes/api.php b/routes/api.php index 5a3514c..e2c1287 100644 --- a/routes/api.php +++ b/routes/api.php @@ -9,5 +9,4 @@ require __DIR__.'/../app/Domains/Cart/routes/api.php'; require __DIR__.'/../app/Domains/StorageTest/routes/api.php'; require __DIR__.'/../app/Domains/Purchase/routes/api.php'; require __DIR__.'/../app/Domains/Tenant/routes/api.php'; -require __DIR__.'/../app/Domains/BankAccount/routes/api.php'; require __DIR__.'/../app/Domains/Integration/routes/api.php'; diff --git a/tests/Feature/Tenant/BankAccountControllerTest.php b/tests/Feature/Tenant/BankAccountControllerTest.php deleted file mode 100644 index 422c4a7..0000000 --- a/tests/Feature/Tenant/BankAccountControllerTest.php +++ /dev/null @@ -1,242 +0,0 @@ - $hdrKey, - 'path' => 'tenants/' . $hdrKey . '.png', - 'filename' => 'logo_header.png', - 'type' => \App\Domains\Attachable\Enums\AttachmentType::Image, - 'mime_type' => 'image/png', - ]); - $footerAttachment = \App\Domains\Attachable\Models\Attachment::create([ - 'key' => $ftrKey, - 'path' => 'tenants/' . $ftrKey . '.png', - 'filename' => 'logo_footer.png', - 'type' => \App\Domains\Attachable\Enums\AttachmentType::Image, - 'mime_type' => 'image/png', - ]); - - $this->tenant = Tenant::create([ - 'codigo' => 'acme', - 'nombre' => 'Acme', - 'dominio' => 'acme.com', - 'primary_color' => '#ff0000', - 'secondary_color' => '#00ff00', - 'danger_color' => '#0000ff', - 'success_color' => '#00ff00', - 'header_bg_color' => '#ffffff', - 'footer_bg_color' => '#ffffff', - 'header_logo_id' => $headerAttachment->id, - 'footer_logo_id' => $footerAttachment->id, - ]); - - $this->user = User::factory()->create(); - $this->actingAs($this->user, 'sanctum'); - } - - public function test_it_lists_bank_accounts_for_a_tenant(): void - { - BankAccount::query()->create([ - 'tenant_code' => 'acme', - 'titular' => 'John Doe', - 'entidad' => 'Banco Galicia', - 'alias' => 'john.doe.galicia', - 'cvu' => '1234567890123456789012', - ]); - - $response = $this->getJson("/api/tenants/acme/bank-accounts"); - - $response->assertOk() - ->assertJsonCount(1, 'data') - ->assertJsonPath('data.0.titular', 'John Doe'); - } - - public function test_it_creates_a_bank_account_for_a_tenant(): void - { - $response = $this->postJson("/api/tenants/acme/bank-accounts", [ - 'titular' => 'Jane Doe', - 'entidad' => 'Banco Nación', - 'alias' => 'jane.doe.nacion', - 'cvu' => '9876543210987654321098', - ]); - - $response->assertCreated() - ->assertJsonPath('data.titular', 'Jane Doe'); - - $this->assertDatabaseHas('bank_accounts', [ - 'tenant_code' => 'acme', - 'titular' => 'Jane Doe', - ]); - } - - public function test_it_shows_a_bank_account(): void - { - $account = BankAccount::query()->create([ - 'tenant_code' => 'acme', - 'titular' => 'John Doe', - 'entidad' => 'Banco Galicia', - 'alias' => 'john.doe.galicia', - 'cvu' => '1234567890123456789012', - ]); - - $response = $this->getJson("/api/tenants/acme/bank-accounts/{$account->id}"); - - $response->assertOk() - ->assertJsonPath('data.titular', 'John Doe'); - } - - public function test_it_updates_a_bank_account(): void - { - $account = BankAccount::query()->create([ - 'tenant_code' => 'acme', - 'titular' => 'John Doe', - 'entidad' => 'Banco Galicia', - 'alias' => 'john.doe.galicia', - 'cvu' => '1234567890123456789012', - ]); - - $response = $this->putJson("/api/tenants/acme/bank-accounts/{$account->id}", [ - 'titular' => 'John Doe Updated', - ]); - - $response->assertOk() - ->assertJsonPath('data.titular', 'John Doe Updated'); - - $this->assertDatabaseHas('bank_accounts', [ - 'id' => $account->id, - 'titular' => 'John Doe Updated', - ]); - } - - public function test_it_deletes_a_bank_account(): void - { - $account = BankAccount::query()->create([ - 'tenant_code' => 'acme', - 'titular' => 'John Doe', - 'entidad' => 'Banco Galicia', - 'alias' => 'john.doe.galicia', - 'cvu' => '1234567890123456789012', - ]); - - $response = $this->deleteJson("/api/tenants/acme/bank-accounts/{$account->id}"); - - $response->assertNoContent(); - - $this->assertDatabaseMissing('bank_accounts', ['id' => $account->id]); - } - - public function test_it_selects_a_bank_account_for_a_tenant(): void - { - $account = BankAccount::query()->create([ - 'tenant_code' => 'acme', - 'titular' => 'John Doe', - 'entidad' => 'Banco Galicia', - 'alias' => 'john.doe.galicia', - 'cvu' => '1234567890123456789012', - ]); - - $response = $this->postJson("/api/tenants/acme/bank-accounts/{$account->id}/select"); - - $response->assertOk() - ->assertJsonPath('data.selected_bank_account_id', $account->id); - - $this->tenant->refresh(); - $this->assertEquals($account->id, $this->tenant->selected_bank_account_id); - } - - public function test_it_deletes_related_bank_accounts_when_tenant_is_deleted(): void - { - $account = BankAccount::query()->create([ - 'tenant_code' => 'acme', - 'titular' => 'John Doe', - 'entidad' => 'Banco Galicia', - 'alias' => 'john.doe.galicia', - 'cvu' => '1234567890123456789012', - ]); - - $this->assertDatabaseHas('bank_accounts', ['id' => $account->id]); - - $this->tenant->delete(); - - $this->assertDatabaseMissing('bank_accounts', ['id' => $account->id]); - } - - public function test_it_sets_selected_bank_account_id_to_null_when_selected_bank_account_is_deleted(): void - { - $account = BankAccount::query()->create([ - 'tenant_code' => 'acme', - 'titular' => 'John Doe', - 'entidad' => 'Banco Galicia', - 'alias' => 'john.doe.galicia', - 'cvu' => '1234567890123456789012', - ]); - - $this->tenant->selected_bank_account_id = $account->id; - $this->tenant->save(); - - $account->delete(); - - $this->tenant->refresh(); - $this->assertNull($this->tenant->selected_bank_account_id); - } - - public function test_it_gets_the_selected_bank_account_for_a_tenant(): void - { - $account = BankAccount::query()->create([ - 'tenant_code' => 'acme', - 'titular' => 'John Doe', - 'entidad' => 'Banco Galicia', - 'alias' => 'john.doe.galicia', - 'cvu' => '1234567890123456789012', - ]); - - // When no bank account is selected - $response = $this->getJson("/api/tenants/acme/bank-accounts/selected"); - $response->assertNotFound(); - - // Select the bank account - $this->tenant->selected_bank_account_id = $account->id; - $this->tenant->save(); - - // Get selected bank account - $response = $this->getJson("/api/tenants/acme/bank-accounts/selected"); - $response->assertOk() - ->assertJsonPath('data.id', $account->id) - ->assertJsonPath('data.titular', 'John Doe'); - } - - public function test_it_rejects_unauthenticated_requests(): void - { - $this->app['auth']->forgetGuards(); - - $response = $this->getJson("/api/tenants/acme/bank-accounts/selected"); - $response->assertStatus(401); - - $response2 = $this->getJson("/api/tenants/acme/bank-accounts"); - $response2->assertStatus(401); - - $response3 = $this->postJson("/api/tenants/acme/bank-accounts", []); - $response3->assertStatus(401); - } -}