From d6a4f4b4ca0e3d96ddd55e038aac3212ab38d955 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Wed, 24 Jul 2024 12:27:09 +1000 Subject: [PATCH 01/12] Improvements for task imports --- app/Console/Commands/BackupUpdate.php | 1 - app/Export/CSV/BaseExport.php | 1 + app/Export/CSV/InvoiceExport.php | 6 +- app/Export/Decorators/InvoiceDecorator.php | 1 + app/Http/Controllers/ChartController.php | 2 +- .../ValidationRules/Account/BlackListRule.php | 3 +- app/Import/Providers/BaseImport.php | 2 + .../Transformer/Csv/TaskTransformer.php | 6 +- app/Models/Gateway.php | 30 ++--- app/Models/Project.php | 2 +- app/PaymentDrivers/Forte/ACH.php | 5 +- app/PaymentDrivers/Forte/CreditCard.php | 4 +- .../Stripe/Jobs/ChargeRefunded.php | 70 ++++++++---- app/PaymentDrivers/StripePaymentDriver.php | 104 ++++++++++-------- app/Services/Payment/RefundPayment.php | 10 +- app/Services/Template/TemplateService.php | 3 +- composer.lock | 16 +-- lang/en/texts.php | 2 +- routes/api.php | 1 + 19 files changed, 155 insertions(+), 114 deletions(-) diff --git a/app/Console/Commands/BackupUpdate.php b/app/Console/Commands/BackupUpdate.php index 33b421ea38..b2a16bff25 100644 --- a/app/Console/Commands/BackupUpdate.php +++ b/app/Console/Commands/BackupUpdate.php @@ -177,7 +177,6 @@ class BackupUpdate extends Command $doc_bin = $document->getFile(); } catch(\Exception $e) { nlog("Exception:: BackupUpdate::" . $e->getMessage()); - nlog($e->getMessage()); } if ($doc_bin) { diff --git a/app/Export/CSV/BaseExport.php b/app/Export/CSV/BaseExport.php index 374e7783c3..9dbf186b90 100644 --- a/app/Export/CSV/BaseExport.php +++ b/app/Export/CSV/BaseExport.php @@ -172,6 +172,7 @@ class BaseExport 'tax_rate3' => 'invoice.tax_rate3', 'recurring_invoice' => 'invoice.recurring_id', 'auto_bill' => 'invoice.auto_bill_enabled', + 'project' => 'invoice.project', ]; protected array $recurring_invoice_report_keys = [ diff --git a/app/Export/CSV/InvoiceExport.php b/app/Export/CSV/InvoiceExport.php index d87c49ff94..39ece67a28 100644 --- a/app/Export/CSV/InvoiceExport.php +++ b/app/Export/CSV/InvoiceExport.php @@ -153,9 +153,9 @@ class InvoiceExport extends BaseExport private function decorateAdvancedFields(Invoice $invoice, array $entity): array { - // if (in_array('invoice.status', $this->input['report_keys'])) { - // $entity['invoice.status'] = $invoice->stringStatus($invoice->status_id); - // } + if (in_array('invoice.project', $this->input['report_keys'])) { + $entity['invoice.project'] = $invoice->project ? $invoice->project->name : ''; + } if (in_array('invoice.recurring_id', $this->input['report_keys'])) { $entity['invoice.recurring_id'] = $invoice->recurring_invoice->number ?? ''; diff --git a/app/Export/Decorators/InvoiceDecorator.php b/app/Export/Decorators/InvoiceDecorator.php index 35985decba..b6579b7f54 100644 --- a/app/Export/Decorators/InvoiceDecorator.php +++ b/app/Export/Decorators/InvoiceDecorator.php @@ -92,6 +92,7 @@ class InvoiceDecorator extends Decorator implements DecoratorInterface { return $invoice->recurring_invoice ? $invoice->recurring_invoice->number : ''; } + public function auto_bill_enabled(Invoice $invoice) { return $invoice->auto_bill_enabled ? ctrans('texts.yes') : ctrans('texts.no'); diff --git a/app/Http/Controllers/ChartController.php b/app/Http/Controllers/ChartController.php index 394e762d97..07fc7fc238 100644 --- a/app/Http/Controllers/ChartController.php +++ b/app/Http/Controllers/ChartController.php @@ -66,7 +66,7 @@ class ChartController extends BaseController return response()->json($cs->chart_summary($request->input('start_date'), $request->input('end_date')), 200); } - public function calculatedField(ShowCalculatedFieldRequest $request) + public function calculatedFields(ShowCalculatedFieldRequest $request) { /** @var \App\Models\User auth()->user() */ diff --git a/app/Http/ValidationRules/Account/BlackListRule.php b/app/Http/ValidationRules/Account/BlackListRule.php index 1d65de052f..0d5e5a13a8 100644 --- a/app/Http/ValidationRules/Account/BlackListRule.php +++ b/app/Http/ValidationRules/Account/BlackListRule.php @@ -19,8 +19,9 @@ use Illuminate\Contracts\Validation\ValidationRule; */ class BlackListRule implements ValidationRule { - /** Bad domains +/- dispoable email domains */ + /** Bad domains +/- disposable email domains */ private array $blacklist = [ + 'padvn.com', 'anonaddy.me', 'nqmo.com', 'wireconnected.com', diff --git a/app/Import/Providers/BaseImport.php b/app/Import/Providers/BaseImport.php index b2897352cc..0366970037 100644 --- a/app/Import/Providers/BaseImport.php +++ b/app/Import/Providers/BaseImport.php @@ -473,6 +473,8 @@ class BaseImport $tasks = $this->groupTasks($tasks, $task_number_key); + nlog($tasks); + foreach ($tasks as $raw_task) { $task_data = []; diff --git a/app/Import/Transformer/Csv/TaskTransformer.php b/app/Import/Transformer/Csv/TaskTransformer.php index edd8737131..54636349f0 100644 --- a/app/Import/Transformer/Csv/TaskTransformer.php +++ b/app/Import/Transformer/Csv/TaskTransformer.php @@ -46,6 +46,7 @@ class TaskTransformer extends BaseTransformer 'company_id' => $this->company->id, 'number' => $this->getString($task_data, 'task.number'), 'user_id' => $this->getString($task_data, 'task.user_id'), + 'rate' => $this->getFloat($task_data, 'task.rate'), 'client_id' => $clientId, 'project_id' => $this->getProjectId($projectId, $clientId), 'description' => $this->getString($task_data, 'task.description'), @@ -87,8 +88,7 @@ class TaskTransformer extends BaseTransformer $is_billable = true; } - if(isset($item['task.start_date']) && - isset($item['task.end_date'])) { + if(isset($item['task.start_date'])) { $start_date = $this->resolveStartDate($item); $end_date = $this->resolveEndDate($item); } elseif(isset($item['task.duration'])) { @@ -136,7 +136,7 @@ class TaskTransformer extends BaseTransformer private function resolveEndDate($item) { - $stub_end_date = $item['task.end_date']; + $stub_end_date = isset($item['task.end_date']) ? $item['task.end_date'] : $item['task.start_date']; $stub_end_date .= isset($item['task.end_time']) ? " ".$item['task.end_time'] : ''; try { diff --git a/app/Models/Gateway.php b/app/Models/Gateway.php index 46ae2abc56..2fcdfe7ee4 100644 --- a/app/Models/Gateway.php +++ b/app/Models/Gateway.php @@ -139,23 +139,23 @@ class Gateway extends StaticModel case 20: case 56: return [ - GatewayType::CREDIT_CARD => ['refund' => true, 'token_billing' => true, 'webhooks' => ['payment_intent.succeeded', 'payment_intent.payment_failed']], - GatewayType::BANK_TRANSFER => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded', 'customer.source.updated', 'payment_intent.processing', 'payment_intent.payment_failed', 'charge.failed']], - GatewayType::DIRECT_DEBIT => ['refund' => false, 'token_billing' => false, 'webhooks' => ['payment_intent.processing', 'payment_intent.succeeded', 'payment_intent.partially_funded', 'payment_intent.payment_failed']], + GatewayType::CREDIT_CARD => ['refund' => true, 'token_billing' => true, 'webhooks' => ['payment_intent.succeeded', 'charge.refunded', 'payment_intent.payment_failed']], + GatewayType::BANK_TRANSFER => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.refunded','charge.succeeded', 'customer.source.updated', 'payment_intent.processing', 'payment_intent.payment_failed', 'charge.failed']], + GatewayType::DIRECT_DEBIT => ['refund' => false, 'token_billing' => false, 'webhooks' => ['payment_intent.processing', 'charge.refunded', 'payment_intent.succeeded', 'payment_intent.partially_funded', 'payment_intent.payment_failed']], GatewayType::ALIPAY => ['refund' => false, 'token_billing' => false], GatewayType::APPLE_PAY => ['refund' => false, 'token_billing' => false], - GatewayType::BACS => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded', 'charge.failed', 'payment_intent.processing', 'payment_intent.succeeded', 'mandate.updated', 'payment_intent.payment_failed']], - GatewayType::SOFORT => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded', 'charge.failed', 'payment_intent.succeeded', 'payment_intent.payment_failed']], - GatewayType::KLARNA => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded', 'charge.failed', 'payment_intent.succeeded', 'payment_intent.payment_failed']], - GatewayType::SEPA => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded', 'charge.failed', 'payment_intent.succeeded', 'payment_intent.payment_failed']], - GatewayType::PRZELEWY24 => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded', 'charge.failed', 'payment_intent.succeeded', 'payment_intent.payment_failed']], - GatewayType::GIROPAY => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded', 'charge.failed', 'payment_intent.succeeded', 'payment_intent.payment_failed']], - GatewayType::EPS => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded', 'charge.failed', 'payment_intent.succeeded', 'payment_intent.payment_failed']], - GatewayType::BANCONTACT => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded', 'charge.failed', 'payment_intent.succeeded', 'payment_intent.payment_failed']], - GatewayType::BECS => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded', 'charge.failed', 'payment_intent.succeeded', 'payment_intent.payment_failed']], - GatewayType::IDEAL => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded', 'charge.failed', 'payment_intent.succeeded', 'payment_intent.payment_failed']], - GatewayType::ACSS => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded', 'charge.failed', 'payment_intent.succeeded', 'payment_intent.payment_failed']], - GatewayType::FPX => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded', 'charge.failed',]], + GatewayType::BACS => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded', 'charge.refunded', 'charge.failed', 'payment_intent.processing', 'payment_intent.succeeded', 'mandate.updated', 'payment_intent.payment_failed']], + GatewayType::SOFORT => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded', 'charge.refunded', 'charge.failed', 'payment_intent.succeeded', 'payment_intent.payment_failed']], + GatewayType::KLARNA => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded', 'charge.refunded', 'charge.failed', 'payment_intent.succeeded', 'payment_intent.payment_failed']], + GatewayType::SEPA => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded', 'charge.refunded', 'charge.failed', 'payment_intent.succeeded', 'payment_intent.payment_failed']], + GatewayType::PRZELEWY24 => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded', 'charge.refunded', 'charge.failed', 'payment_intent.succeeded', 'payment_intent.payment_failed']], + GatewayType::GIROPAY => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded', 'charge.refunded', 'charge.failed', 'payment_intent.succeeded', 'payment_intent.payment_failed']], + GatewayType::EPS => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded', 'charge.refunded', 'charge.failed', 'payment_intent.succeeded', 'payment_intent.payment_failed']], + GatewayType::BANCONTACT => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded', 'charge.refunded', 'charge.failed', 'payment_intent.succeeded', 'payment_intent.payment_failed']], + GatewayType::BECS => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded', 'charge.refunded', 'charge.failed', 'payment_intent.succeeded', 'payment_intent.payment_failed']], + GatewayType::IDEAL => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded', 'charge.refunded', 'charge.failed', 'payment_intent.succeeded', 'payment_intent.payment_failed']], + GatewayType::ACSS => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded', 'charge.refunded', 'charge.failed', 'payment_intent.succeeded', 'payment_intent.payment_failed']], + GatewayType::FPX => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded', 'charge.refunded', 'charge.failed',]], ]; case 39: return [GatewayType::CREDIT_CARD => ['refund' => true, 'token_billing' => true, 'webhooks' => [' ']]]; //Checkout diff --git a/app/Models/Project.php b/app/Models/Project.php index d341a3fb85..c786dcec08 100644 --- a/app/Models/Project.php +++ b/app/Models/Project.php @@ -129,7 +129,7 @@ class Project extends BaseModel public function invoices(): HasMany { - return $this->hasMany(Invoice::class); + return $this->hasMany(Invoice::class)->withTrashed(); } public function quotes(): HasMany diff --git a/app/PaymentDrivers/Forte/ACH.php b/app/PaymentDrivers/Forte/ACH.php index aef043d50a..8ea313e772 100644 --- a/app/PaymentDrivers/Forte/ACH.php +++ b/app/PaymentDrivers/Forte/ACH.php @@ -170,6 +170,9 @@ class ACH ]; $payment = $this->forte->createPayment($data, Payment::STATUS_COMPLETED); - return redirect('client/invoices')->withSuccess('Invoice paid.'); + // return redirect('client/invoices')->withSuccess('Invoice paid.'); + + return redirect()->route('client.payments.show', ['payment' => $payment->hashed_id]); + } } diff --git a/app/PaymentDrivers/Forte/CreditCard.php b/app/PaymentDrivers/Forte/CreditCard.php index 67c4041901..5a317f4ec8 100644 --- a/app/PaymentDrivers/Forte/CreditCard.php +++ b/app/PaymentDrivers/Forte/CreditCard.php @@ -187,6 +187,8 @@ class CreditCard 'gateway_type_id' => GatewayType::CREDIT_CARD, ]; $payment = $this->forte->createPayment($data, Payment::STATUS_COMPLETED); - return redirect('client/invoices')->withSuccess('Invoice paid.'); + // return redirect('client/invoices')->withSuccess('Invoice paid.'); + return redirect()->route('client.payments.show', ['payment' => $payment->hashed_id]); + } } diff --git a/app/PaymentDrivers/Stripe/Jobs/ChargeRefunded.php b/app/PaymentDrivers/Stripe/Jobs/ChargeRefunded.php index 36f766dd73..405f696742 100644 --- a/app/PaymentDrivers/Stripe/Jobs/ChargeRefunded.php +++ b/app/PaymentDrivers/Stripe/Jobs/ChargeRefunded.php @@ -11,18 +11,22 @@ namespace App\PaymentDrivers\Stripe\Jobs; -use App\Libraries\MultiDB; use App\Models\Company; -use App\Models\CompanyGateway; use App\Models\Payment; +use App\Libraries\MultiDB; use App\Models\PaymentHash; -use App\PaymentDrivers\Stripe\Utilities; +use App\Services\Email\Email; use Illuminate\Bus\Queueable; +use App\Models\CompanyGateway; +use App\Services\Email\EmailObject; +use Illuminate\Support\Facades\App; +use Illuminate\Mail\Mailables\Address; +use Illuminate\Queue\SerializesModels; +use App\PaymentDrivers\Stripe\Utilities; +use Illuminate\Queue\InteractsWithQueue; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; -use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\Middleware\WithoutOverlapping; -use Illuminate\Queue\SerializesModels; class ChargeRefunded implements ShouldQueue { @@ -36,19 +40,10 @@ class ChargeRefunded implements ShouldQueue public $deleteWhenMissingModels = true; - public $stripe_request; - - public $company_key; - - private $company_gateway_id; - public $payment_completed = false; - public function __construct($stripe_request, $company_key, $company_gateway_id) + public function __construct(public array $stripe_request, private string $company_key) { - $this->stripe_request = $stripe_request; - $this->company_key = $company_key; - $this->company_gateway_id = $company_gateway_id; } public function handle() @@ -64,8 +59,8 @@ class ChargeRefunded implements ShouldQueue $payment_hash_key = $source['metadata']['payment_hash'] ?? null; - $company_gateway = CompanyGateway::query()->find($this->company_gateway_id); $payment_hash = PaymentHash::query()->where('hash', $payment_hash_key)->first(); + $company_gateway = $payment_hash->payment->company_gateway; $stripe_driver = $company_gateway->driver()->init(); @@ -79,7 +74,7 @@ class ChargeRefunded implements ShouldQueue ->first(); //don't touch if already refunded - if(!$payment || in_array($payment->status_id, [Payment::STATUS_PARTIALLY_REFUNDED, Payment::STATUS_REFUNDED])) { + if(!$payment || $payment->status_id == Payment::STATUS_REFUNDED || $payment->is_deleted){ return; } @@ -94,8 +89,19 @@ class ChargeRefunded implements ShouldQueue return; } - if($payment->status_id == Payment::STATUS_COMPLETED) { + usleep(rand(200000,300000)); + $payment = $payment->fresh(); + if($payment->status_id == Payment::STATUS_PARTIALLY_REFUNDED){ + //determine the delta in the refunded amount - how much has already been refunded and only apply the delta. + + if(floatval($payment->refunded) >= floatval($amount_refunded)) + return; + + $amount_refunded -= $payment->refunded; + + } + $invoice_collection = $payment->paymentables ->where('paymentable_type', 'invoices') ->map(function ($pivot) { @@ -117,9 +123,24 @@ class ChargeRefunded implements ShouldQueue ]; }); - } elseif($invoice_collection->sum('amount') != $amount_refunded) { - //too many edges cases at this point, return early + } + elseif($invoice_collection->sum('amount') != $amount_refunded) { + + $refund_text = "A partial refund was processed for Payment #{$payment_hash->payment->number}.

This payment is associated with multiple invoices, so you will need to manually apply the refund to the correct invoice/s."; + + App::setLocale($payment_hash->payment->company->getLocale()); + + $mo = new EmailObject(); + $mo->subject = "Refund processed in Stripe for multiple invoices, action required."; + $mo->body = $refund_text; + $mo->text_body = $refund_text; + $mo->company_key = $payment_hash->payment->company->company_key; + $mo->html_template = 'email.template.generic'; + $mo->to = [new Address($payment_hash->payment->company->owner()->email, $payment_hash->payment->company->owner()->present()->name())]; + + Email::dispatch($mo, $payment_hash->payment->company); return; + } $invoices = $invoice_collection->toArray(); @@ -131,20 +152,21 @@ class ChargeRefunded implements ShouldQueue 'date' => now()->format('Y-m-d'), 'gateway_refund' => false, 'email_receipt' => false, + 'via_webhook' => true, ]; nlog($data); $payment->refund($data); - $payment->private_notes .= 'Refunded via Stripe'; - return; - } + $payment->private_notes .= 'Refunded via Stripe '; + + $payment->saveQuietly(); } public function middleware() { - return [new WithoutOverlapping($this->company_gateway_id)]; + return [new WithoutOverlapping($this->company_key)]; } } diff --git a/app/PaymentDrivers/StripePaymentDriver.php b/app/PaymentDrivers/StripePaymentDriver.php index 69920e31e6..d91e39fc37 100644 --- a/app/PaymentDrivers/StripePaymentDriver.php +++ b/app/PaymentDrivers/StripePaymentDriver.php @@ -12,54 +12,55 @@ namespace App\PaymentDrivers; -use App\Exceptions\PaymentFailed; -use App\Exceptions\StripeConnectFailure; -use App\Http\Requests\Payments\PaymentWebhookRequest; -use App\Http\Requests\Request; -use App\Jobs\Util\SystemLogger; -use App\Models\Client; -use App\Models\ClientGatewayToken; -use App\Models\GatewayType; -use App\Models\Payment; -use App\Models\PaymentHash; -use App\Models\SystemLog; -use App\PaymentDrivers\Stripe\ACH; -use App\PaymentDrivers\Stripe\ACSS; -use App\PaymentDrivers\Stripe\Alipay; -use App\PaymentDrivers\Stripe\BACS; -use App\PaymentDrivers\Stripe\Bancontact; -use App\PaymentDrivers\Stripe\BankTransfer; -use App\PaymentDrivers\Stripe\BECS; -use App\PaymentDrivers\Stripe\BrowserPay; -use App\PaymentDrivers\Stripe\Charge; -use App\PaymentDrivers\Stripe\Connect\Verify; -use App\PaymentDrivers\Stripe\CreditCard; -use App\PaymentDrivers\Stripe\EPS; -use App\PaymentDrivers\Stripe\FPX; -use App\PaymentDrivers\Stripe\GIROPAY; -use App\PaymentDrivers\Stripe\iDeal; -use App\PaymentDrivers\Stripe\ImportCustomers; -use App\PaymentDrivers\Stripe\Jobs\PaymentIntentFailureWebhook; -use App\PaymentDrivers\Stripe\Jobs\PaymentIntentPartiallyFundedWebhook; -use App\PaymentDrivers\Stripe\Jobs\PaymentIntentProcessingWebhook; -use App\PaymentDrivers\Stripe\Jobs\PaymentIntentWebhook; -use App\PaymentDrivers\Stripe\Klarna; -use App\PaymentDrivers\Stripe\PRZELEWY24; -use App\PaymentDrivers\Stripe\SEPA; -use App\PaymentDrivers\Stripe\SOFORT; -use App\PaymentDrivers\Stripe\Utilities; -use App\Utils\Traits\MakesHash; use Exception; -use Illuminate\Http\RedirectResponse; -use Laracasts\Presenter\Exceptions\PresenterException; +use Stripe\Stripe; use Stripe\Account; use Stripe\Customer; -use Stripe\Exception\ApiErrorException; +use App\Models\Client; +use App\Models\Payment; +use Stripe\SetupIntent; +use Stripe\StripeClient; +use App\Models\SystemLog; use Stripe\PaymentIntent; use Stripe\PaymentMethod; -use Stripe\SetupIntent; -use Stripe\Stripe; -use Stripe\StripeClient; +use App\Models\GatewayType; +use App\Models\PaymentHash; +use App\Http\Requests\Request; +use App\Jobs\Util\SystemLogger; +use App\Utils\Traits\MakesHash; +use App\Exceptions\PaymentFailed; +use App\Models\ClientGatewayToken; +use App\PaymentDrivers\Stripe\ACH; +use App\PaymentDrivers\Stripe\EPS; +use App\PaymentDrivers\Stripe\FPX; +use App\PaymentDrivers\Stripe\ACSS; +use App\PaymentDrivers\Stripe\BACS; +use App\PaymentDrivers\Stripe\BECS; +use App\PaymentDrivers\Stripe\SEPA; +use App\PaymentDrivers\Stripe\iDeal; +use App\PaymentDrivers\Stripe\Alipay; +use App\PaymentDrivers\Stripe\Charge; +use App\PaymentDrivers\Stripe\Klarna; +use App\PaymentDrivers\Stripe\SOFORT; +use Illuminate\Http\RedirectResponse; +use App\PaymentDrivers\Stripe\GIROPAY; +use Stripe\Exception\ApiErrorException; +use App\Exceptions\StripeConnectFailure; +use App\PaymentDrivers\Stripe\Utilities; +use App\PaymentDrivers\Stripe\Bancontact; +use App\PaymentDrivers\Stripe\BrowserPay; +use App\PaymentDrivers\Stripe\CreditCard; +use App\PaymentDrivers\Stripe\PRZELEWY24; +use App\PaymentDrivers\Stripe\BankTransfer; +use App\PaymentDrivers\Stripe\Connect\Verify; +use App\PaymentDrivers\Stripe\ImportCustomers; +use App\PaymentDrivers\Stripe\Jobs\ChargeRefunded; +use App\Http\Requests\Payments\PaymentWebhookRequest; +use Laracasts\Presenter\Exceptions\PresenterException; +use App\PaymentDrivers\Stripe\Jobs\PaymentIntentWebhook; +use App\PaymentDrivers\Stripe\Jobs\PaymentIntentFailureWebhook; +use App\PaymentDrivers\Stripe\Jobs\PaymentIntentProcessingWebhook; +use App\PaymentDrivers\Stripe\Jobs\PaymentIntentPartiallyFundedWebhook; class StripePaymentDriver extends BaseDriver { @@ -670,31 +671,39 @@ class StripePaymentDriver extends BaseDriver public function processWebhookRequest(PaymentWebhookRequest $request) { + nlog($request->all()); + if ($request->type === 'customer.source.updated') { $ach = new ACH($this); $ach->updateBankAccount($request->all()); } if ($request->type === 'payment_intent.processing') { - PaymentIntentProcessingWebhook::dispatch($request->data, $request->company_key, $this->company_gateway->id)->delay(now()->addSeconds(rand(10, 12))); + PaymentIntentProcessingWebhook::dispatch($request->data, $request->company_key, $this->company_gateway->id)->delay(now()->addSeconds(5)); return response()->json([], 200); } //payment_intent.succeeded - this will confirm or cancel the payment if ($request->type === 'payment_intent.succeeded') { - PaymentIntentWebhook::dispatch($request->data, $request->company_key, $this->company_gateway->id)->delay(now()->addSeconds(rand(10, 15))); + PaymentIntentWebhook::dispatch($request->data, $request->company_key, $this->company_gateway->id)->delay(now()->addSeconds(5)); return response()->json([], 200); } if ($request->type === 'payment_intent.partially_funded') { - PaymentIntentPartiallyFundedWebhook::dispatch($request->data, $request->company_key, $this->company_gateway->id)->delay(now()->addSeconds(rand(10, 15))); + PaymentIntentPartiallyFundedWebhook::dispatch($request->data, $request->company_key, $this->company_gateway->id)->delay(now()->addSeconds(5)); return response()->json([], 200); } if (in_array($request->type, ['payment_intent.payment_failed', 'charge.failed'])) { - PaymentIntentFailureWebhook::dispatch($request->data, $request->company_key, $this->company_gateway->id)->delay(now()->addSeconds(rand(5, 10))); + PaymentIntentFailureWebhook::dispatch($request->data, $request->company_key, $this->company_gateway->id)->delay(now()->addSeconds(2)); + + return response()->json([], 200); + } + + if ($request->type === 'charge.refunded' && $request->data['object']['status'] == 'succeeded') { + ChargeRefunded::dispatch($request->data, $request->company_key)->delay(now()->addSeconds(5)); return response()->json([], 200); } @@ -702,7 +711,6 @@ class StripePaymentDriver extends BaseDriver if ($request->type === 'charge.succeeded') { foreach ($request->data as $transaction) { - $payment = Payment::query() ->where('company_id', $this->company_gateway->company_id) ->where(function ($query) use ($transaction) { diff --git a/app/Services/Payment/RefundPayment.php b/app/Services/Payment/RefundPayment.php index a17baa6705..ed7b51deed 100644 --- a/app/Services/Payment/RefundPayment.php +++ b/app/Services/Payment/RefundPayment.php @@ -44,7 +44,6 @@ class RefundPayment ->setStatus() //sets status of payment ->updatePaymentables() //update the paymentable items ->adjustInvoices() - ->finalize() ->save(); if (array_key_exists('email_receipt', $this->refund_data) && $this->refund_data['email_receipt'] == 'true') { @@ -52,10 +51,11 @@ class RefundPayment EmailRefundPayment::dispatch($this->payment, $this->payment->company, $contact); } - $notes = ctrans('texts.refunded') . " : {$this->total_refund} - " . ctrans('texts.gateway_refund') . " : "; - $notes .= $this->refund_data['gateway_refund'] !== false ? ctrans('texts.yes') : ctrans('texts.no'); - + $is_gateway_refund = ($this->refund_data['gateway_refund'] !== false || $this->refund_failed || (isset($this->refund_data['via_webhook']) && $this->refund_data['via_webhook'] !== false)) ? ctrans('texts.yes') : ctrans('texts.no'); + $notes = ctrans('texts.refunded') . " : {$this->total_refund} - " . ctrans('texts.gateway_refund') . " : " . $is_gateway_refund; + $this->createActivity($notes); + $this->finalize(); return $this->payment; } @@ -178,7 +178,7 @@ class RefundPayment */ private function setStatus() { - if ($this->total_refund == $this->payment->amount) { + if ($this->total_refund == $this->payment->amount || floatval($this->payment->amount) == floatval($this->payment->refunded)) { $this->payment->status_id = Payment::STATUS_REFUNDED; } else { $this->payment->status_id = Payment::STATUS_PARTIALLY_REFUNDED; diff --git a/app/Services/Template/TemplateService.php b/app/Services/Template/TemplateService.php index 5a033c2f53..13adb454d7 100644 --- a/app/Services/Template/TemplateService.php +++ b/app/Services/Template/TemplateService.php @@ -1023,7 +1023,8 @@ class TemplateService 'vat_number' => $project->client->vat_number ?? '', 'currency' => $project->client->currency()->code ?? 'USD', ] : [], - 'user' => $this->userInfo($project->user) + 'user' => $this->userInfo($project->user), + 'invoices' => $this->processInvoices($project->invoices) ]; } diff --git a/composer.lock b/composer.lock index 541f0c0452..4d331a5d00 100644 --- a/composer.lock +++ b/composer.lock @@ -5407,16 +5407,16 @@ }, { "name": "league/commonmark", - "version": "2.4.2", + "version": "2.5.0", "source": { "type": "git", "url": "https://github.com/thephpleague/commonmark.git", - "reference": "91c24291965bd6d7c46c46a12ba7492f83b1cadf" + "reference": "0026475f5c9a104410ae824cb5a4d63fa3bdb1df" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/91c24291965bd6d7c46c46a12ba7492f83b1cadf", - "reference": "91c24291965bd6d7c46c46a12ba7492f83b1cadf", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/0026475f5c9a104410ae824cb5a4d63fa3bdb1df", + "reference": "0026475f5c9a104410ae824cb5a4d63fa3bdb1df", "shasum": "" }, "require": { @@ -5429,8 +5429,8 @@ }, "require-dev": { "cebe/markdown": "^1.0", - "commonmark/cmark": "0.30.3", - "commonmark/commonmark.js": "0.30.0", + "commonmark/cmark": "0.31.0", + "commonmark/commonmark.js": "0.31.0", "composer/package-versions-deprecated": "^1.8", "embed/embed": "^4.4", "erusev/parsedown": "^1.0", @@ -5452,7 +5452,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.5-dev" + "dev-main": "2.6-dev" } }, "autoload": { @@ -5509,7 +5509,7 @@ "type": "tidelift" } ], - "time": "2024-02-02T11:59:32+00:00" + "time": "2024-07-22T18:18:14+00:00" }, { "name": "league/config", diff --git a/lang/en/texts.php b/lang/en/texts.php index e2bad2efda..f00d22cdcf 100644 --- a/lang/en/texts.php +++ b/lang/en/texts.php @@ -5124,7 +5124,7 @@ $lang = array( 'all_contacts' => 'All Contacts', 'insert_below' => 'Insert Below', 'nordigen_handler_subtitle' => 'Bank account authentication. Selecting your institution to complete the request with your account credentials.', - 'nordigen_handler_error_heading_unknown' => 'An error has occured', + 'nordigen_handler_error_heading_unknown' => 'An error has occurred', 'nordigen_handler_error_contents_unknown' => 'An unknown error has occurred! Reason:', 'nordigen_handler_error_heading_token_invalid' => 'Invalid Token', 'nordigen_handler_error_contents_token_invalid' => 'The provided token was invalid. Contact support for help, if this issue persists.', diff --git a/routes/api.php b/routes/api.php index 0b0ffa772b..2a5a2350f1 100644 --- a/routes/api.php +++ b/routes/api.php @@ -164,6 +164,7 @@ Route::group(['middleware' => ['throttle:api', 'api_db', 'token_auth', 'locale'] Route::post('charts/totals_v2', [ChartController::class, 'totalsV2'])->name('chart.totals_v2'); Route::post('charts/chart_summary_v2', [ChartController::class, 'chart_summaryV2'])->name('chart.chart_summary_v2'); + Route::post('charts/calculated_fields', [ChartController::class, 'calculatedFields'])->name('chart.calculated_fields'); Route::post('claim_license', [LicenseController::class, 'index'])->name('license.index'); From 210a25b9baae14a94a15c339d12a6d2edd03c5b1 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Wed, 24 Jul 2024 14:01:46 +1000 Subject: [PATCH 02/12] Improvements for Wave imports --- app/Http/Controllers/ImportController.php | 2 +- app/Import/Providers/BaseImport.php | 2 +- app/Import/Providers/Wave.php | 21 +++++++++++-------- .../Transformer/Wave/ExpenseTransformer.php | 14 ++++++++++--- 4 files changed, 25 insertions(+), 14 deletions(-) diff --git a/app/Http/Controllers/ImportController.php b/app/Http/Controllers/ImportController.php index 66eed43075..f0b26ad7d7 100644 --- a/app/Http/Controllers/ImportController.php +++ b/app/Http/Controllers/ImportController.php @@ -85,7 +85,7 @@ class ImportController extends Controller $contents = $this->convertEncoding($contents); // Store the csv in cache with an expiry of 10 minutes - Cache::put($hash.'-'.$entityType, base64_encode($contents), 600); + Cache::put($hash.'-'.$entityType, base64_encode($contents), 1200); // Parse CSV $csv_array = $this->getCsvData($contents); diff --git a/app/Import/Providers/BaseImport.php b/app/Import/Providers/BaseImport.php index 0366970037..339eabea1f 100644 --- a/app/Import/Providers/BaseImport.php +++ b/app/Import/Providers/BaseImport.php @@ -98,7 +98,7 @@ class BaseImport } /** @var string $base64_encoded_csv */ - $base64_encoded_csv = Cache::pull($this->hash.'-'.$entity_type); + $base64_encoded_csv = Cache::get($this->hash.'-'.$entity_type); if (empty($base64_encoded_csv)) { return null; diff --git a/app/Import/Providers/Wave.php b/app/Import/Providers/Wave.php index 89c3ef9931..1fbd58b0e0 100644 --- a/app/Import/Providers/Wave.php +++ b/app/Import/Providers/Wave.php @@ -172,7 +172,7 @@ class Wave extends BaseImport implements ImportInterface { $entity_type = 'expense'; - $data = $this->getCsvData($entity_type); + $data = $this->getCsvData('invoice'); if (!$data) { $this->entity_count['expense'] = 0; @@ -244,14 +244,17 @@ class Wave extends BaseImport implements ImportInterface if (empty($expense_data['vendor_id'])) { $vendor_data['user_id'] = $this->getUserIDForRecord($expense_data); - $vendor_repository->save( - ['name' => $raw_expense['Vendor Name']], - $vendor = VendorFactory::create( - $this->company->id, - $vendor_data['user_id'] - ) - ); - $expense_data['vendor_id'] = $vendor->id; + if(isset($raw_expense['Vendor Name']) || isset($raw_expense['Vendor'])) + { + $vendor_repository->save( + ['name' => isset($raw_expense['Vendor Name']) ? $raw_expense['Vendor Name'] : isset($raw_expense['Vendor'])], + $vendor = VendorFactory::create( + $this->company->id, + $vendor_data['user_id'] + ) + ); + $expense_data['vendor_id'] = $vendor->id; + } } $validator = Validator::make( diff --git a/app/Import/Transformer/Wave/ExpenseTransformer.php b/app/Import/Transformer/Wave/ExpenseTransformer.php index 8f37c94b78..afd282b80d 100644 --- a/app/Import/Transformer/Wave/ExpenseTransformer.php +++ b/app/Import/Transformer/Wave/ExpenseTransformer.php @@ -36,18 +36,26 @@ class ExpenseTransformer extends BaseTransformer $total_tax += floatval($record['Sales Tax Amount']); } - $tax_rate = round(($total_tax / $amount) * 100, 3); + $tax_rate = $total_tax > 0 ? round(($total_tax / $amount) * 100, 3) : 0; + + if(isset($data['Notes / Memo']) && strlen($data['Notes / Memo']) > 1) + $public_notes = $data['Notes / Memo']; + elseif (isset($data['Transaction Description']) && strlen($data['Transaction Description']) > 1) + $public_notes = $data['Transaction Description']; + else + $public_notes = ''; + $transformed = [ 'company_id' => $this->company->id, 'vendor_id' => $this->getVendorIdOrCreate($this->getString($data, 'Vendor')), 'number' => $this->getString($data, 'Bill Number'), - 'public_notes' => $this->getString($data, 'Notes / Memo'), + 'public_notes' => $public_notes, 'date' => $this->parseDate($data['Transaction Date Added']) ?: now()->format('Y-m-d'), //27-01-2022 'currency_id' => $this->company->settings->currency_id, 'category_id' => $this->getOrCreateExpenseCategry($data['Account Name']), 'amount' => $amount, - 'tax_name1' => $data['Sales Tax Name'], + 'tax_name1' => isset($data['Sales Tax Name']) ? $data['Sales Tax Name'] : '', 'tax_rate1' => $tax_rate, ]; From 665398006710df814f6903764df263f2b54f5eb8 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Wed, 24 Jul 2024 14:13:10 +1000 Subject: [PATCH 03/12] Fixes for invoice item exports --- app/Export/CSV/InvoiceItemExport.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/Export/CSV/InvoiceItemExport.php b/app/Export/CSV/InvoiceItemExport.php index 14a38aebee..b2b13b523a 100644 --- a/app/Export/CSV/InvoiceItemExport.php +++ b/app/Export/CSV/InvoiceItemExport.php @@ -265,6 +265,10 @@ class InvoiceItemExport extends BaseExport $entity['invoice.user_id'] = $invoice->user ? $invoice->user->present()->name() : '';// @phpstan-ignore-line } + if (in_array('invoice.project', $this->input['report_keys'])) { + $entity['invoice.project'] = $invoice->project ? $invoice->project->name : '';// @phpstan-ignore-line + } + return $entity; } From c4df1b5dd7841ca33c264bfd58ac30f47eded40c Mon Sep 17 00:00:00 2001 From: David Bomba Date: Thu, 25 Jul 2024 08:15:14 +1000 Subject: [PATCH 04/12] Flags for draft documents in reports --- app/Export/CSV/BaseExport.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/Export/CSV/BaseExport.php b/app/Export/CSV/BaseExport.php index 9dbf186b90..efac973651 100644 --- a/app/Export/CSV/BaseExport.php +++ b/app/Export/CSV/BaseExport.php @@ -1039,6 +1039,10 @@ class BaseExport $recurring_filters = []; + if($this->company->getSetting('report_include_drafts')){ + $recurring_filters[] = RecurringInvoice::STATUS_DRAFT; + } + if (in_array('active', $status_parameters)) { $recurring_filters[] = RecurringInvoice::STATUS_ACTIVE; } From 379656bc2b264376b2d9867d26498f25b043c4a3 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Thu, 25 Jul 2024 08:23:16 +1000 Subject: [PATCH 05/12] Updates for build info for react release --- .github/workflows/react_release.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/react_release.yml b/.github/workflows/react_release.yml index c4d6f63994..68ee2fc25c 100644 --- a/.github/workflows/react_release.yml +++ b/.github/workflows/react_release.yml @@ -38,6 +38,9 @@ jobs: sudo php artisan cache:clear sudo find ./vendor/bin/ -type f -exec chmod +x {} \; sudo find ./ -type d -exec chmod 755 {} \; + - name: Set current date to variable + id: set_date + run: echo "current_date=$(date '+%Y-%m-%d')" >> $GITHUB_ENV - name: Prepare React FrontEnd run: | @@ -46,6 +49,7 @@ jobs: git checkout develop cp .env.example .env cp ../vite.config.ts.react ./vite.config.js + sed -i '/"version"/c\ "version": " Latest Build - ${{ env.current_date }}",' package.json npm i npm run build cp -r dist/* ../public/ From 78fc17b1cb716ce1db8acb9c7051a73f86f2fe60 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Thu, 25 Jul 2024 08:25:37 +1000 Subject: [PATCH 06/12] Fixes for wave (set import prefix to -invoice as there is only a single accounting file for wave --- tests/Feature/Import/Wave/WaveTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Feature/Import/Wave/WaveTest.php b/tests/Feature/Import/Wave/WaveTest.php index f8f3edf47f..3a194dd0b7 100644 --- a/tests/Feature/Import/Wave/WaveTest.php +++ b/tests/Feature/Import/Wave/WaveTest.php @@ -196,7 +196,7 @@ class WaveTest extends TestCase 'import_type' => 'waveaccounting', ]; - Cache::put($hash.'-expense', base64_encode($csv), 360); + Cache::put($hash.'-invoice', base64_encode($csv), 360); $csv_importer = new Wave($data, $this->company); From 4008b24acd8e77dac7abfa2d8dd6772d793c8d4a Mon Sep 17 00:00:00 2001 From: David Bomba Date: Sat, 27 Jul 2024 08:48:51 +1000 Subject: [PATCH 07/12] Paypal refactor --- app/Models/CompanyGateway.php | 5 + app/Services/Client/PaymentMethod.php | 6 + app/Services/Invoice/AutoBillInvoice.php | 15 +- public/build/assets/app-234e3402.js | 109 ------------- public/build/assets/app-f3b33400.css | 1 - public/build/assets/payment-1bdbd169.js | 9 -- public/build/manifest.json | 6 +- resources/js/clients/invoices/payment.js | 17 +- .../livewire/pay-now-dropdown.blade.php | 2 + .../includes/required-fields.blade.php | 153 ++++++++++++++++-- .../ninja2020/invoices/payment.blade.php | 3 + 11 files changed, 185 insertions(+), 141 deletions(-) delete mode 100644 public/build/assets/app-234e3402.js delete mode 100644 public/build/assets/app-f3b33400.css delete mode 100644 public/build/assets/payment-1bdbd169.js diff --git a/app/Models/CompanyGateway.php b/app/Models/CompanyGateway.php index 9311699f31..62ba38ee8e 100644 --- a/app/Models/CompanyGateway.php +++ b/app/Models/CompanyGateway.php @@ -159,6 +159,11 @@ class CompanyGateway extends BaseModel protected $touches = []; + public function isPayPal() + { + return in_array($this->gateway_key, ['80af24a6a691230bbec33e930ab40666','80af24a6a691230bbec33e930ab40665']); + } + public function getEntityType() { return self::class; diff --git a/app/Services/Client/PaymentMethod.php b/app/Services/Client/PaymentMethod.php index de5e162258..fd02ccae1e 100644 --- a/app/Services/Client/PaymentMethod.php +++ b/app/Services/Client/PaymentMethod.php @@ -192,6 +192,7 @@ class PaymentMethod 'label' => ctrans('texts.apply_credit'), 'company_gateway_id' => CompanyGateway::GATEWAY_CREDIT, 'gateway_type_id' => GatewayType::CREDIT, + 'is_paypal' => $gateway->isPayPal(), ]; } @@ -210,12 +211,14 @@ class PaymentMethod 'label' => $gateway->getConfigField('name').$fee_label, 'company_gateway_id' => $gateway->id, 'gateway_type_id' => GatewayType::CREDIT_CARD, + 'is_paypal' => $gateway->isPayPal(), ]; } else { $this->payment_urls[] = [ 'label' => $gateway->getTypeAlias($type).$fee_label, 'company_gateway_id' => $gateway->id, 'gateway_type_id' => $type, + 'is_paypal' => $gateway->isPayPal(), ]; } @@ -236,12 +239,14 @@ class PaymentMethod 'label' => $gateway->getConfigField('name').$fee_label, 'company_gateway_id' => $gateway_id, 'gateway_type_id' => GatewayType::CREDIT_CARD, + 'is_paypal' => $gateway->isPayPal(), ]; } else { $this->payment_urls[] = [ 'label' => $gateway->getTypeAlias($gateway_type_id).$fee_label, 'company_gateway_id' => $gateway_id, 'gateway_type_id' => $gateway_type_id, + 'is_paypal' => $gateway->isPayPal(), ]; } } @@ -259,6 +264,7 @@ class PaymentMethod 'label' => ctrans('texts.apply_credit'), 'company_gateway_id' => CompanyGateway::GATEWAY_CREDIT, 'gateway_type_id' => GatewayType::CREDIT, + 'is_paypal' => $gateway->isPayPal(), ]; } diff --git a/app/Services/Invoice/AutoBillInvoice.php b/app/Services/Invoice/AutoBillInvoice.php index a9c9f41539..53c51145d8 100644 --- a/app/Services/Invoice/AutoBillInvoice.php +++ b/app/Services/Invoice/AutoBillInvoice.php @@ -42,6 +42,9 @@ class AutoBillInvoice extends AbstractService public function __construct(private Invoice $invoice, protected string $db) { + + $this->client = $this->invoice->client; + } public function run() @@ -49,8 +52,7 @@ class AutoBillInvoice extends AbstractService MultiDB::setDb($this->db); /* @var \App\Modesl\Client $client */ - $this->client = $this->invoice->client; - + $is_partial = false; /* Is the invoice payable? */ @@ -272,7 +274,7 @@ class AutoBillInvoice extends AbstractService * * @return self */ - private function applyUnappliedPayment(): self + public function applyUnappliedPayment(): self { $unapplied_payments = Payment::query() ->where('client_id', $this->client->id) @@ -284,6 +286,11 @@ class AutoBillInvoice extends AbstractService ->get(); $available_unapplied_balance = $unapplied_payments->sum('amount') - $unapplied_payments->sum('applied'); + + nlog($this->client->id); + nlog($this->invoice->id); + nlog($unapplied_payments->sum('amount')); + nlog($unapplied_payments->sum('applied')); nlog("available unapplied balance = {$available_unapplied_balance}"); @@ -347,7 +354,7 @@ class AutoBillInvoice extends AbstractService * * @return $this */ - private function applyCreditPayment(): self + public function applyCreditPayment(): self { $available_credits = Credit::query()->where('client_id', $this->client->id) ->where('is_deleted', false) diff --git a/public/build/assets/app-234e3402.js b/public/build/assets/app-234e3402.js deleted file mode 100644 index 987442a687..0000000000 --- a/public/build/assets/app-234e3402.js +++ /dev/null @@ -1,109 +0,0 @@ -import{A as Sl}from"./index-08e160a7.js";import{c as zt,g as El}from"./_commonjsHelpers-725317a4.js";var Ol={visa:{niceType:"Visa",type:"visa",patterns:[4],gaps:[4,8,12],lengths:[16,18,19],code:{name:"CVV",size:3}},mastercard:{niceType:"Mastercard",type:"mastercard",patterns:[[51,55],[2221,2229],[223,229],[23,26],[270,271],2720],gaps:[4,8,12],lengths:[16],code:{name:"CVC",size:3}},"american-express":{niceType:"American Express",type:"american-express",patterns:[34,37],gaps:[4,10],lengths:[15],code:{name:"CID",size:4}},"diners-club":{niceType:"Diners Club",type:"diners-club",patterns:[[300,305],36,38,39],gaps:[4,10],lengths:[14,16,19],code:{name:"CVV",size:3}},discover:{niceType:"Discover",type:"discover",patterns:[6011,[644,649],65],gaps:[4,8,12],lengths:[16,19],code:{name:"CID",size:3}},jcb:{niceType:"JCB",type:"jcb",patterns:[2131,1800,[3528,3589]],gaps:[4,8,12],lengths:[16,17,18,19],code:{name:"CVV",size:3}},unionpay:{niceType:"UnionPay",type:"unionpay",patterns:[620,[624,626],[62100,62182],[62184,62187],[62185,62197],[62200,62205],[622010,622999],622018,[622019,622999],[62207,62209],[622126,622925],[623,626],6270,6272,6276,[627700,627779],[627781,627799],[6282,6289],6291,6292,810,[8110,8131],[8132,8151],[8152,8163],[8164,8171]],gaps:[4,8,12],lengths:[14,15,16,17,18,19],code:{name:"CVN",size:3}},maestro:{niceType:"Maestro",type:"maestro",patterns:[493698,[5e5,504174],[504176,506698],[506779,508999],[56,59],63,67,6],gaps:[4,8,12],lengths:[12,13,14,15,16,17,18,19],code:{name:"CVC",size:3}},elo:{niceType:"Elo",type:"elo",patterns:[401178,401179,438935,457631,457632,431274,451416,457393,504175,[506699,506778],[509e3,509999],627780,636297,636368,[650031,650033],[650035,650051],[650405,650439],[650485,650538],[650541,650598],[650700,650718],[650720,650727],[650901,650978],[651652,651679],[655e3,655019],[655021,655058]],gaps:[4,8,12],lengths:[16],code:{name:"CVE",size:3}},mir:{niceType:"Mir",type:"mir",patterns:[[2200,2204]],gaps:[4,8,12],lengths:[16,17,18,19],code:{name:"CVP2",size:3}},hiper:{niceType:"Hiper",type:"hiper",patterns:[637095,63737423,63743358,637568,637599,637609,637612],gaps:[4,8,12],lengths:[16],code:{name:"CVC",size:3}},hipercard:{niceType:"Hipercard",type:"hipercard",patterns:[606282],gaps:[4,8,12],lengths:[16],code:{name:"CVC",size:3}}},Cl=Ol,ni={},Sn={};Object.defineProperty(Sn,"__esModule",{value:!0});Sn.clone=void 0;function Al(e){return e?JSON.parse(JSON.stringify(e)):null}Sn.clone=Al;var ii={};Object.defineProperty(ii,"__esModule",{value:!0});ii.matches=void 0;function Tl(e,r,n){var a=String(r).length,s=e.substr(0,a),l=parseInt(s,10);return r=parseInt(String(r).substr(0,s.length),10),n=parseInt(String(n).substr(0,s.length),10),l>=r&&l<=n}function Pl(e,r){return r=String(r),r.substring(0,e.length)===e.substring(0,r.length)}function Rl(e,r){return Array.isArray(r)?Tl(e,r[0],r[1]):Pl(e,r)}ii.matches=Rl;Object.defineProperty(ni,"__esModule",{value:!0});ni.addMatchingCardsToResults=void 0;var Ml=Sn,kl=ii;function Nl(e,r,n){var a,s;for(a=0;a=s&&(v.matchStrength=s),n.push(v);break}}}ni.addMatchingCardsToResults=Nl;var ai={};Object.defineProperty(ai,"__esModule",{value:!0});ai.isValidInputType=void 0;function Ll(e){return typeof e=="string"||e instanceof String}ai.isValidInputType=Ll;var oi={};Object.defineProperty(oi,"__esModule",{value:!0});oi.findBestMatch=void 0;function jl(e){var r=e.filter(function(n){return n.matchStrength}).length;return r>0&&r===e.length}function Il(e){return jl(e)?e.reduce(function(r,n){return!r||Number(r.matchStrength)Hl?vn(!1,!1):Ul.test(e)?vn(!1,!0):vn(!0,!0)}si.cardholderName=ql;var li={};function Vl(e){for(var r=0,n=!1,a=e.length-1,s;a>=0;)s=parseInt(e.charAt(a),10),n&&(s*=2,s>9&&(s=s%10+1)),n=!n,r+=s,a--;return r%10===0}var zl=Vl;Object.defineProperty(li,"__esModule",{value:!0});li.cardNumber=void 0;var Wl=zl,ao=Uo;function wr(e,r,n){return{card:e,isPotentiallyValid:r,isValid:n}}function Kl(e,r){r===void 0&&(r={});var n,a,s;if(typeof e!="string"&&typeof e!="number")return wr(null,!1,!1);var l=String(e).replace(/-|\s/g,"");if(!/^\d*$/.test(l))return wr(null,!1,!1);var v=ao(l);if(v.length===0)return wr(null,!1,!1);if(v.length!==1)return wr(null,!0,!1);var m=v[0];if(r.maxLength&&l.length>r.maxLength)return wr(m,!1,!1);m.type===ao.types.UNIONPAY&&r.luhnValidateUnionPay!==!0?a=!0:a=Wl(l),s=Math.max.apply(null,m.lengths),r.maxLength&&(s=Math.min(r.maxLength,s));for(var P=0;P4)return ir(!1,!1);var m=parseInt(e,10),P=Number(String(s).substr(2,2)),U=!1;if(a===2){if(String(s).substr(0,2)===e)return ir(!1,!0);n=P===m,U=m>=P&&m<=P+r}else a===4&&(n=s===m,U=m>=s&&m<=s+r);return ir(U,U,n)}Xr.expirationYear=Gl;var fi={};Object.defineProperty(fi,"__esModule",{value:!0});fi.isArray=void 0;fi.isArray=Array.isArray||function(e){return Object.prototype.toString.call(e)==="[object Array]"};Object.defineProperty(ci,"__esModule",{value:!0});ci.parseDate=void 0;var Yl=Xr,Xl=fi;function Ql(e){var r=Number(e[0]),n;return r===0?2:r>1||r===1&&Number(e[1])>2?1:r===1?(n=e.substr(1),Yl.expirationYear(n).isPotentiallyValid?1:2):e.length===5?1:e.length>5?2:1}function Zl(e){var r;if(/^\d{4}-\d{1,2}$/.test(e)?r=e.split("-").reverse():/\//.test(e)?r=e.split(/\s*\/\s*/g):/\s/.test(e)&&(r=e.split(/ +/g)),Xl.isArray(r))return{month:r[0]||"",year:r.slice(1).join()};var n=Ql(e),a=e.substr(0,n);return{month:a,year:e.substr(a.length)}}ci.parseDate=Zl;var On={};Object.defineProperty(On,"__esModule",{value:!0});On.expirationMonth=void 0;function yn(e,r,n){return{isValid:e,isPotentiallyValid:r,isValidForThisYear:n||!1}}function eu(e){var r=new Date().getMonth()+1;if(typeof e!="string")return yn(!1,!1);if(e.replace(/\s/g,"")===""||e==="0")return yn(!1,!0);if(!/^\d*$/.test(e))return yn(!1,!1);var n=parseInt(e,10);if(isNaN(Number(e)))return yn(!1,!1);var a=n>0&&n<13;return yn(a,a,a&&n>=r)}On.expirationMonth=eu;var ra=zt&&zt.__assign||function(){return ra=Object.assign||function(e){for(var r,n=1,a=arguments.length;nr?e[n]:r;return r}function Hr(e,r){return{isValid:e,isPotentiallyValid:r}}function su(e,r){return r===void 0&&(r=Ho),r=r instanceof Array?r:[r],typeof e!="string"||!/^\d*$/.test(e)?Hr(!1,!1):au(r,e.length)?Hr(!0,!0):e.lengthou(r)?Hr(!1,!1):Hr(!0,!0)}di.cvv=su;var pi={};Object.defineProperty(pi,"__esModule",{value:!0});pi.postalCode=void 0;var lu=3;function Ji(e,r){return{isValid:e,isPotentiallyValid:r}}function uu(e,r){r===void 0&&(r={});var n=r.minLength||lu;return typeof e!="string"?Ji(!1,!1):e.lengthfunction(){return r||(0,e[Vo(e)[0]])((r={exports:{}}).exports,r),r.exports},Tu=(e,r,n,a)=>{if(r&&typeof r=="object"||typeof r=="function")for(let s of Vo(r))!Au.call(e,s)&&s!==n&&qo(e,s,{get:()=>r[s],enumerable:!(a=Ou(r,s))||a.enumerable});return e},tt=(e,r,n)=>(n=e!=null?Eu(Cu(e)):{},Tu(r||!e||!e.__esModule?qo(n,"default",{value:e,enumerable:!0}):n,e)),Ot=Zt({"../alpine/packages/alpinejs/dist/module.cjs.js"(e,r){var n=Object.create,a=Object.defineProperty,s=Object.getOwnPropertyDescriptor,l=Object.getOwnPropertyNames,v=Object.getPrototypeOf,m=Object.prototype.hasOwnProperty,P=(t,i)=>function(){return i||(0,t[l(t)[0]])((i={exports:{}}).exports,i),i.exports},U=(t,i)=>{for(var o in i)a(t,o,{get:i[o],enumerable:!0})},ne=(t,i,o,c)=>{if(i&&typeof i=="object"||typeof i=="function")for(let d of l(i))!m.call(t,d)&&d!==o&&a(t,d,{get:()=>i[d],enumerable:!(c=s(i,d))||c.enumerable});return t},ie=(t,i,o)=>(o=t!=null?n(v(t)):{},ne(i||!t||!t.__esModule?a(o,"default",{value:t,enumerable:!0}):o,t)),K=t=>ne(a({},"__esModule",{value:!0}),t),Y=P({"node_modules/@vue/shared/dist/shared.cjs.js"(t){Object.defineProperty(t,"__esModule",{value:!0});function i(b,W){const ee=Object.create(null),fe=b.split(",");for(let qe=0;qe!!ee[qe.toLowerCase()]:qe=>!!ee[qe]}var o={1:"TEXT",2:"CLASS",4:"STYLE",8:"PROPS",16:"FULL_PROPS",32:"HYDRATE_EVENTS",64:"STABLE_FRAGMENT",128:"KEYED_FRAGMENT",256:"UNKEYED_FRAGMENT",512:"NEED_PATCH",1024:"DYNAMIC_SLOTS",2048:"DEV_ROOT_FRAGMENT",[-1]:"HOISTED",[-2]:"BAIL"},c={1:"STABLE",2:"DYNAMIC",3:"FORWARDED"},d="Infinity,undefined,NaN,isFinite,isNaN,parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,BigInt",p=i(d),g=2;function x(b,W=0,ee=b.length){let fe=b.split(/(\r?\n)/);const qe=fe.filter((xt,dt)=>dt%2===1);fe=fe.filter((xt,dt)=>dt%2===0);let et=0;const wt=[];for(let xt=0;xt=W){for(let dt=xt-g;dt<=xt+g||ee>et;dt++){if(dt<0||dt>=fe.length)continue;const gn=dt+1;wt.push(`${gn}${" ".repeat(Math.max(3-String(gn).length,0))}| ${fe[dt]}`);const Br=fe[dt].length,Zn=qe[dt]&&qe[dt].length||0;if(dt===xt){const Ur=W-(et-(Br+Zn)),Wi=Math.max(1,ee>et?Br-Ur:ee-W);wt.push(" | "+" ".repeat(Ur)+"^".repeat(Wi))}else if(dt>xt){if(ee>et){const Ur=Math.max(Math.min(ee-et,Br),1);wt.push(" | "+"^".repeat(Ur))}et+=Br+Zn}}break}return wt.join(` -`)}var M="itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly",Z=i(M),Me=i(M+",async,autofocus,autoplay,controls,default,defer,disabled,hidden,loop,open,required,reversed,scoped,seamless,checked,muted,multiple,selected"),Qe=/[>/="'\u0009\u000a\u000c\u0020]/,De={};function Je(b){if(De.hasOwnProperty(b))return De[b];const W=Qe.test(b);return W&&console.error(`unsafe attribute name: ${b}`),De[b]=!W}var Tt={acceptCharset:"accept-charset",className:"class",htmlFor:"for",httpEquiv:"http-equiv"},Ut=i("animation-iteration-count,border-image-outset,border-image-slice,border-image-width,box-flex,box-flex-group,box-ordinal-group,column-count,columns,flex,flex-grow,flex-positive,flex-shrink,flex-negative,flex-order,grid-row,grid-row-end,grid-row-span,grid-row-start,grid-column,grid-column-end,grid-column-span,grid-column-start,font-weight,line-clamp,line-height,opacity,order,orphans,tab-size,widows,z-index,zoom,fill-opacity,flood-opacity,stop-opacity,stroke-dasharray,stroke-dashoffset,stroke-miterlimit,stroke-opacity,stroke-width"),we=i("accept,accept-charset,accesskey,action,align,allow,alt,async,autocapitalize,autocomplete,autofocus,autoplay,background,bgcolor,border,buffered,capture,challenge,charset,checked,cite,class,code,codebase,color,cols,colspan,content,contenteditable,contextmenu,controls,coords,crossorigin,csp,data,datetime,decoding,default,defer,dir,dirname,disabled,download,draggable,dropzone,enctype,enterkeyhint,for,form,formaction,formenctype,formmethod,formnovalidate,formtarget,headers,height,hidden,high,href,hreflang,http-equiv,icon,id,importance,integrity,ismap,itemprop,keytype,kind,label,lang,language,loading,list,loop,low,manifest,max,maxlength,minlength,media,min,multiple,muted,name,novalidate,open,optimum,pattern,ping,placeholder,poster,preload,radiogroup,readonly,referrerpolicy,rel,required,reversed,rows,rowspan,sandbox,scope,scoped,selected,shape,size,sizes,slot,span,spellcheck,src,srcdoc,srclang,srcset,start,step,style,summary,tabindex,target,title,translate,type,usemap,value,width,wrap");function Ue(b){if(Dt(b)){const W={};for(let ee=0;ee{if(ee){const fe=ee.split(He);fe.length>1&&(W[fe[0].trim()]=fe[1].trim())}}),W}function It(b){let W="";if(!b)return W;for(const ee in b){const fe=b[ee],qe=ee.startsWith("--")?ee:Xn(ee);(vr(fe)||typeof fe=="number"&&Ut(qe))&&(W+=`${qe}:${fe};`)}return W}function Ht(b){let W="";if(vr(b))W=b;else if(Dt(b))for(let ee=0;ee]/;function Ii(b){const W=""+b,ee=ji.exec(W);if(!ee)return W;let fe="",qe,et,wt=0;for(et=ee.index;et||--!>|Mr(ee,W))}var Bn=b=>b==null?"":qt(b)?JSON.stringify(b,Fi,2):String(b),Fi=(b,W)=>mr(W)?{[`Map(${W.size})`]:[...W.entries()].reduce((ee,[fe,qe])=>(ee[`${fe} =>`]=qe,ee),{})}:$t(W)?{[`Set(${W.size})`]:[...W.values()]}:qt(W)&&!Dt(W)&&!Wn(W)?String(W):W,Bi=["bigInt","optionalChaining","nullishCoalescingOperator"],un=Object.freeze({}),cn=Object.freeze([]),fn=()=>{},kr=()=>!1,Nr=/^on[^a-z]/,Lr=b=>Nr.test(b),jr=b=>b.startsWith("onUpdate:"),Un=Object.assign,Hn=(b,W)=>{const ee=b.indexOf(W);ee>-1&&b.splice(ee,1)},qn=Object.prototype.hasOwnProperty,Vn=(b,W)=>qn.call(b,W),Dt=Array.isArray,mr=b=>yr(b)==="[object Map]",$t=b=>yr(b)==="[object Set]",dn=b=>b instanceof Date,pn=b=>typeof b=="function",vr=b=>typeof b=="string",Ui=b=>typeof b=="symbol",qt=b=>b!==null&&typeof b=="object",Ir=b=>qt(b)&&pn(b.then)&&pn(b.catch),zn=Object.prototype.toString,yr=b=>zn.call(b),Hi=b=>yr(b).slice(8,-1),Wn=b=>yr(b)==="[object Object]",Kn=b=>vr(b)&&b!=="NaN"&&b[0]!=="-"&&""+parseInt(b,10)===b,Jn=i(",key,ref,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),br=b=>{const W=Object.create(null);return ee=>W[ee]||(W[ee]=b(ee))},Gn=/-(\w)/g,Yn=br(b=>b.replace(Gn,(W,ee)=>ee?ee.toUpperCase():"")),qi=/\B([A-Z])/g,Xn=br(b=>b.replace(qi,"-$1").toLowerCase()),_r=br(b=>b.charAt(0).toUpperCase()+b.slice(1)),Vi=br(b=>b?`on${_r(b)}`:""),hn=(b,W)=>b!==W&&(b===b||W===W),zi=(b,W)=>{for(let ee=0;ee{Object.defineProperty(b,W,{configurable:!0,enumerable:!1,value:ee})},$r=b=>{const W=parseFloat(b);return isNaN(W)?b:W},Fr,Qn=()=>Fr||(Fr=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});t.EMPTY_ARR=cn,t.EMPTY_OBJ=un,t.NO=kr,t.NOOP=fn,t.PatchFlagNames=o,t.babelParserDefaultPlugins=Bi,t.camelize=Yn,t.capitalize=_r,t.def=Dr,t.escapeHtml=Ii,t.escapeHtmlComment=Di,t.extend=Un,t.generateCodeFrame=x,t.getGlobalThis=Qn,t.hasChanged=hn,t.hasOwn=Vn,t.hyphenate=Xn,t.invokeArrayFns=zi,t.isArray=Dt,t.isBooleanAttr=Me,t.isDate=dn,t.isFunction=pn,t.isGloballyWhitelisted=p,t.isHTMLTag=Pr,t.isIntegerKey=Kn,t.isKnownAttr=we,t.isMap=mr,t.isModelListener=jr,t.isNoUnitNumericStyleProp=Ut,t.isObject=qt,t.isOn=Lr,t.isPlainObject=Wn,t.isPromise=Ir,t.isReservedProp=Jn,t.isSSRSafeAttrName=Je,t.isSVGTag=Li,t.isSet=$t,t.isSpecialBooleanAttr=Z,t.isString=vr,t.isSymbol=Ui,t.isVoidTag=Rr,t.looseEqual=Mr,t.looseIndexOf=Fn,t.makeMap=i,t.normalizeClass=Ht,t.normalizeStyle=Ue,t.objectToString=zn,t.parseStringStyle=_t,t.propsToAttrMap=Tt,t.remove=Hn,t.slotFlagsText=c,t.stringifyStyle=It,t.toDisplayString=Bn,t.toHandlerKey=Vi,t.toNumber=$r,t.toRawType=Hi,t.toTypeString=yr}}),O=P({"node_modules/@vue/shared/index.js"(t,i){i.exports=Y()}}),y=P({"node_modules/@vue/reactivity/dist/reactivity.cjs.js"(t){Object.defineProperty(t,"__esModule",{value:!0});var i=O(),o=new WeakMap,c=[],d,p=Symbol("iterate"),g=Symbol("Map key iterate");function x(u){return u&&u._isEffect===!0}function M(u,A=i.EMPTY_OBJ){x(u)&&(u=u.raw);const N=Qe(u,A);return A.lazy||N(),N}function Z(u){u.active&&(De(u),u.options.onStop&&u.options.onStop(),u.active=!1)}var Me=0;function Qe(u,A){const N=function(){if(!N.active)return u();if(!c.includes(N)){De(N);try{return we(),c.push(N),d=N,u()}finally{c.pop(),Ue(),d=c[c.length-1]}}};return N.id=Me++,N.allowRecurse=!!A.allowRecurse,N._isEffect=!0,N.active=!0,N.raw=u,N.deps=[],N.options=A,N}function De(u){const{deps:A}=u;if(A.length){for(let N=0;N{vt&&vt.forEach(Ft=>{(Ft!==d||Ft.allowRecurse)&&nt.add(Ft)})};if(A==="clear")Le.forEach(St);else if(N==="length"&&i.isArray(u))Le.forEach((vt,Ft)=>{(Ft==="length"||Ft>=oe)&&St(vt)});else switch(N!==void 0&&St(Le.get(N)),A){case"add":i.isArray(u)?i.isIntegerKey(N)&&St(Le.get("length")):(St(Le.get(p)),i.isMap(u)&&St(Le.get(g)));break;case"delete":i.isArray(u)||(St(Le.get(p)),i.isMap(u)&&St(Le.get(g)));break;case"set":i.isMap(u)&&St(Le.get(p));break}const mn=vt=>{vt.options.onTrigger&&vt.options.onTrigger({effect:vt,target:u,key:N,type:A,newValue:oe,oldValue:J,oldTarget:ge}),vt.options.scheduler?vt.options.scheduler(vt):vt()};nt.forEach(mn)}var _t=i.makeMap("__proto__,__v_isRef,__isVue"),It=new Set(Object.getOwnPropertyNames(Symbol).map(u=>Symbol[u]).filter(i.isSymbol)),Ht=Rr(),Tr=Rr(!1,!0),sn=Rr(!0),ln=Rr(!0,!0),Pr=Li();function Li(){const u={};return["includes","indexOf","lastIndexOf"].forEach(A=>{u[A]=function(...N){const oe=b(this);for(let ge=0,Le=this.length;ge{u[A]=function(...N){Ut();const oe=b(this)[A].apply(this,N);return Ue(),oe}}),u}function Rr(u=!1,A=!1){return function(oe,J,ge){if(J==="__v_isReactive")return!u;if(J==="__v_isReadonly")return u;if(J==="__v_raw"&&ge===(u?A?Yn:Gn:A?br:Jn).get(oe))return oe;const Le=i.isArray(oe);if(!u&&Le&&i.hasOwn(Pr,J))return Reflect.get(Pr,J,ge);const nt=Reflect.get(oe,J,ge);return(i.isSymbol(J)?It.has(J):_t(J))||(u||Ne(oe,"get",J),A)?nt:fe(nt)?!Le||!i.isIntegerKey(J)?nt.value:nt:i.isObject(nt)?u?hn(nt):_r(nt):nt}}var ji=$n(),Ii=$n(!0);function $n(u=!1){return function(N,oe,J,ge){let Le=N[oe];if(!u&&(J=b(J),Le=b(Le),!i.isArray(N)&&fe(Le)&&!fe(J)))return Le.value=J,!0;const nt=i.isArray(N)&&i.isIntegerKey(oe)?Number(oe)i.isObject(u)?_r(u):u,cn=u=>i.isObject(u)?hn(u):u,fn=u=>u,kr=u=>Reflect.getPrototypeOf(u);function Nr(u,A,N=!1,oe=!1){u=u.__v_raw;const J=b(u),ge=b(A);A!==ge&&!N&&Ne(J,"get",A),!N&&Ne(J,"get",ge);const{has:Le}=kr(J),nt=oe?fn:N?cn:un;if(Le.call(J,A))return nt(u.get(A));if(Le.call(J,ge))return nt(u.get(ge));u!==J&&u.get(A)}function Lr(u,A=!1){const N=this.__v_raw,oe=b(N),J=b(u);return u!==J&&!A&&Ne(oe,"has",u),!A&&Ne(oe,"has",J),u===J?N.has(u):N.has(u)||N.has(J)}function jr(u,A=!1){return u=u.__v_raw,!A&&Ne(b(u),"iterate",p),Reflect.get(u,"size",u)}function Un(u){u=b(u);const A=b(this);return kr(A).has.call(A,u)||(A.add(u),He(A,"add",u,u)),this}function Hn(u,A){A=b(A);const N=b(this),{has:oe,get:J}=kr(N);let ge=oe.call(N,u);ge?Kn(N,oe,u):(u=b(u),ge=oe.call(N,u));const Le=J.call(N,u);return N.set(u,A),ge?i.hasChanged(A,Le)&&He(N,"set",u,A,Le):He(N,"add",u,A),this}function qn(u){const A=b(this),{has:N,get:oe}=kr(A);let J=N.call(A,u);J?Kn(A,N,u):(u=b(u),J=N.call(A,u));const ge=oe?oe.call(A,u):void 0,Le=A.delete(u);return J&&He(A,"delete",u,void 0,ge),Le}function Vn(){const u=b(this),A=u.size!==0,N=i.isMap(u)?new Map(u):new Set(u),oe=u.clear();return A&&He(u,"clear",void 0,void 0,N),oe}function Dt(u,A){return function(oe,J){const ge=this,Le=ge.__v_raw,nt=b(Le),St=A?fn:u?cn:un;return!u&&Ne(nt,"iterate",p),Le.forEach((mn,vt)=>oe.call(J,St(mn),St(vt),ge))}}function mr(u,A,N){return function(...oe){const J=this.__v_raw,ge=b(J),Le=i.isMap(ge),nt=u==="entries"||u===Symbol.iterator&&Le,St=u==="keys"&&Le,mn=J[u](...oe),vt=N?fn:A?cn:un;return!A&&Ne(ge,"iterate",St?g:p),{next(){const{value:Ft,done:Ki}=mn.next();return Ki?{value:Ft,done:Ki}:{value:nt?[vt(Ft[0]),vt(Ft[1])]:vt(Ft),done:Ki}},[Symbol.iterator](){return this}}}}function $t(u){return function(...A){{const N=A[0]?`on key "${A[0]}" `:"";console.warn(`${i.capitalize(u)} operation ${N}failed: target is readonly.`,b(this))}return u==="delete"?!1:this}}function dn(){const u={get(ge){return Nr(this,ge)},get size(){return jr(this)},has:Lr,add:Un,set:Hn,delete:qn,clear:Vn,forEach:Dt(!1,!1)},A={get(ge){return Nr(this,ge,!1,!0)},get size(){return jr(this)},has:Lr,add:Un,set:Hn,delete:qn,clear:Vn,forEach:Dt(!1,!0)},N={get(ge){return Nr(this,ge,!0)},get size(){return jr(this,!0)},has(ge){return Lr.call(this,ge,!0)},add:$t("add"),set:$t("set"),delete:$t("delete"),clear:$t("clear"),forEach:Dt(!0,!1)},oe={get(ge){return Nr(this,ge,!0,!0)},get size(){return jr(this,!0)},has(ge){return Lr.call(this,ge,!0)},add:$t("add"),set:$t("set"),delete:$t("delete"),clear:$t("clear"),forEach:Dt(!0,!0)};return["keys","values","entries",Symbol.iterator].forEach(ge=>{u[ge]=mr(ge,!1,!1),N[ge]=mr(ge,!0,!1),A[ge]=mr(ge,!1,!0),oe[ge]=mr(ge,!0,!0)}),[u,N,A,oe]}var[pn,vr,Ui,qt]=dn();function Ir(u,A){const N=A?u?qt:Ui:u?vr:pn;return(oe,J,ge)=>J==="__v_isReactive"?!u:J==="__v_isReadonly"?u:J==="__v_raw"?oe:Reflect.get(i.hasOwn(N,J)&&J in oe?N:oe,J,ge)}var zn={get:Ir(!1,!1)},yr={get:Ir(!1,!0)},Hi={get:Ir(!0,!1)},Wn={get:Ir(!0,!0)};function Kn(u,A,N){const oe=b(N);if(oe!==N&&A.call(u,oe)){const J=i.toRawType(u);console.warn(`Reactive ${J} contains both the raw and reactive versions of the same object${J==="Map"?" as keys":""}, which can lead to inconsistencies. Avoid differentiating between the raw and reactive versions of an object and only use the reactive version if possible.`)}}var Jn=new WeakMap,br=new WeakMap,Gn=new WeakMap,Yn=new WeakMap;function qi(u){switch(u){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function Xn(u){return u.__v_skip||!Object.isExtensible(u)?0:qi(i.toRawType(u))}function _r(u){return u&&u.__v_isReadonly?u:Dr(u,!1,Fn,zn,Jn)}function Vi(u){return Dr(u,!1,Fi,yr,br)}function hn(u){return Dr(u,!0,Bn,Hi,Gn)}function zi(u){return Dr(u,!0,Bi,Wn,Yn)}function Dr(u,A,N,oe,J){if(!i.isObject(u))return console.warn(`value cannot be made reactive: ${String(u)}`),u;if(u.__v_raw&&!(A&&u.__v_isReactive))return u;const ge=J.get(u);if(ge)return ge;const Le=Xn(u);if(Le===0)return u;const nt=new Proxy(u,Le===2?oe:N);return J.set(u,nt),nt}function $r(u){return Fr(u)?$r(u.__v_raw):!!(u&&u.__v_isReactive)}function Fr(u){return!!(u&&u.__v_isReadonly)}function Qn(u){return $r(u)||Fr(u)}function b(u){return u&&b(u.__v_raw)||u}function W(u){return i.def(u,"__v_skip",!0),u}var ee=u=>i.isObject(u)?_r(u):u;function fe(u){return!!(u&&u.__v_isRef===!0)}function qe(u){return xt(u)}function et(u){return xt(u,!0)}var wt=class{constructor(u,A=!1){this._shallow=A,this.__v_isRef=!0,this._rawValue=A?u:b(u),this._value=A?u:ee(u)}get value(){return Ne(b(this),"get","value"),this._value}set value(u){u=this._shallow?u:b(u),i.hasChanged(u,this._rawValue)&&(this._rawValue=u,this._value=this._shallow?u:ee(u),He(b(this),"set","value",u))}};function xt(u,A=!1){return fe(u)?u:new wt(u,A)}function dt(u){He(b(u),"set","value",u.value)}function gn(u){return fe(u)?u.value:u}var Br={get:(u,A,N)=>gn(Reflect.get(u,A,N)),set:(u,A,N,oe)=>{const J=u[A];return fe(J)&&!fe(N)?(J.value=N,!0):Reflect.set(u,A,N,oe)}};function Zn(u){return $r(u)?u:new Proxy(u,Br)}var Ur=class{constructor(u){this.__v_isRef=!0;const{get:A,set:N}=u(()=>Ne(this,"get","value"),()=>He(this,"set","value"));this._get=A,this._set=N}get value(){return this._get()}set value(u){this._set(u)}};function Wi(u){return new Ur(u)}function bl(u){Qn(u)||console.warn("toRefs() expects a reactive object but received a plain one.");const A=i.isArray(u)?new Array(u.length):{};for(const N in u)A[N]=io(u,N);return A}var _l=class{constructor(u,A){this._object=u,this._key=A,this.__v_isRef=!0}get value(){return this._object[this._key]}set value(u){this._object[this._key]=u}};function io(u,A){return fe(u[A])?u[A]:new _l(u,A)}var wl=class{constructor(u,A,N){this._setter=A,this._dirty=!0,this.__v_isRef=!0,this.effect=M(u,{lazy:!0,scheduler:()=>{this._dirty||(this._dirty=!0,He(b(this),"set","value"))}}),this.__v_isReadonly=N}get value(){const u=b(this);return u._dirty&&(u._value=this.effect(),u._dirty=!1),Ne(u,"get","value"),u._value}set value(u){this._setter(u)}};function xl(u){let A,N;return i.isFunction(u)?(A=u,N=()=>{console.warn("Write operation failed: computed value is readonly")}):(A=u.get,N=u.set),new wl(A,N,i.isFunction(u)||!u.set)}t.ITERATE_KEY=p,t.computed=xl,t.customRef=Wi,t.effect=M,t.enableTracking=we,t.isProxy=Qn,t.isReactive=$r,t.isReadonly=Fr,t.isRef=fe,t.markRaw=W,t.pauseTracking=Ut,t.proxyRefs=Zn,t.reactive=_r,t.readonly=hn,t.ref=qe,t.resetTracking=Ue,t.shallowReactive=Vi,t.shallowReadonly=zi,t.shallowRef=et,t.stop=Z,t.toRaw=b,t.toRef=io,t.toRefs=bl,t.track=Ne,t.trigger=He,t.triggerRef=dt,t.unref=gn}}),_=P({"node_modules/@vue/reactivity/index.js"(t,i){i.exports=y()}}),S={};U(S,{Alpine:()=>no,default:()=>yl}),r.exports=K(S);var T=!1,j=!1,H=[],Ce=-1;function D(t){C(t)}function C(t){H.includes(t)||H.push(t),re()}function L(t){let i=H.indexOf(t);i!==-1&&i>Ce&&H.splice(i,1)}function re(){!j&&!T&&(T=!0,queueMicrotask(ye))}function ye(){T=!1,j=!0;for(let t=0;tt.effect(i,{scheduler:o=>{Ye?D(o):o()}}),Ge=t.raw}function ht(t){X=t}function yt(t){let i=()=>{};return[c=>{let d=X(c);return t._x_effects||(t._x_effects=new Set,t._x_runEffects=()=>{t._x_effects.forEach(p=>p())}),t._x_effects.add(d),i=()=>{d!==void 0&&(t._x_effects.delete(d),Te(d))},d},()=>{i()}]}function Ct(t,i){let o=!0,c,d=X(()=>{let p=t();JSON.stringify(p),o?c=p:queueMicrotask(()=>{i(p,c),c=p}),o=!1});return()=>Te(d)}var Ee=[],be=[],Oe=[];function xe(t){Oe.push(t)}function de(t,i){typeof i=="function"?(t._x_cleanups||(t._x_cleanups=[]),t._x_cleanups.push(i)):(i=t,be.push(i))}function Q(t){Ee.push(t)}function Ve(t,i,o){t._x_attributeCleanups||(t._x_attributeCleanups={}),t._x_attributeCleanups[i]||(t._x_attributeCleanups[i]=[]),t._x_attributeCleanups[i].push(o)}function z(t,i){t._x_attributeCleanups&&Object.entries(t._x_attributeCleanups).forEach(([o,c])=>{(i===void 0||i.includes(o))&&(c.forEach(d=>d()),delete t._x_attributeCleanups[o])})}function ae(t){if(t._x_cleanups)for(;t._x_cleanups.length;)t._x_cleanups.pop()()}var ve=new MutationObserver(We),$e=!1;function me(){ve.observe(document,{subtree:!0,childList:!0,attributes:!0,attributeOldValue:!0}),$e=!0}function ue(){Ze(),ve.disconnect(),$e=!1}var ut=[];function Ze(){let t=ve.takeRecords();ut.push(()=>t.length>0&&We(t));let i=ut.length;queueMicrotask(()=>{if(ut.length===i)for(;ut.length>0;)ut.shift()()})}function te(t){if(!$e)return t();ue();let i=t();return me(),i}var k=!1,I=[];function he(){k=!0}function V(){k=!1,We(I),I=[]}function We(t){if(k){I=I.concat(t);return}let i=new Set,o=new Set,c=new Map,d=new Map;for(let p=0;pg.nodeType===1&&i.add(g)),t[p].removedNodes.forEach(g=>g.nodeType===1&&o.add(g))),t[p].type==="attributes")){let g=t[p].target,x=t[p].attributeName,M=t[p].oldValue,Z=()=>{c.has(g)||c.set(g,[]),c.get(g).push({name:x,value:g.getAttribute(x)})},Me=()=>{d.has(g)||d.set(g,[]),d.get(g).push(x)};g.hasAttribute(x)&&M===null?Z():g.hasAttribute(x)?(Me(),Z()):Me()}d.forEach((p,g)=>{z(g,p)}),c.forEach((p,g)=>{Ee.forEach(x=>x(g,p))});for(let p of o)i.has(p)||be.forEach(g=>g(p));i.forEach(p=>{p._x_ignoreSelf=!0,p._x_ignore=!0});for(let p of i)o.has(p)||p.isConnected&&(delete p._x_ignoreSelf,delete p._x_ignore,Oe.forEach(g=>g(p)),p._x_ignore=!0,p._x_ignoreSelf=!0);i.forEach(p=>{delete p._x_ignoreSelf,delete p._x_ignore}),i=null,o=null,c=null,d=null}function pe(t){return ce(q(t))}function $(t,i,o){return t._x_dataStack=[i,...q(o||t)],()=>{t._x_dataStack=t._x_dataStack.filter(c=>c!==i)}}function q(t){return t._x_dataStack?t._x_dataStack:typeof ShadowRoot=="function"&&t instanceof ShadowRoot?q(t.host):t.parentNode?q(t.parentNode):[]}function ce(t){return new Proxy({objects:t},Be)}var Be={ownKeys({objects:t}){return Array.from(new Set(t.flatMap(i=>Object.keys(i))))},has({objects:t},i){return i==Symbol.unscopables?!1:t.some(o=>Object.prototype.hasOwnProperty.call(o,i)||Reflect.has(o,i))},get({objects:t},i,o){return i=="toJSON"?Ae:Reflect.get(t.find(c=>Reflect.has(c,i))||{},i,o)},set({objects:t},i,o,c){const d=t.find(g=>Object.prototype.hasOwnProperty.call(g,i))||t[t.length-1],p=Object.getOwnPropertyDescriptor(d,i);return p!=null&&p.set&&(p!=null&&p.get)?p.set.call(c,o)||!0:Reflect.set(d,i,o)}};function Ae(){return Reflect.ownKeys(this).reduce((i,o)=>(i[o]=Reflect.get(this,o),i),{})}function ot(t){let i=c=>typeof c=="object"&&!Array.isArray(c)&&c!==null,o=(c,d="")=>{Object.entries(Object.getOwnPropertyDescriptors(c)).forEach(([p,{value:g,enumerable:x}])=>{if(x===!1||g===void 0||typeof g=="object"&&g!==null&&g.__v_skip)return;let M=d===""?p:`${d}.${p}`;typeof g=="object"&&g!==null&&g._x_interceptor?c[p]=g.initialize(t,M,p):i(g)&&g!==c&&!(g instanceof Element)&&o(g,M)})};return o(t)}function it(t,i=()=>{}){let o={initialValue:void 0,_x_interceptor:!0,initialize(c,d,p){return t(this.initialValue,()=>Rt(c,d),g=>Lt(c,d,g),d,p)}};return i(o),c=>{if(typeof c=="object"&&c!==null&&c._x_interceptor){let d=o.initialize.bind(o);o.initialize=(p,g,x)=>{let M=c.initialize(p,g,x);return o.initialValue=M,d(p,g,x)}}else o.initialValue=c;return o}}function Rt(t,i){return i.split(".").reduce((o,c)=>o[c],t)}function Lt(t,i,o){if(typeof i=="string"&&(i=i.split(".")),i.length===1)t[i[0]]=o;else{if(i.length===0)throw error;return t[i[0]]||(t[i[0]]={}),Lt(t[i[0]],i.slice(1),o)}}var lr={};function At(t,i){lr[t]=i}function Wt(t,i){return Object.entries(lr).forEach(([o,c])=>{let d=null;function p(){if(d)return d;{let[g,x]=G(i);return d={interceptor:it,...g},de(i,x),d}}Object.defineProperty(t,`$${o}`,{get(){return c(i,p())},enumerable:!1})}),t}function ur(t,i,o,...c){try{return o(...c)}catch(d){er(d,t,i)}}function er(t,i,o=void 0){t=Object.assign(t??{message:"No error message given."},{el:i,expression:o}),console.warn(`Alpine Expression Error: ${t.message} - -${o?'Expression: "'+o+`" - -`:""}`,i),setTimeout(()=>{throw t},0)}var cr=!0;function An(t){let i=cr;cr=!1;let o=t();return cr=i,o}function Kt(t,i,o={}){let c;return bt(t,i)(d=>c=d,o),c}function bt(...t){return Tn(...t)}var Tn=Qr;function Pn(t){Tn=t}function Qr(t,i){let o={};Wt(o,t);let c=[o,...q(t)],d=typeof i=="function"?yi(c,i):_i(c,i,t);return ur.bind(null,t,i,d)}function yi(t,i){return(o=()=>{},{scope:c={},params:d=[]}={})=>{let p=i.apply(ce([c,...t]),d);Cr(o,p)}}var Zr={};function bi(t,i){if(Zr[t])return Zr[t];let o=Object.getPrototypeOf(async function(){}).constructor,c=/^[\n\s]*if.*\(.*\)/.test(t.trim())||/^(let|const)\s/.test(t.trim())?`(async()=>{ ${t} })()`:t,p=(()=>{try{let g=new o(["__self","scope"],`with (scope) { __self.result = ${c} }; __self.finished = true; return __self.result;`);return Object.defineProperty(g,"name",{value:`[Alpine] ${t}`}),g}catch(g){return er(g,i,t),Promise.resolve()}})();return Zr[t]=p,p}function _i(t,i,o){let c=bi(i,o);return(d=()=>{},{scope:p={},params:g=[]}={})=>{c.result=void 0,c.finished=!1;let x=ce([p,...t]);if(typeof c=="function"){let M=c(c,x).catch(Z=>er(Z,o,i));c.finished?(Cr(d,c.result,x,g,o),c.result=void 0):M.then(Z=>{Cr(d,Z,x,g,o)}).catch(Z=>er(Z,o,i)).finally(()=>c.result=void 0)}}}function Cr(t,i,o,c,d){if(cr&&typeof i=="function"){let p=i.apply(o,c);p instanceof Promise?p.then(g=>Cr(t,g,o,c)).catch(g=>er(g,d,i)):t(p)}else typeof i=="object"&&i instanceof Promise?i.then(p=>t(p)):t(i)}var en="x-";function Jt(t=""){return en+t}function Rn(t){en=t}var fr={};function st(t,i){return fr[t]=i,{before(o){if(!fr[o]){console.warn(String.raw`Cannot find directive \`${o}\`. \`${t}\` will use the default order of execution`);return}const c=Ke.indexOf(o);Ke.splice(c>=0?c:Ke.indexOf("DEFAULT"),0,t)}}}function f(t){return Object.keys(fr).includes(t)}function h(t,i,o){if(i=Array.from(i),t._x_virtualDirectives){let p=Object.entries(t._x_virtualDirectives).map(([x,M])=>({name:x,value:M})),g=w(p);p=p.map(x=>g.find(M=>M.name===x.name)?{name:`x-bind:${x.name}`,value:`"${x.value}"`}:x),i=i.concat(p)}let c={};return i.map(Pe((p,g)=>c[p]=g)).filter(Re).map(rt(c,o)).sort(ct).map(p=>se(t,p))}function w(t){return Array.from(t).map(Pe()).filter(i=>!Re(i))}var E=!1,R=new Map,F=Symbol();function B(t){E=!0;let i=Symbol();F=i,R.set(i,[]);let o=()=>{for(;R.get(i).length;)R.get(i).shift()();R.delete(i)},c=()=>{E=!1,o()};t(o),c()}function G(t){let i=[],o=x=>i.push(x),[c,d]=yt(t);return i.push(d),[{Alpine:on,effect:c,cleanup:o,evaluateLater:bt.bind(bt,t),evaluate:Kt.bind(Kt,t)},()=>i.forEach(x=>x())]}function se(t,i){let o=()=>{},c=fr[i.type]||o,[d,p]=G(t);Ve(t,i.original,p);let g=()=>{t._x_ignore||t._x_ignoreSelf||(c.inline&&c.inline(t,i,d),c=c.bind(c,t,i,d),E?R.get(F).push(c):c())};return g.runCleanups=p,g}var le=(t,i)=>({name:o,value:c})=>(o.startsWith(t)&&(o=o.replace(t,i)),{name:o,value:c}),ke=t=>t;function Pe(t=()=>{}){return({name:i,value:o})=>{let{name:c,value:d}=Fe.reduce((p,g)=>g(p),{name:i,value:o});return c!==i&&t(c,i),{name:c,value:d}}}var Fe=[];function _e(t){Fe.push(t)}function Re({name:t}){return je().test(t)}var je=()=>new RegExp(`^${en}([^:^.]+)\\b`);function rt(t,i){return({name:o,value:c})=>{let d=o.match(je()),p=o.match(/:([a-zA-Z0-9\-_:]+)/),g=o.match(/\.[^.\]]+(?=[^\]]*$)/g)||[],x=i||t[o]||o;return{type:d?d[1]:null,value:p?p[1]:null,modifiers:g.map(M=>M.replace(".","")),expression:c,original:x}}}var Ie="DEFAULT",Ke=["ignore","ref","data","id","anchor","bind","init","for","model","modelable","transition","show","if",Ie,"teleport"];function ct(t,i){let o=Ke.indexOf(t.type)===-1?Ie:t.type,c=Ke.indexOf(i.type)===-1?Ie:i.type;return Ke.indexOf(o)-Ke.indexOf(c)}function mt(t,i,o={}){t.dispatchEvent(new CustomEvent(i,{detail:o,bubbles:!0,composed:!0,cancelable:!0}))}function Xe(t,i){if(typeof ShadowRoot=="function"&&t instanceof ShadowRoot){Array.from(t.children).forEach(d=>Xe(d,i));return}let o=!1;if(i(t,()=>o=!0),o)return;let c=t.firstElementChild;for(;c;)Xe(c,i),c=c.nextElementSibling}function ft(t,...i){console.warn(`Alpine Warning: ${t}`,...i)}var dr=!1;function pr(){dr&&ft("Alpine has already been initialized on this page. Calling Alpine.start() more than once can cause problems."),dr=!0,document.body||ft("Unable to initialize. Trying to load Alpine before `` is available. Did you forget to add `defer` in Alpine's ` + diff --git a/resources/views/portal/ninja2020/invoices/payment.blade.php b/resources/views/portal/ninja2020/invoices/payment.blade.php index f11b69c723..4887ae40a2 100644 --- a/resources/views/portal/ninja2020/invoices/payment.blade.php +++ b/resources/views/portal/ninja2020/invoices/payment.blade.php @@ -22,6 +22,9 @@ + + +
From 0f8737bdf7f6d831cfdd73db8d5fcb1d589571e5 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Sat, 27 Jul 2024 15:18:21 +1000 Subject: [PATCH 08/12] Updates for paypal + RFF --- .../ClientPortal/InvitationController.php | 4 +- .../ClientPortal/PaymentController.php | 10 +- app/Models/ClientContact.php | 6 +- app/Services/ClientPortal/InstantPayment.php | 13 +- composer.lock | 338 +++++++++--------- public/build/manifest.json | 4 +- resources/js/clients/invoices/payment.js | 80 ++--- .../includes/required-fields.blade.php | 6 +- .../ninja2020/invoices/payment.blade.php | 1 - .../portal/ninja2020/invoices/show.blade.php | 1 - 10 files changed, 232 insertions(+), 231 deletions(-) diff --git a/app/Http/Controllers/ClientPortal/InvitationController.php b/app/Http/Controllers/ClientPortal/InvitationController.php index f1993693a9..ec30aacc37 100644 --- a/app/Http/Controllers/ClientPortal/InvitationController.php +++ b/app/Http/Controllers/ClientPortal/InvitationController.php @@ -300,7 +300,9 @@ class InvitationController extends Controller 'signature' => false, 'contact_first_name' => $invitation->contact->first_name ?? '', 'contact_last_name' => $invitation->contact->last_name ?? '', - 'contact_email' => $invitation->contact->email ?? '' + 'contact_email' => $invitation->contact->email ?? '', + 'client_city' => $invitation->client->city ?? '', + 'client_postal_code' => $invitation->client->postal_code ?? '', ]; $request->replace($data); diff --git a/app/Http/Controllers/ClientPortal/PaymentController.php b/app/Http/Controllers/ClientPortal/PaymentController.php index 728df5eb1d..94a46bd5cb 100644 --- a/app/Http/Controllers/ClientPortal/PaymentController.php +++ b/app/Http/Controllers/ClientPortal/PaymentController.php @@ -108,11 +108,11 @@ class PaymentController extends Controller */ public function process(Request $request) { - $request->validate([ - 'contact_first_name' => ['required'], - 'contact_last_name' => ['required'], - 'contact_email' => ['required', 'email'], - ]); + // $request->validate([ + // 'contact_first_name' => ['required'], + // 'contact_last_name' => ['required'], + // 'contact_email' => ['required', 'email'], + // ]); return (new InstantPayment($request))->run(); } diff --git a/app/Models/ClientContact.php b/app/Models/ClientContact.php index fd47d0e6fe..0885db2c6c 100644 --- a/app/Models/ClientContact.php +++ b/app/Models/ClientContact.php @@ -351,9 +351,9 @@ class ClientContact extends Authenticatable implements HasLocalePreference public function showRff(): bool { - if (\strlen($this->first_name) === 0 || \strlen($this->last_name) === 0 || \strlen($this->email) === 0) { - return true; - } + // if (\strlen($this->first_name ?? '') === 0 || \strlen($this->last_name ?? '') === 0 || \strlen($this->email ?? '') === 0) { + // return true; + // } return false; } diff --git a/app/Services/ClientPortal/InstantPayment.php b/app/Services/ClientPortal/InstantPayment.php index d46052fafb..f41e4ff1b4 100644 --- a/app/Services/ClientPortal/InstantPayment.php +++ b/app/Services/ClientPortal/InstantPayment.php @@ -44,17 +44,16 @@ class InstantPayment public function run() { - nlog($this->request->all()); - /** @var \App\Models\ClientContact $cc */ - $cc = auth()->guard('contact')->user(); - $cc->first_name = $this->request->contact_first_name; $cc->last_name = $this->request->contact_last_name; $cc->email = $this->request->contact_email; - - $cc->save(); + $cc->client->postal_code = strlen($cc->client->postal_code ?? '') > 1 ? $cc->client->postal_code : $this->request->client_postal_code; + $cc->client->city = strlen($cc->client->city ?? '') > 1 ? $cc->client->city : $this->request->client_city; + $cc->client->shipping_postal_code = strlen($cc->client->shipping_postal_code ?? '') > 1 ? $cc->client->shipping_postal_code : $cc->client->postal_code; + $cc->client->shipping_city = strlen($cc->client->shipping_city ?? '') > 1 ? $cc->client->shipping_city : $cc->client->city; + $cc->pushQuietly(); $is_credit_payment = false; @@ -73,8 +72,6 @@ class InstantPayment */ $payable_invoices = collect($this->request->payable_invoices); - nlog($payable_invoices); - $invoices = Invoice::query()->whereIn('id', $this->transformKeys($payable_invoices->pluck('invoice_id')->toArray()))->withTrashed()->get(); $invoices->each(function ($invoice) { diff --git a/composer.lock b/composer.lock index 4d331a5d00..f736181bd8 100644 --- a/composer.lock +++ b/composer.lock @@ -740,16 +740,16 @@ }, { "name": "braintree/braintree_php", - "version": "6.18.0", + "version": "6.19.0", "source": { "type": "git", "url": "https://github.com/braintree/braintree_php.git", - "reference": "8ca67004fe2405ef0b6b33a5897594fdcf417e0e" + "reference": "f3178632ca098d1f96a429d665aabc4e95346c03" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/braintree/braintree_php/zipball/8ca67004fe2405ef0b6b33a5897594fdcf417e0e", - "reference": "8ca67004fe2405ef0b6b33a5897594fdcf417e0e", + "url": "https://api.github.com/repos/braintree/braintree_php/zipball/f3178632ca098d1f96a429d665aabc4e95346c03", + "reference": "f3178632ca098d1f96a429d665aabc4e95346c03", "shasum": "" }, "require": { @@ -783,9 +783,9 @@ "description": "Braintree PHP Client Library", "support": { "issues": "https://github.com/braintree/braintree_php/issues", - "source": "https://github.com/braintree/braintree_php/tree/6.18.0" + "source": "https://github.com/braintree/braintree_php/tree/6.19.0" }, - "time": "2024-03-26T21:08:13+00:00" + "time": "2024-07-23T20:09:58+00:00" }, { "name": "brick/math", @@ -2804,16 +2804,16 @@ }, { "name": "guzzlehttp/guzzle", - "version": "7.9.1", + "version": "7.9.2", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "a629e5b69db96eb4939c1b34114130077dd4c6fc" + "reference": "d281ed313b989f213357e3be1a179f02196ac99b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/a629e5b69db96eb4939c1b34114130077dd4c6fc", - "reference": "a629e5b69db96eb4939c1b34114130077dd4c6fc", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/d281ed313b989f213357e3be1a179f02196ac99b", + "reference": "d281ed313b989f213357e3be1a179f02196ac99b", "shasum": "" }, "require": { @@ -2910,7 +2910,7 @@ ], "support": { "issues": "https://github.com/guzzle/guzzle/issues", - "source": "https://github.com/guzzle/guzzle/tree/7.9.1" + "source": "https://github.com/guzzle/guzzle/tree/7.9.2" }, "funding": [ { @@ -2926,7 +2926,7 @@ "type": "tidelift" } ], - "time": "2024-07-19T16:19:57+00:00" + "time": "2024-07-24T11:22:20+00:00" }, { "name": "guzzlehttp/promises", @@ -4614,16 +4614,16 @@ }, { "name": "laravel/framework", - "version": "v11.16.0", + "version": "v11.18.1", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "bd4808aaf103ccb5cb4b00bcee46140c070c0ec4" + "reference": "b19ba518c56852567e99fbae9321bc436c2cc5a8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/bd4808aaf103ccb5cb4b00bcee46140c070c0ec4", - "reference": "bd4808aaf103ccb5cb4b00bcee46140c070c0ec4", + "url": "https://api.github.com/repos/laravel/framework/zipball/b19ba518c56852567e99fbae9321bc436c2cc5a8", + "reference": "b19ba518c56852567e99fbae9321bc436c2cc5a8", "shasum": "" }, "require": { @@ -4816,20 +4816,20 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2024-07-16T14:33:07+00:00" + "time": "2024-07-26T10:39:29+00:00" }, { "name": "laravel/pint", - "version": "v1.16.2", + "version": "v1.17.0", "source": { "type": "git", "url": "https://github.com/laravel/pint.git", - "reference": "51f1ba679a6afe0315621ad143d788bd7ded0eca" + "reference": "4dba80c1de4b81dc4c4fb10ea6f4781495eb29f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/pint/zipball/51f1ba679a6afe0315621ad143d788bd7ded0eca", - "reference": "51f1ba679a6afe0315621ad143d788bd7ded0eca", + "url": "https://api.github.com/repos/laravel/pint/zipball/4dba80c1de4b81dc4c4fb10ea6f4781495eb29f5", + "reference": "4dba80c1de4b81dc4c4fb10ea6f4781495eb29f5", "shasum": "" }, "require": { @@ -4882,7 +4882,7 @@ "issues": "https://github.com/laravel/pint/issues", "source": "https://github.com/laravel/pint" }, - "time": "2024-07-09T15:58:08+00:00" + "time": "2024-07-23T16:40:20+00:00" }, { "name": "laravel/prompts", @@ -5004,16 +5004,16 @@ }, { "name": "laravel/slack-notification-channel", - "version": "v3.2.0", + "version": "v3.3.0", "source": { "type": "git", "url": "https://github.com/laravel/slack-notification-channel.git", - "reference": "fc8d1873e3db63a480bc57aebb4bf5ec05332d91" + "reference": "8cd988fad1a08ed88dfd852f140477376c60217f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/slack-notification-channel/zipball/fc8d1873e3db63a480bc57aebb4bf5ec05332d91", - "reference": "fc8d1873e3db63a480bc57aebb4bf5ec05332d91", + "url": "https://api.github.com/repos/laravel/slack-notification-channel/zipball/8cd988fad1a08ed88dfd852f140477376c60217f", + "reference": "8cd988fad1a08ed88dfd852f140477376c60217f", "shasum": "" }, "require": { @@ -5063,9 +5063,9 @@ ], "support": { "issues": "https://github.com/laravel/slack-notification-channel/issues", - "source": "https://github.com/laravel/slack-notification-channel/tree/v3.2.0" + "source": "https://github.com/laravel/slack-notification-channel/tree/v3.3.0" }, - "time": "2024-01-15T20:07:45+00:00" + "time": "2024-07-10T19:39:44+00:00" }, { "name": "laravel/socialite", @@ -5407,16 +5407,16 @@ }, { "name": "league/commonmark", - "version": "2.5.0", + "version": "2.5.1", "source": { "type": "git", "url": "https://github.com/thephpleague/commonmark.git", - "reference": "0026475f5c9a104410ae824cb5a4d63fa3bdb1df" + "reference": "ac815920de0eff6de947eac0a6a94e5ed0fb147c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/0026475f5c9a104410ae824cb5a4d63fa3bdb1df", - "reference": "0026475f5c9a104410ae824cb5a4d63fa3bdb1df", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/ac815920de0eff6de947eac0a6a94e5ed0fb147c", + "reference": "ac815920de0eff6de947eac0a6a94e5ed0fb147c", "shasum": "" }, "require": { @@ -5509,7 +5509,7 @@ "type": "tidelift" } ], - "time": "2024-07-22T18:18:14+00:00" + "time": "2024-07-24T12:52:09+00:00" }, { "name": "league/config", @@ -11342,16 +11342,16 @@ }, { "name": "symfony/console", - "version": "v7.1.2", + "version": "v7.1.3", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "0aa29ca177f432ab68533432db0de059f39c92ae" + "reference": "cb1dcb30ebc7005c29864ee78adb47b5fb7c3cd9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/0aa29ca177f432ab68533432db0de059f39c92ae", - "reference": "0aa29ca177f432ab68533432db0de059f39c92ae", + "url": "https://api.github.com/repos/symfony/console/zipball/cb1dcb30ebc7005c29864ee78adb47b5fb7c3cd9", + "reference": "cb1dcb30ebc7005c29864ee78adb47b5fb7c3cd9", "shasum": "" }, "require": { @@ -11415,7 +11415,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.1.2" + "source": "https://github.com/symfony/console/tree/v7.1.3" }, "funding": [ { @@ -11431,7 +11431,7 @@ "type": "tidelift" } ], - "time": "2024-06-28T10:03:55+00:00" + "time": "2024-07-26T12:41:01+00:00" }, { "name": "symfony/css-selector", @@ -11567,16 +11567,16 @@ }, { "name": "symfony/error-handler", - "version": "v7.1.2", + "version": "v7.1.3", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "2412d3dddb5c9ea51a39cfbff1c565fc9844ca32" + "reference": "432bb369952795c61ca1def65e078c4a80dad13c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/2412d3dddb5c9ea51a39cfbff1c565fc9844ca32", - "reference": "2412d3dddb5c9ea51a39cfbff1c565fc9844ca32", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/432bb369952795c61ca1def65e078c4a80dad13c", + "reference": "432bb369952795c61ca1def65e078c4a80dad13c", "shasum": "" }, "require": { @@ -11622,7 +11622,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/error-handler/tree/v7.1.2" + "source": "https://github.com/symfony/error-handler/tree/v7.1.3" }, "funding": [ { @@ -11638,7 +11638,7 @@ "type": "tidelift" } ], - "time": "2024-06-25T19:55:06+00:00" + "time": "2024-07-26T13:02:51+00:00" }, { "name": "symfony/event-dispatcher", @@ -11864,16 +11864,16 @@ }, { "name": "symfony/finder", - "version": "v7.1.1", + "version": "v7.1.3", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "fbb0ba67688b780efbc886c1a0a0948dcf7205d6" + "reference": "717c6329886f32dc65e27461f80f2a465412fdca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/fbb0ba67688b780efbc886c1a0a0948dcf7205d6", - "reference": "fbb0ba67688b780efbc886c1a0a0948dcf7205d6", + "url": "https://api.github.com/repos/symfony/finder/zipball/717c6329886f32dc65e27461f80f2a465412fdca", + "reference": "717c6329886f32dc65e27461f80f2a465412fdca", "shasum": "" }, "require": { @@ -11908,7 +11908,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v7.1.1" + "source": "https://github.com/symfony/finder/tree/v7.1.3" }, "funding": [ { @@ -11924,20 +11924,20 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:57:53+00:00" + "time": "2024-07-24T07:08:44+00:00" }, { "name": "symfony/http-client", - "version": "v6.4.9", + "version": "v6.4.10", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "6e9db0025db565bcf8f1d46ed734b549e51e6045" + "reference": "b5e498f763e0bf5eed8dcd946e50a3b3f71d4ded" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/6e9db0025db565bcf8f1d46ed734b549e51e6045", - "reference": "6e9db0025db565bcf8f1d46ed734b549e51e6045", + "url": "https://api.github.com/repos/symfony/http-client/zipball/b5e498f763e0bf5eed8dcd946e50a3b3f71d4ded", + "reference": "b5e498f763e0bf5eed8dcd946e50a3b3f71d4ded", "shasum": "" }, "require": { @@ -12001,7 +12001,7 @@ "http" ], "support": { - "source": "https://github.com/symfony/http-client/tree/v6.4.9" + "source": "https://github.com/symfony/http-client/tree/v6.4.10" }, "funding": [ { @@ -12017,7 +12017,7 @@ "type": "tidelift" } ], - "time": "2024-06-28T07:59:05+00:00" + "time": "2024-07-15T09:26:24+00:00" }, { "name": "symfony/http-client-contracts", @@ -12099,16 +12099,16 @@ }, { "name": "symfony/http-foundation", - "version": "v7.1.1", + "version": "v7.1.3", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "74d171d5b6a1d9e4bfee09a41937c17a7536acfa" + "reference": "f602d5c17d1fa02f8019ace2687d9d136b7f4a1a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/74d171d5b6a1d9e4bfee09a41937c17a7536acfa", - "reference": "74d171d5b6a1d9e4bfee09a41937c17a7536acfa", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/f602d5c17d1fa02f8019ace2687d9d136b7f4a1a", + "reference": "f602d5c17d1fa02f8019ace2687d9d136b7f4a1a", "shasum": "" }, "require": { @@ -12156,7 +12156,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v7.1.1" + "source": "https://github.com/symfony/http-foundation/tree/v7.1.3" }, "funding": [ { @@ -12172,20 +12172,20 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:57:53+00:00" + "time": "2024-07-26T12:41:01+00:00" }, { "name": "symfony/http-kernel", - "version": "v7.1.2", + "version": "v7.1.3", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "ae3fa717db4d41a55d14c2bd92399e37cf5bc0f6" + "reference": "db9702f3a04cc471ec8c70e881825db26ac5f186" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/ae3fa717db4d41a55d14c2bd92399e37cf5bc0f6", - "reference": "ae3fa717db4d41a55d14c2bd92399e37cf5bc0f6", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/db9702f3a04cc471ec8c70e881825db26ac5f186", + "reference": "db9702f3a04cc471ec8c70e881825db26ac5f186", "shasum": "" }, "require": { @@ -12270,7 +12270,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v7.1.2" + "source": "https://github.com/symfony/http-kernel/tree/v7.1.3" }, "funding": [ { @@ -12286,7 +12286,7 @@ "type": "tidelift" } ], - "time": "2024-06-28T13:13:31+00:00" + "time": "2024-07-26T14:58:15+00:00" }, { "name": "symfony/intl", @@ -12456,16 +12456,16 @@ }, { "name": "symfony/mailgun-mailer", - "version": "v6.4.9", + "version": "v6.4.10", "source": { "type": "git", "url": "https://github.com/symfony/mailgun-mailer.git", - "reference": "c4917eb14f31fb5c21442375c6baf7f51bd924e8" + "reference": "3eb7c7b644179a766f5d816620b7b6d4a4e7ec43" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mailgun-mailer/zipball/c4917eb14f31fb5c21442375c6baf7f51bd924e8", - "reference": "c4917eb14f31fb5c21442375c6baf7f51bd924e8", + "url": "https://api.github.com/repos/symfony/mailgun-mailer/zipball/3eb7c7b644179a766f5d816620b7b6d4a4e7ec43", + "reference": "3eb7c7b644179a766f5d816620b7b6d4a4e7ec43", "shasum": "" }, "require": { @@ -12505,7 +12505,7 @@ "description": "Symfony Mailgun Mailer Bridge", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/mailgun-mailer/tree/v6.4.9" + "source": "https://github.com/symfony/mailgun-mailer/tree/v6.4.10" }, "funding": [ { @@ -12521,7 +12521,7 @@ "type": "tidelift" } ], - "time": "2024-06-28T07:59:05+00:00" + "time": "2024-07-04T11:16:22+00:00" }, { "name": "symfony/mime", @@ -13540,16 +13540,16 @@ }, { "name": "symfony/process", - "version": "v7.1.1", + "version": "v7.1.3", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "febf90124323a093c7ee06fdb30e765ca3c20028" + "reference": "7f2f542c668ad6c313dc4a5e9c3321f733197eca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/febf90124323a093c7ee06fdb30e765ca3c20028", - "reference": "febf90124323a093c7ee06fdb30e765ca3c20028", + "url": "https://api.github.com/repos/symfony/process/zipball/7f2f542c668ad6c313dc4a5e9c3321f733197eca", + "reference": "7f2f542c668ad6c313dc4a5e9c3321f733197eca", "shasum": "" }, "require": { @@ -13581,7 +13581,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v7.1.1" + "source": "https://github.com/symfony/process/tree/v7.1.3" }, "funding": [ { @@ -13597,7 +13597,7 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:57:53+00:00" + "time": "2024-07-26T12:44:47+00:00" }, { "name": "symfony/property-access", @@ -13677,16 +13677,16 @@ }, { "name": "symfony/property-info", - "version": "v7.1.2", + "version": "v7.1.3", "source": { "type": "git", "url": "https://github.com/symfony/property-info.git", - "reference": "d7b91e4aa07e822a9b935fc29a7254c12d502f16" + "reference": "88a279df2db5b7919cac6f35d6a5d1d7147e6a9b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-info/zipball/d7b91e4aa07e822a9b935fc29a7254c12d502f16", - "reference": "d7b91e4aa07e822a9b935fc29a7254c12d502f16", + "url": "https://api.github.com/repos/symfony/property-info/zipball/88a279df2db5b7919cac6f35d6a5d1d7147e6a9b", + "reference": "88a279df2db5b7919cac6f35d6a5d1d7147e6a9b", "shasum": "" }, "require": { @@ -13741,7 +13741,7 @@ "validator" ], "support": { - "source": "https://github.com/symfony/property-info/tree/v7.1.2" + "source": "https://github.com/symfony/property-info/tree/v7.1.3" }, "funding": [ { @@ -13757,20 +13757,20 @@ "type": "tidelift" } ], - "time": "2024-06-26T07:21:35+00:00" + "time": "2024-07-26T07:36:36+00:00" }, { "name": "symfony/psr-http-message-bridge", - "version": "v7.1.1", + "version": "v7.1.3", "source": { "type": "git", "url": "https://github.com/symfony/psr-http-message-bridge.git", - "reference": "9a5dbb606da711f5d40a7596ad577856f9402140" + "reference": "1365d10f5476f74a27cf9c2d1eee70c069019db0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/9a5dbb606da711f5d40a7596ad577856f9402140", - "reference": "9a5dbb606da711f5d40a7596ad577856f9402140", + "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/1365d10f5476f74a27cf9c2d1eee70c069019db0", + "reference": "1365d10f5476f74a27cf9c2d1eee70c069019db0", "shasum": "" }, "require": { @@ -13824,7 +13824,7 @@ "psr-7" ], "support": { - "source": "https://github.com/symfony/psr-http-message-bridge/tree/v7.1.1" + "source": "https://github.com/symfony/psr-http-message-bridge/tree/v7.1.3" }, "funding": [ { @@ -13840,20 +13840,20 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:57:53+00:00" + "time": "2024-07-17T06:10:24+00:00" }, { "name": "symfony/routing", - "version": "v7.1.1", + "version": "v7.1.3", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "60c31bab5c45af7f13091b87deb708830f3c96c0" + "reference": "8a908a3f22d5a1b5d297578c2ceb41b02fa916d0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/60c31bab5c45af7f13091b87deb708830f3c96c0", - "reference": "60c31bab5c45af7f13091b87deb708830f3c96c0", + "url": "https://api.github.com/repos/symfony/routing/zipball/8a908a3f22d5a1b5d297578c2ceb41b02fa916d0", + "reference": "8a908a3f22d5a1b5d297578c2ceb41b02fa916d0", "shasum": "" }, "require": { @@ -13905,7 +13905,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v7.1.1" + "source": "https://github.com/symfony/routing/tree/v7.1.3" }, "funding": [ { @@ -13921,20 +13921,20 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:57:53+00:00" + "time": "2024-07-17T06:10:24+00:00" }, { "name": "symfony/serializer", - "version": "v7.1.2", + "version": "v7.1.3", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "d2077674aaaff02a95f290de512aa358947e6bbe" + "reference": "0d5ddac365fbfffc30ca9bc944ad3eb9b3763c09" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/d2077674aaaff02a95f290de512aa358947e6bbe", - "reference": "d2077674aaaff02a95f290de512aa358947e6bbe", + "url": "https://api.github.com/repos/symfony/serializer/zipball/0d5ddac365fbfffc30ca9bc944ad3eb9b3763c09", + "reference": "0d5ddac365fbfffc30ca9bc944ad3eb9b3763c09", "shasum": "" }, "require": { @@ -14002,7 +14002,7 @@ "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/serializer/tree/v7.1.2" + "source": "https://github.com/symfony/serializer/tree/v7.1.3" }, "funding": [ { @@ -14018,7 +14018,7 @@ "type": "tidelift" } ], - "time": "2024-06-28T07:42:43+00:00" + "time": "2024-07-17T06:10:24+00:00" }, { "name": "symfony/service-contracts", @@ -14105,16 +14105,16 @@ }, { "name": "symfony/string", - "version": "v7.1.2", + "version": "v7.1.3", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "14221089ac66cf82e3cf3d1c1da65de305587ff8" + "reference": "ea272a882be7f20cad58d5d78c215001617b7f07" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/14221089ac66cf82e3cf3d1c1da65de305587ff8", - "reference": "14221089ac66cf82e3cf3d1c1da65de305587ff8", + "url": "https://api.github.com/repos/symfony/string/zipball/ea272a882be7f20cad58d5d78c215001617b7f07", + "reference": "ea272a882be7f20cad58d5d78c215001617b7f07", "shasum": "" }, "require": { @@ -14172,7 +14172,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.1.2" + "source": "https://github.com/symfony/string/tree/v7.1.3" }, "funding": [ { @@ -14188,20 +14188,20 @@ "type": "tidelift" } ], - "time": "2024-06-28T09:27:18+00:00" + "time": "2024-07-22T10:25:37+00:00" }, { "name": "symfony/translation", - "version": "v7.1.1", + "version": "v7.1.3", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "cf5ae136e124fc7681b34ce9fac9d5b9ae8ceee3" + "reference": "8d5e50c813ba2859a6dfc99a0765c550507934a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/cf5ae136e124fc7681b34ce9fac9d5b9ae8ceee3", - "reference": "cf5ae136e124fc7681b34ce9fac9d5b9ae8ceee3", + "url": "https://api.github.com/repos/symfony/translation/zipball/8d5e50c813ba2859a6dfc99a0765c550507934a1", + "reference": "8d5e50c813ba2859a6dfc99a0765c550507934a1", "shasum": "" }, "require": { @@ -14266,7 +14266,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v7.1.1" + "source": "https://github.com/symfony/translation/tree/v7.1.3" }, "funding": [ { @@ -14282,7 +14282,7 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:57:53+00:00" + "time": "2024-07-26T12:41:01+00:00" }, { "name": "symfony/translation-contracts", @@ -14520,16 +14520,16 @@ }, { "name": "symfony/validator", - "version": "v7.1.2", + "version": "v7.1.3", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "bed12b7d5bd4dac452db5fa6203331c876b489e7" + "reference": "ba711a6cfc008544dad059abb3c1d997f1472237" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/bed12b7d5bd4dac452db5fa6203331c876b489e7", - "reference": "bed12b7d5bd4dac452db5fa6203331c876b489e7", + "url": "https://api.github.com/repos/symfony/validator/zipball/ba711a6cfc008544dad059abb3c1d997f1472237", + "reference": "ba711a6cfc008544dad059abb3c1d997f1472237", "shasum": "" }, "require": { @@ -14597,7 +14597,7 @@ "description": "Provides tools to validate values", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/validator/tree/v7.1.2" + "source": "https://github.com/symfony/validator/tree/v7.1.3" }, "funding": [ { @@ -14613,20 +14613,20 @@ "type": "tidelift" } ], - "time": "2024-06-25T19:55:06+00:00" + "time": "2024-07-26T12:41:01+00:00" }, { "name": "symfony/var-dumper", - "version": "v7.1.2", + "version": "v7.1.3", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "5857c57c6b4b86524c08cf4f4bc95327270a816d" + "reference": "86af4617cca75a6e28598f49ae0690f3b9d4591f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/5857c57c6b4b86524c08cf4f4bc95327270a816d", - "reference": "5857c57c6b4b86524c08cf4f4bc95327270a816d", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/86af4617cca75a6e28598f49ae0690f3b9d4591f", + "reference": "86af4617cca75a6e28598f49ae0690f3b9d4591f", "shasum": "" }, "require": { @@ -14680,7 +14680,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v7.1.2" + "source": "https://github.com/symfony/var-dumper/tree/v7.1.3" }, "funding": [ { @@ -14696,7 +14696,7 @@ "type": "tidelift" } ], - "time": "2024-06-28T08:00:31+00:00" + "time": "2024-07-26T12:41:01+00:00" }, { "name": "symfony/yaml", @@ -15856,30 +15856,38 @@ }, { "name": "composer/pcre", - "version": "3.1.4", + "version": "3.2.0", "source": { "type": "git", "url": "https://github.com/composer/pcre.git", - "reference": "04229f163664973f68f38f6f73d917799168ef24" + "reference": "ea4ab6f9580a4fd221e0418f2c357cdd39102a90" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/pcre/zipball/04229f163664973f68f38f6f73d917799168ef24", - "reference": "04229f163664973f68f38f6f73d917799168ef24", + "url": "https://api.github.com/repos/composer/pcre/zipball/ea4ab6f9580a4fd221e0418f2c357cdd39102a90", + "reference": "ea4ab6f9580a4fd221e0418f2c357cdd39102a90", "shasum": "" }, "require": { "php": "^7.4 || ^8.0" }, + "conflict": { + "phpstan/phpstan": "<1.11.8" + }, "require-dev": { - "phpstan/phpstan": "^1.3", + "phpstan/phpstan": "^1.11.8", "phpstan/phpstan-strict-rules": "^1.1", - "symfony/phpunit-bridge": "^5" + "phpunit/phpunit": "^8 || ^9" }, "type": "library", "extra": { "branch-alias": { "dev-main": "3.x-dev" + }, + "phpstan": { + "includes": [ + "extension.neon" + ] } }, "autoload": { @@ -15907,7 +15915,7 @@ ], "support": { "issues": "https://github.com/composer/pcre/issues", - "source": "https://github.com/composer/pcre/tree/3.1.4" + "source": "https://github.com/composer/pcre/tree/3.2.0" }, "funding": [ { @@ -15923,7 +15931,7 @@ "type": "tidelift" } ], - "time": "2024-05-27T13:40:54+00:00" + "time": "2024-07-25T09:36:02+00:00" }, { "name": "composer/semver", @@ -16253,16 +16261,16 @@ }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.59.3", + "version": "v3.60.0", "source": { "type": "git", "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", - "reference": "30ba9ecc2b0e5205e578fe29973c15653d9bfd29" + "reference": "e595e4e070d17c5d42ed8c4206f630fcc5f401a4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/30ba9ecc2b0e5205e578fe29973c15653d9bfd29", - "reference": "30ba9ecc2b0e5205e578fe29973c15653d9bfd29", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/e595e4e070d17c5d42ed8c4206f630fcc5f401a4", + "reference": "e595e4e070d17c5d42ed8c4206f630fcc5f401a4", "shasum": "" }, "require": { @@ -16344,7 +16352,7 @@ ], "support": { "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", - "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.59.3" + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.60.0" }, "funding": [ { @@ -16352,7 +16360,7 @@ "type": "github" } ], - "time": "2024-06-16T14:17:03+00:00" + "time": "2024-07-25T09:26:51+00:00" }, { "name": "hamcrest/hamcrest-php", @@ -17022,16 +17030,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.11.7", + "version": "1.11.8", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "52d2bbfdcae7f895915629e4694e9497d0f8e28d" + "reference": "6adbd118e6c0515dd2f36b06cde1d6da40f1b8ec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/52d2bbfdcae7f895915629e4694e9497d0f8e28d", - "reference": "52d2bbfdcae7f895915629e4694e9497d0f8e28d", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/6adbd118e6c0515dd2f36b06cde1d6da40f1b8ec", + "reference": "6adbd118e6c0515dd2f36b06cde1d6da40f1b8ec", "shasum": "" }, "require": { @@ -17076,7 +17084,7 @@ "type": "github" } ], - "time": "2024-07-06T11:17:41+00:00" + "time": "2024-07-24T07:01:22+00:00" }, { "name": "phpunit/php-code-coverage", @@ -17874,31 +17882,31 @@ }, { "name": "react/socket", - "version": "v1.15.0", + "version": "v1.16.0", "source": { "type": "git", "url": "https://github.com/reactphp/socket.git", - "reference": "216d3aec0b87f04a40ca04f481e6af01bdd1d038" + "reference": "23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/reactphp/socket/zipball/216d3aec0b87f04a40ca04f481e6af01bdd1d038", - "reference": "216d3aec0b87f04a40ca04f481e6af01bdd1d038", + "url": "https://api.github.com/repos/reactphp/socket/zipball/23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1", + "reference": "23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1", "shasum": "" }, "require": { "evenement/evenement": "^3.0 || ^2.0 || ^1.0", "php": ">=5.3.0", - "react/dns": "^1.11", + "react/dns": "^1.13", "react/event-loop": "^1.2", - "react/promise": "^3 || ^2.6 || ^1.2.1", - "react/stream": "^1.2" + "react/promise": "^3.2 || ^2.6 || ^1.2.1", + "react/stream": "^1.4" }, "require-dev": { "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", - "react/async": "^4 || ^3 || ^2", + "react/async": "^4.3 || ^3.3 || ^2", "react/promise-stream": "^1.4", - "react/promise-timer": "^1.10" + "react/promise-timer": "^1.11" }, "type": "library", "autoload": { @@ -17942,7 +17950,7 @@ ], "support": { "issues": "https://github.com/reactphp/socket/issues", - "source": "https://github.com/reactphp/socket/tree/v1.15.0" + "source": "https://github.com/reactphp/socket/tree/v1.16.0" }, "funding": [ { @@ -17950,7 +17958,7 @@ "type": "open_collective" } ], - "time": "2023-12-15T11:02:10+00:00" + "time": "2024-07-26T10:38:09+00:00" }, { "name": "react/stream", @@ -19011,16 +19019,16 @@ }, { "name": "spatie/error-solutions", - "version": "1.1.0", + "version": "1.1.1", "source": { "type": "git", "url": "https://github.com/spatie/error-solutions.git", - "reference": "a014da18f2675ea15af0ba97f7e9aee59e13964f" + "reference": "ae7393122eda72eed7cc4f176d1e96ea444f2d67" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/error-solutions/zipball/a014da18f2675ea15af0ba97f7e9aee59e13964f", - "reference": "a014da18f2675ea15af0ba97f7e9aee59e13964f", + "url": "https://api.github.com/repos/spatie/error-solutions/zipball/ae7393122eda72eed7cc4f176d1e96ea444f2d67", + "reference": "ae7393122eda72eed7cc4f176d1e96ea444f2d67", "shasum": "" }, "require": { @@ -19073,7 +19081,7 @@ ], "support": { "issues": "https://github.com/spatie/error-solutions/issues", - "source": "https://github.com/spatie/error-solutions/tree/1.1.0" + "source": "https://github.com/spatie/error-solutions/tree/1.1.1" }, "funding": [ { @@ -19081,7 +19089,7 @@ "type": "github" } ], - "time": "2024-07-22T08:18:22+00:00" + "time": "2024-07-25T11:06:04+00:00" }, { "name": "spatie/flare-client-php", diff --git a/public/build/manifest.json b/public/build/manifest.json index 54285537f0..4ae4f8058d 100644 --- a/public/build/manifest.json +++ b/public/build/manifest.json @@ -23,7 +23,7 @@ "src": "resources/js/clients/invoices/action-selectors.js" }, "resources/js/clients/invoices/payment.js": { - "file": "assets/payment-357f3929.js", + "file": "assets/payment-36249364.js", "isEntry": true, "src": "resources/js/clients/invoices/payment.js" }, @@ -240,7 +240,7 @@ "src": "resources/js/setup/setup.js" }, "resources/sass/app.scss": { - "file": "assets/app-906435d5.css", + "file": "assets/app-ec452b34.css", "isEntry": true, "src": "resources/sass/app.scss" } diff --git a/resources/js/clients/invoices/payment.js b/resources/js/clients/invoices/payment.js index 9a5981e1f4..2efdea6782 100644 --- a/resources/js/clients/invoices/payment.js +++ b/resources/js/clients/invoices/payment.js @@ -9,41 +9,47 @@ */ class Payment { - constructor(displayTerms, displaySignature, displayRff) { + constructor(displayTerms, displaySignature) { this.shouldDisplayTerms = displayTerms; this.shouldDisplaySignature = displaySignature; - this.shouldDisplayRff = displayRff; - + this.submitting = false; this.steps = new Map() - if (this.shouldDisplayRff) { - - this.steps.set("rff", { - element: document.getElementById('displayRequiredFieldsModal'), - nextButton: document.getElementById('rff-next-step'), - callback: () => { - const fields = { - firstName: document.querySelector('input[name="rff_first_name"]'), - lastName: document.querySelector('input[name="rff_last_name"]'), - email: document.querySelector('input[name="rff_email"]'), - } - - if (fields.firstName) { - document.querySelector('input[name="contact_first_name"]').value = fields.firstName.value; - } - - if (fields.lastName) { - document.querySelector('input[name="contact_last_name"]').value = fields.lastName.value; - } - - if (fields.email) { - document.querySelector('input[name="contact_email"]').value = fields.email.value; - } - + this.steps.set("rff", { + element: document.getElementById('displayRequiredFieldsModal'), + nextButton: document.getElementById('rff-next-step'), + callback: () => { + const fields = { + firstName: document.querySelector('input[name="rff_first_name"]'), + lastName: document.querySelector('input[name="rff_last_name"]'), + email: document.querySelector('input[name="rff_email"]'), + city: document.querySelector('input[name="rff_city"]'), + postalCode: document.querySelector('input[name="rff_postal_code"]'), } - }); - } + + if (fields.firstName) { + document.querySelector('input[name="contact_first_name"]').value = fields.firstName.value; + } + + if (fields.lastName) { + document.querySelector('input[name="contact_last_name"]').value = fields.lastName.value; + } + + if (fields.email) { + document.querySelector('input[name="contact_email"]').value = fields.email.value; + } + + if (fields.city) { + document.querySelector('input[name="client_city"]').value = fields.city.value; + } + + if (fields.postalCode) { + document.querySelector('input[name="client_postal_code"]').value = fields.postalCode.value; + } + + } + }); if (this.shouldDisplaySignature) { this.steps.set("signature", { @@ -74,17 +80,8 @@ class Payment { document.getElementById("payment_method_id").value = element.dataset.gatewayTypeId; - if (element.dataset.isPaypal == '1') { - - var rff_city = document.getElementById("rff_city"); - var rff_postal_code = document.getElementById("rff_postal_code"); - - if (rff_city) - rff_city.classList.remove('hidden'); - - if (rff_postal_code) - rff_postal_code.classList.remove('hidden'); - + if (element.dataset.isPaypal != '1') { + this.steps.delete("rff"); } if (this.steps.size === 0) { @@ -139,6 +136,5 @@ const signature = document.querySelector( ).content; const terms = document.querySelector('meta[name="show-invoice-terms"]').content; -const rff = document.querySelector('meta[name="show-required-fields-form"]').content; -new Payment(Boolean(+terms), Boolean(+signature), Boolean(+rff)).handle(); +new Payment(Boolean(+terms), Boolean(+signature)).handle(); diff --git a/resources/views/portal/ninja2020/invoices/includes/required-fields.blade.php b/resources/views/portal/ninja2020/invoices/includes/required-fields.blade.php index 4dfc734dab..161d9c600a 100644 --- a/resources/views/portal/ninja2020/invoices/includes/required-fields.blade.php +++ b/resources/views/portal/ninja2020/invoices/includes/required-fields.blade.php @@ -99,7 +99,7 @@ @endif @if(strlen(auth()->guard('contact')->user()->client->city) === 0) -