| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- <?php
- namespace App\Services;
- use App\Enums\NotificationType;
- use App\Jobs\SyncFranchiseeChargeJob;
- use App\Models\CompanyPaymentAccount;
- use App\Models\FranchiseeAccountReceive;
- use App\Models\UnitAccountPayable;
- use Carbon\Carbon;
- use Exception;
- use Illuminate\Support\Facades\DB;
- use Illuminate\Validation\ValidationException;
- class FranchisorReceivableService
- {
- public function __construct(
- protected NotificationService $notifications,
- ) {}
- public function createManual(array $data): FranchiseeAccountReceive
- {
- return DB::transaction(function () use ($data) {
- $unitId = $data['account_type'] === 'unit' ? (int) $data['unit_id'] : null;
- $receivable = FranchiseeAccountReceive::create([
- 'unit_id' => $unitId,
- 'tbr_calculation_id' => null,
- 'financial_plan_account_id' => $data['financial_plan_account_id'] ?? null,
- 'origin' => $unitId ? 'manual_unit' : 'manual_internal',
- 'history' => $data['history'],
- 'value' => $data['value'],
- 'paid_value' => 0,
- 'due_date' => $data['due_date'],
- 'discount' => 0,
- 'fees' => 0,
- 'obs' => $data['obs'] ?? null,
- 'status' => 'pending',
- ]);
- if ($unitId) {
- UnitAccountPayable::create([
- 'unit_id' => $unitId,
- 'franchisee_account_receive_id' => $receivable->id,
- 'origin' => UnitAccountPayable::ORIGIN_MANUAL,
- 'history' => $receivable->history,
- 'value' => $receivable->value,
- 'paid_value' => 0,
- 'discount' => 0,
- 'fine' => 0,
- 'due_date' => $receivable->due_date,
- 'status' => 'pending',
- 'obs' => $receivable->obs,
- ]);
- $this->notifications->dispatch([
- 'origin_table' => 'franchisee_account_receives',
- 'origin_id' => $receivable->id,
- 'unit_id' => $unitId,
- 'type' => NotificationType::ACCOUNT_PAYABLE_CREATED->value,
- 'title' => 'Nova conta a pagar',
- 'message' => "Uma nova conta a pagar foi criada: {$receivable->history}.",
- 'url' => '/financial/accounts-payable',
- 'action_text' => 'Ver Contas a Pagar',
- 'priority' => 'normal',
- 'recipient_user_ids' => $this->notifications->unitUserIds($unitId),
- ]);
- }
- return $receivable->load(['unit', 'details', 'planAccount']);
- });
- }
- public function settle(FranchiseeAccountReceive $receivable, array $data): FranchiseeAccountReceive
- {
- if ($receivable->status->value === 'paid') {
- throw ValidationException::withMessages(['status' => 'Esta conta já está paga.']);
- }
- return DB::transaction(function () use ($receivable, $data) {
- $receivable->update([
- 'status' => 'paid',
- 'paid_value' => $receivable->value,
- 'payment_date' => $data['payment_date'] ?? Carbon::today()->format('Y-m-d'),
- ]);
- UnitAccountPayable::where('franchisee_account_receive_id', $receivable->id)
- ->update([
- 'status' => 'paid',
- 'paid_value' => $receivable->value,
- 'payment_date' => $data['payment_date'] ?? Carbon::today()->format('Y-m-d'),
- ]);
- if ($receivable->unit_id) {
- $this->notifications->dispatch([
- 'origin_table' => 'franchisee_account_receives',
- 'origin_id' => $receivable->id,
- 'unit_id' => $receivable->unit_id,
- 'type' => NotificationType::PAYMENT_CREDITED->value,
- 'title' => 'Pagamento confirmado',
- 'message' => "Sua cobrança {$receivable->history} foi devidamente creditada e consta como paga.",
- 'url' => '/financial/accounts-payable',
- 'action_text' => 'Ver Contas a Pagar',
- 'priority' => 'normal',
- 'recipient_user_ids' => $this->notifications->unitUserIds($receivable->unit_id),
- ]);
- }
- return $receivable->fresh(['unit', 'details', 'planAccount']);
- });
- }
- public function generateCharge(FranchiseeAccountReceive $receivable): FranchiseeAccountReceive
- {
- if (! $receivable->unit_id) {
- throw ValidationException::withMessages([
- 'unit' => 'Cobranças Asaas só podem ser geradas para contas vinculadas a uma unidade.',
- ]);
- }
- if (in_array($receivable->status->value, ['paid', 'cancelled'], true)) {
- throw ValidationException::withMessages([
- 'status' => 'Contas pagas ou canceladas não podem gerar cobrança.',
- ]);
- }
- if ($receivable->asaas_id) {
- throw ValidationException::withMessages([
- 'asaas' => 'Esta conta já possui cobrança gerada.',
- ]);
- }
- if (empty(CompanyPaymentAccount::resolveApiKey())) {
- throw ValidationException::withMessages([
- 'asaas' => 'A franqueadora não possui chave Asaas configurada.',
- ]);
- }
- try {
- SyncFranchiseeChargeJob::dispatchSync($receivable);
- } catch (Exception) {
- throw ValidationException::withMessages([
- 'asaas' => 'Não foi possível gerar a cobrança na Asaas. Tente novamente.',
- ]);
- }
- return $receivable->fresh(['unit', 'details', 'planAccount']);
- }
- public function reopen(FranchiseeAccountReceive $receivable): FranchiseeAccountReceive
- {
- throw ValidationException::withMessages([
- 'status' => 'Uma conta paga não pode voltar para um status anterior.',
- ]);
- }
- }
|