From d9ae4b2edd7323bf8cabe3b49b1c995fe11f70c6 Mon Sep 17 00:00:00 2001 From: Raul Perusquia Date: Tue, 15 Oct 2024 18:19:06 +0800 Subject: [PATCH] =?UTF-8?q?#287=20Fetch=20Aurora=20Payments=20=F0=9F=92=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Accounting/Payment/StorePayment.php | 84 +++++++++++-------- .../Accounting/Payment/UpdatePayment.php | 19 ++++- .../Transfers/Aurora/FetchAuroraPayments.php | 40 ++++++--- app/Transfers/Aurora/FetchAuroraPayment.php | 38 ++++----- ...023_02_26_200658_create_payments_table.php | 2 +- 5 files changed, 110 insertions(+), 73 deletions(-) diff --git a/app/Actions/Accounting/Payment/StorePayment.php b/app/Actions/Accounting/Payment/StorePayment.php index a49818a387..69ac1e9d7d 100644 --- a/app/Actions/Accounting/Payment/StorePayment.php +++ b/app/Actions/Accounting/Payment/StorePayment.php @@ -25,6 +25,7 @@ use App\Models\Accounting\PaymentAccount; use App\Models\CRM\Customer; use Illuminate\Support\Arr; +use Illuminate\Support\Facades\DB; use Illuminate\Validation\Rule; use Lorisleiva\Actions\ActionRequest; use Lorisleiva\Actions\Concerns\AsCommand; @@ -35,9 +36,11 @@ class StorePayment extends OrgAction public string $commandSignature = 'payment:create {customer} {paymentAccount} {scope}'; + /** + * @throws \Throwable + */ public function handle(Customer $customer, PaymentAccount $paymentAccount, array $modelData): Payment { - // $items = Arr::pull($modelData, 'items'); $currencyCode = Arr::pull($modelData, 'currency_code'); $totalAmount = Arr::pull($modelData, 'total_amount'); @@ -55,25 +58,30 @@ public function handle(Customer $customer, PaymentAccount $paymentAccount, array data_set($modelData, 'org_amount', Arr::get($modelData, 'amount') * GetCurrencyExchange::run($customer->shop->currency, $paymentAccount->organisation->currency), overwrite: false); data_set($modelData, 'group_amount', Arr::get($modelData, 'amount') * GetCurrencyExchange::run($customer->shop->currency, $paymentAccount->organisation->group->currency), overwrite: false); - /** @var Payment $payment */ - $payment = $paymentAccount->payments()->create($modelData); - $paypalData = [ - 'total_amount' => $totalAmount, - //'items' => $items, - 'currency_code' => $currencyCode, - ]; + $payment = DB::transaction(function () use ($paymentAccount, $modelData, $currencyCode, $totalAmount) { + /** @var Payment $payment */ + $payment = $paymentAccount->payments()->create($modelData); - if ($this->strict) { - match ($paymentAccount->type->value) { - PaymentAccountTypeEnum::CHECKOUT->value => MakePaymentUsingCheckout::run($payment, $modelData), - PaymentAccountTypeEnum::XENDIT->value => MakePaymentUsingXendit::run($payment), - PaymentAccountTypeEnum::PAYPAL->value => MakePaymentUsingPaypal::run($payment, $paypalData), - default => null - }; - } + $paypalData = [ + 'total_amount' => $totalAmount, + 'currency_code' => $currencyCode, + ]; + + if ($this->strict) { + match ($paymentAccount->type->value) { + PaymentAccountTypeEnum::CHECKOUT->value => MakePaymentUsingCheckout::run($payment, $modelData), + PaymentAccountTypeEnum::XENDIT->value => MakePaymentUsingXendit::run($payment), + PaymentAccountTypeEnum::PAYPAL->value => MakePaymentUsingPaypal::run($payment, $paypalData), + default => null + }; + } + + $payment->refresh(); + + return $payment; + }); - $payment->refresh(); GroupHydratePayments::dispatch($payment->group)->delay($this->hydratorsDelay); OrganisationHydratePayments::dispatch($paymentAccount->organisation)->delay($this->hydratorsDelay); @@ -99,31 +107,38 @@ public function authorize(ActionRequest $request): bool public function rules(): array { $rules = [ - 'reference' => ['nullable', 'string', 'max:255'], - 'amount' => ['required', 'decimal:0,2'], - 'total_amount' => ['sometimes', 'decimal:0,2'], - 'org_amount' => ['sometimes', 'numeric'], - 'group_amount' => ['sometimes', 'numeric'], - 'data' => ['sometimes', 'array'], - 'date' => ['sometimes', 'date'], - 'status' => ['sometimes', 'required', Rule::enum(PaymentStatusEnum::class)], - 'state' => ['sometimes', 'required', Rule::enum(PaymentStateEnum::class)], - 'items' => ['sometimes', 'array'], - 'currency_code' => ['sometimes', 'string'] + 'reference' => ['nullable', 'string', 'max:255'], + 'amount' => ['required', 'decimal:0,2'], + 'total_amount' => ['sometimes', 'decimal:0,2'], + 'org_amount' => ['sometimes', 'numeric'], + 'group_amount' => ['sometimes', 'numeric'], + 'data' => ['sometimes', 'array'], + 'date' => ['sometimes', 'date'], + 'status' => ['sometimes', 'required', Rule::enum(PaymentStatusEnum::class)], + 'state' => ['sometimes', 'required', Rule::enum(PaymentStateEnum::class)], + 'items' => ['sometimes', 'array'], + 'currency_code' => ['sometimes', 'string'] ]; if (!$this->strict) { - $rules['source_id'] = ['sometimes', 'string']; - $rules['cancelled_at'] = ['sometimes', 'nullable', 'date']; - $rules['completed_at'] = ['sometimes', 'nullable', 'date']; - $rules['created_at'] = ['sometimes', 'date']; + $rules['source_id'] = ['sometimes', 'string']; + $rules['cancelled_at'] = ['sometimes', 'nullable', 'date']; + $rules['completed_at'] = ['sometimes', 'nullable', 'date']; + $rules['created_at'] = ['sometimes', 'date']; + $rules['fetched_at'] = ['sometimes', 'date']; } return $rules; } - public function action(Customer $customer, PaymentAccount $paymentAccount, array $modelData, int $hydratorsDelay = 0, bool $strict = true): Payment + /** + * @throws \Throwable + */ + public function action(Customer $customer, PaymentAccount $paymentAccount, array $modelData, int $hydratorsDelay = 0, bool $strict = true, $audit = true): Payment { + if (!$audit) { + Customer::disableAuditing(); + } $this->asAction = true; $this->strict = $strict; $this->hydratorsDelay = $hydratorsDelay; @@ -132,6 +147,9 @@ public function action(Customer $customer, PaymentAccount $paymentAccount, array return $this->handle($customer, $paymentAccount, $this->validatedData); } + /** + * @throws \Throwable + */ public function asController(Customer $customer, PaymentAccount $paymentAccount, ActionRequest $request, int $hydratorsDelay = 0): void { $this->hydratorsDelay = $hydratorsDelay; diff --git a/app/Actions/Accounting/Payment/UpdatePayment.php b/app/Actions/Accounting/Payment/UpdatePayment.php index dab67b8d2a..6bb6d7fdbd 100644 --- a/app/Actions/Accounting/Payment/UpdatePayment.php +++ b/app/Actions/Accounting/Payment/UpdatePayment.php @@ -21,7 +21,8 @@ class UpdatePayment extends OrgAction public function handle(Payment $payment, array $modelData): Payment { $payment = $this->update($payment, $modelData, ['data']); - PaymentHydrateUniversalSearch::dispatch($payment)->delay($this->hydratorsDelay); + + PaymentHydrateUniversalSearch::dispatch($payment); return $payment; } @@ -32,21 +33,31 @@ public function authorize(ActionRequest $request): bool return true; } - return $request->user()->hasPermissionTo("accounting.edit"); + return $request->user()->hasPermissionTo("accounting.{$this->organisation->id}.edit"); } public function rules(): array { - return [ + $rules = [ 'reference' => ['sometimes', 'nullable', 'max:255', 'string'], 'amount' => ['sometimes', 'decimal:0,2'], 'org_amount' => ['sometimes', 'numeric'], 'group_amount' => ['sometimes', 'numeric'], ]; + + if (!$this->strict) { + $rules['last_fetched_at'] = ['sometimes', 'date']; + } + + return $rules; } - public function action(Payment $payment, array $modelData, int $hydratorsDelay = 0): Payment + public function action(Payment $payment, array $modelData, int $hydratorsDelay = 0, bool $strict = true, bool $audit = true): Payment { + $this->strict = $strict; + if (!$audit) { + Payment::disableAuditing(); + } $this->asAction = true; $this->hydratorsDelay = $hydratorsDelay; $this->initialisationFromShop($payment->shop, $modelData); diff --git a/app/Actions/Transfers/Aurora/FetchAuroraPayments.php b/app/Actions/Transfers/Aurora/FetchAuroraPayments.php index e0b93058fd..2cca48a563 100644 --- a/app/Actions/Transfers/Aurora/FetchAuroraPayments.php +++ b/app/Actions/Transfers/Aurora/FetchAuroraPayments.php @@ -13,7 +13,9 @@ use App\Transfers\SourceOrganisationService; use Exception; use Illuminate\Database\Query\Builder; +use Illuminate\Support\Arr; use Illuminate\Support\Facades\DB; +use Throwable; class FetchAuroraPayments extends FetchAuroraAction { @@ -28,9 +30,12 @@ public function handle(SourceOrganisationService $organisationSource, int $organ $payment = UpdatePayment::make()->action( payment: $payment, modelData: $paymentData['payment'], - hydratorsDelay: $this->hydratorsDelay + hydratorsDelay: 60, + strict: false, + audit: false ); - $this->markAuroraModel($payment); + $this->recordChange($organisationSource, $payment->wasChanged()); + } catch (Exception $e) { $this->recordError($organisationSource, $e, $paymentData['payment'], 'Payment', 'update'); @@ -42,11 +47,26 @@ public function handle(SourceOrganisationService $organisationSource, int $organ customer: $paymentData['customer'], paymentAccount: $paymentData['paymentAccount'], modelData: $paymentData['payment'], - hydratorsDelay: $this->hydratorsDelay, - strict: false + hydratorsDelay: 60, + strict: false, + audit: false ); - $this->markAuroraModel($payment); - } catch (Exception $e) { + + + Payment::enableAuditing(); + $this->saveMigrationHistory( + $payment, + Arr::except($paymentData['payment'], ['fetched_at', 'last_fetched_at', 'source_id']) + ); + + $this->recordNew($organisationSource); + + $sourceData = explode(':', $payment->source_id); + DB::connection('aurora')->table('Payment Dimension') + ->where('Payment Key', $sourceData[1]) + ->update(['aiku_id' => $payment->id]); + + } catch (Exception|Throwable $e) { $this->recordError($organisationSource, $e, $paymentData['payment'], 'Payment', 'store'); return null; @@ -60,13 +80,7 @@ public function handle(SourceOrganisationService $organisationSource, int $organ return null; } - public function markAuroraModel(Payment $payment): void - { - $sourceData = explode(':', $payment->source_id); - DB::connection('aurora')->table('Payment Dimension') - ->where('Payment Key', $sourceData[1]) - ->update(['aiku_id' => $payment->id]); - } + public function getModelsQuery(): Builder { diff --git a/app/Transfers/Aurora/FetchAuroraPayment.php b/app/Transfers/Aurora/FetchAuroraPayment.php index 7460173b68..bd477de23b 100644 --- a/app/Transfers/Aurora/FetchAuroraPayment.php +++ b/app/Transfers/Aurora/FetchAuroraPayment.php @@ -17,7 +17,6 @@ class FetchAuroraPayment extends FetchAurora { protected function parseModel(): void { - $data = []; if ($this->auroraModelData->{'Payment Currency Exchange Rate'} and @@ -34,8 +33,7 @@ protected function parseModel(): void dd('Error Payment Account not found'); } - $this->parsedData['customer'] = $this->parseCustomer($this->organisation->id.':'.$this->auroraModelData->{'Payment Customer Key'}); - + $this->parsedData['customer'] = $this->parseCustomer($this->organisation->id.':'.$this->auroraModelData->{'Payment Customer Key'}); $state = Str::lower($this->auroraModelData->{'Payment Transaction Status'}); @@ -72,31 +70,27 @@ protected function parseModel(): void $lastUpdatedDate = $createdAt; } - $this->parsedData['payment'] = [ - 'reference' => $this->auroraModelData->{'Payment Transaction ID'}, - 'amount' => $this->auroraModelData->{'Payment Transaction Amount'}, - 'org_amount' => $this->auroraModelData->{'Payment Transaction Amount'} * GetHistoricCurrencyExchange::run($shop->currency, $shop->organisation->currency, $createdAt), - 'group_amount' => $this->auroraModelData->{'Payment Transaction Amount'} * GetHistoricCurrencyExchange::run($shop->currency, $shop->group->currency, $createdAt), - 'data' => $data, - 'currency_id' => $this->parseCurrencyID($this->auroraModelData->{'Payment Currency Code'}), - - 'date' => $lastUpdatedDate, - 'created_at' => $createdAt, - 'completed_at' => $this->parseDatetime($this->auroraModelData->{'Payment Completed Date'}), - - 'cancelled_at' => $this->parseDatetime($this->auroraModelData->{'Payment Cancelled Date'}), - - 'state' => $state, - 'status' => $status, - 'source_id' => $this->organisation->id.':'.$this->auroraModelData->{'Payment Key'}, - + 'reference' => $this->auroraModelData->{'Payment Transaction ID'}, + 'amount' => $this->auroraModelData->{'Payment Transaction Amount'}, + 'org_amount' => $this->auroraModelData->{'Payment Transaction Amount'} * GetHistoricCurrencyExchange::run($shop->currency, $shop->organisation->currency, $createdAt), + 'group_amount' => $this->auroraModelData->{'Payment Transaction Amount'} * GetHistoricCurrencyExchange::run($shop->currency, $shop->group->currency, $createdAt), + 'data' => $data, + 'currency_id' => $this->parseCurrencyID($this->auroraModelData->{'Payment Currency Code'}), + 'date' => $lastUpdatedDate, + 'created_at' => $createdAt, + 'completed_at' => $this->parseDatetime($this->auroraModelData->{'Payment Completed Date'}), + 'cancelled_at' => $this->parseDatetime($this->auroraModelData->{'Payment Cancelled Date'}), + 'state' => $state, + 'status' => $status, + 'source_id' => $this->organisation->id.':'.$this->auroraModelData->{'Payment Key'}, + 'fetched_at' => now(), + 'last_fetched_at' => now(), ]; } - protected function fetchData($id): object|null { return DB::connection('aurora') diff --git a/database/migrations/2023_02_26_200658_create_payments_table.php b/database/migrations/2023_02_26_200658_create_payments_table.php index 613f155555..8b34ffbe41 100644 --- a/database/migrations/2023_02_26_200658_create_payments_table.php +++ b/database/migrations/2023_02_26_200658_create_payments_table.php @@ -43,9 +43,9 @@ public function up(): void $table->dateTimeTz('date')->index()->comment('Most relevant date at current state'); $table->dateTimeTz('completed_at')->nullable(); $table->dateTimeTz('cancelled_at')->nullable(); + $table->timestampstz(); $table->datetimeTz('fetched_at')->nullable(); $table->datetimeTz('last_fetched_at')->nullable(); - $table->timestampstz(); $table->softDeletesTz(); $table->boolean('with_refund')->default(false); $table->string('source_id')->index()->nullable();