diff --git a/app/DataMapper/Analytics/LegalEntityCreated.php b/app/DataMapper/Analytics/LegalEntityCreated.php new file mode 100644 index 000000000000..781a3b45e1a3 --- /dev/null +++ b/app/DataMapper/Analytics/LegalEntityCreated.php @@ -0,0 +1,83 @@ +string_metric7 = $string_metric7; + $this->string_metric8 = $string_metric8; + } +} diff --git a/app/DataMapper/CompanySettings.php b/app/DataMapper/CompanySettings.php index 9fde1fee410b..2e201f637fe9 100644 --- a/app/DataMapper/CompanySettings.php +++ b/app/DataMapper/CompanySettings.php @@ -518,7 +518,12 @@ class CompanySettings extends BaseSettings public string $payment_flow = 'default'; //smooth + public string $email_subject_payment_failed = ''; + public string $email_template_payment_failed = ''; + public static $casts = [ + 'email_template_payment_failed' => 'string', + 'email_subject_payment_failed' => 'string', 'payment_flow' => 'string', 'enable_quote_reminder1' => 'bool', 'quote_num_days_reminder1' => 'int', diff --git a/app/DataMapper/EmailTemplateDefaults.php b/app/DataMapper/EmailTemplateDefaults.php index 7633b7edd073..a63b7f89011d 100644 --- a/app/DataMapper/EmailTemplateDefaults.php +++ b/app/DataMapper/EmailTemplateDefaults.php @@ -30,6 +30,7 @@ class EmailTemplateDefaults 'email_template_custom2', 'email_template_custom3', 'email_template_purchase_order', + 'email_template_payment_failed' ]; public static function getDefaultTemplate($template, $locale) @@ -39,6 +40,8 @@ class EmailTemplateDefaults switch ($template) { /* Template */ + case 'email_template_payment_failed': + return self::emailPaymentFailedTemplate(); case 'email_template_invoice': return self::emailInvoiceTemplate(); case 'email_template_quote': @@ -73,6 +76,9 @@ class EmailTemplateDefaults case 'email_subject_invoice': return self::emailInvoiceSubject(); + case 'email_subject_payment_failed': + return self::emailPaymentFailedSubject(); + case 'email_subject_quote': return self::emailQuoteSubject(); @@ -127,6 +133,16 @@ class EmailTemplateDefaults } } + public static function emailPaymentFailedSubject() + { + return ctrans('texts.notification_invoice_payment_failed_subject', ['invoice' => '$number']); + } + + public static function emailPaymentFailedTemplate() + { + return '

$client

'.ctrans('texts.client_payment_failure_body', ['invoice' => '$number', 'amount' => '$amount']).'

$gateway_payment_error

$payment_button
'; + } + public static function emailQuoteReminder1Subject() { return ctrans('texts.quote_reminder_subject', ['quote' => '$number', 'company' => '$company.name']); @@ -135,9 +151,7 @@ class EmailTemplateDefaults public static function emailQuoteReminder1Body() { - $invoice_message = '

$client

'.self::transformText('quote_reminder_message').'

$view_button
'; - - return $invoice_message; + return '

$client

'.self::transformText('quote_reminder_message').'

$view_button
'; } diff --git a/app/DataMapper/QuickbooksSettings.php b/app/DataMapper/QuickbooksSettings.php index 553215f02d13..43013d2b41ac 100644 --- a/app/DataMapper/QuickbooksSettings.php +++ b/app/DataMapper/QuickbooksSettings.php @@ -29,6 +29,7 @@ class QuickbooksSettings implements Castable public int $refreshTokenExpiresAt; + public string $baseURL; /** * entity client,invoice,quote,purchase_order,vendor,payment * sync true/false diff --git a/app/Events/Invoice/InvoiceAutoBillFailed.php b/app/Events/Invoice/InvoiceAutoBillFailed.php new file mode 100644 index 000000000000..ce8d94a8ceb1 --- /dev/null +++ b/app/Events/Invoice/InvoiceAutoBillFailed.php @@ -0,0 +1,35 @@ +quantity = $faker->numberBetween(1, 10); + $item->cost = $faker->randomFloat(2, 1, 1000); + $item->line_total = $item->quantity * $item->cost; + $item->is_amount_discount = true; + $item->discount = $faker->numberBetween(1, 10); + $item->notes = str_replace(['"',"'"], ['',""], $faker->realText(20)); + $item->product_key = $faker->word(); + // $item->custom_value1 = $faker->realText(10); + // $item->custom_value2 = $faker->realText(10); + // $item->custom_value3 = $faker->realText(10); + // $item->custom_value4 = $faker->realText(10); + $item->tax_name1 = 'GST'; + $item->tax_rate1 = 10.00; + $item->type_id = '2'; + + $data[] = $item; + + return $data; } diff --git a/app/Filters/ExpenseFilters.php b/app/Filters/ExpenseFilters.php index ac12b6356de9..fa7f71ff7f0b 100644 --- a/app/Filters/ExpenseFilters.php +++ b/app/Filters/ExpenseFilters.php @@ -99,6 +99,12 @@ class ExpenseFilters extends QueryFilters }); } + if (in_array('uninvoiced', $status_parameters)) { + $query->orWhere(function ($query) { + $query->whereNull('invoice_id'); + }); + } + if (in_array('paid', $status_parameters)) { $query->orWhere(function ($query) { $query->whereNotNull('payment_date'); diff --git a/app/Helpers/Bank/Nordigen/Transformer/TransactionTransformer.php b/app/Helpers/Bank/Nordigen/Transformer/TransactionTransformer.php index fa015510355c..3a2f95e0d0a1 100644 --- a/app/Helpers/Bank/Nordigen/Transformer/TransactionTransformer.php +++ b/app/Helpers/Bank/Nordigen/Transformer/TransactionTransformer.php @@ -104,6 +104,7 @@ class TransactionTransformer implements BankRevenueInterface } $amount = (float) $transaction["transactionAmount"]["amount"]; + $base_type = $amount < 0 ? 'DEBIT' : 'CREDIT'; // description could be in varios places $description = ''; @@ -140,7 +141,7 @@ class TransactionTransformer implements BankRevenueInterface return [ 'transaction_id' => 0, 'nordigen_transaction_id' => $transactionId, - 'amount' => $amount, + 'amount' => abs($amount), 'currency_id' => $this->convertCurrency($transaction["transactionAmount"]["currency"]), 'category_id' => null, 'category_type' => array_key_exists('additionalInformation', $transaction) ? $transaction["additionalInformation"] : '', @@ -148,7 +149,7 @@ class TransactionTransformer implements BankRevenueInterface 'description' => $description, 'participant' => $participant, 'participant_name' => $participant_name, - 'base_type' => $amount < 0 ? 'DEBIT' : 'CREDIT', + 'base_type' => $base_type, ]; } diff --git a/app/Http/Controllers/ClientPortal/InvitationController.php b/app/Http/Controllers/ClientPortal/InvitationController.php index ea4b65c97156..4ef3afb5cbc5 100644 --- a/app/Http/Controllers/ClientPortal/InvitationController.php +++ b/app/Http/Controllers/ClientPortal/InvitationController.php @@ -117,6 +117,7 @@ class InvitationController extends Controller if(!auth()->guard('contact')->check()) { $this->middleware('auth:contact'); + /** @var \App\Models\InvoiceInvitation | \App\Models\QuoteInvitation | \App\Models\CreditInvitation | \App\Models\RecurringInvoiceInvitation $invitation */ return redirect()->route('client.login', ['intended' => route('client.'.$entity.'.show', [$entity => $this->encodePrimaryKey($invitation->{$key}), 'silent' => $is_silent])]); } diff --git a/app/Http/Controllers/ClientPortal/PrePaymentController.php b/app/Http/Controllers/ClientPortal/PrePaymentController.php index 6a666e9c7d9d..ba190324bfeb 100644 --- a/app/Http/Controllers/ClientPortal/PrePaymentController.php +++ b/app/Http/Controllers/ClientPortal/PrePaymentController.php @@ -35,11 +35,16 @@ class PrePaymentController extends Controller /** * Show the list of payments. * - * @return Factory|View + * @return Factory|View|\Illuminate\Http\RedirectResponse */ public function index() { + $client = auth()->guard('contact')->user()->client; + + if(!$client->getSetting('client_initiated_payments')) + return redirect()->route('client.dashboard'); + $minimum = $client->getSetting('client_initiated_payments_minimum'); $minimum_amount = $minimum == 0 ? "" : Number::formatMoney($minimum, $client); diff --git a/app/Http/Controllers/EInvoice/SelfhostController.php b/app/Http/Controllers/EInvoice/SelfhostController.php new file mode 100644 index 000000000000..3d6c07e57d5f --- /dev/null +++ b/app/Http/Controllers/EInvoice/SelfhostController.php @@ -0,0 +1,26 @@ +toArray(); - + //Exact string match foreach($headers as $key => $value) { + foreach($translated_keys as $tkey => $tvalue) { + + $concat_needle = str_ireplace(" ", "", $tvalue['index'].$tvalue['label']); + $concat_value = str_ireplace(" ", "", $value); + + if($this->testMatch($concat_value, $concat_needle)) { + + $hit = $tvalue['key']; + $hints[$key] = $hit; + unset($translated_keys[$tkey]); + break; + + } else { + $hints[$key] = null; + } + + } + + } + + //Label Match + foreach($headers as $key => $value) { + + if(isset($hints[$key])) { + continue; + } + foreach($translated_keys as $tkey => $tvalue) { if($this->testMatch($value, $tvalue['label'])) { @@ -134,10 +161,9 @@ class ImportController extends Controller } - } - //second pass using the index of the translation here + //Index matching pass using the index of the translation here foreach($headers as $key => $value) { if(isset($hints[$key])) { continue; diff --git a/app/Http/Controllers/ImportQuickbooksController.php b/app/Http/Controllers/ImportQuickbooksController.php index 88e6a180b846..e1d75589e3ea 100644 --- a/app/Http/Controllers/ImportQuickbooksController.php +++ b/app/Http/Controllers/ImportQuickbooksController.php @@ -60,75 +60,4 @@ class ImportQuickbooksController extends BaseController return redirect()->to($authorizationUrl); } - public function preimport(string $type, string $hash) - { - // // Check for authorization otherwise - // // Create a reference - // $data = [ - // 'hash' => $hash, - // 'type' => $type - // ]; - // $this->getData($data); - } - - protected function getData($data) - { - - // $entity = $this->import_entities[$data['type']]; - // $cache_name = "{$data['hash']}-{$data['type']}"; - // // TODO: Get or put cache or DB? - // if(! Cache::has($cache_name)) { - // $contents = call_user_func([$this->service, "fetch{$entity}s"]); - // if($contents->isEmpty()) { - // return; - // } - - // Cache::put($cache_name, base64_encode($contents->toJson()), 600); - // } - } - - /** - * @OA\Post( - * path="/api/v1/import_json", - * operationId="getImportJson", - * tags={"import"}, - * summary="Import data from the system", - * description="Import data from the system", - * @OA\Parameter(ref="#/components/parameters/X-Requested-With"), - * @OA\Response( - * response=200, - * description="success", - * @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"), - * @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"), - * @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"), - * ), - * @OA\Response( - * response=422, - * description="Validation error", - * @OA\JsonContent(ref="#/components/schemas/ValidationError"), - * ), - * @OA\Response( - * response="default", - * description="Unexpected Error", - * @OA\JsonContent(ref="#/components/schemas/Error"), - * ), - * ) - */ - public function import(Request $request) - { - // $hash = Str::random(32); - // foreach($request->input('import_types') as $type) { - // $this->preimport($type, $hash); - // } - // /** @var \App\Models\User $user */ - // // $user = auth()->user() ?? Auth::loginUsingId(60); - // $data = ['import_types' => $request->input('import_types') ] + compact('hash'); - // if (Ninja::isHosted()) { - // QuickbooksIngest::dispatch($data, $user->company()); - // } else { - // QuickbooksIngest::dispatch($data, $user->company()); - // } - - // return response()->json(['message' => 'Processing'], 200); - } } diff --git a/app/Http/Requests/Company/UpdateCompanyRequest.php b/app/Http/Requests/Company/UpdateCompanyRequest.php index c48ee397ee0e..51c71c000165 100644 --- a/app/Http/Requests/Company/UpdateCompanyRequest.php +++ b/app/Http/Requests/Company/UpdateCompanyRequest.php @@ -65,7 +65,7 @@ class UpdateCompanyRequest extends Request $rules['smtp_local_domain'] = 'sometimes|string|nullable'; // $rules['smtp_verify_peer'] = 'sometimes|string'; - $rules['e_invoice'] = ['sometimes','nullable', new ValidCompanyScheme()]; + $rules['e_invoice'] = ['sometimes', 'nullable', new ValidCompanyScheme()]; if (isset($input['portal_mode']) && ($input['portal_mode'] == 'domain' || $input['portal_mode'] == 'iframe')) { $rules['portal_domain'] = 'bail|nullable|sometimes|url'; diff --git a/app/Http/Requests/EInvoice/SignupRequest.php b/app/Http/Requests/EInvoice/SignupRequest.php new file mode 100644 index 000000000000..0ac28df0c52f --- /dev/null +++ b/app/Http/Requests/EInvoice/SignupRequest.php @@ -0,0 +1,28 @@ +{$entity}(); - } - - //collate any errors - - // $this->finalizeImport(); - } - - public function client() - { - $entity_type = 'client'; - $data = $this->getData($entity_type); - if (empty($data)) { - $this->entity_count['clients'] = 0; - - return; - } - - $this->request_name = StoreClientRequest::class; - $this->repository_name = ClientRepository::class; - $this->factory_name = ClientFactory::class; - $this->repository = app()->make($this->repository_name); - $this->repository->import_mode = true; - $this->transformer = new ClientTransformer($this->company); - $client_count = $this->ingest($data, $entity_type); - $this->entity_count['clients'] = $client_count; - } - - public function product() - { - $entity_type = 'product'; - $data = $this->getData($entity_type); - if (empty($data)) { - $this->entity_count['products'] = 0; - - return; - } - - $this->request_name = StoreProductRequest::class; - $this->repository_name = ProductRepository::class; - $this->factory_name = ProductFactory::class; - $this->repository = app()->make($this->repository_name); - $this->repository->import_mode = true; - $this->transformer = new ProductTransformer($this->company); - $count = $this->ingest($data, $entity_type); - $this->entity_count['products'] = $count; - } - - public function getData($type) - { - - // get the data from cache? file? or api ? - return json_decode(base64_decode(Cache::get("{$this->hash}-{$type}")), true); - } - - public function payment() - { - $entity_type = 'payment'; - $data = $this->getData($entity_type); - if (empty($data)) { - $this->entity_count['payments'] = 0; - - return; - } - - $this->request_name = StorePaymentRequest::class; - $this->repository_name = PaymentRepository::class; - $this->factory_name = PaymentFactory::class; - $this->repository = app()->make($this->repository_name); - $this->repository->import_mode = true; - $this->transformer = new PaymentTransformer($this->company); - $count = $this->ingest($data, $entity_type); - $this->entity_count['payments'] = $count; - } - - public function invoice() - { - //make sure we update and create products - $initial_update_products_value = $this->company->update_products; - $this->company->update_products = true; - - $this->company->save(); - - $entity_type = 'invoice'; - $data = $this->getData($entity_type); - - if (empty($data)) { - $this->entity_count['invoices'] = 0; - - return; - } - - $this->request_name = StoreInvoiceRequest::class; - $this->repository_name = InvoiceRepository::class; - $this->factory_name = InvoiceFactory::class; - $this->repository = app()->make($this->repository_name); - $this->repository->import_mode = true; - $this->transformer = new InvoiceTransformer($this->company); - $invoice_count = $this->ingestInvoices($data, ''); - $this->entity_count['invoices'] = $invoice_count; - $this->company->update_products = $initial_update_products_value; - $this->company->save(); - } - - public function ingestInvoices($invoices, $invoice_number_key) - { - $count = 0; - $invoice_transformer = $this->transformer; - /** @var ClientRepository $client_repository */ - $client_repository = app()->make(ClientRepository::class); - $client_repository->import_mode = true; - $invoice_repository = new InvoiceRepository(); - $invoice_repository->import_mode = true; - - foreach ($invoices as $raw_invoice) { - if(!is_array($raw_invoice)) { - continue; - } - - try { - $invoice_data = $invoice_transformer->transform($raw_invoice); - $invoice_data['user_id'] = $this->company->owner()->id; - $invoice_data['line_items'] = (array) $invoice_data['line_items']; - $invoice_data['line_items'] = $this->cleanItems( - $invoice_data['line_items'] ?? [] - ); - - if ( - empty($invoice_data['client_id']) && - ! empty($invoice_data['client']) - ) { - $client_data = $invoice_data['client']; - $client_data['user_id'] = $this->getUserIDForRecord( - $invoice_data - ); - $client_repository->save( - $client_data, - $client = ClientFactory::create( - $this->company->id, - $client_data['user_id'] - ) - ); - $invoice_data['client_id'] = $client->id; - unset($invoice_data['client']); - } - - $validator = $this->request_name::runFormRequest($invoice_data); - if ($validator->fails()) { - $this->error_array['invoice'][] = [ - 'invoice' => $invoice_data, - 'error' => $validator->errors()->all(), - ]; - } else { - if(!Invoice::where('number', $invoice_data['number'])->first()) { - $invoice = InvoiceFactory::create( - $this->company->id, - $this->company->owner()->id - ); - $invoice->mergeFillable(['partial','amount','balance','line_items']); - if (! empty($invoice_data['status_id'])) { - $invoice->status_id = $invoice_data['status_id']; - } - - $saveable_invoice_data = $invoice_data; - if(array_key_exists('payments', $saveable_invoice_data)) { - unset($saveable_invoice_data['payments']); - } - - $invoice->fill($saveable_invoice_data); - $invoice->save(); - $count++; - - } - // $this->actionInvoiceStatus( - // $invoice, - // $invoice_data, - // $invoice_repository - // ); - } - } catch (\Exception $ex) { - if (\DB::connection(config('database.default'))->transactionLevel() > 0) { - \DB::connection(config('database.default'))->rollBack(); - } - - if ($ex instanceof ImportException) { - $message = $ex->getMessage(); - } else { - report($ex); - $message = 'Unknown error '; - nlog($ex->getMessage()); - nlog($raw_invoice); - } - - $this->error_array['invoice'][] = [ - 'invoice' => $raw_invoice, - 'error' => $message, - ]; - } - } - - return $count; - } - -} diff --git a/app/Jobs/Bank/MatchBankTransactions.php b/app/Jobs/Bank/MatchBankTransactions.php index d886846a8c32..402edbebd47e 100644 --- a/app/Jobs/Bank/MatchBankTransactions.php +++ b/app/Jobs/Bank/MatchBankTransactions.php @@ -238,6 +238,7 @@ class MatchBankTransactions implements ShouldQueue $amount = $this->bt->amount; if ($_invoices->count() > 0 && $this->checkPayable($_invoices)) { + $this->createPayment($_invoices, $amount); $this->bts->push($this->bt->id); @@ -293,6 +294,8 @@ class MatchBankTransactions implements ShouldQueue $this->attachable_invoices = []; $this->available_balance = $amount; + nlog($invoices->count()); + \DB::connection(config('database.default'))->transaction(function () use ($invoices) { $invoices->each(function ($invoice) { $this->invoice = Invoice::withTrashed()->where('id', $invoice->id)->lockForUpdate()->first(); @@ -326,11 +329,16 @@ class MatchBankTransactions implements ShouldQueue }); }, 2); + nlog("pre"); + // @phpstan-ignore-next-line if (!$this->invoice) { return; } + +nlog("post"); + /* Create Payment */ $payment = PaymentFactory::create($this->invoice->company_id, $this->invoice->user_id); @@ -395,6 +403,9 @@ class MatchBankTransactions implements ShouldQueue $this->bt->status_id = BankTransaction::STATUS_CONVERTED; $this->bt->payment_id = $payment->id; $this->bt->save(); + +nlog($this->bt->toArray()); + } private function resolveCategory($input): ?int diff --git a/app/Jobs/EDocument/CreateEDocument.php b/app/Jobs/EDocument/CreateEDocument.php index 7f96af177a91..be53d0a92a85 100644 --- a/app/Jobs/EDocument/CreateEDocument.php +++ b/app/Jobs/EDocument/CreateEDocument.php @@ -70,7 +70,7 @@ class CreateEDocument implements ShouldQueue if ($this->document instanceof Invoice) { switch ($e_document_type) { case "PEPPOL": - return (new Peppol($this->document))->toXml(); + return (new Peppol($this->document))->run()->toXml(); case "FACT1": return (new RoEInvoice($this->document))->generateXml(); case "FatturaPA": diff --git a/app/Jobs/Import/QuickbooksIngest.php b/app/Jobs/Import/QuickbooksIngest.php deleted file mode 100644 index b32db16f0eeb..000000000000 --- a/app/Jobs/Import/QuickbooksIngest.php +++ /dev/null @@ -1,48 +0,0 @@ -company = $company; - $this->request = $request; - } - - /** - * Execute the job. - */ - public function handle(): void - { - MultiDB::setDb($this->company->db); - set_time_limit(0); - - $engine = new Quickbooks(['import_type' => 'client', 'hash' => $this->request['hash'] ], $this->company); - foreach ($this->request['import_types'] as $entity) { - $engine->import($entity); - } - - $engine->finalizeImport(); - } -} diff --git a/app/Jobs/Mail/NinjaMailerJob.php b/app/Jobs/Mail/NinjaMailerJob.php index 7f2cac34585c..2cf7563ea483 100644 --- a/app/Jobs/Mail/NinjaMailerJob.php +++ b/app/Jobs/Mail/NinjaMailerJob.php @@ -48,6 +48,7 @@ class NinjaMailerJob implements ShouldQueue use MakesHash; public $tries = 4; //number of retries + public $deleteWhenMissingModels = true; /** @var null|\App\Models\Company $company **/ diff --git a/app/Jobs/Mail/PaymentFailedMailer.php b/app/Jobs/Mail/PaymentFailedMailer.php index c5fd61eae8af..079c8be6e02c 100644 --- a/app/Jobs/Mail/PaymentFailedMailer.php +++ b/app/Jobs/Mail/PaymentFailedMailer.php @@ -84,7 +84,7 @@ class PaymentFailedMailer implements ShouldQueue $invoice = false; if ($this->payment_hash) { - // $amount = array_sum(array_column($this->payment_hash->invoices(), 'amount')) + $this->payment_hash->fee_total; + $amount = $this->payment_hash?->amount_with_fee() ?: 0; $invoice = Invoice::query()->whereIn('id', $this->transformKeys(array_column($this->payment_hash->invoices(), 'invoice_id')))->withTrashed()->first(); } diff --git a/app/Listeners/Invoice/InvoiceAutoBillFailedActivity.php b/app/Listeners/Invoice/InvoiceAutoBillFailedActivity.php new file mode 100644 index 000000000000..6db4087daa5e --- /dev/null +++ b/app/Listeners/Invoice/InvoiceAutoBillFailedActivity.php @@ -0,0 +1,59 @@ +activity_repo = $activity_repo; + } + + /** + * Handle the event. + * + * @param object $event + * @return void + */ + public function handle($event) + { + MultiDB::setDB($event->company->db); + + $fields = new stdClass(); + + $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->invoice->user_id; + + $fields->user_id = $user_id; + $fields->client_id = $event->invoice->client_id; + $fields->company_id = $event->invoice->company_id; + $fields->activity_type_id = Activity::AUTOBILL_FAILURE; + $fields->invoice_id = $event->invoice->id; + $fields->notes = $event->notes ?? ''; + + $this->activity_repo->save($fields, $event->invoice, $event->event_vars); + + } +} diff --git a/app/Listeners/Invoice/InvoiceAutoBillSuccessActivity.php b/app/Listeners/Invoice/InvoiceAutoBillSuccessActivity.php new file mode 100644 index 000000000000..c936fdd49a30 --- /dev/null +++ b/app/Listeners/Invoice/InvoiceAutoBillSuccessActivity.php @@ -0,0 +1,58 @@ +activity_repo = $activity_repo; + } + + /** + * Handle the event. + * + * @param object $event + * @return void + */ + public function handle($event) + { + MultiDB::setDB($event->company->db); + + $fields = new stdClass(); + + $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->invoice->user_id; + + $fields->user_id = $user_id; + $fields->client_id = $event->invoice->client_id; + $fields->company_id = $event->invoice->company_id; + $fields->activity_type_id = Activity::AUTOBILL_SUCCESS; + $fields->invoice_id = $event->invoice->id; + + $this->activity_repo->save($fields, $event->invoice, $event->event_vars); + + } +} diff --git a/app/Livewire/EInvoice/Portal.php b/app/Livewire/EInvoice/Portal.php new file mode 100644 index 000000000000..44cccb92072c --- /dev/null +++ b/app/Livewire/EInvoice/Portal.php @@ -0,0 +1,142 @@ +api_url = config('ninja.hosted_ninja_url'); + + $this->getCompanies(); + + } + + private function getCompanies(): self + { + + $this->companies = auth()->guard('user')->check() ? auth()->guard('user')->user()->account->companies->map(function ($company) { + return [ + 'key' => $company->company_key, + 'city' => $company->settings->city, + 'country' => $company->country()->iso_3166_2, + 'county' => $company->settings->state, + 'line1' => $company->settings->address1, + 'line2' => $company->settings->address2, + 'party_name' => $company->settings->name, + 'vat_number' => $company->settings->vat_number, + 'zip' => $company->settings->postal_code, + 'legal_entity_id' => $company->legal_entity_id, + 'tax_registered' => (bool) strlen($company->settings->vat_number ?? '') > 2, + 'tenant_id' => $company->company_key, + 'classification' => strlen($company->settings->classification ?? '') > 2 ? $company->settings->classification : 'business', + ]; + })->toArray() : []; + + return $this; + + } + + public function login() + { + $credentials = ['email' => $this->email, 'password' => $this->password]; + + if (Auth::attempt($credentials)) { + session()->flash('message', 'Logged in successfully.'); + + App::setLocale(auth()->guard('user')->user()->account->companies->first()->getLocale()); + + $this->getCOmpanies(); + + + } else { + session()->flash('error', 'Invalid credentials.'); + } + } + + public function logout() + { + Auth::logout(); + + session()->flash('message', 'Logged out!'); + + } + + public function register(string $company_key) + { + + $register_company = [ + 'acts_as_receiver' => true, + 'acts_as_sender' => true, + 'advertisements' => ['invoice'] + ]; + + foreach($this->companies as $company) + { + if($company['key'] == $company_key) + $register_company = array_merge($company, $register_company); + } + + $r = Http::withHeaders($this->getHeaders()) + ->post("{$this->api_url}/api/einvoice/createLegalEntity", $register_company); + + if($r->successful()) + { + + nlog($r->body()); + $response = $r->json(); + + $_company = auth()->guard('user')->user()->account->companies()->where('company_key', $company_key)->first(); + $_company->legal_entity_id = $response['id']; + $_company->save(); + + $this->getCompanies(); + + return; + } + + if($r->failed()) + nlog($r->getBody()->getContents()); + + $error = json_decode($r->getBody()->getContents(),true); + + session()->flash('error', $error['message']); + + } + + private function getHeaders() + { + return [ + 'X-API-SELF-HOST-TOKEN' => config('ninja.license_key'), + "X-Requested-With" => "XMLHttpRequest", + "Content-Type" => "application/json", + ]; + } + + public function render() + { + return view('livewire.e-invoice.portal'); + } +} diff --git a/app/Livewire/Flow2/ProcessPayment.php b/app/Livewire/Flow2/ProcessPayment.php index 175092a98ca7..a761b8440dab 100644 --- a/app/Livewire/Flow2/ProcessPayment.php +++ b/app/Livewire/Flow2/ProcessPayment.php @@ -59,7 +59,7 @@ class ProcessPayment extends Component } $driver = $company_gateway - ->driver($invitation->contact->client) + ->driver($invitation->contact->client) // @phpstan-ignore-line ->setPaymentMethod($data['payment_method_id']) ->setPaymentHash($responder_data['payload']['ph']); diff --git a/app/Livewire/Flow2/RequiredFields.php b/app/Livewire/Flow2/RequiredFields.php index 5cce417df6f6..e3a31830755c 100644 --- a/app/Livewire/Flow2/RequiredFields.php +++ b/app/Livewire/Flow2/RequiredFields.php @@ -88,7 +88,7 @@ class RequiredFields extends Component $rff = new RFFService( fields: $this->getContext()['fields'], database: $this->getContext()['db'], - company_gateway_id: $this->company_gateway->id, + company_gateway_id: (string)$this->company_gateway->id, ); /** @var \App\Models\ClientContact $contact */ @@ -111,7 +111,7 @@ class RequiredFields extends Component $rff = new RFFService( fields: $this->fields, database: $this->getContext()['db'], - company_gateway_id: $this->company_gateway->id, + company_gateway_id: (string) $this->company_gateway->id, ); $contact = auth()->user(); diff --git a/app/Mail/Admin/ClientPaymentFailureObject.php b/app/Mail/Admin/ClientPaymentFailureObject.php index c0dc385072fa..842d0f84fb26 100644 --- a/app/Mail/Admin/ClientPaymentFailureObject.php +++ b/app/Mail/Admin/ClientPaymentFailureObject.php @@ -11,12 +11,14 @@ namespace App\Mail\Admin; +use stdClass; +use App\Utils\Ninja; use App\Models\Invoice; use App\Utils\HtmlEngine; -use App\Utils\Ninja; use App\Utils\Traits\MakesHash; use Illuminate\Support\Facades\App; -use stdClass; +use App\DataMapper\EmailTemplateDefaults; +use App\Utils\Number; class ClientPaymentFailureObject { @@ -60,20 +62,20 @@ class ClientPaymentFailureObject } App::forgetInstance('translator'); - /* Init a new copy of the translator*/ $t = app('translator'); - /* Set the locale*/ App::setLocale($this->client->locale()); - /* Set customized translations _NOW_ */ $t->replace(Ninja::transformTranslations($this->company->settings)); $this->invoices = Invoice::withTrashed()->whereIn('id', $this->transformKeys(array_column($this->payment_hash->invoices(), 'invoice_id')))->get(); + $data = $this->getData(); + $mail_obj = new stdClass(); $mail_obj->amount = $this->getAmount(); - $mail_obj->subject = $this->getSubject(); + $mail_obj->subject = $data['subject']; $mail_obj->data = $this->getData(); - $mail_obj->markdown = 'email.client.generic'; + + $mail_obj->markdown = 'email.template.client'; $mail_obj->tag = $this->company->company_key; $mail_obj->text_view = 'email.template.text'; @@ -82,16 +84,32 @@ class ClientPaymentFailureObject private function getAmount() { - return array_sum(array_column($this->payment_hash->invoices(), 'amount')) + $this->payment_hash->fee_total; + $amount = array_sum(array_column($this->payment_hash->invoices(), 'amount')) + $this->payment_hash->fee_total; + + return Number::formatMoney($amount, $this->client); } private function getSubject() { - return - ctrans( - 'texts.notification_invoice_payment_failed_subject', - ['invoice' => implode(',', $this->invoices->pluck('number')->toArray())] - ); + + if(strlen($this->client->getSetting('email_subject_payment_failed') ?? '') > 2){ + return $this->client->getSetting('email_subject_payment_failed'); + } + else { + return EmailTemplateDefaults::getDefaultTemplate('email_subject_payment_failed', $this->client->locale()); + } + + } + + private function getBody() + { + + if(strlen($this->client->getSetting('email_template_payment_failed') ?? '') > 2) { + return $this->client->getSetting('email_template_payment_failed'); + } else { + return EmailTemplateDefaults::getDefaultTemplate('email_template_payment_failed', $this->client->locale()); + } + } private function getData() @@ -104,17 +122,17 @@ class ClientPaymentFailureObject $signature = $this->client->getSetting('email_signature'); $html_variables = (new HtmlEngine($invitation))->makeValues(); + + $html_variables['$gateway_payment_error'] = $this->error ?? ''; + $html_variables['$total'] = $this->getAmount(); + $signature = str_replace(array_keys($html_variables), array_values($html_variables), $signature); + $subject = str_replace(array_keys($html_variables), array_values($html_variables), $this->getSubject()); + $content = str_replace(array_keys($html_variables), array_values($html_variables), $this->getBody()); $data = [ - 'title' => ctrans( - 'texts.notification_invoice_payment_failed_subject', - [ - 'invoice' => $this->invoices->first()->number, - ] - ), - 'greeting' => ctrans('texts.email_salutation', ['name' => $this->client->present()->name()]), - 'content' => ctrans('texts.client_payment_failure_body', ['invoice' => implode(',', $this->invoices->pluck('number')->toArray()), 'amount' => $this->getAmount()]), + 'subject' => $subject, + 'body' => $content, 'signature' => $signature, 'logo' => $this->company->present()->logo(), 'settings' => $this->client->getMergedSettings(), diff --git a/app/Models/Activity.php b/app/Models/Activity.php index c2f7d6c50198..392260fb83cb 100644 --- a/app/Models/Activity.php +++ b/app/Models/Activity.php @@ -265,6 +265,12 @@ class Activity extends StaticModel public const QUOTE_REMINDER1_SENT = 142; + public const AUTOBILL_SUCCESS = 143; + + public const AUTOBILL_FAILURE = 144; + + public const EMAIL_EINVOICE_SUCCESS = 145; + protected $casts = [ 'is_system' => 'boolean', 'updated_at' => 'timestamp', @@ -280,13 +286,11 @@ class Activity extends StaticModel 'backup', ]; - public function getHashedIdAttribute(): string { return $this->encodePrimaryKey($this->id); } - public function getEntityType() { return self::class; diff --git a/app/Models/BaseModel.php b/app/Models/BaseModel.php index fa06c90c60a3..5ea237f04a7b 100644 --- a/app/Models/BaseModel.php +++ b/app/Models/BaseModel.php @@ -17,6 +17,7 @@ use App\Utils\Traits\MakesHash; use App\Jobs\Entity\CreateRawPdf; use App\Jobs\Util\WebhookHandler; use App\Models\Traits\Excludable; +use App\Services\EDocument\Jobes\SendEDocument; use App\Services\PdfMaker\PdfMerge; use Illuminate\Database\Eloquent\Model; use App\Utils\Traits\UserSessionAttributes; @@ -31,6 +32,7 @@ use Illuminate\Database\Eloquent\ModelNotFoundException as ModelNotFoundExceptio * @package App\Models * @property-read mixed $hashed_id * @property string $number + * @property object|array|null $e_invoice * @property int $company_id * @property int $id * @property int $user_id @@ -294,6 +296,12 @@ class BaseModel extends Model if ($subscriptions) { WebhookHandler::dispatch($event_id, $this->withoutRelations(), $this->company, $additional_data); } + + // special catch here for einvoicing eventing + if($event_id == Webhook::EVENT_SENT_INVOICE && ($this instanceof Invoice) && is_null($this->backup)){ + \App\Services\EDocument\Jobs\SendEDocument::dispatch(get_class($this), $this->id, $this->company->db); + } + } /** diff --git a/app/Models/Company.php b/app/Models/Company.php index b996e47d835c..f2c1bd6b480a 100644 --- a/app/Models/Company.php +++ b/app/Models/Company.php @@ -121,6 +121,7 @@ use Laracasts\Presenter\PresentableTrait; * @property string|null $smtp_local_domain * @property \App\DataMapper\QuickbooksSettings|null $quickbooks * @property boolean $smtp_verify_peer + * @property int|null $legal_entity_id * @property-read \App\Models\Account $account * @property-read \Illuminate\Database\Eloquent\Collection $activities * @property-read int|null $activities_count @@ -366,7 +367,7 @@ class Company extends BaseModel 'smtp_encryption', 'smtp_local_domain', 'smtp_verify_peer', - 'e_invoice', + // 'e_invoice', ]; protected $hidden = [ diff --git a/app/PaymentDrivers/BTCPayPaymentDriver.php b/app/PaymentDrivers/BTCPayPaymentDriver.php index 4c93c9842c83..4d1c02b273c9 100644 --- a/app/PaymentDrivers/BTCPayPaymentDriver.php +++ b/app/PaymentDrivers/BTCPayPaymentDriver.php @@ -12,18 +12,19 @@ namespace App\PaymentDrivers; -use App\Utils\Traits\MakesHash; -use App\Models\PaymentHash; -use App\Models\GatewayType; -use App\PaymentDrivers\BTCPay\BTCPay; -use App\Models\SystemLog; -use App\Models\Payment; use App\Models\Client; -use App\Exceptions\PaymentFailed; -use App\Models\PaymentType; -use BTCPayServer\Client\Webhook; -use App\Http\Requests\Payments\PaymentWebhookRequest; use App\Models\Invoice; +use App\Models\Payment; +use App\Models\SystemLog; +use App\Models\GatewayType; +use App\Models\PaymentHash; +use App\Models\PaymentType; +use App\Utils\Traits\MakesHash; +use BTCPayServer\Client\Webhook; +use App\Exceptions\PaymentFailed; +use App\PaymentDrivers\BTCPay\BTCPay; +use App\Jobs\Mail\PaymentFailedMailer; +use App\Http\Requests\Payments\PaymentWebhookRequest; class BTCPayPaymentDriver extends BaseDriver { @@ -138,8 +139,6 @@ class BTCPayPaymentDriver extends BaseDriver $_invoice = $this->payment_hash->fee_invoice; - // Invoice::with('client')->withTrashed()->find($this->payment_hash->fee_invoice_id); - $this->client = $_invoice->client; $dataPayment = [ @@ -158,21 +157,49 @@ class BTCPayPaymentDriver extends BaseDriver } switch ($btcpayRep->type) { case "InvoiceExpired": + + if ($payment->status_id == Payment::STATUS_PENDING) { + $payment->service()->deletePayment(); + $this->failedPaymentNotification($payment); + } + $StatusId = Payment::STATUS_CANCELLED; break; case "InvoiceInvalid": + + if ($payment->status_id == Payment::STATUS_PENDING) { + $payment->service()->deletePayment(); + $this->failedPaymentNotification($payment); + } + $StatusId = Payment::STATUS_FAILED; break; case "InvoiceSettled": $StatusId = Payment::STATUS_COMPLETED; break; } + if ($payment->status_id != $StatusId) { $payment->status_id = $StatusId; $payment->save(); } } + private function failedPaymentNotification(Payment $payment): void + { + + $error = ctrans('texts.client_payment_failure_body', [ + 'invoice' => implode(',', $payment->invoices->pluck('number')->toArray()), + 'amount' => array_sum(array_column($this->payment_hash->invoices(), 'amount')) + $this->payment_hash->fee_total, ]); + + PaymentFailedMailer::dispatch( + $this->payment_hash, + $payment->client->company, + $payment->client, + $error + ); + + } public function refund(Payment $payment, $amount, $return_client_response = false) { diff --git a/app/PaymentDrivers/BaseDriver.php b/app/PaymentDrivers/BaseDriver.php index e7ea1efd83d4..4ee0e8dae968 100644 --- a/app/PaymentDrivers/BaseDriver.php +++ b/app/PaymentDrivers/BaseDriver.php @@ -232,7 +232,6 @@ class BaseDriver extends AbstractPaymentDriver * * @param ClientGatewayToken $cgt The client gateway token object * @param PaymentHash $payment_hash The Payment hash containing the payment meta data - * @return ?Payment|bool The payment response */ public function tokenBilling(ClientGatewayToken $cgt, PaymentHash $payment_hash) { diff --git a/app/PaymentDrivers/Forte/CreditCard.php b/app/PaymentDrivers/Forte/CreditCard.php index 16ceb030fdf0..04942e046b74 100644 --- a/app/PaymentDrivers/Forte/CreditCard.php +++ b/app/PaymentDrivers/Forte/CreditCard.php @@ -109,8 +109,8 @@ class CreditCard SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_FAILURE, SystemLog::TYPE_FORTE, - $this->client, - $this->client->company, + $this->forte->client, + $this->forte->client->company, ); throw new \App\Exceptions\PaymentFailed("Unable to store payment method: {$error->response->response_desc}", 400); diff --git a/app/PaymentDrivers/PayPalExpressPaymentDriver.php b/app/PaymentDrivers/PayPalExpressPaymentDriver.php deleted file mode 100644 index fa96aa67e27f..000000000000 --- a/app/PaymentDrivers/PayPalExpressPaymentDriver.php +++ /dev/null @@ -1,261 +0,0 @@ -omnipay_gateway = Omnipay::create( - $this->company_gateway->gateway->provider - ); - - $this->omnipay_gateway->initialize((array) $this->company_gateway->getConfig()); - } - - public function setPaymentMethod($payment_method_id) - { - // PayPal doesn't have multiple ways of paying. - // There's just one, off-site redirect. - - return $this; - } - - public function authorizeView($payment_method) - { - // PayPal doesn't support direct authorization. - - return $this; - } - - public function authorizeResponse($request) - { - // PayPal doesn't support direct authorization. - - return $this; - } - - public function processPaymentView($data) - { - $this->initializeOmnipayGateway(); - - $this->payment_hash->data = array_merge((array) $this->payment_hash->data, ['amount' => $data['total']['amount_with_fee']]); - $this->payment_hash->save(); - - $response = $this->omnipay_gateway - ->purchase($this->generatePaymentDetails($data)) - ->setItems($this->generatePaymentItems($data)) - ->send(); - - if ($response->isRedirect()) { - return redirect($response->getRedirectUrl()); - } - - // $this->sendFailureMail($response->getMessage() ?: ''); - - $message = [ - 'server_response' => $response->getMessage(), - 'data' => $this->payment_hash->data, - ]; - - SystemLogger::dispatch( - $message, - SystemLog::CATEGORY_GATEWAY_RESPONSE, - SystemLog::EVENT_GATEWAY_FAILURE, - SystemLog::TYPE_PAYPAL, - $this->client, - $this->client->company, - ); - - throw new PaymentFailed($response->getMessage(), $response->getCode()); - } - - public function processPaymentResponse($request) - { - $this->initializeOmnipayGateway(); - - $response = $this->omnipay_gateway - ->completePurchase(['amount' => $this->payment_hash->data->amount, 'currency' => $this->client->getCurrencyCode()]) - ->send(); - - if ($response->isCancelled() && $this->client->getSetting('enable_client_portal')) { - return redirect()->route('client.invoices.index')->with('warning', ctrans('texts.status_cancelled')); - } elseif($response->isCancelled() && !$this->client->getSetting('enable_client_portal')) { - redirect()->route('client.invoices.show', ['invoice' => $this->payment_hash->fee_invoice])->with('warning', ctrans('texts.status_cancelled')); - } - - if ($response->isSuccessful()) { - $data = [ - 'payment_method' => $response->getData()['TOKEN'], - 'payment_type' => PaymentType::PAYPAL, - 'amount' => $this->payment_hash->data->amount, - 'transaction_reference' => $response->getTransactionReference(), - 'gateway_type_id' => GatewayType::PAYPAL, - ]; - - $payment = $this->createPayment($data, \App\Models\Payment::STATUS_COMPLETED); - - SystemLogger::dispatch( - ['response' => (array) $response->getData(), 'data' => $data], - SystemLog::CATEGORY_GATEWAY_RESPONSE, - SystemLog::EVENT_GATEWAY_SUCCESS, - SystemLog::TYPE_PAYPAL, - $this->client, - $this->client->company, - ); - - return redirect()->route('client.payments.show', ['payment' => $this->encodePrimaryKey($payment->id)]); - } - - if (! $response->isSuccessful()) { - $data = $response->getData(); - - $this->sendFailureMail($response->getMessage() ?: ''); - - $message = [ - 'server_response' => $data['L_LONGMESSAGE0'], - 'data' => $this->payment_hash->data, - ]; - - SystemLogger::dispatch( - $message, - SystemLog::CATEGORY_GATEWAY_RESPONSE, - SystemLog::EVENT_GATEWAY_FAILURE, - SystemLog::TYPE_PAYPAL, - $this->client, - $this->client->company, - ); - - throw new PaymentFailed($response->getMessage(), $response->getCode()); - } - } - - public function generatePaymentDetails(array $data) - { - $_invoice = collect($this->payment_hash->data->invoices)->first(); - $invoice = Invoice::withTrashed()->find($this->decodePrimaryKey($_invoice->invoice_id)); - - // $this->fee = $this->feeCalc($invoice, $data['total']['amount_with_fee']); - - return [ - 'currency' => $this->client->getCurrencyCode(), - 'transactionType' => 'Purchase', - 'clientIp' => request()->getClientIp(), - // 'amount' => round(($data['total']['amount_with_fee'] + $this->fee),2), - 'amount' => round($data['total']['amount_with_fee'], 2), - 'returnUrl' => route('client.payments.response', [ - 'company_gateway_id' => $this->company_gateway->id, - 'payment_hash' => $this->payment_hash->hash, - 'payment_method_id' => GatewayType::PAYPAL, - ]), - 'cancelUrl' => $this->client->company->domain()."/client/invoices/{$invoice->hashed_id}", - 'description' => implode(',', collect($this->payment_hash->data->invoices) - ->map(function ($invoice) { - return sprintf('%s: %s', ctrans('texts.invoice_number'), $invoice->invoice_number); - })->toArray()), - 'transactionId' => $this->payment_hash->hash.'-'.time(), - 'ButtonSource' => 'InvoiceNinja_SP', - 'solutionType' => 'Sole', - 'no_shipping' => $this->company_gateway->require_shipping_address ? 0 : 1, - ]; - } - - public function generatePaymentItems(array $data) - { - $_invoice = collect($this->payment_hash->data->invoices)->first(); - $invoice = Invoice::withTrashed()->find($this->decodePrimaryKey($_invoice->invoice_id)); - - $items = []; - - $items[] = new Item([ - 'name' => ' ', - 'description' => ctrans('texts.invoice_number').'# '.$invoice->number, - 'price' => $data['total']['amount_with_fee'], - 'quantity' => 1, - ]); - - return $items; - } - - private function feeCalc($invoice, $invoice_total) - { - $invoice->service()->removeUnpaidGatewayFees(); - $invoice = $invoice->fresh(); - - $balance = floatval($invoice->balance); - - $_updated_invoice = $invoice->service()->addGatewayFee($this->company_gateway, GatewayType::PAYPAL, $invoice_total)->save(); - - if (floatval($_updated_invoice->balance) > $balance) { - $fee = floatval($_updated_invoice->balance) - $balance; - - $this->payment_hash->fee_total = $fee; - $this->payment_hash->save(); - - return $fee; - } - - return 0; - } - - public function livewirePaymentView(array $data): string - { - $this->processPaymentView($data); - - return ''; // Gateway is offsite. - } - - public function processPaymentViewData(array $data): array - { - return $data; - } -} diff --git a/app/PaymentDrivers/Stripe/UpdatePaymentMethods.php b/app/PaymentDrivers/Stripe/UpdatePaymentMethods.php index 244be05bfc1d..db354bce9cd0 100644 --- a/app/PaymentDrivers/Stripe/UpdatePaymentMethods.php +++ b/app/PaymentDrivers/Stripe/UpdatePaymentMethods.php @@ -49,6 +49,18 @@ class UpdatePaymentMethods $this->addOrUpdateCard($method, $customer->id, $client, GatewayType::CREDIT_CARD); } + $link_methods = PaymentMethod::all( + [ + 'customer' => $customer->id, + 'type' => 'link', + ], + $this->stripe->stripe_connect_auth + ); + + foreach ($link_methods as $method) { + $this->addOrUpdateCard($method, $customer->id, $client, GatewayType::CREDIT_CARD); + } + $alipay_methods = PaymentMethod::all( [ 'customer' => $customer->id, @@ -217,9 +229,14 @@ class UpdatePaymentMethods private function buildPaymentMethodMeta(PaymentMethod $method, $type_id) { + nlog($method->type); + switch ($type_id) { case GatewayType::CREDIT_CARD: + if($method->type == 'link') + return new \stdClass(); + /** * @class \Stripe\PaymentMethod $method * @property \Stripe\StripeObject $card @@ -240,7 +257,7 @@ class UpdatePaymentMethods return $payment_meta; case GatewayType::ALIPAY: case GatewayType::SOFORT: - + return new \stdClass(); case GatewayType::SEPA: diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index 57ddd8d7e19a..caa924253cc0 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -155,6 +155,8 @@ use App\Listeners\Activity\TaskUpdatedActivity; use App\Listeners\Invoice\InvoiceEmailActivity; use App\Listeners\SendVerificationNotification; use App\Events\Credit\CreditWasEmailedAndFailed; +use App\Events\Invoice\InvoiceAutoBillFailed; +use App\Events\Invoice\InvoiceAutoBillSuccess; use App\Listeners\Activity\CreatedQuoteActivity; use App\Listeners\Activity\DeleteClientActivity; use App\Listeners\Activity\DeleteCreditActivity; @@ -250,6 +252,8 @@ use App\Events\RecurringExpense\RecurringExpenseWasArchived; use App\Events\RecurringExpense\RecurringExpenseWasRestored; use App\Events\RecurringInvoice\RecurringInvoiceWasArchived; use App\Events\RecurringInvoice\RecurringInvoiceWasRestored; +use App\Listeners\Invoice\InvoiceAutoBillFailedActivity; +use App\Listeners\Invoice\InvoiceAutoBillSuccessActivity; use App\Listeners\PurchaseOrder\CreatePurchaseOrderActivity; use App\Listeners\PurchaseOrder\PurchaseOrderViewedActivity; use App\Listeners\PurchaseOrder\UpdatePurchaseOrderActivity; @@ -426,6 +430,12 @@ class EventServiceProvider extends ServiceProvider ExpenseRestoredActivity::class, ], //Invoices + InvoiceAutoBillSuccess::class => [ + InvoiceAutoBillSuccessActivity::class, + ], + InvoiceAutoBillFailed::class => [ + InvoiceAutoBillFailedActivity::class, + ], InvoiceWasMarkedSent::class => [ ], InvoiceWasUpdated::class => [ diff --git a/app/Providers/StaticServiceProvider.php b/app/Providers/StaticServiceProvider.php index 00aa774c204f..848bddb77b1c 100644 --- a/app/Providers/StaticServiceProvider.php +++ b/app/Providers/StaticServiceProvider.php @@ -222,6 +222,10 @@ class StaticServiceProvider extends ServiceProvider 'subject' => EmailTemplateDefaults::emailPaymentSubject(), 'body' => EmailTemplateDefaults::emailPaymentTemplate(), ], + 'payment_failed' => [ + 'subject' => EmailTemplateDefaults::emailPaymentFailedSubject(), + 'body' => EmailTemplateDefaults::emailPaymentFailedTemplate(), + ], 'quote_reminder1' => [ 'subject' => EmailTemplateDefaults::emailQuoteReminder1Subject(), 'body' => EmailTemplateDefaults::emailQuoteReminder1Body(), diff --git a/app/Repositories/CompanyRepository.php b/app/Repositories/CompanyRepository.php index 4a6d58d45d14..a2a2195d3b85 100644 --- a/app/Repositories/CompanyRepository.php +++ b/app/Repositories/CompanyRepository.php @@ -11,8 +11,9 @@ namespace App\Repositories; -use App\Models\Company; use App\Utils\Ninja; +use App\Models\Company; +use App\Repositories\BaseRepository; /** * CompanyRepository. @@ -57,11 +58,36 @@ class CompanyRepository extends BaseRepository $company->smtp_password = $data['smtp_password']; } + if(isset($data['e_invoice']) && is_array($data['e_invoice'])){ + //ensure it is normalized first! + $data['e_invoice'] = $this->arrayFilterRecursive($data['e_invoice']); + + $company->e_invoice = $data['e_invoice']; + } + $company->save(); return $company; } + + private function arrayFilterRecursive(array $array): array + { + foreach ($array as $key => $value) { + if (is_array($value)) { + // Recursively filter the nested array + $array[$key] = $this->arrayFilterRecursive($value); + } + // Remove null values + if (is_null($array[$key])) { + unset($array[$key]); + } + } + + return $array; + } + + /** * parseCustomFields * diff --git a/app/Services/Bank/ProcessBankRules.php b/app/Services/Bank/ProcessBankRules.php index 6199368d7db1..61bef394c300 100644 --- a/app/Services/Bank/ProcessBankRules.php +++ b/app/Services/Bank/ProcessBankRules.php @@ -13,6 +13,7 @@ namespace App\Services\Bank; use App\Factory\ExpenseCategoryFactory; use App\Factory\ExpenseFactory; +use App\Jobs\Bank\MatchBankTransactions; use App\Models\BankTransaction; use App\Models\Client; use App\Models\ExpenseCategory; @@ -20,12 +21,14 @@ use App\Models\Invoice; use App\Models\Payment; use App\Services\AbstractService; use App\Utils\Traits\GeneratesCounter; +use App\Utils\Traits\MakesHash; use Illuminate\Support\Carbon; use Illuminate\Support\Facades\Cache; class ProcessBankRules extends AbstractService { use GeneratesCounter; + use MakesHash; protected $credit_rules; @@ -87,6 +90,8 @@ class ProcessBankRules extends AbstractService foreach ($bank_transaction_rule['rules'] as $rule) { + $results = []; + $payments = Payment::query() ->withTrashed() ->whereIn('status_id', [1,4]) @@ -101,28 +106,26 @@ class ProcessBankRules extends AbstractService ->where('is_deleted', 0) ->get(); - $results = []; - match($rule['search_key']) { '$payment.amount' => $results = [Payment::class, $this->searchPaymentResource('amount', $rule, $payments)], '$payment.transaction_reference' => $results = [Payment::class, $this->searchPaymentResource('transaction_reference', $rule, $payments)], - '$payment.custom1' => $results = [Payment::class, $this->searchPaymentResource('custom1', $rule, $payments)], - '$payment.custom2' => $results = [Payment::class, $this->searchPaymentResource('custom2', $rule, $payments)], - '$payment.custom3' => $results = [Payment::class, $this->searchPaymentResource('custom3', $rule, $payments)], - '$payment.custom4' => $results = [Payment::class, $this->searchPaymentResource('custom4', $rule, $payments)], + '$payment.custom1' => $results = [Payment::class, $this->searchPaymentResource('custom_value1', $rule, $payments)], + '$payment.custom2' => $results = [Payment::class, $this->searchPaymentResource('custom_value2', $rule, $payments)], + '$payment.custom3' => $results = [Payment::class, $this->searchPaymentResource('custom_value3', $rule, $payments)], + '$payment.custom4' => $results = [Payment::class, $this->searchPaymentResource('custom_value4', $rule, $payments)], '$invoice.amount' => $results = [Invoice::class, $this->searchInvoiceResource('amount', $rule, $invoices)], '$invoice.number' => $results = [Invoice::class, $this->searchInvoiceResource('number', $rule, $invoices)], '$invoice.po_number' => $results = [Invoice::class, $this->searchInvoiceResource('po_number', $rule, $invoices)], - '$invoice.custom1' => $results = [Invoice::class, $this->searchInvoiceResource('custom1', $rule, $invoices)], - '$invoice.custom2' => $results = [Invoice::class, $this->searchInvoiceResource('custom2', $rule, $invoices)], - '$invoice.custom3' => $results = [Invoice::class, $this->searchInvoiceResource('custom3', $rule, $invoices)], - '$invoice.custom4' => $results = [Invoice::class, $this->searchInvoiceResource('custom4', $rule, $invoices)], + '$invoice.custom1' => $results = [Invoice::class, $this->searchInvoiceResource('custom_value1', $rule, $invoices)], + '$invoice.custom2' => $results = [Invoice::class, $this->searchInvoiceResource('custom_value2', $rule, $invoices)], + '$invoice.custom3' => $results = [Invoice::class, $this->searchInvoiceResource('custom_value3', $rule, $invoices)], + '$invoice.custom4' => $results = [Invoice::class, $this->searchInvoiceResource('custom_value4', $rule, $invoices)], '$client.id_number' => $results = [Client::class, $this->searchClientResource('id_number', $rule, $invoices, $payments)], '$client.email' => $results = [Client::class, $this->searchClientResource('email', $rule, $invoices, $payments)], - '$client.custom1' => $results = [Client::class, $this->searchClientResource('custom1', $rule, $invoices, $payments)], - '$client.custom2' => $results = [Client::class, $this->searchClientResource('custom2', $rule, $invoices, $payments)], - '$client.custom3' => $results = [Client::class, $this->searchClientResource('custom3', $rule, $invoices, $payments)], - '$client.custom4' => $results = [Client::class, $this->searchClientResource('custom4', $rule, $invoices, $payments)], + '$client.custom1' => $results = [Client::class, $this->searchClientResource('custom_value1', $rule, $invoices, $payments)], + '$client.custom2' => $results = [Client::class, $this->searchClientResource('custom_value2', $rule, $invoices, $payments)], + '$client.custom3' => $results = [Client::class, $this->searchClientResource('custom_value3', $rule, $invoices, $payments)], + '$client.custom4' => $results = [Client::class, $this->searchClientResource('custom_value4', $rule, $invoices, $payments)], default => $results = [Client::class, [collect([]), Invoice::class]], }; @@ -139,74 +142,50 @@ class ProcessBankRules extends AbstractService $match_set[] = $results; } } + + if (($bank_transaction_rule['matches_on_all'] && $this->checkMatchSetForKey($match_set, $rule_count)) || (!$bank_transaction_rule['matches_on_all'] && count($match_set) > 0)) + { - if (($bank_transaction_rule['matches_on_all'] && $this->checkMatchSetForKey($match_set, $rule_count)) || (!$bank_transaction_rule['matches_on_all'] && count($match_set) > 0)) { - - $this->bank_transaction->vendor_id = $bank_transaction_rule->vendor_id; - $this->bank_transaction->ninja_category_id = $bank_transaction_rule->category_id; $this->bank_transaction->status_id = BankTransaction::STATUS_MATCHED; $this->bank_transaction->bank_transaction_rule_id = $bank_transaction_rule->id; $this->bank_transaction->save(); + $first_result = reset($match_set); - //auto-convert + $invoice_id = false; + $payment_id = false; + + if($first_result[0] == Payment::class) { + $payment_id = $first_result[1][0]; + } + elseif($first_result[0] == Invoice::class) { + $invoice_id = $first_result[1][0]; + } if ($bank_transaction_rule['auto_convert']) { + (new MatchBankTransactions($this->bank_transaction->company->id, $this->bank_transaction->company->db, [ + 'transactions' => [ + [ + 'id' => $this->bank_transaction->id, + 'invoice_ids' => $invoice_id ?? '', + 'payment_id' => $payment_id ?? '', + ], + ], + ]))->handle(); + } + else { - //all types must match. - $entity = $match_set[0][0]; - - foreach($match_set as $set) - { - if($set[0] != $entity) - return false; + if($invoice_id){ + $this->bank_transaction->invoice_ids = $this->encodePrimaryKey($invoice_id); + } + elseif($payment_id){ + $this->bank_transaction->payment_id = $payment_id; } - -// $result_set = []; - -// foreach($match_set as $key => $set) { - -// $parseable_set = $match_set; -// unset($parseable_set[$key]); - -// $entity_ids = $set[1]; - -// foreach($parseable_set as $kkey => $vvalue) { - -// $i = array_intersect($vvalue[1], $entity_ids); - -// if(count($i) == 0) { -// return false; -// } - - -// $result_set[] = $i; - -// } - - -// $commonValues = $result_set[0]; // Start with the first sub-array - -// foreach ($result_set as $subArray) { -// $commonValues = array_intersect($commonValues, $subArray); -// } - -// echo print_r($commonValues, true); - -//just need to ensure the result count = rule count -// } - - - - //there must be a key in each set - - //no misses allowed - - $this->bank_transaction->status_id = BankTransaction::STATUS_CONVERTED; $this->bank_transaction->save(); } + } } @@ -221,13 +200,13 @@ class ProcessBankRules extends AbstractService private function searchInvoiceResource(string $column, array $rule, $invoices) { - return $invoices->when($rule['search_key'] == 'description', function ($q) use ($rule, $column) { - return $q->cursor()->filter(function ($record) use ($rule, $column) { + return $invoices->when($column != 'amount', function ($q) use ($rule, $column) { + return $q->filter(function ($record) use ($rule, $column) { return $this->matchStringOperator($this->bank_transaction->description, $record->{$column}, $rule['operator']); }); }) - ->when($rule['search_key'] == 'amount', function ($q) use ($rule, $column) { - return $q->cursor()->filter(function ($record) use ($rule, $column) { + ->when($column == 'amount', function ($q) use ($rule, $column) { + return $q->filter(function ($record) use ($rule, $column) { return $this->matchNumberOperator($this->bank_transaction->amount, $record->{$column}, $rule['operator']); }); })->pluck("id"); @@ -236,17 +215,18 @@ class ProcessBankRules extends AbstractService private function searchPaymentResource(string $column, array $rule, $payments) { - - return $payments->when($rule['search_key'] == 'description', function ($q) use ($rule, $column) { - return $q->cursor()->filter(function ($record) use ($rule, $column) { - return $this->matchStringOperator($this->bank_transaction->description, $record->{$column}, $rule['operator']); + return $payments->when($column != 'amount', function ($q) use ($rule, $column) { + return $q->filter(function ($record) use ($rule, $column) { + + $bool = $this->matchStringOperator($this->bank_transaction->description, $record->{$column}, $rule['operator']); + return $bool; }); }) - ->when($rule['search_key'] == 'amount', function ($q) use ($rule, $column) { - return $q->cursor()->filter(function ($record) use ($rule, $column) { - return $this->matchNumberOperator($this->bank_transaction->amount, $record->{$column}, $rule['operator']); - }); - })->pluck("id"); + ->when($column == 'amount', function ($q) use ($rule, $column) { + return $q->filter(function ($record) use ($rule, $column) { + return $this->matchNumberOperator($this->bank_transaction->amount, $record->{$column}, $rule['operator']); + }); + })->pluck("id"); } @@ -297,325 +277,7 @@ class ProcessBankRules extends AbstractService return [Client::class, collect([])]; } - // $payment.amount => "Payment Amount", float - // $payment.transaction_reference => "Payment Transaction Reference", string - // $invoice.amount => "Invoice Amount", float - // $invoice.number => "Invoice Number", string - // $client.id_number => "Client ID Number", string - // $client.email => "Client Email", string - // $invoice.po_number => "Invoice Purchase Order Number", string - - - // private function matchCredit() - // { - // $this->invoices = Invoice::query()->where('company_id', $this->bank_transaction->company_id) - // ->whereIn('status_id', [1,2,3]) - // ->where('is_deleted', 0) - // ->get(); - - // $invoice = $this->invoices->first(function ($value, $key) { - // return str_contains($this->bank_transaction->description, $value->number) || str_contains(str_replace("\n", "", $this->bank_transaction->description), $value->number); - // }); - - // if ($invoice) { - // $this->bank_transaction->invoice_ids = $invoice->hashed_id; - // $this->bank_transaction->status_id = BankTransaction::STATUS_MATCHED; - // $this->bank_transaction->save(); - // return; - // } - - // $this->credit_rules = $this->bank_transaction->company->credit_rules(); - - // //stub for credit rules - // foreach ($this->credit_rules as $bank_transaction_rule) { - // $matches = 0; - - // if (!is_array($bank_transaction_rule['rules'])) { - // continue; - // } - - // foreach ($bank_transaction_rule['rules'] as $rule) { - // $rule_count = count($bank_transaction_rule['rules']); - - // $invoiceNumbers = false; - // $invoiceNumber = false; - // $invoiceAmounts = false; - // $paymentAmounts = false; - // $paymentReferences = false; - // $clientIdNumbers = false; - // $clientEmails = false; - // $invoicePONumbers = false; - - // if ($rule['search_key'] == '$invoice.number') { - - // $invoiceNumbers = Invoice::query()->where('company_id', $this->bank_transaction->company_id) - // ->whereIn('status_id', [1,2,3]) - // ->where('is_deleted', 0) - // ->get(); - - // $invoiceNumber = $invoiceNumbers->first(function ($value, $key) { - // return str_contains($this->bank_transaction->description, $value->number) || str_contains(str_replace("\n", "", $this->bank_transaction->description), $value->number); - // }); - - // if($invoiceNumber) - // $matches++; - - // } - - // if ($rule['search_key'] == '$invoice.po_number') { - - // $invoicePONumbers = Invoice::query()->where('company_id', $this->bank_transaction->company_id) - // ->whereIn('status_id', [1,2,3]) - // ->where('is_deleted', 0) - // ->where('po_number', $this->bank_transaction->description) - // ->get(); - - // if($invoicePONumbers->count() > 0) { - // $matches++; - // } - - // } - - // if ($rule['search_key'] == '$invoice.amount') { - - // $$invoiceAmounts = Invoice::query()->where('company_id', $this->bank_transaction->company_id) - // ->whereIn('status_id', [1,2,3]) - // ->where('is_deleted', 0) - // ->where('amount', $rule['operator'], $this->bank_transaction->amount) - // ->get(); - - // $invoiceAmounts = $this->invoices; - - // if($invoiceAmounts->count() > 0) { - // $matches++; - // } - - // } - - // if ($rule['search_key'] == '$payment.amount') { - - - // $paymentAmounts = Payment::query()->where('company_id', $this->bank_transaction->company_id) - // ->whereIn('status_id', [1,4]) - // ->where('is_deleted', 0) - // ->whereNull('transaction_id') - // ->where('amount', $rule['operator'], $this->bank_transaction->amount) - // ->get(); - - - - // if($paymentAmounts->count() > 0) { - // $matches++; - // } - - // } - - - // if ($rule['search_key'] == '$payment.transaction_reference') { - - // $ref_search = $this->bank_transaction->description; - - // switch ($rule['operator']) { - // case 'is': - // $operator = '='; - // break; - // case 'contains': - // $ref_search = "%".$ref_search."%"; - // $operator = 'LIKE'; - // break; - - // default: - // $operator = '='; - // break; - // } - - // $paymentReferences = Payment::query()->where('company_id', $this->bank_transaction->company_id) - // ->whereIn('status_id', [1,4]) - // ->where('is_deleted', 0) - // ->whereNull('transaction_id') - // ->where('transaction_reference', $operator, $ref_search) - // ->get(); - - - - // if($paymentReferences->count() > 0) { - // $matches++; - // } - - // } - - // if ($rule['search_key'] == '$client.id_number') { - - // $ref_search = $this->bank_transaction->description; - - // switch ($rule['operator']) { - // case 'is': - // $operator = '='; - // break; - // case 'contains': - // $ref_search = "%".$ref_search."%"; - // $operator = 'LIKE'; - // break; - - // default: - // $operator = '='; - // break; - // } - - // $clientIdNumbers = Client::query()->where('company_id', $this->bank_transaction->company_id) - // ->where('id_number', $operator, $ref_search) - // ->get(); - - // if($clientIdNumbers->count() > 0) { - // $matches++; - // } - - // } - - - // if ($rule['search_key'] == '$client.email') { - - // $clientEmails = Client::query() - // ->where('company_id', $this->bank_transaction->company_id) - // ->whereHas('contacts', function ($q){ - // $q->where('email', $this->bank_transaction->description); - // }) - // ->get(); - - - // if($clientEmails->count() > 0) { - // $matches++; - // } - - // if (($bank_transaction_rule['matches_on_all'] && ($matches == $rule_count)) || (!$bank_transaction_rule['matches_on_all'] && $matches > 0)) { - - // //determine which combination has succeeded, ie link a payment / or / invoice - // $invoice_ids = null; - // $payment_id = null; - - // if($invoiceNumber){ - // $invoice_ids = $invoiceNumber->hashed_id; - // } - - // if($invoicePONumbers && strlen($invoice_ids ?? '') == 0){ - - // if($clientEmails){ // @phpstan-ignore-line - - // $invoice_ids = $this->matchInvoiceAndClient($invoicePONumbers, $clientEmails); - - // } - - // if($clientIdNumbers && strlen($invoice_ids ?? '') == 0) - // { - - // $invoice_ids = $this->matchInvoiceAndClient($invoicePONumbers, $clientIdNumbers); - - // } - - // if(strlen($invoice_ids ?? '') == 0) - // { - // $invoice_ids = $invoicePONumbers->first()->hashed_id; - // } - - // } - - - // if($invoiceAmounts && strlen($invoice_ids ?? '') == 0) { - - // if($clientEmails) {// @phpstan-ignore-line - - // $invoice_ids = $this->matchInvoiceAndClient($invoiceAmounts, $clientEmails); - - // } - - // if($clientIdNumbers && strlen($invoice_ids ?? '') == 0) { - - // $invoice_ids = $this->matchInvoiceAndClient($invoiceAmounts, $clientIdNumbers); - - // } - - // if(strlen($invoice_ids ?? '') == 0) { - // $invoice_ids = $invoiceAmounts->first()->hashed_id; - // } - - // } - - - // if($paymentAmounts && strlen($invoice_ids ?? '') == 0 && is_null($payment_id)) { - - // if($clientEmails) {// @phpstan-ignore-line - - // $payment_id = $this->matchPaymentAndClient($paymentAmounts, $clientEmails); - - // } - - // if($clientIdNumbers && is_null($payment_id)) { - - - // $payment_id = $this->matchPaymentAndClient($paymentAmounts, $clientEmails); - - // } - - // if(is_null($payment_id)) { - // $payment_id = $paymentAmounts->first()->id; - // } - - // } - - // if(strlen($invoice_ids ?? '') > 1 || is_int($payment_id)) - // { - - // $this->bank_transaction->payment_id = $payment_id; - // $this->bank_transaction->invoice_ids = $invoice_ids; - // $this->bank_transaction->status_id = BankTransaction::STATUS_MATCHED; - // $this->bank_transaction->bank_transaction_rule_id = $bank_transaction_rule->id; - // $this->bank_transaction->save(); - - // } - - // } - - // } - - // } - - // } - - // } - - - // private function matchPaymentAndClient($payments, $clients): ?int - // { - // /** @var \Illuminate\Support\Collection $payments */ - // foreach($payments as $payment) { - // foreach($clients as $client) { - - // if($payment->client_id == $client->id) { - // return $payment->id; - - // } - // } - // } - - // return null; - // } - - // private function matchInvoiceAndClient($invoices, $clients): ?Invoice - // { - // /** @var \Illuminate\Support\Collection $invoices */ - // foreach($invoices as $invoice) { - // foreach($clients as $client) { - - // if($invoice->client_id == $client->id) { - // return $invoice->hashed_id; - - // } - // } - // } - - // return null; - // } - + private function matchDebit() { $this->debit_rules = $this->bank_transaction->company->debit_rules(); @@ -726,13 +388,336 @@ class ProcessBankRules extends AbstractService $bt_value = strtolower(str_replace(" ", "", $bt_value)); $rule_value = strtolower(str_replace(" ", "", $rule_value)); $rule_length = iconv_strlen($rule_value); - +// nlog($bt_value); +// nlog($rule_value); +// nlog($rule_length); return match ($operator) { 'is' => $bt_value == $rule_value, - 'contains' => stripos($bt_value, $rule_value) !== false, - 'starts_with' => substr($bt_value, 0, $rule_length) == $rule_value, + 'contains' => stripos($bt_value, $rule_value) !== false && strlen($rule_value) > 1, + 'starts_with' => substr($bt_value, 0, $rule_length) == $rule_value && strlen($rule_value) > 1, 'is_empty' => empty($bt_value), default => false, }; } } + + + +// $payment.amount => "Payment Amount", float +// $payment.transaction_reference => "Payment Transaction Reference", string +// $invoice.amount => "Invoice Amount", float +// $invoice.number => "Invoice Number", string +// $client.id_number => "Client ID Number", string +// $client.email => "Client Email", string +// $invoice.po_number => "Invoice Purchase Order Number", string + + +// private function matchCredit() +// { +// $this->invoices = Invoice::query()->where('company_id', $this->bank_transaction->company_id) +// ->whereIn('status_id', [1,2,3]) +// ->where('is_deleted', 0) +// ->get(); + +// $invoice = $this->invoices->first(function ($value, $key) { +// return str_contains($this->bank_transaction->description, $value->number) || str_contains(str_replace("\n", "", $this->bank_transaction->description), $value->number); +// }); + +// if ($invoice) { +// $this->bank_transaction->invoice_ids = $invoice->hashed_id; +// $this->bank_transaction->status_id = BankTransaction::STATUS_MATCHED; +// $this->bank_transaction->save(); +// return; +// } + +// $this->credit_rules = $this->bank_transaction->company->credit_rules(); + +// //stub for credit rules +// foreach ($this->credit_rules as $bank_transaction_rule) { +// $matches = 0; + +// if (!is_array($bank_transaction_rule['rules'])) { +// continue; +// } + +// foreach ($bank_transaction_rule['rules'] as $rule) { +// $rule_count = count($bank_transaction_rule['rules']); + +// $invoiceNumbers = false; +// $invoiceNumber = false; +// $invoiceAmounts = false; +// $paymentAmounts = false; +// $paymentReferences = false; +// $clientIdNumbers = false; +// $clientEmails = false; +// $invoicePONumbers = false; + +// if ($rule['search_key'] == '$invoice.number') { + +// $invoiceNumbers = Invoice::query()->where('company_id', $this->bank_transaction->company_id) +// ->whereIn('status_id', [1,2,3]) +// ->where('is_deleted', 0) +// ->get(); + +// $invoiceNumber = $invoiceNumbers->first(function ($value, $key) { +// return str_contains($this->bank_transaction->description, $value->number) || str_contains(str_replace("\n", "", $this->bank_transaction->description), $value->number); +// }); + +// if($invoiceNumber) +// $matches++; + +// } + +// if ($rule['search_key'] == '$invoice.po_number') { + +// $invoicePONumbers = Invoice::query()->where('company_id', $this->bank_transaction->company_id) +// ->whereIn('status_id', [1,2,3]) +// ->where('is_deleted', 0) +// ->where('po_number', $this->bank_transaction->description) +// ->get(); + +// if($invoicePONumbers->count() > 0) { +// $matches++; +// } + +// } + +// if ($rule['search_key'] == '$invoice.amount') { + +// $$invoiceAmounts = Invoice::query()->where('company_id', $this->bank_transaction->company_id) +// ->whereIn('status_id', [1,2,3]) +// ->where('is_deleted', 0) +// ->where('amount', $rule['operator'], $this->bank_transaction->amount) +// ->get(); + +// $invoiceAmounts = $this->invoices; + +// if($invoiceAmounts->count() > 0) { +// $matches++; +// } + +// } + +// if ($rule['search_key'] == '$payment.amount') { + + +// $paymentAmounts = Payment::query()->where('company_id', $this->bank_transaction->company_id) +// ->whereIn('status_id', [1,4]) +// ->where('is_deleted', 0) +// ->whereNull('transaction_id') +// ->where('amount', $rule['operator'], $this->bank_transaction->amount) +// ->get(); + + + +// if($paymentAmounts->count() > 0) { +// $matches++; +// } + +// } + + +// if ($rule['search_key'] == '$payment.transaction_reference') { + +// $ref_search = $this->bank_transaction->description; + +// switch ($rule['operator']) { +// case 'is': +// $operator = '='; +// break; +// case 'contains': +// $ref_search = "%".$ref_search."%"; +// $operator = 'LIKE'; +// break; + +// default: +// $operator = '='; +// break; +// } + +// $paymentReferences = Payment::query()->where('company_id', $this->bank_transaction->company_id) +// ->whereIn('status_id', [1,4]) +// ->where('is_deleted', 0) +// ->whereNull('transaction_id') +// ->where('transaction_reference', $operator, $ref_search) +// ->get(); + + + +// if($paymentReferences->count() > 0) { +// $matches++; +// } + +// } + +// if ($rule['search_key'] == '$client.id_number') { + +// $ref_search = $this->bank_transaction->description; + +// switch ($rule['operator']) { +// case 'is': +// $operator = '='; +// break; +// case 'contains': +// $ref_search = "%".$ref_search."%"; +// $operator = 'LIKE'; +// break; + +// default: +// $operator = '='; +// break; +// } + +// $clientIdNumbers = Client::query()->where('company_id', $this->bank_transaction->company_id) +// ->where('id_number', $operator, $ref_search) +// ->get(); + +// if($clientIdNumbers->count() > 0) { +// $matches++; +// } + +// } + + +// if ($rule['search_key'] == '$client.email') { + +// $clientEmails = Client::query() +// ->where('company_id', $this->bank_transaction->company_id) +// ->whereHas('contacts', function ($q){ +// $q->where('email', $this->bank_transaction->description); +// }) +// ->get(); + + +// if($clientEmails->count() > 0) { +// $matches++; +// } + +// if (($bank_transaction_rule['matches_on_all'] && ($matches == $rule_count)) || (!$bank_transaction_rule['matches_on_all'] && $matches > 0)) { + +// //determine which combination has succeeded, ie link a payment / or / invoice +// $invoice_ids = null; +// $payment_id = null; + +// if($invoiceNumber){ +// $invoice_ids = $invoiceNumber->hashed_id; +// } + +// if($invoicePONumbers && strlen($invoice_ids ?? '') == 0){ + +// if($clientEmails){ // @phpstan-ignore-line + +// $invoice_ids = $this->matchInvoiceAndClient($invoicePONumbers, $clientEmails); + +// } + +// if($clientIdNumbers && strlen($invoice_ids ?? '') == 0) +// { + +// $invoice_ids = $this->matchInvoiceAndClient($invoicePONumbers, $clientIdNumbers); + +// } + +// if(strlen($invoice_ids ?? '') == 0) +// { +// $invoice_ids = $invoicePONumbers->first()->hashed_id; +// } + +// } + + +// if($invoiceAmounts && strlen($invoice_ids ?? '') == 0) { + +// if($clientEmails) {// @phpstan-ignore-line + +// $invoice_ids = $this->matchInvoiceAndClient($invoiceAmounts, $clientEmails); + +// } + +// if($clientIdNumbers && strlen($invoice_ids ?? '') == 0) { + +// $invoice_ids = $this->matchInvoiceAndClient($invoiceAmounts, $clientIdNumbers); + +// } + +// if(strlen($invoice_ids ?? '') == 0) { +// $invoice_ids = $invoiceAmounts->first()->hashed_id; +// } + +// } + + +// if($paymentAmounts && strlen($invoice_ids ?? '') == 0 && is_null($payment_id)) { + +// if($clientEmails) {// @phpstan-ignore-line + +// $payment_id = $this->matchPaymentAndClient($paymentAmounts, $clientEmails); + +// } + +// if($clientIdNumbers && is_null($payment_id)) { + + +// $payment_id = $this->matchPaymentAndClient($paymentAmounts, $clientEmails); + +// } + +// if(is_null($payment_id)) { +// $payment_id = $paymentAmounts->first()->id; +// } + +// } + +// if(strlen($invoice_ids ?? '') > 1 || is_int($payment_id)) +// { + +// $this->bank_transaction->payment_id = $payment_id; +// $this->bank_transaction->invoice_ids = $invoice_ids; +// $this->bank_transaction->status_id = BankTransaction::STATUS_MATCHED; +// $this->bank_transaction->bank_transaction_rule_id = $bank_transaction_rule->id; +// $this->bank_transaction->save(); + +// } + +// } + +// } + +// } + +// } + +// } + + +// private function matchPaymentAndClient($payments, $clients): ?int +// { +// /** @var \Illuminate\Support\Collection $payments */ +// foreach($payments as $payment) { +// foreach($clients as $client) { + +// if($payment->client_id == $client->id) { +// return $payment->id; + +// } +// } +// } + +// return null; +// } + +// private function matchInvoiceAndClient($invoices, $clients): ?Invoice +// { +// /** @var \Illuminate\Support\Collection $invoices */ +// foreach($invoices as $invoice) { +// foreach($clients as $client) { + +// if($invoice->client_id == $client->id) { +// return $invoice->hashed_id; + +// } +// } +// } + +// return null; +// } diff --git a/app/Services/ClientPortal/LivewireInstantPayment.php b/app/Services/ClientPortal/LivewireInstantPayment.php index 83b0a5e540b0..e08a61759eb9 100644 --- a/app/Services/ClientPortal/LivewireInstantPayment.php +++ b/app/Services/ClientPortal/LivewireInstantPayment.php @@ -109,11 +109,10 @@ class LivewireInstantPayment $client = $invoices->first()->client; /* pop non payable invoice from the $payable_invoices array */ - $payable_invoices = $payable_invoices->filter(function ($payable_invoice) use ($invoices) { + $payable_invoices = $payable_invoices->filter(function ($payable_invoice) use ($invoices) { // @phpstan-ignore-line return $invoices->where('hashed_id', $payable_invoice['invoice_id'])->first(); }); - //$payable_invoices = $payable_invoices->map(function ($payable_invoice) use ($invoices, $settings) { $payable_invoice_collection = collect(); foreach ($payable_invoices as $payable_invoice) { diff --git a/app/Services/EDocument/Gateway/Storecove/Storecove.php b/app/Services/EDocument/Gateway/Storecove/Storecove.php index cff98750761f..335012f473dc 100644 --- a/app/Services/EDocument/Gateway/Storecove/Storecove.php +++ b/app/Services/EDocument/Gateway/Storecove/Storecove.php @@ -11,8 +11,13 @@ namespace App\Services\EDocument\Gateway\Storecove; +use App\DataMapper\Analytics\LegalEntityCreated; use App\Models\Company; use Illuminate\Support\Facades\Http; +use GuzzleHttp\Exception\ClientException; +use GuzzleHttp\Exception\ServerException; +use Illuminate\Http\Client\RequestException; +use Turbo124\Beacon\Facades\LightLogs; enum HttpVerb: string { @@ -24,9 +29,11 @@ enum HttpVerb: string } class Storecove -{ +{ + /** @var string $base_url */ private string $base_url = 'https://api.storecove.com/api/v2/'; - + + /** @var array $peppol_discovery */ private array $peppol_discovery = [ "documentTypes" => ["invoice"], "network" => "peppol", @@ -34,7 +41,8 @@ class Storecove "scheme" => "de:lwid", "identifier" => "DE:VAT" ]; - + + /** @var array $dbn_discovery */ private array $dbn_discovery = [ "documentTypes" => ["invoice"], "network" => "dbnalliance", @@ -43,18 +51,22 @@ class Storecove "identifier" => "1200109963131" ]; + public StorecoveRouter $router; public function __construct() { + $this->router = new StorecoveRouter(); } - - //config('ninja.storecove_api_key'); - - //https://app.storecove.com/en/docs#_test_identifiers - //check if identifier is able to send on the network. - - //response = { "code": "OK", "email": false} - public function discovery($identifier, $scheme, $network = 'peppol') + + /** + * Discovery + * + * @param string $identifier + * @param string $scheme + * @param string $network + * @return bool + */ + public function discovery(string $identifier, string $scheme, string $network = 'peppol'): bool { $network_data = []; @@ -71,50 +83,23 @@ class Storecove return ($r->successful() && $r->json()['code'] == 'OK') ? true : false; } - - //response = "guid" : "xx", - + /** - * If the receiver cannot be found, then an - * email is sent to that user if a appropriate - * email is included in the document payload + * Unused as yet * - * { - "routing": { - "emails": [ - "test@example.com" - ], - "eIdentifiers": [] - } - } - * - * - * - // documentType : invoice/invoice_response/order - // rawDocumentData : { - // document: base64_encode($ubl) - // parse: true - // parseStrategy: ubl - // } + * @param mixed $document + * @return string|bool */ public function sendJsonDocument($document) { $payload = [ - "legalEntityId" => 290868, + // "legalEntityId" => 290868, "idempotencyGuid" => \Illuminate\Support\Str::uuid(), "routing" => [ "eIdentifiers" => [], "emails" => ["david@invoiceninja.com"] ], - // "document" => [ - // 'documentType' => 'invoice', - // "rawDocumentData" => [ - // "document" => base64_encode($document), - // "parse" => true, - // "parseStrategy" => "ubl", - // ], - // ], "document" => [ "documentType" => "invoice", "invoice" => $document, @@ -123,13 +108,8 @@ class Storecove $uri = "document_submissions"; - nlog($payload); - $r = $this->httpClient($uri, (HttpVerb::POST)->value, $payload, $this->getHeaders()); - nlog($r->body()); - nlog($r->json()); - if($r->successful()) { return $r->json()['guid']; } @@ -137,7 +117,16 @@ class Storecove return false; } - + + /** + * Send Document via StoreCove + * + * @param string $document + * @param int $routing_id + * @param array $override_payload + * + * @return string|\Illuminate\Http\Client\Response + */ public function sendDocument(string $document, int $routing_id, array $override_payload = []) { @@ -155,7 +144,6 @@ class Storecove $payload = array_merge($payload, $override_payload); - $payload['document']['documentType'] = 'invoice'; $payload['document']["rawDocumentData"] = [ "document" => base64_encode($document), @@ -165,103 +153,72 @@ class Storecove $uri = "document_submissions"; - nlog($payload); - $r = $this->httpClient($uri, (HttpVerb::POST)->value, $payload, $this->getHeaders()); nlog($r->body()); - nlog($r->json()); + // nlog($r->json()); if($r->successful()) { return $r->json()['guid']; } - return false; + return $r; } - //document submission sending evidence + /** + * Get Sending Evidence + * + * @param string $guid + * @return mixed + */ public function getSendingEvidence(string $guid) { $uri = "document_submissions/{$guid}"; + $r = $this->httpClient($uri, (HttpVerb::GET)->value, [], $this->getHeaders()); + if($r->successful()) + return $r->json(); + + return $r; } - // { - // "party_name": "", - // "line1": "", - // "city": "", - // "zip": "", - // "country": "EH", - // "line2": "", - // "county": "", - // "tenant_id": "", - // "public": true, - // "advertisements": [ - // "invoice" - // ], - // "third_party_username": "", - // "third_party_password": "", - // "rea": { - // "province": "AR", - // "identifier": "", - // "capital": "", - // "partners": "SM", - // "liquidation_status": "LN" - // }, - // "acts_as_sender": true, - // "acts_as_receiver": true, - // "tax_registered": true - // } - - // acts_as_receiver - optional - Default : true - // acts_as_sender - optional - Default : true - // advertisements - optional < enum (invoice, invoice_response, order, ordering, order_response, selfbilling) > array - // city - required - Length : 2 - 64 - // country - required - ISO 3166-1 alpha-2 - // county - optional - Maximal length : 64 - // line1 - required - The first address line - Length : 2 - 192 - // line2 - optional - The second address line, if applicable Maximal length : 192 - // party_name - required - The name of the company. Length : 2 - 64 - // public - optional - Whether or not this LegalEntity is public. Public means it will be entered into the PEPPOL directory at https://directory.peppol.eu/ Default : true - // rea - optional - The REA details for the LegalEntity. Only applies to IT (Italian) LegalEntities. - https://www.storecove.com/docs/#_openapi_rea (schema) - - // capital - optional - The captial for the company. - number - // identifier - optional - The identifier. Length : 2 - 20 - // liquidation_status - optional - The liquidation status of the company. enum (LN, LS) - // partners - optional - The number of partners. enum (SU, SM) - // province - optional - The provincia of the ufficio that issued the identifier.enum (AG, AL, AN, AO, AQ, AR, AP, AT, AV, BA, BT, BL, BN, BG, BI, BO, BZ, BS, BR, CA, CL, CB, CI, CE, CT, CZ, CH, CO, CS, CR, KR, CN, EN, FM, FE, FI, FG, FC, FR, GE, GO, GR, IM, IS, SP, LT, LE, LC, LI, LO, LU, MC, MN, MS, MT, VS, ME, MI, MO, MB, NA, NO, NU, OG, OT, OR, PD, PA, PR, PV, PG, PU, PE, PC, PI, PT, PN, PZ, PO, RG, RA, RC, RE, RI, RN, RO, SA, SS, SV, SI, SR, SO, TA, TE, TR, TO, TP, TN, TV, TS, UD, VA, VE, VB, VC, VR, VV, VI, VT) - - // tax_registered - optional - Whether or not this LegalEntity is tax registered. This influences the validation of the data presented when sending documents. Default : true - // tenant_id - optional - The id of the tenant, to be used in case of single-tenant solutions that share webhook URLs. This property will included in webhook events. Maximal length : 64 - // third_party_password - optional - The password to use to authenticate to a system through which to send the document, or to obtain tax authority approval to send it. This field is currently relevant only for India and mandatory when creating an IN LegalEntity. Length : 2 - 64 - // third_party_username - optional - The username to use to authenticate to a system through which to send the document, or to obtain tax authority approval to send it. This field is currently relevant only for India and mandatory when creating an IN LegalEntity. Length : 2 - 64 - // zip - required - The zipcode. Length : 2 - 32 - /** * CreateLegalEntity * + * Creates a base entity. + * + * Following creation, you will also need to create a Peppol Identifier + * * @url https://www.storecove.com/docs/#_openapi_legalentitycreate + * * @return mixed */ - public function createLegalEntity(array $data, Company $company) + public function createLegalEntity(array $data, ?Company $company = null) { $uri = 'legal_entities'; + if($company){ + + $data = array_merge([ + 'city' => $company->settings->city, + 'country' => $company->country()->iso_3166_2, + 'county' => $company->settings->state, + 'line1' => $company->settings->address1, + 'line2' => $company->settings->address2, + 'party_name' => $company->settings->name, + 'tax_registered' => (bool)strlen($company->settings->vat_number ?? '') > 2, + 'tenant_id' => $company->company_key, + 'zip' => $company->settings->postal_code, + ], $data); + + } + $company_defaults = [ 'acts_as_receiver' => true, 'acts_as_sender' => true, 'advertisements' => ['invoice'], - 'city' => $company->settings->city, - 'country' => $company->country()->iso_3166_2, - 'county' => $company->settings->state, - 'line1' => $company->settings->address1, - 'line2' => $company->settings->address2, - 'party_name' => $company->settings->name, - 'tax_registered' => true, - 'tenant_id' => $company->company_key, - 'zip' => $company->settings->postal_code, ]; $payload = array_merge($company_defaults, $data); @@ -275,10 +232,18 @@ class Storecove return $r; } - + + /** + * GetLegalEntity + * + * @param int $id + * @return mixed + */ public function getLegalEntity($id) { + // $uri = "legal_entities"; + $uri = "legal_entities/{$id}"; $r = $this->httpClient($uri, (HttpVerb::GET)->value, []); @@ -290,8 +255,15 @@ class Storecove return $r; } - - public function updateLegalEntity($id, array $data) + + /** + * UpdateLegalEntity + * + * @param int $id + * @param array $data + * @return array + */ + public function updateLegalEntity(int $id, array $data) { $uri = "legal_entities/{$id}"; @@ -305,7 +277,17 @@ class Storecove return $r; } - + + /** + * AddIdentifier + * + * Add a Peppol identifier to the legal entity + * + * @param int $legal_entity_id + * @param string $identifier + * @param string $scheme + * @return mixed + */ public function addIdentifier(int $legal_entity_id, string $identifier, string $scheme) { $uri = "legal_entities/{$legal_entity_id}/peppol_identifiers"; @@ -319,12 +301,29 @@ class Storecove $r = $this->httpClient($uri, (HttpVerb::POST)->value, $data); if($r->successful()) { - return $r->json(); + $data = $r->json(); + + return $data; } return $r; } + + /** + * deleteIdentifier + * + * @param int $legal_entity_id + * @return bool + */ + public function deleteIdentifier(int $legal_entity_id): bool + { + $uri = "/legal_entities/{$legal_entity_id}"; + + $r = $this->httpClient($uri, (HttpVerb::DELETE)->value, []); + + return $r->successful(); + } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// private function getHeaders(array $headers = []) @@ -336,15 +335,37 @@ class Storecove ], $headers); } - + + /** + * httpClient + * + * @param string $uri + * @param string $verb + * @param array $data + * @param array $headers + * @return \Illuminate\Http\Client\Response + */ private function httpClient(string $uri, string $verb, array $data, ?array $headers = []) { - $r = Http::withToken(config('ninja.storecove_api_key')) - ->withHeaders($this->getHeaders($headers)) - ->{$verb}("{$this->base_url}{$uri}", $data); + try { + $r = Http::withToken(config('ninja.storecove_api_key')) + ->withHeaders($this->getHeaders($headers)) + ->{$verb}("{$this->base_url}{$uri}", $data)->throw(); + } + catch (ClientException $e) { + // 4xx errors + nlog("Client error: " . $e->getMessage()); + nlog("Response body: " . $e->getResponse()->getBody()->getContents()); + } catch (ServerException $e) { + // 5xx errors + nlog("Server error: " . $e->getMessage()); + nlog("Response body: " . $e->getResponse()->getBody()->getContents()); + } catch (RequestException $e) { + nlog("Request error: {$e->getCode()}: " . $e->getMessage()); + } - return $r; + return $r; // @phpstan-ignore-line } } diff --git a/app/Services/EDocument/Gateway/Storecove/StorecoveRouter.php b/app/Services/EDocument/Gateway/Storecove/StorecoveRouter.php new file mode 100644 index 000000000000..5030410fdf66 --- /dev/null +++ b/app/Services/EDocument/Gateway/Storecove/StorecoveRouter.php @@ -0,0 +1,165 @@ + [ + ["B","DUNS, GLN, LEI","US:EIN","DUNS, GLN, LEI"], + // ["B","DUNS, GLN, LEI","US:SSN","DUNS, GLN, LEI"], + ], + "CA" => ["B","CA:CBN",false,"CA:CBN"], + "MX" => ["B","MX:RFC",false,"MX:RFC"], + "AU" => ["B+G","AU:ABN",false,"AU:ABN"], + "NZ" => ["B+G","GLN","NZ:GST","GLN"], + "CH" => ["B+G","CH:UIDB","CH:VAT","CH:UIDB"], + "IS" => ["B+G","IS:KTNR","IS:VAT","IS:KTNR"], + "LI" => ["B+G","","LI:VAT","LI:VAT"], + "NO" => ["B+G","NO:ORG","NO:VAT","NO:ORG"], + "AD" => ["B+G","","AD:VAT","AD:VAT"], + "AL" => ["B+G","","AL:VAT","AL:VAT"], + "AT" => [ + ["G","AT:GOV",false,"9915:b"], + ["B","","AT:VAT","AT:VAT"], + ], + "BA" => ["B+G","","BA:VAT","BA:VAT"], + "BE" => ["B+G","BE:EN","BE:VAT","BE:EN"], + "BG" => ["B+G","","BG:VAT","BG:VAT"], + "CY" => ["B+G","","CY:VAT","CY:VAT"], + "CZ" => ["B+G","","CZ:VAT","CZ:VAT"], + "DE" => [ + ["G","DE:LWID",false,"DE:LWID"], + ["B","","DE:VAT","DE:VAT"], + ], + "DK" => ["B+G","DK:DIGST","DK:ERST","DK:DIGST"], + "EE" => ["B+G","EE:CC","EE:VAT","EE:CC"], + "ES" => ["B","","ES:VAT","ES:VAT"], + "FI" => ["B+G","FI:OVT","FI:VAT","FI:OVT"], + "FR" => [ + ["G","FR:SIRET + customerAssignedAccountIdValue",false,"0009:11000201100044"], + ["B","FR:SIRENE or FR:SIRET","FR:VAT","FR:SIRENE or FR:SIRET"], + ], + "GR" => ["B+G","","GR:VAT","GR:VAT"], + "HR" => ["B+G","","HR:VAT","HR:VAT"], + "HU" => ["B+G","","HU:VAT","HU:VAT"], + "IE" => ["B+G","","IE:VAT","IE:VAT"], + "IT" => [ + ["G","","IT:IVA","IT:CUUO"], // (Peppol) + ["B","","IT:IVA","IT:CUUO"], // (SDI) + // ["B","","IT:CF","IT:CUUO"], // (SDI) + ["C","","IT:CF","Email"],// (SDI) + ["G","","IT:IVA","IT:CUUO"],// (SDI) + ], + "LT" => ["B+G","LT:LEC","LT:VAT","LT:LEC"], + "LU" => ["B+G","LU:MAT","LU:VAT","LU:VAT"], + "LV" => ["B+G","","LV:VAT","LV:VAT"], + "MC" => ["B+G","","MC:VAT","MC:VAT"], + "ME" => ["B+G","","ME:VAT","ME:VAT"], + "MK" => ["B+G","","MK:VAT","MK:VAT"], + "MT" => ["B+G","","MT:VAT","MT:VAT"], + "NL" => ["G","NL:OINO",false,"NL:OINO"], + "NL" => ["B","NL:KVK","NL:VAT","NL:KVK or NL:VAT"], + "PL" => ["G+B","","PL:VAT","PL:VAT"], + "PT" => ["G+B","","PT:VAT","PT:VAT"], + "RO" => ["G+B","","RO:VAT","RO:VAT"], + "RS" => ["G+B","","RS:VAT","RS:VAT"], + "SE" => ["G+B","SE:ORGNR","SE:VAT","SE:ORGNR"], + "SI" => ["G+B","","SI:VAT","SI:VAT"], + "SK" => ["G+B","","SK:VAT","SK:VAT"], + "SM" => ["G+B","","SM:VAT","SM:VAT"], + "TR" => ["G+B","","TR:VAT","TR:VAT"], + "VA" => ["G+B","","VA:VAT","VA:VAT"], + "IN" => ["B","","IN:GSTIN","Email"], + "JP" => ["B","JP:SST","JP:IIN","JP:SST"], + "MY" => ["B","MY:EIF","MY:TIN","MY:EIF"], + "SG" => [ + ["G","SG:UEN",false,"0195:SGUENT08GA0028A"], + ["B","SG:UEN","SG:GST","SG:UEN"], + ], + "GB" => ["B","","GB:VAT","GB:VAT"], + "SA" => ["B","","SA:TIN","Email"], + "Other" => ["B","DUNS, GLN, LEI",false,"DUNS, GLN, LEI"], + ]; + + public function __construct() + { + } + + /** + * Return the routing code based on country and entity classification + * + * @param string $country + * @param ?string $classification + * @return string + */ + public function resolveRouting(string $country, ?string $classification = 'business'): string + { + $rules = $this->routing_rules[$country]; + + if(is_array($rules) && !is_array($rules[0])) { + return $rules[3]; + } + + $code = 'B'; + + match($classification) { + "business" => $code = "B", + "government" => $code = "G", + "individual" => $code = "C", + default => $code = "B", + }; + + foreach($rules as $rule) { + if(stripos($rule[0], $code) !== false) { + return $rule[3]; + } + } + + return $rules[0][3]; + } + + /** + * resolveTaxScheme + * + * @param string $country + * @param ?string $classification + * @return string + */ + public function resolveTaxScheme(string $country, ?string $classification = "business"): string + { + + $rules = isset($this->routing_rules[$country]) ? $this->routing_rules[$country] : [false, false, false, false]; + + $code = "B"; + + match($classification) { + "business" => $code = "B", + "government" => $code = "G", + "individual" => $code = "C", + default => $code = "B", + }; + + //single array + if(is_array($rules) && !is_array($rules[0])) { + return $rules[2]; + } + + foreach($rules as $rule) { + if(stripos($rule[0], $code) !== false) { + return $rule[2]; + } + } + + return $rules[0][2]; + } +} \ No newline at end of file diff --git a/app/Services/EDocument/Jobs/SendEDocument.php b/app/Services/EDocument/Jobs/SendEDocument.php new file mode 100644 index 000000000000..a1d6e1d429b2 --- /dev/null +++ b/app/Services/EDocument/Jobs/SendEDocument.php @@ -0,0 +1,161 @@ +db); + + $model = $this->entity::find($this->id); + $e_invoice_standard = $model->client ? $model->client->getSetting('e_invoice_type') : $model->company->getSetting('e_invoice_type'); + + if($e_invoice_standard != 'PEPPOL') + return; + + if(Ninja::isSelfHost() && ($model instanceof Invoice) && $model->company->legal_entity_id) + { + + $p = new Peppol($model); + + $p->run(); + $xml = $p->toXml(); + $identifiers = $p->getStorecoveMeta(); + + $payload = [ + 'legal_entity_id' => $model->company->legal_entity_id, + 'document' => base64_encode($xml), + 'tenant_id' => $model->company->company_key, + 'identifiers' => $identifiers, + ]; + + $r = Http::withHeaders($this->getHeaders()) + ->post(config('ninja.hosted_ninja_url')."/api/einvoice/submission", $payload); + + if($r->successful()) { + nlog("Model {$model->number} was successfully sent for third party processing via hosted Invoice Ninja"); + + $data = $r->json(); + return $this->writeActivity($model, $data['guid']); + + } + + if($r->failed()) { + nlog("Model {$model->number} failed to be accepted by invoice ninja, error follows:"); + nlog($r->getBody()->getContents()); + } + + //self hosted sender + } + + if(Ninja::isHosted() && ($model instanceof Invoice) && $model->company->legal_entity_id) + { + //hosted sender + $p = new Peppol($model); + + $p->run(); + $xml = $p->toXml(); + $identifiers = $p->getStorecoveMeta(); + + $sc = new \App\Services\EDocument\Gateway\Storecove\Storecove(); + $r = $sc->sendDocument($xml, $model->company->legal_entity_id, $identifiers); + + if(is_string($r)) + return $this->writeActivity($model, $r); + + if($r->failed()) { + nlog("Model {$model->number} failed to be accepted by invoice ninja, error follows:"); + nlog($r->getBody()->getContents()); + } + + } + + } + + private function writeActivity($model, string $guid) + { + $activity = new Activity(); + $activity->user_id = $model->user_id; + $activity->client_id = $model->client_id ?? $model->vendor_id; + $activity->company_id = $model->company_id; + $activity->activity_type_id = Activity::EMAIL_EINVOICE_SUCCESS; + $activity->invoice_id = $model->id; + $activity->notes = $guid; + $activity->save(); + + $model->backup = $guid; + $model->saveQuietly(); + + } + + /** + * Self hosted request headers + * + * @return array + */ + private function getHeaders(): array + { + return [ + 'X-API-SELF-HOST-TOKEN' => config('ninja.license_key'), + "X-Requested-With" => "XMLHttpRequest", + "Content-Type" => "application/json", + ]; + } + + public function failed($exception = null) + { + if ($exception) { + nlog("EXCEPTION:: SENDEDOCUMENT::"); + nlog($exception->getMessage()); + } + + config(['queue.failed.driver' => null]); + } + + public function middleware() + { + return [new WithoutOverlapping($this->entity.$this->id.$this->db)]; + } +} diff --git a/app/Services/EDocument/Standards/Peppol.php b/app/Services/EDocument/Standards/Peppol.php index f2d3722b1660..11adde48f8b7 100644 --- a/app/Services/EDocument/Standards/Peppol.php +++ b/app/Services/EDocument/Standards/Peppol.php @@ -29,6 +29,7 @@ use InvoiceNinja\EInvoice\Models\Peppol\AddressType\Address; use InvoiceNinja\EInvoice\Models\Peppol\ContactType\Contact; use InvoiceNinja\EInvoice\Models\Peppol\CountryType\Country; use InvoiceNinja\EInvoice\Models\Peppol\PartyIdentification; +use App\Services\EDocument\Gateway\Storecove\StorecoveRouter; use InvoiceNinja\EInvoice\Models\Peppol\AmountType\TaxAmount; use InvoiceNinja\EInvoice\Models\Peppol\Party as PeppolParty; use InvoiceNinja\EInvoice\Models\Peppol\TaxTotalType\TaxTotal; @@ -42,18 +43,17 @@ use InvoiceNinja\EInvoice\Models\Peppol\TaxTotal as PeppolTaxTotal; use InvoiceNinja\EInvoice\Models\Peppol\InvoiceLineType\InvoiceLine; use InvoiceNinja\EInvoice\Models\Peppol\TaxCategoryType\TaxCategory; use InvoiceNinja\EInvoice\Models\Peppol\TaxSubtotalType\TaxSubtotal; -use InvoiceNinja\EInvoice\Models\Peppol\TaxScheme as PeppolTaxScheme; use InvoiceNinja\EInvoice\Models\Peppol\AmountType\TaxExclusiveAmount; use InvoiceNinja\EInvoice\Models\Peppol\AmountType\TaxInclusiveAmount; +use InvoiceNinja\EInvoice\Models\Peppol\LocationType\PhysicalLocation; use InvoiceNinja\EInvoice\Models\Peppol\AmountType\LineExtensionAmount; use InvoiceNinja\EInvoice\Models\Peppol\OrderReferenceType\OrderReference; use InvoiceNinja\EInvoice\Models\Peppol\MonetaryTotalType\LegalMonetaryTotal; use InvoiceNinja\EInvoice\Models\Peppol\TaxCategoryType\ClassifiedTaxCategory; +use InvoiceNinja\EInvoice\Models\Peppol\IdentifierType\CustomerAssignedAccountID; use InvoiceNinja\EInvoice\Models\Peppol\CustomerPartyType\AccountingCustomerParty; use InvoiceNinja\EInvoice\Models\Peppol\SupplierPartyType\AccountingSupplierParty; use InvoiceNinja\EInvoice\Models\Peppol\FinancialAccountType\PayeeFinancialAccount; -use InvoiceNinja\EInvoice\Models\Peppol\IdentifierType\CustomerAssignedAccountID; -use InvoiceNinja\EInvoice\Models\Peppol\LocationType\PhysicalLocation; class Peppol extends AbstractService { @@ -261,6 +261,38 @@ class Peppol extends AbstractService $this->e = new EInvoice(); $this->setSettings()->setInvoice(); } + + /** + * Entry point for building document + * + * @return self + */ + public function run(): self + { + $this->p_invoice->ID = $this->invoice->number; + $this->p_invoice->IssueDate = new \DateTime($this->invoice->date); + + if($this->invoice->due_date) { + $this->p_invoice->DueDate = new \DateTime($this->invoice->due_date); + } + + $this->p_invoice->InvoiceTypeCode = 380; // + $this->p_invoice->AccountingSupplierParty = $this->getAccountingSupplierParty(); + $this->p_invoice->AccountingCustomerParty = $this->getAccountingCustomerParty(); + $this->p_invoice->InvoiceLine = $this->getInvoiceLines(); + + // $this->p_invoice->TaxTotal = $this->getTotalTaxes(); it only wants the aggregate here!! + $this->p_invoice->LegalMonetaryTotal = $this->getLegalMonetaryTotal(); + + $this->senderSpecificLevelMutators() + ->receiverSpecificLevelMutators(); + + $this->invoice->e_invoice = $this->toObject(); + $this->invoice->save(); + + return $this; + + } /** * Rehydrates an existing e invoice - or - scaffolds a new one @@ -272,7 +304,7 @@ class Peppol extends AbstractService if($this->invoice->e_invoice) { - $this->p_invoice = $this->e->decode('Peppol', json_encode($this->invoice->e_invoice->Invoice), 'json'); + $this->p_invoice = $this->e->decode('Peppol', json_encode($this->invoice->e_invoice), 'json'); return $this; @@ -299,14 +331,24 @@ class Peppol extends AbstractService return $this; } - + + /** + * getInvoice + * + * @return InvoiceNinja\EInvoice\Models\Peppol\Invoice + */ public function getInvoice(): \InvoiceNinja\EInvoice\Models\Peppol\Invoice { //@todo - need to process this and remove null values return $this->p_invoice; } - + + /** + * toXml + * + * @return string + */ public function toXml(): string { $e = new EInvoice(); @@ -321,7 +363,12 @@ class Peppol extends AbstractService return str_ireplace(['\n',''], ['', $prefix], $xml); } - + + /** + * toJson + * + * @return string + */ public function toJson(): string { $e = new EInvoice(); @@ -330,36 +377,32 @@ class Peppol extends AbstractService return $json; } - + + /** + * toObject + * + * @return mixed + */ + public function toObject(): mixed + { + return json_decode($this->toJson()); + } + + /** + * toArray + * + * @return array + */ public function toArray(): array { return json_decode($this->toJson(), true); } - - public function run() - { - $this->p_invoice->ID = $this->invoice->number; - $this->p_invoice->IssueDate = new \DateTime($this->invoice->date); - - if($this->invoice->due_date) { - $this->p_invoice->DueDate = new \DateTime($this->invoice->due_date); - } - - $this->p_invoice->InvoiceTypeCode = 380; // - $this->p_invoice->AccountingSupplierParty = $this->getAccountingSupplierParty(); - $this->p_invoice->AccountingCustomerParty = $this->getAccountingCustomerParty(); - $this->p_invoice->InvoiceLine = $this->getInvoiceLines(); - - // $this->p_invoice->TaxTotal = $this->getTotalTaxes(); it only wants the aggregate here!! - $this->p_invoice->LegalMonetaryTotal = $this->getLegalMonetaryTotal(); - - $this->senderSpecificLevelMutators() - ->receiverSpecificLevelMutators(); - - return $this; - - } - + + /** + * getLegalMonetaryTotal + * + * @return LegalMonetaryTotal + */ private function getLegalMonetaryTotal(): LegalMonetaryTotal { $taxable = $this->getTaxable(); @@ -388,7 +431,12 @@ class Peppol extends AbstractService return $lmt; } - + + /** + * getTotalTaxAmount + * + * @return float + */ private function getTotalTaxAmount(): float { if(!$this->invoice->total_taxes) { @@ -399,7 +447,12 @@ class Peppol extends AbstractService return $this->calcAmountLineTax($this->invoice->tax_rate1, $this->invoice->amount) ?? 0; } - + + /** + * getTotalTaxes + * + * @return array + */ private function getTotalTaxes(): array { $taxes = []; @@ -421,10 +474,14 @@ class Peppol extends AbstractService $tax_subtotal->TaxableAmount = $taxable_amount; $tc = new TaxCategory(); - $tc->ID = $type_id == '2' ? 'HUR' : 'C62'; + $id = new ID(); + $id->value = $type_id == '2' ? 'HUR' : 'C62'; + $tc->ID = $id; $tc->Percent = $this->invoice->tax_rate1; - $ts = new PeppolTaxScheme(); - $ts->ID = strlen($this->invoice->tax_name1 ?? '') > 1 ? $this->invoice->tax_name1 : '0'; + $ts = new TaxScheme(); + $id = new ID(); + $id->value = strlen($this->invoice->tax_name1 ?? '') > 1 ? $this->invoice->tax_name1 : '0'; + $ts->ID = $id; $tc->TaxScheme = $ts; $tax_subtotal->TaxCategory = $tc; @@ -453,10 +510,14 @@ class Peppol extends AbstractService $tc = new TaxCategory(); - $tc->ID = $type_id == '2' ? 'HUR' : 'C62'; + $id = new ID(); + $id->value = $type_id == '2' ? 'HUR' : 'C62'; + $tc->ID = $id; $tc->Percent = $this->invoice->tax_rate2; - $ts = new PeppolTaxScheme(); - $ts->ID = $this->invoice->tax_name2; + $ts = new TaxScheme(); + $id = new ID(); + $id->value = $this->invoice->tax_name2; + $ts->ID = $id; $tc->TaxScheme = $ts; $tax_subtotal->TaxCategory = $tc; @@ -483,16 +544,21 @@ class Peppol extends AbstractService $taxable_amount->amount = $this->invoice->uses_inclusive_taxes ? $this->invoice->amount - $this->invoice->total_taxes : $this->invoice->amount; $tax_subtotal->TaxableAmount = $taxable_amount; - $tc = new TaxCategory(); - $tc->ID = $type_id == '2' ? 'HUR' : 'C62'; + + $id = new ID(); + $id->value = $type_id == '2' ? 'HUR' : 'C62'; + $tc->ID = $id; $tc->Percent = $this->invoice->tax_rate3; - $ts = new PeppolTaxScheme(); - $ts->ID = $this->invoice->tax_name3; + $ts = new TaxScheme(); + + $id = new ID(); + $id->value = $this->invoice->tax_name3; + + $ts->ID = $id; $tc->TaxScheme = $ts; $tax_subtotal->TaxCategory = $tc; - $tax_total = new TaxTotal(); $tax_total->TaxAmount = $tax_amount; $tax_total->TaxSubtotal[] = $tax_subtotal; @@ -501,7 +567,6 @@ class Peppol extends AbstractService } - return $taxes; } @@ -516,7 +581,10 @@ class Peppol extends AbstractService $_item->Description = $item->notes; $line = new InvoiceLine(); - $line->ID = $key + 1; + + $id = new ID(); + $id->value = (string) ($key+1); + $line->ID = $id; $line->InvoicedQuantity = $item->quantity; $lea = new LineExtensionAmount(); @@ -538,7 +606,7 @@ class Peppol extends AbstractService $price = new Price(); $pa = new PriceAmount(); $pa->currencyID = $this->invoice->client->currency()->code; - $pa->amount = $this->costWithDiscount($item) - ($this->invoice->uses_inclusive_taxes ? ($this->calcInclusiveLineTax($item->tax_rate1, $item->line_total) / $item->quantity) : 0); + $pa->amount = (string) ($this->costWithDiscount($item) - ($this->invoice->uses_inclusive_taxes ? ($this->calcInclusiveLineTax($item->tax_rate1, $item->line_total) / $item->quantity) : 0)); $price->PriceAmount = $pa; $line->Price = $price; @@ -548,8 +616,14 @@ class Peppol extends AbstractService return $lines; } - - private function costWithDiscount($item) + + /** + * costWithDiscount + * + * @param mixed $item + * @return float + */ + private function costWithDiscount($item): float { $cost = $item->cost; @@ -563,7 +637,12 @@ class Peppol extends AbstractService return $cost; } - + + /** + * zeroTaxAmount + * + * @return array + */ private function zeroTaxAmount(): array { $blank_tax = []; @@ -579,10 +658,15 @@ class Peppol extends AbstractService $taxable_amount->amount = '0'; $tax_subtotal->TaxableAmount = $taxable_amount; $tc = new TaxCategory(); - $tc->ID = 'Z'; - $tc->Percent = 0; - $ts = new PeppolTaxScheme(); - $ts->ID = '0'; + $id = new ID(); + $id->value = 'Z'; + $tc->ID = $id; + $tc->Percent = '0'; + $ts = new TaxScheme(); + + $id = new ID(); + $id->value = '0'; + $ts->ID = $id; $tc->TaxScheme = $ts; $tax_subtotal->TaxCategory = $tc; @@ -594,7 +678,13 @@ class Peppol extends AbstractService return $blank_tax; } - + + /** + * getItemTaxes + * + * @param object $item + * @return array + */ private function getItemTaxes(object $item): array { $item_taxes = []; @@ -612,10 +702,18 @@ class Peppol extends AbstractService $taxable_amount->amount = $this->invoice->uses_inclusive_taxes ? $item->line_total - $tax_amount->amount : $item->line_total; $tax_subtotal->TaxableAmount = $taxable_amount; $tc = new TaxCategory(); - $tc->ID = $item->type_id == '2' ? 'HUR' : 'C62'; + + $id = new ID(); + $id->value = $item->type_id == '2' ? 'HUR' : 'C62'; + + $tc->ID = $id; $tc->Percent = $item->tax_rate1; - $ts = new PeppolTaxScheme(); - $ts->ID = $item->tax_name1; + $ts = new TaxScheme(); + + $id = new ID(); + $id->value = $item->tax_name1; + + $ts->ID = $id; $tc->TaxScheme = $ts; $tax_subtotal->TaxCategory = $tc; @@ -645,10 +743,18 @@ class Peppol extends AbstractService $tc = new TaxCategory(); - $tc->ID = $item->type_id == '2' ? 'HUR' : 'C62'; + + $id = new ID(); + $id->value = $item->type_id == '2' ? 'HUR' : 'C62'; + + $tc->ID = $id; $tc->Percent = $item->tax_rate2; - $ts = new PeppolTaxScheme(); - $ts->ID = $item->tax_name2; + $ts = new TaxScheme(); + + $id = new ID(); + $id->value = $item->tax_name2; + + $ts->ID = $id; $tc->TaxScheme = $ts; $tax_subtotal->TaxCategory = $tc; @@ -658,7 +764,6 @@ class Peppol extends AbstractService $tax_total->TaxSubtotal[] = $tax_subtotal; $item_taxes[] = $tax_total; - } @@ -679,10 +784,18 @@ class Peppol extends AbstractService $tc = new TaxCategory(); - $tc->ID = $item->type_id == '2' ? 'HUR' : 'C62'; + + $id = new ID(); + $id->value = $item->type_id == '2' ? 'HUR' : 'C62'; + + $tc->ID = $id; $tc->Percent = $item->tax_rate3; - $ts = new PeppolTaxScheme(); - $ts->ID = $item->tax_name3; + $ts = new TaxScheme(); + + $id = new ID(); + $id->value = $item->tax_name3; + + $ts->ID = $id; $tc->TaxScheme = $ts; $tax_subtotal->TaxCategory = $tc; @@ -696,7 +809,12 @@ class Peppol extends AbstractService return $item_taxes; } - + + /** + * getAccountingSupplierParty + * + * @return AccountingSupplierParty + */ private function getAccountingSupplierParty(): AccountingSupplierParty { @@ -733,34 +851,46 @@ class Peppol extends AbstractService return $asp; } - - private function resolveTaxScheme(): mixed + + /** + * resolveTaxScheme + * + * @return string + */ + private function resolveTaxScheme(): string { - $rules = isset($this->routing_rules[$this->invoice->client->country->iso_3166_2]) ? $this->routing_rules[$this->invoice->client->country->iso_3166_2] : [false, false, false, false,]; + return (new StorecoveRouter())->resolveTaxScheme($this->invoice->client->country->iso_3166_2, $this->invoice->client->classification); - $code = false; + // $rules = isset($this->routing_rules[$this->invoice->client->country->iso_3166_2]) ? $this->routing_rules[$this->invoice->client->country->iso_3166_2] : [false, false, false, false,]; - match($this->invoice->client->classification) { - "business" => $code = "B", - "government" => $code = "G", - "individual" => $code = "C", - default => $code = false, - }; + // $code = false; - //single array - if(is_array($rules) && !is_array($rules[0])) { - return $rules[2]; - } + // match($this->invoice->client->classification) { + // "business" => $code = "B", + // "government" => $code = "G", + // "individual" => $code = "C", + // default => $code = false, + // }; - foreach($rules as $rule) { - if(stripos($rule[0], $code) !== false) { - return $rule[2]; - } - } + // //single array + // if(is_array($rules) && !is_array($rules[0])) { + // return $rules[2]; + // } - return false; + // foreach($rules as $rule) { + // if(stripos($rule[0], $code) !== false) { + // return $rule[2]; + // } + // } + + // return false; } - + + /** + * getAccountingCustomerParty + * + * @return AccountingCustomerParty + */ private function getAccountingCustomerParty(): AccountingCustomerParty { @@ -819,7 +949,12 @@ class Peppol extends AbstractService return $acp; } - + + /** + * getTaxable + * + * @return float + */ private function getTaxable(): float { $total = 0; @@ -867,25 +1002,32 @@ class Peppol extends AbstractService } ///////////////// Helper Methods ///////////////////////// - + + /** + * getClientRoutingCode + * + * @return string + */ private function getClientRoutingCode(): string { - $receiver_identifiers = $this->routing_rules[$this->invoice->client->country->iso_3166_2]; - $client_classification = $this->invoice->client->classification == 'government' ? 'G' : 'B'; + // $receiver_identifiers = $this->routing_rules[$this->invoice->client->country->iso_3166_2]; + // $client_classification = $this->invoice->client->classification == 'government' ? 'G' : 'B'; - if(count($receiver_identifiers) > 1) { + // if(count($receiver_identifiers) > 1) { - foreach($receiver_identifiers as $ident) { - if(str_contains($ident[0], $client_classification)) { - return $ident[3]; - } - } + // foreach($receiver_identifiers as $ident) { + // if(str_contains($ident[0], $client_classification)) { + // return $ident[3]; + // } + // } - } elseif(count($receiver_identifiers) == 1) { - return $receiver_identifiers[3]; - } + // } elseif(count($receiver_identifiers) == 1) { + // return $receiver_identifiers[3]; + // } + + return (new StorecoveRouter())->resolveRouting($this->invoice->client->country->iso_3166_2, $this->invoice->client->classification); - throw new \Exception("e-invoice generation halted:: Could not resolve the Tax Code for this client? {$this->invoice->client->hashed_id}"); + // throw new \Exception("e-invoice generation halted:: Could not resolve the Tax Code for this client? {$this->invoice->client->hashed_id}"); } @@ -946,16 +1088,29 @@ class Peppol extends AbstractService return null; } - + + /** + * getClientSetting + * + * @param string $property_path + * @return mixed + */ private function getClientSetting(string $property_path): mixed { return PropertyResolver::resolve($this->_client_settings, $property_path); } - + + /** + * getCompanySetting + * + * @param string $property_path + * @return mixed + */ private function getCompanySetting(string $property_path): mixed { return PropertyResolver::resolve($this->_company_settings, $property_path); } + /** * senderSpecificLevelMutators * @@ -1111,7 +1266,6 @@ class Peppol extends AbstractService */ private function buildRouting(array $identifiers): array { - return [ "routing" => [ @@ -1121,7 +1275,13 @@ class Peppol extends AbstractService ] ]; } - + + /** + * setEmailRouting + * + * @param string $email + * @return self + */ private function setEmailRouting(string $email): self { nlog($email); @@ -1156,7 +1316,12 @@ class Peppol extends AbstractService return $this; } - + + /** + * getStorecoveMeta + * + * @return array + */ public function getStorecoveMeta(): array { return $this->storecove_meta; @@ -1165,9 +1330,6 @@ class Peppol extends AbstractService - - - ////////////////////////// Country level mutators ///////////////////////////////////// /** @@ -1281,7 +1443,12 @@ class Peppol extends AbstractService return $this; } - + + /** + * FI + * + * @return self + */ private function FI(): self { @@ -1344,7 +1511,12 @@ class Peppol extends AbstractService return $this; } - + + /** + * IT + * + * @return self + */ private function IT(): self { @@ -1390,7 +1562,12 @@ class Peppol extends AbstractService return $this; } - + + /** + * client_IT + * + * @return self + */ private function client_IT(): self { @@ -1407,13 +1584,23 @@ class Peppol extends AbstractService return $this; } - + + /** + * MY + * + * @return self + */ private function MY(): self { //way too much to digest here, delayed. return $this; } - + + /** + * NL + * + * @return self + */ private function NL(): self { @@ -1423,13 +1610,23 @@ class Peppol extends AbstractService return $this; } - + + /** + * NZ + * + * @return self + */ private function NZ(): self { // New Zealand uses a GLN to identify businesses. In addition, when sending invoices to a New Zealand customer, make sure you include the pseudo identifier NZ:GST as their tax identifier. return $this; } - + + /** + * PL + * + * @return self + */ private function PL(): self { @@ -1455,7 +1652,12 @@ class Peppol extends AbstractService return $this; } - + + /** + * RO + * + * @return self + */ private function RO(): self { // Because using this network is not yet mandatory, the default workflow is to not use this network. Therefore, you have to force its use, as follows: @@ -1489,7 +1691,12 @@ class Peppol extends AbstractService return $this; } - + + /** + * SG + * + * @return self + */ private function SG(): self { //delayed - stage 2 diff --git a/app/Services/Email/Email.php b/app/Services/Email/Email.php index c3e0909824cc..2e21bb8b4af7 100644 --- a/app/Services/Email/Email.php +++ b/app/Services/Email/Email.php @@ -646,7 +646,7 @@ class Email implements ShouldQueue $user = $this->resolveSendingUser(); - $sending_email = (isset($this->email_object->settings->custom_sending_email) && stripos($this->email_object->settings->custom_sending_email, "@")) ? $this->email_object->settings->custom_sending_email : $user->email; + $sending_email = (isset($this->email_object->settings->custom_sending_email) && (stripos($this->email_object->settings->custom_sending_email, "@")) !== false) ? $this->email_object->settings->custom_sending_email : $user->email; $sending_user = (isset($this->email_object->settings->email_from_name) && strlen($this->email_object->settings->email_from_name) > 2) ? $this->email_object->settings->email_from_name : $user->name(); $this->mailable diff --git a/app/Services/Invoice/AutoBillInvoice.php b/app/Services/Invoice/AutoBillInvoice.php index 15e4ef6454d1..cfb686dac5bd 100644 --- a/app/Services/Invoice/AutoBillInvoice.php +++ b/app/Services/Invoice/AutoBillInvoice.php @@ -23,6 +23,8 @@ use App\Models\PaymentHash; use App\Models\PaymentType; use Illuminate\Support\Str; use App\DataMapper\InvoiceItem; +use App\Events\Invoice\InvoiceAutoBillFailed; +use App\Events\Invoice\InvoiceAutoBillSuccess; use App\Factory\PaymentFactory; use App\Services\AbstractService; use App\Models\ClientGatewayToken; @@ -157,6 +159,8 @@ class AutoBillInvoice extends AbstractService } catch (\Exception $e) { nlog('payment NOT captured for '.$this->invoice->number.' with error '.$e->getMessage()); + event(new InvoiceAutoBillFailed($this->invoice, $this->invoice->company, Ninja::eventVars(), $e->getMessage())); + } $this->invoice->auto_bill_tries += 1; @@ -170,6 +174,7 @@ class AutoBillInvoice extends AbstractService if ($payment) { info('Auto Bill payment captured for '.$this->invoice->number); + event(new InvoiceAutoBillSuccess($this->invoice, $this->invoice->company, Ninja::eventVars())); } } diff --git a/app/Services/Quickbooks/Jobs/QuickbooksSync.php b/app/Services/Quickbooks/Jobs/QuickbooksSync.php index 9a7d0dbac7a5..86057a06bd22 100644 --- a/app/Services/Quickbooks/Jobs/QuickbooksSync.php +++ b/app/Services/Quickbooks/Jobs/QuickbooksSync.php @@ -66,7 +66,7 @@ class QuickbooksSync implements ShouldQueue { MultiDB::setDb($this->db); - $this->company = Company::find($this->company_id); + $this->company = Company::query()->find($this->company_id); $this->qbs = new QuickbooksService($this->company); $this->settings = $this->company->quickbooks->settings; diff --git a/app/Services/Quickbooks/QuickbooksService.php b/app/Services/Quickbooks/QuickbooksService.php index d61e1065bbe6..38d5bceae909 100644 --- a/app/Services/Quickbooks/QuickbooksService.php +++ b/app/Services/Quickbooks/QuickbooksService.php @@ -88,7 +88,7 @@ class QuickbooksService */ public function syncFromQb() { - QuickbooksSync::dispatch($this->company); + QuickbooksSync::dispatch($this->company->id, $this->company->db); } } diff --git a/app/Services/Quickbooks/SdkWrapper.php b/app/Services/Quickbooks/SdkWrapper.php index eda0006b333f..946353abdf0d 100644 --- a/app/Services/Quickbooks/SdkWrapper.php +++ b/app/Services/Quickbooks/SdkWrapper.php @@ -97,8 +97,8 @@ class SdkWrapper 8726400 ); - $token->setAccessTokenExpiresAt($token_object->accessTokenExpiresAt); - $token->setRefreshTokenExpiresAt($token_object->refreshTokenExpiresAt); + $token->setAccessTokenExpiresAt($token_object->accessTokenExpiresAt); //@phpstan-ignore-line + $token->setRefreshTokenExpiresAt($token_object->refreshTokenExpiresAt); //@phpstan-ignore-line $token->setAccessTokenValidationPeriodInSeconds(3600); $token->setRefreshTokenValidationPeriodInSeconds(8726400); diff --git a/app/Services/Report/ClientBalanceReport.php b/app/Services/Report/ClientBalanceReport.php index a4a6b9f7eb1b..bf9cbf5c9d15 100644 --- a/app/Services/Report/ClientBalanceReport.php +++ b/app/Services/Report/ClientBalanceReport.php @@ -39,6 +39,7 @@ class ClientBalanceReport extends BaseExport 'invoices', 'invoice_balance', 'credit_balance', + 'payment_balance', ]; /** @@ -119,6 +120,7 @@ class ClientBalanceReport extends BaseExport $query->count(), $query->sum('balance'), $client->credit_balance, + $client->payment_balance, ]; } } diff --git a/app/Services/Template/TemplateMock.php b/app/Services/Template/TemplateMock.php index 7a1ac6592f65..f5e56ab9097c 100644 --- a/app/Services/Template/TemplateMock.php +++ b/app/Services/Template/TemplateMock.php @@ -22,7 +22,7 @@ class TemplateMock public array $variables = []; - public string $credit_data = '[{"id":"mWZdPwbKgR","user_id":"wMvbmOeYAl","project_id":"","assigned_user_id":"","vendor_id":"","amount":881.03,"balance":548.03,"client_id":"QJ0dN6dLOv","status_id":"3","design_id":"Wpmbk5ezJn","created_at":1695796650,"updated_at":1695799160,"archived_at":0,"is_deleted":false,"number":"0001","discount":2,"po_number":"Quisquam.","date":"2023-06-30","last_sent_date":"","next_send_date":"","reminder1_sent":"","reminder2_sent":"","reminder3_sent":"","reminder_last_sent":"","due_date":"2007-03-30","terms":"Voluptatem et aliquid enim dolorem rerum voluptatem. Doloremque magni nesciunt unde nobis omnis quas. Aut totam adipisci voluptatum explicabo qui fugit assumenda. Soluta architecto sit exercitationem amet doloribus ad vel qui. Eos porro qui voluptatum sint. Consequatur voluptatem eveniet vitae illo ea. Rem enim sit impedit odit.","public_notes":"","private_notes":"","uses_inclusive_taxes":false,"tax_name1":"GST","tax_rate1":10,"tax_name2":"VAT","tax_rate2":17.5,"tax_name3":"","tax_rate3":0,"total_taxes":190.03,"is_amount_discount":true,"footer":"","partial":0,"partial_due_date":"","custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","has_tasks":false,"has_expenses":false,"custom_surcharge1":0,"custom_surcharge2":0,"custom_surcharge3":0,"custom_surcharge4":0,"custom_surcharge_tax1":false,"custom_surcharge_tax2":false,"custom_surcharge_tax3":false,"custom_surcharge_tax4":false,"line_items":[{"quantity":1,"cost":693,"product_key":"Sed.","notes":"Est sequi.","discount":0,"is_amount_discount":true,"tax_name1":"","tax_rate1":0,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":693,"gross_line_total":693,"custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"56","custom_value3":"Dolores porro quia.","custom_value4":"Perferendis itaque.","type_id":"1","product_cost":0,"tax_amount":0,"date":"","tax_id":"","task_id":"","expense_id":""}],"entity_type":"credit","exchange_rate":1,"paid_to_date":333,"subscription_id":"","client":{"id":"QJ0dN6dLOv","user_id":"wMvbmOeYAl","assigned_user_id":"","name":"Paucek and Sons","website":"http:\/\/www.wiegand.com\/sit-repellendus-enim-porro-aut-voluptas-voluptates.html","private_notes":"In nihil non voluptas voluptatibus molestiae et. Nihil labore eligendi omnis id. Et cumque reiciendis blanditiis fugiat.","balance":19958.86,"group_settings_id":"","paid_to_date":18895.75,"payment_balance":0,"credit_balance":573.53,"last_login":0,"size_id":"","public_notes":"","client_hash":"ngQe8O6SInYp1D0SKacHE8f6nzr3Gc1UkkoyGMKI","address1":"873","address2":"220 Hand Glen","phone":"","city":"Lake Kallie","state":"Ohio","postal_code":"77890","country_id":"535","industry_id":"","custom_value1":"1974-10-02 21:56:55","custom_value2":"Aqua","custom_value3":"modi","custom_value4":"xhomenick@hotmail.com","shipping_address1":"89064","shipping_address2":"87854 Meda Junction","shipping_city":"South Aryanna","shipping_state":"Connecticut","shipping_postal_code":"52527-1873","shipping_country_id":"4","settings":{"entity":"App\\Models\\Client","industry_id":"","size_id":"","currency_id":"1"},"is_deleted":false,"vat_number":"881403416","id_number":"MU19IWUA7340242407223765691CMM","updated_at":1695811138,"archived_at":0,"created_at":1695796650,"display_name":"Paucek and Sons","number":"0005","has_valid_vat_number":false,"is_tax_exempt":false,"routing_id":"","tax_info":{},"contacts":[{"id":"yMYerkEaOB","first_name":"Bret","last_name":"Beatty","email":"user@example.com","created_at":1695796650,"updated_at":1695796650,"archived_at":0,"is_primary":true,"is_locked":false,"phone":"1-985-403-1242","custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","contact_key":"juMXBqyvDashDUvoYXsdcbZV2SRrFf0BOUFjsc6G","send_email":true,"last_login":0,"password":"**********","link":"http:\/\/ninja.test:8000\/client\/key_login\/juMXBqyvDashDUvoYXsdcbZV2SRrFf0BOUFjsc6G"},{"id":"gl9av2maG1","first_name":"Sandra","last_name":"Daniel","email":"linnie.aufderhar@example.net","created_at":1695796650,"updated_at":1695796650,"archived_at":0,"is_primary":false,"is_locked":false,"phone":"+17319151379","custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","contact_key":"sm53aNvvsGUmLXFku0RLPUrP0zLj3rzBcTaGMjHd","send_email":true,"last_login":0,"password":"**********","link":"http:\/\/ninja.test:8000\/client\/key_login\/sm53aNvvsGUmLXFku0RLPUrP0zLj3rzBcTaGMjHd"},{"id":"7LDdwpRe1Y","first_name":"Leone","last_name":"Bode","email":"ipollich@example.org","created_at":1695796650,"updated_at":1695796650,"archived_at":0,"is_primary":false,"is_locked":false,"phone":"(424) 789-3412","custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","contact_key":"gDUwiOqRehgCHWbbctW8qgKiLmma3xvsZi10a5Ma","send_email":true,"last_login":0,"password":"**********","link":"http:\/\/ninja.test:8000\/client\/key_login\/gDUwiOqRehgCHWbbctW8qgKiLmma3xvsZi10a5Ma"}],"documents":{"data":[]},"gateway_tokens":{"data":[]}}},{"id":"Oy5eVOMaEP","user_id":"wMvbmOeYAl","project_id":"","assigned_user_id":"","vendor_id":"","amount":25.5,"balance":25.5,"client_id":"QJ0dN6dLOv","status_id":"2","design_id":"Wpmbk5ezJn","created_at":1695811134,"updated_at":1695811138,"archived_at":0,"is_deleted":false,"number":"0009","discount":2,"po_number":"","date":"2023-09-27","last_sent_date":"","next_send_date":"","reminder1_sent":"","reminder2_sent":"","reminder3_sent":"","reminder_last_sent":"","due_date":"","terms":"

Voluptatem et aliquid enim dolorem rerum voluptatem. Doloremque magni nesciunt unde nobis omnis quas. Aut totam adipisci voluptatum explicabo qui fugit assumenda. Soluta architecto sit exercitationem amet doloribus ad vel qui. Eos porro qui voluptatum sint. Consequatur voluptatem eveniet vitae illo ea. Rem enim sit impedit odit.<\/p>","public_notes":"","private_notes":"","uses_inclusive_taxes":false,"tax_name1":"GST","tax_rate1":10,"tax_name2":"VAT","tax_rate2":17.5,"tax_name3":"","tax_rate3":0,"total_taxes":5.5,"is_amount_discount":true,"footer":"","partial":0,"partial_due_date":"","custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","has_tasks":false,"has_expenses":false,"custom_surcharge1":0,"custom_surcharge2":0,"custom_surcharge3":0,"custom_surcharge4":0,"custom_surcharge_tax1":false,"custom_surcharge_tax2":false,"custom_surcharge_tax3":false,"custom_surcharge_tax4":false,"line_items":[{"quantity":1,"cost":22,"product_key":"Sed.","notes":"Est sequi.","discount":0,"is_amount_discount":true,"tax_name1":"","tax_rate1":0,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":"0","line_total":22,"gross_line_total":22,"custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"56","custom_value3":"Dolores porro quia.","custom_value4":"Perferendis itaque.","type_id":"1","product_cost":0,"tax_amount":0,"date":"","tax_id":"1","task_id":"","expense_id":"","_id":"ab67ad52-725e-4106-b80b-1eabe84ca90a"}],"entity_type":"credit","exchange_rate":1,"paid_to_date":0,"subscription_id":"","client":{"id":"QJ0dN6dLOv","user_id":"wMvbmOeYAl","assigned_user_id":"","name":"Paucek and Sons","website":"http:\/\/www.wiegand.com\/sit-repellendus-enim-porro-aut-voluptas-voluptates.html","private_notes":"In nihil non voluptas voluptatibus molestiae et. Nihil labore eligendi omnis id. Et cumque reiciendis blanditiis fugiat.","balance":19958.86,"group_settings_id":"","paid_to_date":18895.75,"payment_balance":0,"credit_balance":573.53,"last_login":0,"size_id":"","public_notes":"","client_hash":"ngQe8O6SInYp1D0SKacHE8f6nzr3Gc1UkkoyGMKI","address1":"873","address2":"220 Hand Glen","phone":"","city":"Lake Kallie","state":"Ohio","postal_code":"77890","country_id":"535","industry_id":"","custom_value1":"1974-10-02 21:56:55","custom_value2":"Aqua","custom_value3":"modi","custom_value4":"xhomenick@hotmail.com","shipping_address1":"89064","shipping_address2":"87854 Meda Junction","shipping_city":"South Aryanna","shipping_state":"Connecticut","shipping_postal_code":"52527-1873","shipping_country_id":"4","settings":{"entity":"App\\Models\\Client","industry_id":"","size_id":"","currency_id":"1"},"is_deleted":false,"vat_number":"881403416","id_number":"MU19IWUA7340242407223765691CMM","updated_at":1695811138,"archived_at":0,"created_at":1695796650,"display_name":"Paucek and Sons","number":"0005","has_valid_vat_number":false,"is_tax_exempt":false,"routing_id":"","tax_info":{},"contacts":[{"id":"yMYerkEaOB","first_name":"Bret","last_name":"Beatty","email":"user@example.com","created_at":1695796650,"updated_at":1695796650,"archived_at":0,"is_primary":true,"is_locked":false,"phone":"1-985-403-1242","custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","contact_key":"juMXBqyvDashDUvoYXsdcbZV2SRrFf0BOUFjsc6G","send_email":true,"last_login":0,"password":"**********","link":"http:\/\/ninja.test:8000\/client\/key_login\/juMXBqyvDashDUvoYXsdcbZV2SRrFf0BOUFjsc6G"},{"id":"gl9av2maG1","first_name":"Sandra","last_name":"Daniel","email":"linnie.aufderhar@example.net","created_at":1695796650,"updated_at":1695796650,"archived_at":0,"is_primary":false,"is_locked":false,"phone":"+17319151379","custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","contact_key":"sm53aNvvsGUmLXFku0RLPUrP0zLj3rzBcTaGMjHd","send_email":true,"last_login":0,"password":"**********","link":"http:\/\/ninja.test:8000\/client\/key_login\/sm53aNvvsGUmLXFku0RLPUrP0zLj3rzBcTaGMjHd"},{"id":"7LDdwpRe1Y","first_name":"Leone","last_name":"Bode","email":"ipollich@example.org","created_at":1695796650,"updated_at":1695796650,"archived_at":0,"is_primary":false,"is_locked":false,"phone":"(424) 789-3412","custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","contact_key":"gDUwiOqRehgCHWbbctW8qgKiLmma3xvsZi10a5Ma","send_email":true,"last_login":0,"password":"**********","link":"http:\/\/ninja.test:8000\/client\/key_login\/gDUwiOqRehgCHWbbctW8qgKiLmma3xvsZi10a5Ma"}],"documents":{"data":[]},"gateway_tokens":{"data":[]}}}]'; + public string $credit_data = '[{"id":1,"client_id":1,"user_id":1,"assigned_user_id":null,"company_id":1,"status_id":2,"project_id":null,"vendor_id":null,"recurring_id":null,"design_id":2,"invoice_id":null,"number":"0001","discount":1,"is_amount_discount":false,"po_number":"Molestias.","date":"1986-08-02","last_sent_date":null,"due_date":null,"next_send_date":null,"is_deleted":false,"line_items":[{"quantity":1,"cost":637,"product_key":"Nisi.","notes":"Ut ipsa rerum.","discount":0,"is_amount_discount":false,"tax_name1":"VAT","tax_rate1":17.5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"637.00","gross_line_total":747.36,"custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"42","custom_value3":"Maxime dolores.","custom_value4":"Odio consequatur.","type_id":"2","product_cost":0,"tax_amount":110.36,"date":"","tax_id":"","task_id":"","expense_id":""},{"quantity":1,"cost":637,"product_key":"Nisi.","notes":"Ut ipsa rerum.","discount":0,"is_amount_discount":false,"tax_name1":"VAT","tax_rate1":17.5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"637.00","gross_line_total":747.36,"custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"42","custom_value3":"Maxime dolores.","custom_value4":"Odio consequatur.","type_id":"2","product_cost":0,"tax_amount":110.36,"date":"","tax_id":"","task_id":"","expense_id":""},{"quantity":1,"cost":637,"product_key":"Nisi.","notes":"Ut ipsa rerum.","discount":0,"is_amount_discount":false,"tax_name1":"VAT","tax_rate1":17.5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"637.00","gross_line_total":747.36,"custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"42","custom_value3":"Maxime dolores.","custom_value4":"Odio consequatur.","type_id":"2","product_cost":0,"tax_amount":110.36,"date":"","tax_id":"","task_id":"","expense_id":""},{"quantity":1,"cost":637,"product_key":"Nisi.","notes":"Ut ipsa rerum.","discount":0,"is_amount_discount":false,"tax_name1":"VAT","tax_rate1":17.5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"637.00","gross_line_total":747.36,"custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"42","custom_value3":"Maxime dolores.","custom_value4":"Odio consequatur.","type_id":"1","product_cost":0,"tax_amount":110.36,"date":"","tax_id":"","task_id":"","expense_id":""},{"quantity":1,"cost":637,"product_key":"Nisi.","notes":"Ut ipsa rerum.","discount":0,"is_amount_discount":false,"tax_name1":"GST","tax_rate1":10,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"637.00","gross_line_total":700.06,"custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"42","custom_value3":"Maxime dolores.","custom_value4":"Odio consequatur.","type_id":"1","product_cost":0,"tax_amount":63.06,"date":"","tax_id":"","task_id":"","expense_id":""},{"quantity":1,"cost":637,"product_key":"Nisi.","notes":"Ut ipsa rerum.","discount":0,"is_amount_discount":false,"tax_name1":"","tax_rate1":0,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"637.00","gross_line_total":637,"custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"42","custom_value3":"Maxime dolores.","custom_value4":"Odio consequatur.","type_id":"1","product_cost":0,"tax_amount":0,"date":"","tax_id":"","task_id":"","expense_id":""},{"quantity":1,"cost":637,"product_key":"Nisi.","notes":"Ut ipsa rerum.","discount":0,"is_amount_discount":false,"tax_name1":"GST","tax_rate1":10,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"637.00","gross_line_total":700.06,"custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"42","custom_value3":"Maxime dolores.","custom_value4":"Odio consequatur.","type_id":"1","product_cost":0,"tax_amount":63.06,"date":"","tax_id":"","task_id":"","expense_id":""},{"quantity":1,"cost":637,"product_key":"Nisi.","notes":"Ut ipsa rerum.","discount":0,"is_amount_discount":false,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"637.00","gross_line_total":668.53,"custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"42","custom_value3":"Maxime dolores.","custom_value4":"Odio consequatur.","type_id":"1","product_cost":0,"tax_amount":31.53,"date":"","tax_id":"","task_id":"","expense_id":""},{"quantity":1,"cost":637,"product_key":"Nisi.","notes":"Ut ipsa rerum.","discount":0,"is_amount_discount":false,"tax_name1":"GST","tax_rate1":10,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"637.00","gross_line_total":700.06,"custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"42","custom_value3":"Maxime dolores.","custom_value4":"Odio consequatur.","type_id":"1","product_cost":0,"tax_amount":63.06,"date":"","tax_id":"","task_id":"","expense_id":""},{"quantity":1,"cost":637,"product_key":"Nisi.","notes":"Ut ipsa rerum.","discount":0,"is_amount_discount":false,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"637.00","gross_line_total":668.53,"custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"42","custom_value3":"Maxime dolores.","custom_value4":"Odio consequatur.","type_id":"1","product_cost":0,"tax_amount":31.53,"date":"","tax_id":"","task_id":"","expense_id":""}],"backup":null,"footer":null,"public_notes":null,"private_notes":null,"terms":null,"tax_name1":"GST","tax_rate1":"10.000000","tax_name2":"VAT","tax_rate2":"17.500000","tax_name3":"THIRDTAX","tax_rate3":"5.000000","total_taxes":"1797.280000","uses_inclusive_taxes":0,"custom_value1":null,"custom_value2":null,"custom_value3":null,"custom_value4":null,"custom_surcharge1":null,"custom_surcharge2":null,"custom_surcharge3":null,"custom_surcharge4":null,"custom_surcharge_tax1":0,"custom_surcharge_tax2":0,"custom_surcharge_tax3":0,"custom_surcharge_tax4":0,"exchange_rate":"1.000000","amount":"6211.690000","balance":"0.000000","partial":null,"partial_due_date":null,"last_viewed":null,"created_at":1695943654,"updated_at":1695943658,"deleted_at":null,"reminder1_sent":null,"reminder2_sent":null,"reminder3_sent":null,"reminder_last_sent":null,"paid_to_date":"0.000000","subscription_id":null,"hashed_id":"VolejRejNm"},{"id":2,"client_id":1,"user_id":1,"assigned_user_id":null,"company_id":1,"status_id":2,"project_id":null,"vendor_id":null,"recurring_id":null,"design_id":2,"invoice_id":null,"number":"0002","discount":9,"is_amount_discount":true,"po_number":"Omnis.","date":"1988-11-22","last_sent_date":null,"due_date":null,"next_send_date":null,"is_deleted":false,"line_items":[{"quantity":1,"cost":637,"product_key":"Nisi.","notes":"Ut ipsa rerum.","discount":0,"is_amount_discount":true,"tax_name1":"VAT","tax_rate1":17.5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":637,"gross_line_total":738.44,"custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"42","custom_value3":"Maxime dolores.","custom_value4":"Odio consequatur.","type_id":"1","product_cost":0,"tax_amount":101.44,"date":"","tax_id":"","task_id":"","expense_id":""},{"quantity":1,"cost":637,"product_key":"Nisi.","notes":"Ut ipsa rerum.","discount":0,"is_amount_discount":true,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":637,"gross_line_total":665.98,"custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"42","custom_value3":"Maxime dolores.","custom_value4":"Odio consequatur.","type_id":"1","product_cost":0,"tax_amount":28.98,"date":"","tax_id":"","task_id":"","expense_id":""},{"quantity":1,"cost":637,"product_key":"Nisi.","notes":"Ut ipsa rerum.","discount":0,"is_amount_discount":true,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":637,"gross_line_total":665.98,"custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"42","custom_value3":"Maxime dolores.","custom_value4":"Odio consequatur.","type_id":"1","product_cost":0,"tax_amount":28.98,"date":"","tax_id":"","task_id":"","expense_id":""},{"quantity":1,"cost":637,"product_key":"Nisi.","notes":"Ut ipsa rerum.","discount":0,"is_amount_discount":true,"tax_name1":"GST","tax_rate1":10,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":637,"gross_line_total":694.97,"custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"42","custom_value3":"Maxime dolores.","custom_value4":"Odio consequatur.","type_id":"1","product_cost":0,"tax_amount":57.97,"date":"","tax_id":"","task_id":"","expense_id":""},{"quantity":1,"cost":637,"product_key":"Nisi.","notes":"Ut ipsa rerum.","discount":0,"is_amount_discount":true,"tax_name1":"VAT","tax_rate1":17.5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":637,"gross_line_total":738.44,"custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"42","custom_value3":"Maxime dolores.","custom_value4":"Odio consequatur.","type_id":"1","product_cost":0,"tax_amount":101.44,"date":"","tax_id":"","task_id":"","expense_id":""}],"backup":null,"footer":null,"public_notes":null,"private_notes":null,"terms":null,"tax_name1":"GST","tax_rate1":"10.000000","tax_name2":"VAT","tax_rate2":"17.500000","tax_name3":"THIRDTAX","tax_rate3":"5.000000","total_taxes":"1381.560000","uses_inclusive_taxes":0,"custom_value1":null,"custom_value2":null,"custom_value3":null,"custom_value4":null,"custom_surcharge1":null,"custom_surcharge2":null,"custom_surcharge3":null,"custom_surcharge4":null,"custom_surcharge_tax1":0,"custom_surcharge_tax2":0,"custom_surcharge_tax3":0,"custom_surcharge_tax4":0,"exchange_rate":"1.000000","amount":"4557.560000","balance":"0.000000","partial":null,"partial_due_date":null,"last_viewed":null,"created_at":1695943654,"updated_at":1696118643,"deleted_at":null,"reminder1_sent":null,"reminder2_sent":null,"reminder3_sent":null,"reminder_last_sent":null,"paid_to_date":"0.000000","subscription_id":null,"hashed_id":"Wpmbk5ezJn"}]'; public string $payment_data = '[{"status":"Refunded","badge":"

Refunded<\/span><\/h6>","amount":"$6,077.51","applied":"$6,077.51","balance":"-$6,077.51","refunded":"$6,077.51","amount_raw":"6077.510000","applied_raw":"6077.510000","refunded_raw":"6077.510000","balance_raw":-6077.51,"date":"30\/Sep\/2023","method":"EuroCard","currency":"USD","exchange_rate":1,"transaction_reference":"Manual entry","is_manual":1,"number":"0001","custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","client":{"name":"cypress","balance":"0.000000","payment_balance":"0.000000","credit_balance":"11661.820000","vat_number":"VAT123"},"paymentables":[{"invoice":"0019","amount_raw":"6077.5100","refunded_raw":"6077.5100","net_raw":0,"amount":"$6,077.51","refunded":"$6,077.51","net":"$0.00","is_credit":false,"created_at":"01\/Oct\/2023","updated_at":"01\/Oct\/2023","timestamp":1696150843}]},{"status":"Refunded","badge":"
Refunded<\/span><\/h6>","amount":"$4,090.64","applied":"$4,090.64","balance":"-$4,090.64","refunded":"$4,090.64","amount_raw":"4090.640000","applied_raw":"4090.640000","refunded_raw":"4090.640000","balance_raw":-4090.64,"date":"30\/Sep\/2023","method":"Discover Card","currency":"USD","exchange_rate":1,"transaction_reference":"Manual entry","is_manual":1,"number":"0002","custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","client":{"name":"cypress","balance":"0.000000","payment_balance":"0.000000","credit_balance":"11661.820000","vat_number":"VAT123"},"paymentables":[{"invoice":"0020","amount_raw":"4090.6400","refunded_raw":"4090.6400","net_raw":0,"amount":"$4,090.64","refunded":"$4,090.64","net":"$0.00","is_credit":false,"created_at":"01\/Oct\/2023","updated_at":"01\/Oct\/2023","timestamp":1696150843}]},{"status":"Refunded","badge":"
Refunded<\/span><\/h6>","amount":"$2,197.26","applied":"$2,197.26","balance":"-$2,197.26","refunded":"$2,197.26","amount_raw":"2197.260000","applied_raw":"2197.260000","refunded_raw":"2197.260000","balance_raw":-2197.26,"date":"30\/Sep\/2023","method":"Diners Card","currency":"USD","exchange_rate":1,"transaction_reference":"Manual entry","is_manual":1,"number":"0003","custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","client":{"name":"Jakubowski Group","balance":"28296.170000","payment_balance":"0.000000","credit_balance":"1084.840000","vat_number":"VAT123"},"paymentables":[{"invoice":"0021","amount_raw":"2197.2600","refunded_raw":"2197.2600","net_raw":0,"amount":"$2,197.26","refunded":"$2,197.26","net":"$0.00","is_credit":false,"created_at":"01\/Oct\/2023","updated_at":"01\/Oct\/2023","timestamp":1696150843}]},{"status":"Partially Refunded","badge":"
Partially Refunded<\/span><\/h6>","amount":"$4,955.50","applied":"$4,955.50","balance":"-$66.00","refunded":"$66.00","amount_raw":"4955.500000","applied_raw":"4955.500000","refunded_raw":"66.000000","balance_raw":-66,"date":"30\/Sep\/2023","method":"Maestro","currency":"USD","exchange_rate":1,"transaction_reference":"Manual entry","is_manual":1,"number":"0004","custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","client":{"name":"Jakubowski Group","balance":"28296.170000","payment_balance":"0.000000","credit_balance":"1084.840000","vat_number":"VAT123"},"paymentables":[{"invoice":"0022","amount_raw":"4955.5000","refunded_raw":"66.0000","net_raw":4889.5,"amount":"$4,955.50","refunded":"$66.00","net":"$4,889.50","is_credit":false,"created_at":"01\/Oct\/2023","updated_at":"01\/Oct\/2023","timestamp":1696150843}]},{"status":"Partially Refunded","badge":"
Partially Refunded<\/span><\/h6>","amount":"$2,290.75","applied":"$2,290.75","balance":"-$34.00","refunded":"$34.00","amount_raw":"2290.750000","applied_raw":"2290.750000","refunded_raw":"34.000000","balance_raw":-34,"date":"30\/Sep\/2023","method":"Diners Card","currency":"USD","exchange_rate":1,"transaction_reference":"Manual entry","is_manual":1,"number":"0005","custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","client":{"name":"Jakubowski Group","balance":"28296.170000","payment_balance":"0.000000","credit_balance":"1084.840000","vat_number":"VAT123"},"paymentables":[{"invoice":"0023","amount_raw":"2290.7500","refunded_raw":"34.0000","net_raw":2256.75,"amount":"$2,290.75","refunded":"$34.00","net":"$2,256.75","is_credit":false,"created_at":"01\/Oct\/2023","updated_at":"01\/Oct\/2023","timestamp":1696150843}]},{"status":"Partially Refunded","badge":"
Partially Refunded<\/span><\/h6>","amount":"$6,802.13","applied":"$6,802.13","balance":"-$444.00","refunded":"$444.00","amount_raw":"6802.130000","applied_raw":"6802.130000","refunded_raw":"444.000000","balance_raw":-444,"date":"30\/Sep\/2023","method":"Maestro","currency":"USD","exchange_rate":1,"transaction_reference":"Manual entry","is_manual":1,"number":"0006","custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","client":{"name":"Jakubowski Group","balance":"28296.170000","payment_balance":"0.000000","credit_balance":"1084.840000","vat_number":"VAT123"},"paymentables":[{"invoice":"0024","amount_raw":"6802.1300","refunded_raw":"444.0000","net_raw":6358.13,"amount":"$6,802.13","refunded":"$444.00","net":"$6,358.13","is_credit":false,"created_at":"01\/Oct\/2023","updated_at":"01\/Oct\/2023","timestamp":1696150843}]},{"status":"Partially Refunded","badge":"
Partially Refunded<\/span><\/h6>","amount":"$10,986.26","applied":"$10,986.26","balance":"-$146.26","refunded":"$146.26","amount_raw":"10986.260000","applied_raw":"10986.260000","refunded_raw":"146.260000","balance_raw":-146.26000000000022,"date":"30\/Sep\/2023","method":"UnionPay","currency":"USD","exchange_rate":1,"transaction_reference":"Manual entry","is_manual":1,"number":"0007","custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","client":{"name":"Jakubowski Group","balance":"28296.170000","payment_balance":"0.000000","credit_balance":"1084.840000","vat_number":"VAT123"},"paymentables":[{"invoice":"0025","amount_raw":"10986.2600","refunded_raw":"146.2600","net_raw":10840,"amount":"$10,986.26","refunded":"$146.26","net":"$10,840.00","is_credit":false,"created_at":"01\/Oct\/2023","updated_at":"01\/Oct\/2023","timestamp":1696150843}]},{"status":"Completed","badge":"
Completed<\/span><\/h6>","amount":"$6,054.13","applied":"$6,054.13","balance":"$0.00","refunded":"$0.00","amount_raw":"6054.130000","applied_raw":"6054.130000","refunded_raw":"0.000000","balance_raw":0,"date":"30\/Sep\/2023","method":"","currency":"USD","exchange_rate":1,"transaction_reference":"Manual entry","is_manual":1,"number":"0008","custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","client":{"name":"Lowe-Paucek","balance":"38124.670000","payment_balance":"0.000000","credit_balance":"2270.590000","vat_number":"VAT123"},"paymentables":[{"invoice":"0015","amount_raw":"6054.1300","refunded_raw":"0.0000","net_raw":6054.13,"amount":"$6,054.13","refunded":"$0.00","net":"$6,054.13","is_credit":false,"created_at":"01\/Oct\/2023","updated_at":"01\/Oct\/2023","timestamp":1696151008}]},{"status":"Completed","badge":"
Completed<\/span><\/h6>","amount":"$3,132.25","applied":"$3,132.25","balance":"$0.00","refunded":"$0.00","amount_raw":"3132.250000","applied_raw":"3132.250000","refunded_raw":"0.000000","balance_raw":0,"date":"30\/Sep\/2023","method":"","currency":"USD","exchange_rate":1,"transaction_reference":"Manual entry","is_manual":1,"number":"0009","custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","client":{"name":"cypress","balance":"0.000000","payment_balance":"0.000000","credit_balance":"11661.820000","vat_number":"VAT123"},"paymentables":[{"invoice":"0016","amount_raw":"3132.2500","refunded_raw":"0.0000","net_raw":3132.25,"amount":"$3,132.25","refunded":"$0.00","net":"$3,132.25","is_credit":false,"created_at":"01\/Oct\/2023","updated_at":"01\/Oct\/2023","timestamp":1696151008}]},{"status":"Completed","badge":"
Completed<\/span><\/h6>","amount":"$9,396.77","applied":"$9,396.77","balance":"$0.00","refunded":"$0.00","amount_raw":"9396.770000","applied_raw":"9396.770000","refunded_raw":"0.000000","balance_raw":0,"date":"30\/Sep\/2023","method":"","currency":"USD","exchange_rate":1,"transaction_reference":"Manual entry","is_manual":1,"number":"0010","custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","client":{"name":"cypress","balance":"0.000000","payment_balance":"0.000000","credit_balance":"11661.820000"},"paymentables":[{"invoice":"0017","amount_raw":"9396.7700","refunded_raw":"0.0000","net_raw":9396.77,"amount":"$9,396.77","refunded":"$0.00","net":"$9,396.77","is_credit":false,"created_at":"01\/Oct\/2023","updated_at":"01\/Oct\/2023","timestamp":1696151008}]}]'; @@ -33,9 +33,9 @@ class TemplateMock public string $task_data = '[{"number":"0001","description":"Reiciendis itaque molestias blanditiis cupiditate ea. Minus officiis natus itaque. Consectetur et aut veritatis quae ut esse ut. Accusantium dolore quaerat sit qui. Magni quia sunt corporis.","duration":149031,"rate":"$71.00","rate_raw":"71.000000","created_at":"19\/Nov\/2023","updated_at":"19\/Nov\/2023","date":"19\/Nov\/2023","project":[],"time_log":[{"start_date_raw":1700428466,"start_date":"19\/Nov\/2023 21:11:26","end_date_raw":1700470150,"end_date":"20\/Nov\/2023 08:11:10","description":"Assumenda nihil vitae odio voluptatem iusto ipsam repellendus.","billable":false,"duration":41684},{"start_date_raw":1700470450,"start_date":"20\/Nov\/2023 08:11:10","end_date_raw":1700485036,"end_date":"20\/Nov\/2023 12:11:16","description":"Adipisci amet optio tempore et.","billable":true,"duration":14586},{"start_date_raw":1700485336,"start_date":"20\/Nov\/2023 13:11:16","end_date_raw":1700572291,"end_date":"21\/Nov\/2023 13:11:31","description":"Ratione repellat saepe mollitia perspiciatis optio.","billable":false,"duration":86955},{"start_date_raw":1700572591,"start_date":"21\/Nov\/2023 13:11:31","end_date_raw":1700578397,"end_date":"21\/Nov\/2023 14:11:17","description":"Molestias perferendis ipsa odit id aut sunt.","billable":true,"duration":5806}],"custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","status":"Done","user":{"name":"Laron Weissnat Danika Flatley","email":"small@example.com"},"client":{"name":"Medhurst Inc","balance":"37633.780000","payment_balance":"0.000000","credit_balance":"1025.100000","vat_number":"VAT123","currency":"USD"}},{"number":"0002","description":"Et dolorem nihil qui quas asperiores nulla aut praesentium. Ea quasi porro facere eligendi. Et assumenda illum nostrum natus repellat eveniet. Sequi odio nulla perspiciatis doloremque.","duration":966982,"rate":"$76.00","rate_raw":"76.000000","created_at":"19\/Nov\/2023","updated_at":"19\/Nov\/2023","date":"19\/Nov\/2023","project":{"name":"Abel Moore","number":"0001","created_at":"19\/Nov\/2023","updated_at":"19\/Nov\/2023","task_rate":"$107.00","task_rate_raw":"107.000000","due_date":"25\/Nov\/2023","private_notes":"","public_notes":"Omnis modi optio maxime ut inventore.","budgeted_hours":339,"custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","color":"#fff","current_hours":390,"tasks":[],"client":{"name":"Hoeger, Hahn and Cole","balance":"0.000000","payment_balance":"0.000000","credit_balance":"1022.550000","vat_number":"VAT123","currency":"USD"},"user":{"name":"Laron Weissnat Danika Flatley","email":"small@example.com"}},"time_log":[{"start_date_raw":1700428466,"start_date":"19\/Nov\/2023 21:11:26","end_date_raw":1700492035,"end_date":"20\/Nov\/2023 14:11:55","description":"Nihil voluptas et sint et.","billable":true,"duration":63569},{"start_date_raw":1700492335,"start_date":"20\/Nov\/2023 14:11:55","end_date_raw":1700554011,"end_date":"21\/Nov\/2023 08:11:51","description":"Aut consequuntur aliquam earum aut reiciendis.","billable":false,"duration":61676},{"start_date_raw":1700554311,"start_date":"21\/Nov\/2023 08:11:51","end_date_raw":1700586651,"end_date":"21\/Nov\/2023 17:11:51","description":"Occaecati consectetur temporibus neque rerum sed rem iure.","billable":true,"duration":32340},{"start_date_raw":1700586951,"start_date":"21\/Nov\/2023 17:11:51","end_date_raw":1700644903,"end_date":"22\/Nov\/2023 09:11:43","description":"Ducimus voluptate aliquid aliquam nobis.","billable":true,"duration":57952},{"start_date_raw":1700645203,"start_date":"22\/Nov\/2023 09:11:43","end_date_raw":1700724132,"end_date":"23\/Nov\/2023 07:11:12","description":"Non ipsam consequatur voluptatem illum.","billable":true,"duration":78929},{"start_date_raw":1700724432,"start_date":"23\/Nov\/2023 07:11:12","end_date_raw":1700790596,"end_date":"24\/Nov\/2023 01:11:56","description":"Aspernatur quia voluptate molestias non.","billable":false,"duration":66164},{"start_date_raw":1700790896,"start_date":"24\/Nov\/2023 01:11:56","end_date_raw":1700812808,"end_date":"24\/Nov\/2023 08:11:08","description":"Sed quod omnis officiis asperiores natus facere minus nemo.","billable":false,"duration":21912},{"start_date_raw":1700813108,"start_date":"24\/Nov\/2023 08:11:08","end_date_raw":1700865275,"end_date":"24\/Nov\/2023 22:11:35","description":"Tenetur quaerat ea magni placeat.","billable":false,"duration":52167},{"start_date_raw":1700865575,"start_date":"24\/Nov\/2023 22:11:35","end_date_raw":1700888516,"end_date":"25\/Nov\/2023 05:11:56","description":"Sequi dolor laborum deserunt rerum.","billable":true,"duration":22941},{"start_date_raw":1700888816,"start_date":"25\/Nov\/2023 05:11:56","end_date_raw":1700933259,"end_date":"25\/Nov\/2023 17:11:39","description":"Est qui velit ipsum et nesciunt qui ut.","billable":true,"duration":44443},{"start_date_raw":1700933559,"start_date":"25\/Nov\/2023 17:11:39","end_date_raw":1700979107,"end_date":"26\/Nov\/2023 06:11:47","description":"Sint et quo quo.","billable":false,"duration":45548},{"start_date_raw":1700979407,"start_date":"26\/Nov\/2023 06:11:47","end_date_raw":1701002669,"end_date":"26\/Nov\/2023 12:11:29","description":"Omnis unde sit similique dolor fugit totam.","billable":true,"duration":23262},{"start_date_raw":1701002969,"start_date":"26\/Nov\/2023 12:11:29","end_date_raw":1701071339,"end_date":"27\/Nov\/2023 07:11:59","description":"Ducimus qui voluptas accusamus.","billable":true,"duration":68370},{"start_date_raw":1701071639,"start_date":"27\/Nov\/2023 07:11:59","end_date_raw":1701100825,"end_date":"27\/Nov\/2023 16:11:25","description":"Soluta sit non nobis ab et ad libero sint.","billable":false,"duration":29186},{"start_date_raw":1701101125,"start_date":"27\/Nov\/2023 16:11:25","end_date_raw":1701157799,"end_date":"28\/Nov\/2023 07:11:59","description":"Cumque dignissimos error qui ut.","billable":true,"duration":56674},{"start_date_raw":1701158099,"start_date":"28\/Nov\/2023 07:11:59","end_date_raw":1701214020,"end_date":"28\/Nov\/2023 23:11:00","description":"Molestias omnis aliquid voluptatem cupiditate ut.","billable":true,"duration":55921},{"start_date_raw":1701214320,"start_date":"28\/Nov\/2023 23:11:00","end_date_raw":1701286375,"end_date":"29\/Nov\/2023 19:11:55","description":"Distinctio commodi est ab.","billable":true,"duration":72055},{"start_date_raw":1701286675,"start_date":"29\/Nov\/2023 19:11:55","end_date_raw":1701330081,"end_date":"30\/Nov\/2023 07:11:21","description":"Nisi dolores omnis veritatis.","billable":false,"duration":43406},{"start_date_raw":1701330381,"start_date":"30\/Nov\/2023 07:11:21","end_date_raw":1701398228,"end_date":"01\/Dec\/2023 02:12:08","description":"Qui aut velit quam dolore qui asperiores.","billable":false,"duration":67847},{"start_date_raw":1701398528,"start_date":"01\/Dec\/2023 02:12:08","end_date_raw":1701401148,"end_date":"01\/Dec\/2023 03:12:48","description":"Laudantium est laudantium ea ut repellendus.","billable":true,"duration":2620}],"custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","status":"Backlog","user":{"name":"Laron Weissnat Danika Flatley","email":"small@example.com"},"client":{"name":"Hoeger, Hahn and Cole","balance":"0.000000","payment_balance":"0.000000","credit_balance":"1022.550000","vat_number":"VAT123","currency":"USD"}},{"number":"0003","description":"Qui excepturi et aut et voluptates eius perferendis. Repellat eum illo quis aliquid occaecati reprehenderit officia. Est earum nihil similique recusandae aut ut est error. Enim molestiae assumenda quaerat neque unde. Consequatur vel placeat commodi molestiae.","duration":259657,"rate":"$9.00","rate_raw":"9.000000","created_at":"19\/Nov\/2023","updated_at":"19\/Nov\/2023","date":"19\/Nov\/2023","project":{"name":"Abel Moore","number":"0001","created_at":"19\/Nov\/2023","updated_at":"19\/Nov\/2023","task_rate":"$107.00","task_rate_raw":"107.000000","due_date":"25\/Nov\/2023","private_notes":"","public_notes":"Omnis modi optio maxime ut inventore.","budgeted_hours":339,"custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","color":"#fff","current_hours":390,"tasks":[],"client":{"name":"Hoeger, Hahn and Cole","balance":"0.000000","payment_balance":"0.000000","credit_balance":"1022.550000","vat_number":"VAT123","currency":"USD"},"user":{"name":"Laron Weissnat Danika Flatley","email":"small@example.com"}},"time_log":[{"start_date_raw":1700428466,"start_date":"19\/Nov\/2023 21:11:26","end_date_raw":1700498928,"end_date":"20\/Nov\/2023 16:11:48","description":"Animi asperiores velit quaerat sapiente dolorem officiis.","billable":false,"duration":70462},{"start_date_raw":1700499228,"start_date":"20\/Nov\/2023 16:11:48","end_date_raw":1700516753,"end_date":"20\/Nov\/2023 21:11:53","description":"Et facere ut tempora similique et sunt culpa.","billable":false,"duration":17525},{"start_date_raw":1700517053,"start_date":"20\/Nov\/2023 21:11:53","end_date_raw":1700523921,"end_date":"20\/Nov\/2023 23:11:21","description":"Consequatur enim non reprehenderit quia.","billable":false,"duration":6868},{"start_date_raw":1700524221,"start_date":"20\/Nov\/2023 23:11:21","end_date_raw":1700609374,"end_date":"21\/Nov\/2023 23:11:34","description":"Nobis non nesciunt ut reprehenderit at.","billable":false,"duration":85153},{"start_date_raw":1700609674,"start_date":"21\/Nov\/2023 23:11:34","end_date_raw":1700689323,"end_date":"22\/Nov\/2023 21:11:03","description":"Blanditiis repellendus quo voluptatum eveniet iste.","billable":false,"duration":79649}],"custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","status":"Ready to do","user":{"name":"Laron Weissnat Danika Flatley","email":"small@example.com"},"client":{"name":"Hoeger, Hahn and Cole","balance":"0.000000","payment_balance":"0.000000","credit_balance":"1022.550000","vat_number":"VAT123","currency":"USD"}},{"number":"0004","description":"Ipsam tempora id vero perferendis. Nulla laudantium iste qui quod et voluptatem. Aliquam et vel est minus ratione.","duration":179131,"rate":"$146.00","rate_raw":"146.000000","created_at":"19\/Nov\/2023","updated_at":"19\/Nov\/2023","date":"19\/Nov\/2023","project":{"name":"Abel Moore","number":"0001","created_at":"19\/Nov\/2023","updated_at":"19\/Nov\/2023","task_rate":"$107.00","task_rate_raw":"107.000000","due_date":"25\/Nov\/2023","private_notes":"","public_notes":"Omnis modi optio maxime ut inventore.","budgeted_hours":339,"custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","color":"#fff","current_hours":390,"tasks":[],"client":{"name":"Hoeger, Hahn and Cole","balance":"0.000000","payment_balance":"0.000000","credit_balance":"1022.550000","vat_number":"VAT123","currency":"USD"},"user":{"name":"Laron Weissnat Danika Flatley","email":"small@example.com"}},"time_log":[{"start_date_raw":1700428466,"start_date":"19\/Nov\/2023 21:11:26","end_date_raw":1700446786,"end_date":"20\/Nov\/2023 02:11:46","description":"Ipsam voluptatum sed officiis eos quo.","billable":true,"duration":18320},{"start_date_raw":1700447086,"start_date":"20\/Nov\/2023 02:11:46","end_date_raw":1700520087,"end_date":"20\/Nov\/2023 22:11:27","description":"Et maxime rem provident veritatis.","billable":true,"duration":73001},{"start_date_raw":1700520387,"start_date":"20\/Nov\/2023 22:11:27","end_date_raw":1700603783,"end_date":"21\/Nov\/2023 21:11:23","description":"Deserunt soluta dolorem harum voluptas necessitatibus eum laborum omnis.","billable":false,"duration":83396},{"start_date_raw":1700604083,"start_date":"21\/Nov\/2023 22:11:23","end_date_raw":1700608497,"end_date":"21\/Nov\/2023 23:11:57","description":"Esse et aperiam nobis dolor voluptas.","billable":true,"duration":4414}],"custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","status":"Backlog","user":{"name":"Laron Weissnat Danika Flatley","email":"small@example.com"},"client":{"name":"Hoeger, Hahn and Cole","balance":"0.000000","payment_balance":"0.000000","credit_balance":"1022.550000","vat_number":"VAT123","currency":"USD"}},{"number":"0005","description":"Enim fugiat at excepturi voluptate debitis ea. Hic officiis quaerat molestiae ullam minus consequuntur ut. Officiis quas consequatur error quae eveniet. Dolorum aliquam provident aperiam asperiores alias modi quae a.","duration":3230,"rate":"$78.00","rate_raw":"78.000000","created_at":"19\/Nov\/2023","updated_at":"19\/Nov\/2023","date":"19\/Nov\/2023","project":[],"time_log":[{"start_date_raw":1700428467,"start_date":"19\/Nov\/2023 21:11:27","end_date_raw":1700431697,"end_date":"19\/Nov\/2023 22:11:17","description":"Repudiandae nam et consequatur consequatur.","billable":false,"duration":3230}],"custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","status":"Done","user":{"name":"Laron Weissnat Danika Flatley","email":"small@example.com"},"client":{"name":"Schroeder-Beahan","balance":"60576.340000","payment_balance":"0.000000","credit_balance":"0.000000","currency":"USD"}},{"number":"0006","description":"Dolor quidem aperiam rerum. Voluptates aut vel ut consequatur. Nam et unde cupiditate qui voluptates voluptatum. Temporibus assumenda enim nam neque.","duration":156986,"rate":"$92.00","rate_raw":"92.000000","created_at":"19\/Nov\/2023","updated_at":"19\/Nov\/2023","date":"19\/Nov\/2023","project":{"name":"Prof. Noah Jaskolski II","number":"0002","created_at":"19\/Nov\/2023","updated_at":"19\/Nov\/2023","task_rate":"$52.00","task_rate_raw":"52.000000","due_date":"25\/Nov\/2023","private_notes":"","public_notes":"Mollitia ut vel quam. Quia et aut minus.","budgeted_hours":660,"custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","color":"#fff","current_hours":57,"tasks":[],"client":{"name":"cypress","balance":"13866.150000","payment_balance":"0.000000","credit_balance":"1013.630000","currency":"USD"},"user":{"name":"Laron Weissnat Danika Flatley","email":"small@example.com"}},"time_log":[{"start_date_raw":1700428467,"start_date":"19\/Nov\/2023 21:11:27","end_date_raw":1700443047,"end_date":"20\/Nov\/2023 01:11:27","description":"Unde sequi dicta corporis odio.","billable":true,"duration":14580},{"start_date_raw":1700443347,"start_date":"20\/Nov\/2023 01:11:27","end_date_raw":1700489146,"end_date":"20\/Nov\/2023 14:11:46","description":"Qui rem id inventore velit corporis vitae.","billable":false,"duration":45799},{"start_date_raw":1700489446,"start_date":"20\/Nov\/2023 14:11:46","end_date_raw":1700514655,"end_date":"20\/Nov\/2023 21:11:55","description":"Rerum repellat unde et blanditiis sunt animi aliquid accusantium.","billable":false,"duration":25209},{"start_date_raw":1700514955,"start_date":"20\/Nov\/2023 21:11:55","end_date_raw":1700515449,"end_date":"20\/Nov\/2023 21:11:09","description":"Quasi velit sit et explicabo quibusdam nam.","billable":true,"duration":494},{"start_date_raw":1700515749,"start_date":"20\/Nov\/2023 21:11:09","end_date_raw":1700586653,"end_date":"21\/Nov\/2023 17:11:53","description":"Numquam eos aut eum est corrupti dolorem et.","billable":false,"duration":70904}],"custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","status":"Ready to do","user":{"name":"Laron Weissnat Danika Flatley","email":"small@example.com"},"client":{"name":"cypress","balance":"13866.150000","payment_balance":"0.000000","credit_balance":"1013.630000","currency":"USD"}},{"number":"0007","description":"Omnis totam eum sed dolores quod rerum. Ducimus voluptate iste quia dolorum consequatur sint. Velit vitae sint qui molestias. Dolores ea rerum voluptates iusto qui natus beatae.","duration":47670,"rate":"$88.00","rate_raw":"88.000000","created_at":"19\/Nov\/2023","updated_at":"19\/Nov\/2023","date":"19\/Nov\/2023","project":{"name":"Prof. Noah Jaskolski II","number":"0002","created_at":"19\/Nov\/2023","updated_at":"19\/Nov\/2023","task_rate":"$52.00","task_rate_raw":"52.000000","due_date":"25\/Nov\/2023","private_notes":"","public_notes":"Mollitia ut vel quam. Quia et aut minus.","budgeted_hours":660,"custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","color":"#fff","current_hours":57,"tasks":[],"client":{"name":"cypress","balance":"13866.150000","payment_balance":"0.000000","credit_balance":"1013.630000","currency":"USD"},"user":{"name":"Laron Weissnat Danika Flatley","email":"small@example.com"}},"time_log":[{"start_date_raw":1700428467,"start_date":"19\/Nov\/2023 21:11:27","end_date_raw":1700476137,"end_date":"20\/Nov\/2023 10:11:57","description":"Sint laudantium quia eveniet quod nobis occaecati nihil.","billable":false,"duration":47670}],"custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","status":"Backlog","user":{"name":"Laron Weissnat Danika Flatley","email":"small@example.com"},"client":{"name":"cypress","balance":"13866.150000","payment_balance":"0.000000","credit_balance":"1013.630000","currency":"USD"}},{"number":"0008","description":"Molestiae dolor explicabo et in commodi eveniet. Expedita voluptatibus nihil ut. Et porro cumque nisi omnis maxime accusantium earum.","duration":638322,"rate":"$130.00","rate_raw":"130.000000","created_at":"19\/Nov\/2023","updated_at":"19\/Nov\/2023","date":"19\/Nov\/2023","project":[],"time_log":[{"start_date_raw":1700428468,"start_date":"19\/Nov\/2023 21:11:28","end_date_raw":1700504838,"end_date":"20\/Nov\/2023 18:11:18","description":"Delectus consequatur esse quaerat vel.","billable":false,"duration":76370},{"start_date_raw":1700505138,"start_date":"20\/Nov\/2023 18:11:18","end_date_raw":1700579924,"end_date":"21\/Nov\/2023 15:11:44","description":"Eveniet culpa qui quo architecto recusandae ut occaecati aut.","billable":true,"duration":74786},{"start_date_raw":1700580224,"start_date":"21\/Nov\/2023 15:11:44","end_date_raw":1700646586,"end_date":"22\/Nov\/2023 09:11:46","description":"Delectus quia officiis vero quia corporis.","billable":true,"duration":66362},{"start_date_raw":1700646886,"start_date":"22\/Nov\/2023 09:11:46","end_date_raw":1700732597,"end_date":"23\/Nov\/2023 09:11:17","description":"Non ut placeat dolorum et.","billable":true,"duration":85711},{"start_date_raw":1700732897,"start_date":"23\/Nov\/2023 09:11:17","end_date_raw":1700740803,"end_date":"23\/Nov\/2023 12:11:03","description":"Numquam natus accusantium voluptatem aliquam maxime fugiat voluptatem.","billable":true,"duration":7906},{"start_date_raw":1700741103,"start_date":"23\/Nov\/2023 12:11:03","end_date_raw":1700807283,"end_date":"24\/Nov\/2023 06:11:03","description":"Quae est ut optio atque fugit non.","billable":false,"duration":66180},{"start_date_raw":1700807583,"start_date":"24\/Nov\/2023 06:11:03","end_date_raw":1700889007,"end_date":"25\/Nov\/2023 05:11:07","description":"Natus voluptas quo id nam iure neque eveniet id.","billable":false,"duration":81424},{"start_date_raw":1700889307,"start_date":"25\/Nov\/2023 05:11:07","end_date_raw":1700949728,"end_date":"25\/Nov\/2023 22:11:08","description":"Sed suscipit voluptatem officia reprehenderit qui occaecati saepe veniam.","billable":false,"duration":60421},{"start_date_raw":1700950028,"start_date":"25\/Nov\/2023 22:11:08","end_date_raw":1700972964,"end_date":"26\/Nov\/2023 04:11:24","description":"Officiis sequi aut natus sapiente.","billable":true,"duration":22936},{"start_date_raw":1700973264,"start_date":"26\/Nov\/2023 04:11:24","end_date_raw":1700986155,"end_date":"26\/Nov\/2023 08:11:15","description":"Et similique odit quasi eaque harum.","billable":false,"duration":12891},{"start_date_raw":1700986455,"start_date":"26\/Nov\/2023 08:11:15","end_date_raw":1701069790,"end_date":"27\/Nov\/2023 07:11:10","description":"Qui magnam vero unde nam dolorem qui.","billable":true,"duration":83335}],"custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","status":"Ready to do","user":{"name":"Laron Weissnat Danika Flatley","email":"small@example.com"},"client":{"name":"Medhurst Inc","balance":"37633.780000","payment_balance":"0.000000","credit_balance":"1025.100000","currency":"USD"}},{"number":"0009","description":"Ipsam numquam nesciunt corporis veritatis vitae porro maiores. Delectus sit itaque dolores. Atque et dolorem nisi est.","duration":439161,"rate":"$120.00","rate_raw":"120.000000","created_at":"19\/Nov\/2023","updated_at":"19\/Nov\/2023","date":"19\/Nov\/2023","project":{"name":"Mr. Easton Streich","number":"0003","created_at":"19\/Nov\/2023","updated_at":"19\/Nov\/2023","task_rate":"$153.00","task_rate_raw":"153.000000","due_date":"28\/Nov\/2023","private_notes":"","public_notes":"Debitis sit ut voluptatem eaque veritatis.","budgeted_hours":216,"custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","color":"#fff","current_hours":496,"tasks":[],"client":{"name":"Walsh-Considine","balance":"0.000000","payment_balance":"0.000000","credit_balance":"1960.450000"},"user":{"name":"Laron Weissnat Danika Flatley","email":"small@example.com"}},"time_log":[{"start_date_raw":1700428468,"start_date":"19\/Nov\/2023 21:11:28","end_date_raw":1700434593,"end_date":"19\/Nov\/2023 22:11:33","description":"At unde dolores quasi quia.","billable":true,"duration":6125},{"start_date_raw":1700434893,"start_date":"19\/Nov\/2023 23:11:33","end_date_raw":1700498703,"end_date":"20\/Nov\/2023 16:11:03","description":"Et quae non voluptatum nam quia velit suscipit.","billable":false,"duration":63810},{"start_date_raw":1700499003,"start_date":"20\/Nov\/2023 16:11:03","end_date_raw":1700548104,"end_date":"21\/Nov\/2023 06:11:24","description":"Quidem delectus sed et.","billable":true,"duration":49101},{"start_date_raw":1700548404,"start_date":"21\/Nov\/2023 06:11:24","end_date_raw":1700629022,"end_date":"22\/Nov\/2023 04:11:02","description":"Soluta velit enim explicabo dolorem commodi.","billable":false,"duration":80618},{"start_date_raw":1700629322,"start_date":"22\/Nov\/2023 05:11:02","end_date_raw":1700647716,"end_date":"22\/Nov\/2023 10:11:36","description":"Est magni qui quis.","billable":false,"duration":18394},{"start_date_raw":1700648016,"start_date":"22\/Nov\/2023 10:11:36","end_date_raw":1700731147,"end_date":"23\/Nov\/2023 09:11:07","description":"Saepe aspernatur non molestias dolor ea quos in.","billable":false,"duration":83131},{"start_date_raw":1700731447,"start_date":"23\/Nov\/2023 09:11:07","end_date_raw":1700782753,"end_date":"23\/Nov\/2023 23:11:13","description":"Alias id nihil laboriosam aliquam odio qui excepturi.","billable":true,"duration":51306},{"start_date_raw":1700783053,"start_date":"23\/Nov\/2023 23:11:13","end_date_raw":1700795456,"end_date":"24\/Nov\/2023 03:11:56","description":"Eos numquam et atque quia a qui nesciunt.","billable":false,"duration":12403},{"start_date_raw":1700795756,"start_date":"24\/Nov\/2023 03:11:56","end_date_raw":1700812488,"end_date":"24\/Nov\/2023 07:11:48","description":"Ut voluptas in natus qui.","billable":false,"duration":16732},{"start_date_raw":1700812788,"start_date":"24\/Nov\/2023 07:11:48","end_date_raw":1700842826,"end_date":"24\/Nov\/2023 16:11:26","description":"Est aut magnam ratione.","billable":false,"duration":30038},{"start_date_raw":1700843126,"start_date":"24\/Nov\/2023 16:11:26","end_date_raw":1700870629,"end_date":"25\/Nov\/2023 00:11:49","description":"Exercitationem non odio quasi ut saepe.","billable":true,"duration":27503}],"custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","status":"Backlog","user":{"name":"Laron Weissnat Danika Flatley","email":"small@example.com"},"client":{"name":"Walsh-Considine","balance":"0.000000","payment_balance":"0.000000","credit_balance":"1960.450000","currency":"USD"}},{"number":"0010","description":"Quo recusandae optio est saepe consectetur optio. Accusantium eum quia eaque. Voluptatum eligendi similique velit dolor eos rerum cumque quaerat.","duration":425934,"rate":"$98.00","rate_raw":"98.000000","created_at":"19\/Nov\/2023","updated_at":"19\/Nov\/2023","date":"19\/Nov\/2023","project":{"name":"Mr. Easton Streich","number":"0003","created_at":"19\/Nov\/2023","updated_at":"19\/Nov\/2023","task_rate":"$153.00","task_rate_raw":"153.000000","due_date":"28\/Nov\/2023","private_notes":"","public_notes":"Debitis sit ut voluptatem eaque veritatis.","budgeted_hours":216,"custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","color":"#fff","current_hours":496,"tasks":[],"client":{"name":"Walsh-Considine","balance":"0.000000","payment_balance":"0.000000","credit_balance":"1960.450000","currency":"USD"},"user":{"name":"Laron Weissnat Danika Flatley","email":"small@example.com"}},"time_log":[{"start_date_raw":1700428468,"start_date":"19\/Nov\/2023 21:11:28","end_date_raw":1700463790,"end_date":"20\/Nov\/2023 07:11:10","description":"Culpa aut consequatur earum ut.","billable":false,"duration":35322},{"start_date_raw":1700464090,"start_date":"20\/Nov\/2023 07:11:10","end_date_raw":1700536862,"end_date":"21\/Nov\/2023 03:11:02","description":"Reprehenderit et esse qui hic quia est iusto.","billable":false,"duration":72772},{"start_date_raw":1700537162,"start_date":"21\/Nov\/2023 03:11:02","end_date_raw":1700592394,"end_date":"21\/Nov\/2023 18:11:34","description":"In est enim dolore nesciunt distinctio magni qui.","billable":true,"duration":55232},{"start_date_raw":1700592694,"start_date":"21\/Nov\/2023 18:11:34","end_date_raw":1700635771,"end_date":"22\/Nov\/2023 06:11:31","description":"Est saepe quasi alias aut odit officiis corporis.","billable":true,"duration":43077},{"start_date_raw":1700636071,"start_date":"22\/Nov\/2023 06:11:31","end_date_raw":1700637953,"end_date":"22\/Nov\/2023 07:11:53","description":"Consequuntur ipsa ut voluptate accusamus quibusdam sint sed.","billable":false,"duration":1882},{"start_date_raw":1700638253,"start_date":"22\/Nov\/2023 07:11:53","end_date_raw":1700687668,"end_date":"22\/Nov\/2023 21:11:28","description":"Sunt similique error et nostrum reprehenderit dolor.","billable":false,"duration":49415},{"start_date_raw":1700687968,"start_date":"22\/Nov\/2023 21:11:28","end_date_raw":1700712068,"end_date":"23\/Nov\/2023 04:11:08","description":"Aut rerum quis fugiat nostrum facilis ut.","billable":false,"duration":24100},{"start_date_raw":1700712368,"start_date":"23\/Nov\/2023 04:11:08","end_date_raw":1700783951,"end_date":"23\/Nov\/2023 23:11:11","description":"Aut culpa omnis sint et quos quisquam sint.","billable":true,"duration":71583},{"start_date_raw":1700784251,"start_date":"24\/Nov\/2023 00:11:11","end_date_raw":1700845166,"end_date":"24\/Nov\/2023 16:11:26","description":"Voluptas ut ratione porro eaque iste voluptas.","billable":true,"duration":60915},{"start_date_raw":1700845466,"start_date":"24\/Nov\/2023 17:11:26","end_date_raw":1700857102,"end_date":"24\/Nov\/2023 20:11:22","description":"Qui ipsa minus sed saepe maiores necessitatibus.","billable":true,"duration":11636}],"custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","status":"Done","user":{"name":"Laron Weissnat Danika Flatley","email":"small@example.com"},"client":{"name":"Walsh-Considine","balance":"0.000000","payment_balance":"0.000000","credit_balance":"1960.450000","currency":"USD"}},{"number":"0011","description":"Eligendi molestiae et quis et tempora esse ut. Sed ut est possimus et minus aut incidunt. Quibusdam rerum incidunt molestias est qui quam temporibus fuga.","duration":637522,"rate":"$120.00","rate_raw":"120.000000","created_at":"19\/Nov\/2023","updated_at":"19\/Nov\/2023","date":"19\/Nov\/2023","project":{"name":"Mr. Easton Streich","number":"0003","created_at":"19\/Nov\/2023","updated_at":"19\/Nov\/2023","task_rate":"$153.00","task_rate_raw":"153.000000","due_date":"28\/Nov\/2023","private_notes":"","public_notes":"Debitis sit ut voluptatem eaque veritatis.","budgeted_hours":216,"custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","color":"#fff","current_hours":496,"tasks":[],"client":{"name":"Walsh-Considine","balance":"0.000000","payment_balance":"0.000000","credit_balance":"1960.450000","currency":"USD"},"user":{"name":"Laron Weissnat Danika Flatley","email":"small@example.com"}},"time_log":[{"start_date_raw":1700428468,"start_date":"19\/Nov\/2023 21:11:28","end_date_raw":1700499282,"end_date":"20\/Nov\/2023 16:11:42","description":"Quasi temporibus doloremque consequatur minus pariatur facere.","billable":true,"duration":70814},{"start_date_raw":1700499582,"start_date":"20\/Nov\/2023 16:11:42","end_date_raw":1700584386,"end_date":"21\/Nov\/2023 16:11:06","description":"Id distinctio sed eos qui.","billable":true,"duration":84804},{"start_date_raw":1700584686,"start_date":"21\/Nov\/2023 16:11:06","end_date_raw":1700635554,"end_date":"22\/Nov\/2023 06:11:54","description":"Facere explicabo non nostrum.","billable":true,"duration":50868},{"start_date_raw":1700635854,"start_date":"22\/Nov\/2023 06:11:54","end_date_raw":1700672533,"end_date":"22\/Nov\/2023 17:11:13","description":"Numquam sit labore facere voluptatibus quibusdam reiciendis et.","billable":true,"duration":36679},{"start_date_raw":1700672833,"start_date":"22\/Nov\/2023 17:11:13","end_date_raw":1700678587,"end_date":"22\/Nov\/2023 18:11:07","description":"Perspiciatis ad hic nostrum et.","billable":true,"duration":5754},{"start_date_raw":1700678887,"start_date":"22\/Nov\/2023 18:11:07","end_date_raw":1700708730,"end_date":"23\/Nov\/2023 03:11:30","description":"Qui culpa iure eos quaerat voluptatum numquam inventore.","billable":true,"duration":29843},{"start_date_raw":1700709030,"start_date":"23\/Nov\/2023 03:11:30","end_date_raw":1700765439,"end_date":"23\/Nov\/2023 18:11:39","description":"Similique molestiae atque voluptatem debitis dolorem quos quis et.","billable":false,"duration":56409},{"start_date_raw":1700765739,"start_date":"23\/Nov\/2023 18:11:39","end_date_raw":1700831780,"end_date":"24\/Nov\/2023 13:11:20","description":"Nam dolorum optio et omnis.","billable":true,"duration":66041},{"start_date_raw":1700832080,"start_date":"24\/Nov\/2023 13:11:20","end_date_raw":1700844498,"end_date":"24\/Nov\/2023 16:11:18","description":"Non eos amet repellat tempore id.","billable":false,"duration":12418},{"start_date_raw":1700844798,"start_date":"24\/Nov\/2023 16:11:18","end_date_raw":1700899153,"end_date":"25\/Nov\/2023 07:11:13","description":"Iste neque nostrum laudantium officia.","billable":false,"duration":54355},{"start_date_raw":1700899453,"start_date":"25\/Nov\/2023 08:11:13","end_date_raw":1700971949,"end_date":"26\/Nov\/2023 04:11:29","description":"Ut quia ratione sed et.","billable":true,"duration":72496},{"start_date_raw":1700972249,"start_date":"26\/Nov\/2023 04:11:29","end_date_raw":1700984833,"end_date":"26\/Nov\/2023 07:11:13","description":"Sapiente quia magni quisquam eos rerum rem.","billable":false,"duration":12584},{"start_date_raw":1700985133,"start_date":"26\/Nov\/2023 07:11:13","end_date_raw":1701069590,"end_date":"27\/Nov\/2023 07:11:50","description":"Nulla et ducimus doloribus est.","billable":true,"duration":84457}],"custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","status":"Done","user":{"name":"Laron Weissnat Danika Flatley","email":"small@example.com"},"client":{"name":"Walsh-Considine","balance":"0.000000","payment_balance":"0.000000","credit_balance":"1960.450000","currency":"USD"}},{"number":"0012","description":"Ea cumque amet quas et suscipit. Voluptatum libero enim minus necessitatibus qui voluptatem. Voluptates soluta quae in et aut possimus veniam.","duration":283580,"rate":"$78.00","rate_raw":"78.000000","created_at":"19\/Nov\/2023","updated_at":"19\/Nov\/2023","date":"19\/Nov\/2023","project":{"name":"Mr. Easton Streich","number":"0003","created_at":"19\/Nov\/2023","updated_at":"19\/Nov\/2023","task_rate":"$153.00","task_rate_raw":"153.000000","due_date":"28\/Nov\/2023","private_notes":"","public_notes":"Debitis sit ut voluptatem eaque veritatis.","budgeted_hours":216,"custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","color":"#fff","current_hours":496,"tasks":[],"client":{"name":"Walsh-Considine","balance":"0.000000","payment_balance":"0.000000","credit_balance":"1960.450000"},"user":{"name":"Laron Weissnat Danika Flatley","email":"small@example.com"}},"time_log":[{"start_date_raw":1700428468,"start_date":"19\/Nov\/2023 21:11:28","end_date_raw":1700469690,"end_date":"20\/Nov\/2023 08:11:30","description":"Placeat vel sit voluptas architecto sed.","billable":true,"duration":41222},{"start_date_raw":1700469990,"start_date":"20\/Nov\/2023 08:11:30","end_date_raw":1700483859,"end_date":"20\/Nov\/2023 12:11:39","description":"Voluptatem est quo est dolorem.","billable":true,"duration":13869},{"start_date_raw":1700484159,"start_date":"20\/Nov\/2023 12:11:39","end_date_raw":1700541376,"end_date":"21\/Nov\/2023 04:11:16","description":"Perferendis nulla quos omnis inventore sint.","billable":false,"duration":57217},{"start_date_raw":1700541676,"start_date":"21\/Nov\/2023 04:11:16","end_date_raw":1700609280,"end_date":"21\/Nov\/2023 23:11:00","description":"Quia quae ad cum neque.","billable":true,"duration":67604},{"start_date_raw":1700609580,"start_date":"21\/Nov\/2023 23:11:00","end_date_raw":1700668490,"end_date":"22\/Nov\/2023 15:11:50","description":"Pariatur et ipsa cumque consequatur voluptatum nemo.","billable":true,"duration":58910},{"start_date_raw":1700668790,"start_date":"22\/Nov\/2023 15:11:50","end_date_raw":1700690815,"end_date":"22\/Nov\/2023 22:11:55","description":"Officia explicabo illo ex tenetur.","billable":true,"duration":22025},{"start_date_raw":1700691115,"start_date":"22\/Nov\/2023 22:11:55","end_date_raw":1700713848,"end_date":"23\/Nov\/2023 04:11:48","description":"Quasi neque tempore aut at.","billable":true,"duration":22733}],"custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","status":"Ready to do","user":{"name":"Laron Weissnat Danika Flatley","email":"small@example.com"},"client":{"name":"Walsh-Considine","balance":"0.000000","payment_balance":"0.000000","credit_balance":"1960.450000","currency":"USD"}},{"number":"0013","description":"Enim eveniet rem illo sed voluptatem vero dolorem. Sed consequatur quia autem culpa. Sed perspiciatis ullam non.","duration":512814,"rate":"$145.00","rate_raw":"145.000000","created_at":"19\/Nov\/2023","updated_at":"19\/Nov\/2023","date":"19\/Nov\/2023","project":[],"time_log":[{"start_date_raw":1700428468,"start_date":"19\/Nov\/2023 21:11:28","end_date_raw":1700442008,"end_date":"20\/Nov\/2023 01:11:08","description":"Et et delectus in rerum fuga et ipsam.","billable":true,"duration":13540},{"start_date_raw":1700442308,"start_date":"20\/Nov\/2023 01:11:08","end_date_raw":1700488304,"end_date":"20\/Nov\/2023 13:11:44","description":"In porro et sed eos.","billable":true,"duration":45996},{"start_date_raw":1700488604,"start_date":"20\/Nov\/2023 13:11:44","end_date_raw":1700529328,"end_date":"21\/Nov\/2023 01:11:28","description":"Eveniet similique sint minima voluptatibus voluptatem sunt.","billable":false,"duration":40724},{"start_date_raw":1700529628,"start_date":"21\/Nov\/2023 01:11:28","end_date_raw":1700560989,"end_date":"21\/Nov\/2023 10:11:09","description":"Ut est fuga id qui ut.","billable":false,"duration":31361},{"start_date_raw":1700561289,"start_date":"21\/Nov\/2023 10:11:09","end_date_raw":1700635644,"end_date":"22\/Nov\/2023 06:11:24","description":"Est consequatur nisi itaque.","billable":false,"duration":74355},{"start_date_raw":1700635944,"start_date":"22\/Nov\/2023 06:11:24","end_date_raw":1700650878,"end_date":"22\/Nov\/2023 11:11:18","description":"Ut vitae et velit magnam aut sed ut.","billable":true,"duration":14934},{"start_date_raw":1700651178,"start_date":"22\/Nov\/2023 11:11:18","end_date_raw":1700672376,"end_date":"22\/Nov\/2023 16:11:36","description":"Id odio laudantium quae similique.","billable":false,"duration":21198},{"start_date_raw":1700672676,"start_date":"22\/Nov\/2023 17:11:36","end_date_raw":1700734868,"end_date":"23\/Nov\/2023 10:11:08","description":"Saepe non vel reiciendis autem quidem quos.","billable":true,"duration":62192},{"start_date_raw":1700735168,"start_date":"23\/Nov\/2023 10:11:08","end_date_raw":1700772446,"end_date":"23\/Nov\/2023 20:11:26","description":"Occaecati commodi cupiditate esse molestiae velit.","billable":true,"duration":37278},{"start_date_raw":1700772746,"start_date":"23\/Nov\/2023 20:11:26","end_date_raw":1700785864,"end_date":"24\/Nov\/2023 00:11:04","description":"Quia et cupiditate expedita cumque quas.","billable":true,"duration":13118},{"start_date_raw":1700786164,"start_date":"24\/Nov\/2023 00:11:04","end_date_raw":1700806681,"end_date":"24\/Nov\/2023 06:11:01","description":"Eos consequatur soluta labore soluta ut.","billable":true,"duration":20517},{"start_date_raw":1700806981,"start_date":"24\/Nov\/2023 06:11:01","end_date_raw":1700839054,"end_date":"24\/Nov\/2023 15:11:34","description":"Impedit vel pariatur dicta necessitatibus at harum eius.","billable":true,"duration":32073},{"start_date_raw":1700839354,"start_date":"24\/Nov\/2023 15:11:34","end_date_raw":1700866888,"end_date":"24\/Nov\/2023 23:11:28","description":"Laboriosam nihil veritatis voluptatum qui laboriosam iusto.","billable":true,"duration":27534},{"start_date_raw":1700867188,"start_date":"24\/Nov\/2023 23:11:28","end_date_raw":1700875021,"end_date":"25\/Nov\/2023 01:11:01","description":"Error accusamus sapiente reiciendis.","billable":true,"duration":7833},{"start_date_raw":1700875321,"start_date":"25\/Nov\/2023 01:11:01","end_date_raw":1700886769,"end_date":"25\/Nov\/2023 04:11:49","description":"Impedit eius consequatur quod qui quod expedita quis.","billable":false,"duration":11448},{"start_date_raw":1700887069,"start_date":"25\/Nov\/2023 04:11:49","end_date_raw":1700945782,"end_date":"25\/Nov\/2023 20:11:22","description":"Tempora omnis nesciunt placeat omnis architecto quis.","billable":true,"duration":58713}],"custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","status":"Done","user":{"name":"Laron Weissnat Danika Flatley","email":"small@example.com"},"client":{"name":"Hoeger, Hahn and Cole","balance":"0.000000","payment_balance":"0.000000","credit_balance":"1022.550000","vat_number":"VAT123"}},{"number":"0014","description":"In soluta aliquid et eius. Molestiae veritatis animi culpa et amet porro modi ut. Id sequi nobis itaque modi explicabo voluptatem quam. Non ex voluptatem error aspernatur odit.","duration":346244,"rate":"$70.00","rate_raw":"70.000000","created_at":"19\/Nov\/2023","updated_at":"19\/Nov\/2023","date":"19\/Nov\/2023","project":{"name":"Elenor Orn","number":"0004","created_at":"19\/Nov\/2023","updated_at":"19\/Nov\/2023","task_rate":"$39.00","task_rate_raw":"39.000000","due_date":"27\/Nov\/2023","private_notes":"","public_notes":"Distinctio ut voluptas deleniti est sed quae.","budgeted_hours":372,"custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","color":"#fff","current_hours":331,"tasks":[],"client":{"name":"Walsh-Considine","balance":"0.000000","payment_balance":"0.000000","credit_balance":"1960.450000"},"user":{"name":"Laron Weissnat Danika Flatley","email":"small@example.com"}},"time_log":[{"start_date_raw":1700428468,"start_date":"19\/Nov\/2023 21:11:28","end_date_raw":1700458211,"end_date":"20\/Nov\/2023 05:11:11","description":"Voluptate aut dicta recusandae consectetur est ducimus.","billable":false,"duration":29743},{"start_date_raw":1700458511,"start_date":"20\/Nov\/2023 05:11:11","end_date_raw":1700516247,"end_date":"20\/Nov\/2023 21:11:27","description":"Dolores incidunt praesentium rerum.","billable":false,"duration":57736},{"start_date_raw":1700516547,"start_date":"20\/Nov\/2023 21:11:27","end_date_raw":1700549251,"end_date":"21\/Nov\/2023 06:11:31","description":"Perspiciatis consequatur et alias praesentium placeat modi aut.","billable":true,"duration":32704},{"start_date_raw":1700549551,"start_date":"21\/Nov\/2023 06:11:31","end_date_raw":1700618445,"end_date":"22\/Nov\/2023 02:11:45","description":"Esse libero incidunt non rem sunt quisquam repudiandae nisi.","billable":true,"duration":68894},{"start_date_raw":1700618745,"start_date":"22\/Nov\/2023 02:11:45","end_date_raw":1700698086,"end_date":"23\/Nov\/2023 00:11:06","description":"Earum consectetur esse fugit sint autem tempore.","billable":true,"duration":79341},{"start_date_raw":1700698386,"start_date":"23\/Nov\/2023 00:11:06","end_date_raw":1700776212,"end_date":"23\/Nov\/2023 21:11:12","description":"Saepe sit consequatur vel eos ad iusto nobis.","billable":true,"duration":77826}],"custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","status":"Ready to do","user":{"name":"Laron Weissnat Danika Flatley","email":"small@example.com"},"client":{"name":"Walsh-Considine","balance":"0.000000","payment_balance":"0.000000","credit_balance":"1960.450000"}},{"number":"0015","description":"Minus accusamus illum quia nihil voluptatum qui mollitia vel. Natus fugiat sequi quod eius occaecati non. Minus rerum ut eos est eveniet quae iure.","duration":410859,"rate":"$13.00","rate_raw":"13.000000","created_at":"19\/Nov\/2023","updated_at":"19\/Nov\/2023","date":"19\/Nov\/2023","project":{"name":"Elenor Orn","number":"0004","created_at":"19\/Nov\/2023","updated_at":"19\/Nov\/2023","task_rate":"$39.00","task_rate_raw":"39.000000","due_date":"27\/Nov\/2023","private_notes":"","public_notes":"Distinctio ut voluptas deleniti est sed quae.","budgeted_hours":372,"custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","color":"#fff","current_hours":331,"tasks":[],"client":{"name":"Walsh-Considine","balance":"0.000000","payment_balance":"0.000000","credit_balance":"1960.450000"},"user":{"name":"Laron Weissnat Danika Flatley","email":"small@example.com"}},"time_log":[{"start_date_raw":1700428468,"start_date":"19\/Nov\/2023 21:11:28","end_date_raw":1700506053,"end_date":"20\/Nov\/2023 18:11:33","description":"Iste neque officiis eum maiores.","billable":true,"duration":77585},{"start_date_raw":1700506353,"start_date":"20\/Nov\/2023 18:11:33","end_date_raw":1700572042,"end_date":"21\/Nov\/2023 13:11:22","description":"Minus perferendis quia amet.","billable":true,"duration":65689},{"start_date_raw":1700572342,"start_date":"21\/Nov\/2023 13:11:22","end_date_raw":1700637291,"end_date":"22\/Nov\/2023 07:11:51","description":"Commodi quaerat hic minus et voluptas velit.","billable":true,"duration":64949},{"start_date_raw":1700637591,"start_date":"22\/Nov\/2023 07:11:51","end_date_raw":1700649610,"end_date":"22\/Nov\/2023 10:11:10","description":"Vitae rerum natus aperiam quia explicabo.","billable":false,"duration":12019},{"start_date_raw":1700649910,"start_date":"22\/Nov\/2023 10:11:10","end_date_raw":1700693674,"end_date":"22\/Nov\/2023 22:11:34","description":"Quos sunt dolorum eveniet provident ut.","billable":false,"duration":43764},{"start_date_raw":1700693974,"start_date":"22\/Nov\/2023 22:11:34","end_date_raw":1700775335,"end_date":"23\/Nov\/2023 21:11:35","description":"Animi quibusdam quisquam ea error earum consectetur.","billable":true,"duration":81361},{"start_date_raw":1700775635,"start_date":"23\/Nov\/2023 21:11:35","end_date_raw":1700808126,"end_date":"24\/Nov\/2023 06:11:06","description":"Ratione ipsam molestiae dolorem sit architecto voluptas.","billable":true,"duration":32491},{"start_date_raw":1700808426,"start_date":"24\/Nov\/2023 06:11:06","end_date_raw":1700817758,"end_date":"24\/Nov\/2023 09:11:38","description":"Maxime reprehenderit voluptates culpa.","billable":false,"duration":9332},{"start_date_raw":1700818058,"start_date":"24\/Nov\/2023 09:11:38","end_date_raw":1700841727,"end_date":"24\/Nov\/2023 16:11:07","description":"Atque deleniti et laboriosam molestias repellat accusamus omnis.","billable":false,"duration":23669}],"custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","status":"Backlog","user":{"name":"Laron Weissnat Danika Flatley","email":"small@example.com"},"client":{"name":"Walsh-Considine","balance":"0.000000","payment_balance":"0.000000","credit_balance":"1960.450000"}},{"number":"0016","description":"Temporibus illum voluptatibus molestias quia omnis illo molestias corporis. Hic et hic quia dolores quas sint dolorem. Repellendus minus quae fuga illum amet in voluptatum. Rerum mollitia est eum voluptatum architecto non nisi qui. Est et dolores omnis placeat repellat sed facilis.","duration":435319,"rate":"$89.00","rate_raw":"89.000000","created_at":"19\/Nov\/2023","updated_at":"19\/Nov\/2023","date":"19\/Nov\/2023","project":{"name":"Elenor Orn","number":"0004","created_at":"19\/Nov\/2023","updated_at":"19\/Nov\/2023","task_rate":"$39.00","task_rate_raw":"39.000000","due_date":"27\/Nov\/2023","private_notes":"","public_notes":"Distinctio ut voluptas deleniti est sed quae.","budgeted_hours":372,"custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","color":"#fff","current_hours":331,"tasks":[],"client":{"name":"Walsh-Considine","balance":"0.000000","payment_balance":"0.000000","credit_balance":"1960.450000"},"user":{"name":"Laron Weissnat Danika Flatley","email":"small@example.com"}},"time_log":[{"start_date_raw":1700428469,"start_date":"19\/Nov\/2023 21:11:29","end_date_raw":1700496403,"end_date":"20\/Nov\/2023 16:11:43","description":"Sunt unde repellat reiciendis quos porro et dolores.","billable":true,"duration":67934},{"start_date_raw":1700496703,"start_date":"20\/Nov\/2023 16:11:43","end_date_raw":1700551129,"end_date":"21\/Nov\/2023 07:11:49","description":"Voluptatem laborum repudiandae enim asperiores.","billable":false,"duration":54426},{"start_date_raw":1700551429,"start_date":"21\/Nov\/2023 07:11:49","end_date_raw":1700631865,"end_date":"22\/Nov\/2023 05:11:25","description":"Placeat numquam magnam occaecati.","billable":false,"duration":80436},{"start_date_raw":1700632165,"start_date":"22\/Nov\/2023 05:11:25","end_date_raw":1700695854,"end_date":"22\/Nov\/2023 23:11:54","description":"Qui quo et est vero autem reprehenderit.","billable":false,"duration":63689},{"start_date_raw":1700696154,"start_date":"22\/Nov\/2023 23:11:54","end_date_raw":1700736857,"end_date":"23\/Nov\/2023 10:11:17","description":"Et voluptatem distinctio dolor fuga hic ea.","billable":false,"duration":40703},{"start_date_raw":1700737157,"start_date":"23\/Nov\/2023 10:11:17","end_date_raw":1700790692,"end_date":"24\/Nov\/2023 01:11:32","description":"Quo expedita quidem ab dolor quam expedita porro.","billable":true,"duration":53535},{"start_date_raw":1700790992,"start_date":"24\/Nov\/2023 01:11:32","end_date_raw":1700817527,"end_date":"24\/Nov\/2023 09:11:47","description":"Adipisci voluptatem officiis quaerat ut quos facilis.","billable":false,"duration":26535},{"start_date_raw":1700817827,"start_date":"24\/Nov\/2023 09:11:47","end_date_raw":1700865888,"end_date":"24\/Nov\/2023 22:11:48","description":"Tenetur ut dolorem vero.","billable":true,"duration":48061}],"custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","status":"Done","user":{"name":"Laron Weissnat Danika Flatley","email":"small@example.com"},"client":{"name":"Walsh-Considine","balance":"0.000000","payment_balance":"0.000000","credit_balance":"1960.450000"}},{"number":"0017","description":"Repudiandae nam labore dolores nihil sunt dolorem recusandae rerum. Ut consequatur vel et aut facilis. Sapiente distinctio cupiditate qui repellat ipsum harum.","duration":835159,"rate":"$65.00","rate_raw":"65.000000","created_at":"19\/Nov\/2023","updated_at":"19\/Nov\/2023","date":"19\/Nov\/2023","project":[],"time_log":[{"start_date_raw":1700428469,"start_date":"19\/Nov\/2023 21:11:29","end_date_raw":1700448921,"end_date":"20\/Nov\/2023 02:11:21","description":"Veniam iusto aperiam quis sunt nihil qui neque.","billable":true,"duration":20452},{"start_date_raw":1700449221,"start_date":"20\/Nov\/2023 03:11:21","end_date_raw":1700480544,"end_date":"20\/Nov\/2023 11:11:24","description":"Molestiae vero ea quis numquam et dicta reprehenderit.","billable":true,"duration":31323},{"start_date_raw":1700480844,"start_date":"20\/Nov\/2023 11:11:24","end_date_raw":1700513241,"end_date":"20\/Nov\/2023 20:11:21","description":"Qui id accusantium eius esse pariatur qui.","billable":false,"duration":32397},{"start_date_raw":1700513541,"start_date":"20\/Nov\/2023 20:11:21","end_date_raw":1700579256,"end_date":"21\/Nov\/2023 15:11:36","description":"Unde porro perspiciatis dolor praesentium dolor.","billable":true,"duration":65715},{"start_date_raw":1700579556,"start_date":"21\/Nov\/2023 15:11:36","end_date_raw":1700631702,"end_date":"22\/Nov\/2023 05:11:42","description":"Laboriosam eligendi deserunt veritatis impedit ipsum rerum voluptas.","billable":false,"duration":52146},{"start_date_raw":1700632002,"start_date":"22\/Nov\/2023 05:11:42","end_date_raw":1700687284,"end_date":"22\/Nov\/2023 21:11:04","description":"Molestiae sint a facere.","billable":true,"duration":55282},{"start_date_raw":1700687584,"start_date":"22\/Nov\/2023 21:11:04","end_date_raw":1700731618,"end_date":"23\/Nov\/2023 09:11:58","description":"Asperiores in repudiandae eligendi sed eveniet sequi quae.","billable":false,"duration":44034},{"start_date_raw":1700731918,"start_date":"23\/Nov\/2023 09:11:58","end_date_raw":1700785496,"end_date":"24\/Nov\/2023 00:11:56","description":"Ratione quia rem odit ea doloremque et.","billable":true,"duration":53578},{"start_date_raw":1700785796,"start_date":"24\/Nov\/2023 00:11:56","end_date_raw":1700814699,"end_date":"24\/Nov\/2023 08:11:39","description":"Deserunt quam alias incidunt sit placeat tenetur.","billable":true,"duration":28903},{"start_date_raw":1700814999,"start_date":"24\/Nov\/2023 08:11:39","end_date_raw":1700889011,"end_date":"25\/Nov\/2023 05:11:11","description":"Libero sed numquam quidem vel esse magni vel laudantium.","billable":false,"duration":74012},{"start_date_raw":1700889311,"start_date":"25\/Nov\/2023 05:11:11","end_date_raw":1700943511,"end_date":"25\/Nov\/2023 20:11:31","description":"Rerum aliquid aliquam error deleniti quo eaque.","billable":true,"duration":54200},{"start_date_raw":1700943811,"start_date":"25\/Nov\/2023 20:11:31","end_date_raw":1701013647,"end_date":"26\/Nov\/2023 15:11:27","description":"Quos vel est rerum nihil id.","billable":false,"duration":69836},{"start_date_raw":1701013947,"start_date":"26\/Nov\/2023 15:11:27","end_date_raw":1701099520,"end_date":"27\/Nov\/2023 15:11:40","description":"Cum quia maxime dignissimos quo.","billable":true,"duration":85573},{"start_date_raw":1701099820,"start_date":"27\/Nov\/2023 15:11:40","end_date_raw":1701163104,"end_date":"28\/Nov\/2023 09:11:24","description":"Amet ea exercitationem quo sed eos corporis.","billable":false,"duration":63284},{"start_date_raw":1701163404,"start_date":"28\/Nov\/2023 09:11:24","end_date_raw":1701220140,"end_date":"29\/Nov\/2023 01:11:00","description":"Sunt voluptas atque odio nesciunt aliquam in earum.","billable":true,"duration":56736},{"start_date_raw":1701220440,"start_date":"29\/Nov\/2023 01:11:00","end_date_raw":1701268128,"end_date":"29\/Nov\/2023 14:11:48","description":"Odio voluptatibus rerum non.","billable":false,"duration":47688}],"custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","status":"Backlog","user":{"name":"Laron Weissnat Danika Flatley","email":"small@example.com"},"client":{"name":"Hoeger, Hahn and Cole","balance":"0.000000","payment_balance":"0.000000","credit_balance":"1022.550000","vat_number":"VAT123"}},{"number":"0018","description":"Odit rerum iusto quibusdam. A mollitia cupiditate enim consequatur omnis qui voluptas quibusdam. Recusandae et non ut ipsum asperiores non iusto.","duration":312865,"rate":"$95.00","rate_raw":"95.000000","created_at":"19\/Nov\/2023","updated_at":"19\/Nov\/2023","date":"19\/Nov\/2023","project":{"name":"Maryjane Macejkovic","number":"0005","created_at":"19\/Nov\/2023","updated_at":"19\/Nov\/2023","task_rate":"$78.00","task_rate_raw":"78.000000","due_date":"26\/Nov\/2023","private_notes":"","public_notes":"Nesciunt est sit ea explicabo.","budgeted_hours":405,"custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","color":"#fff","current_hours":194,"tasks":[],"client":{"name":"Medhurst Inc","balance":"37633.780000","payment_balance":"0.000000","credit_balance":"1025.100000","currency":"USD"},"user":{"name":"Laron Weissnat Danika Flatley","email":"small@example.com"}},"time_log":[{"start_date_raw":1700428469,"start_date":"19\/Nov\/2023 21:11:29","end_date_raw":1700476677,"end_date":"20\/Nov\/2023 10:11:57","description":"Quam dolores ut dolorem quo sint atque.","billable":true,"duration":48208},{"start_date_raw":1700476977,"start_date":"20\/Nov\/2023 10:11:57","end_date_raw":1700520944,"end_date":"20\/Nov\/2023 22:11:44","description":"Unde minus veniam corporis qui laboriosam suscipit quas.","billable":true,"duration":43967},{"start_date_raw":1700521244,"start_date":"20\/Nov\/2023 23:11:44","end_date_raw":1700602639,"end_date":"21\/Nov\/2023 21:11:19","description":"Beatae molestiae molestias sed dolor recusandae et id eligendi.","billable":false,"duration":81395},{"start_date_raw":1700602939,"start_date":"21\/Nov\/2023 21:11:19","end_date_raw":1700682077,"end_date":"22\/Nov\/2023 19:11:17","description":"Repellendus nam perspiciatis exercitationem in iste officia.","billable":true,"duration":79138},{"start_date_raw":1700682377,"start_date":"22\/Nov\/2023 19:11:17","end_date_raw":1700692054,"end_date":"22\/Nov\/2023 22:11:34","description":"Consequatur quaerat dolor consequuntur aperiam enim reiciendis.","billable":true,"duration":9677},{"start_date_raw":1700692354,"start_date":"22\/Nov\/2023 22:11:34","end_date_raw":1700742834,"end_date":"23\/Nov\/2023 12:11:54","description":"Qui quia ut sed accusantium odit reprehenderit quaerat.","billable":true,"duration":50480}],"custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","status":"Backlog","user":{"name":"Laron Weissnat Danika Flatley","email":"small@example.com"},"client":{"name":"Medhurst Inc","balance":"37633.780000","payment_balance":"0.000000","credit_balance":"1025.100000","currency":"USD"}},{"number":"0019","description":"Eius et dolor libero repellendus iste. Nemo sit error sed necessitatibus architecto et. Aspernatur omnis doloremque animi quas sed.","duration":387217,"rate":"$87.00","rate_raw":"87.000000","created_at":"19\/Nov\/2023","updated_at":"19\/Nov\/2023","date":"19\/Nov\/2023","project":{"name":"Maryjane Macejkovic","number":"0005","created_at":"19\/Nov\/2023","updated_at":"19\/Nov\/2023","task_rate":"$78.00","task_rate_raw":"78.000000","due_date":"26\/Nov\/2023","private_notes":"","public_notes":"Nesciunt est sit ea explicabo.","budgeted_hours":405,"custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","color":"#fff","current_hours":194,"tasks":[],"client":{"name":"Medhurst Inc","balance":"37633.780000","payment_balance":"0.000000","credit_balance":"1025.100000","currency":"USD"},"user":{"name":"Laron Weissnat Danika Flatley","email":"small@example.com"}},"time_log":[{"start_date_raw":1700428469,"start_date":"19\/Nov\/2023 21:11:29","end_date_raw":1700434042,"end_date":"19\/Nov\/2023 22:11:22","description":"Aut aliquam totam in reprehenderit sint suscipit earum.","billable":false,"duration":5573},{"start_date_raw":1700434342,"start_date":"19\/Nov\/2023 22:11:22","end_date_raw":1700467844,"end_date":"20\/Nov\/2023 08:11:44","description":"Hic aliquid natus est.","billable":false,"duration":33502},{"start_date_raw":1700468144,"start_date":"20\/Nov\/2023 08:11:44","end_date_raw":1700532877,"end_date":"21\/Nov\/2023 02:11:37","description":"Illo atque dolores eligendi minus et ut consequuntur.","billable":false,"duration":64733},{"start_date_raw":1700533177,"start_date":"21\/Nov\/2023 02:11:37","end_date_raw":1700619369,"end_date":"22\/Nov\/2023 02:11:09","description":"Libero ipsa eligendi sit dolor eligendi quibusdam dicta tenetur.","billable":false,"duration":86192},{"start_date_raw":1700619669,"start_date":"22\/Nov\/2023 02:11:09","end_date_raw":1700646879,"end_date":"22\/Nov\/2023 09:11:39","description":"Dolor unde assumenda blanditiis tenetur blanditiis ipsam quis.","billable":true,"duration":27210},{"start_date_raw":1700647179,"start_date":"22\/Nov\/2023 09:11:39","end_date_raw":1700704537,"end_date":"23\/Nov\/2023 01:11:37","description":"Reprehenderit possimus nisi recusandae.","billable":true,"duration":57358},{"start_date_raw":1700704837,"start_date":"23\/Nov\/2023 02:11:37","end_date_raw":1700733175,"end_date":"23\/Nov\/2023 09:11:55","description":"Aut saepe sint qui magni.","billable":false,"duration":28338},{"start_date_raw":1700733475,"start_date":"23\/Nov\/2023 09:11:55","end_date_raw":1700735626,"end_date":"23\/Nov\/2023 10:11:46","description":"Facere repellendus voluptas illo a.","billable":true,"duration":2151},{"start_date_raw":1700735926,"start_date":"23\/Nov\/2023 10:11:46","end_date_raw":1700769798,"end_date":"23\/Nov\/2023 20:11:18","description":"Voluptatem praesentium ipsum soluta earum.","billable":false,"duration":33872},{"start_date_raw":1700770098,"start_date":"23\/Nov\/2023 20:11:18","end_date_raw":1700818386,"end_date":"24\/Nov\/2023 09:11:06","description":"Dicta eum quis dicta quae.","billable":true,"duration":48288}],"custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","status":"Backlog","user":{"name":"Laron Weissnat Danika Flatley","email":"small@example.com"},"client":{"name":"Medhurst Inc","balance":"37633.780000","payment_balance":"0.000000","credit_balance":"1025.100000","currency":"USD"}}]'; - public string $invoice_data = '[{"amount":"$6,054.13","balance":"$0.00","amount_raw":"6054.13","balance_raw":"0.000000","number":"0015","discount":1,"po_number":"","date":"20\/Sep\/2023","last_sent_date":"","next_send_date":"","due_date":"","terms":"","public_notes":"","private_notes":"","uses_inclusive_taxes":false,"tax_name1":"","tax_rate1":0,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"total_taxes":"$444.13","total_taxes_raw":"444.130000","is_amount_discount":true,"footer":"","partial":"0.000000","partial_due_date":"","custom_value1":"1984-10-01","custom_value2":"no","custom_value3":"","custom_value4":"","custom_surcharge1":0,"custom_surcharge2":0,"custom_surcharge3":0,"custom_surcharge4":0,"exchange_rate":1,"custom_surcharge_tax1":false,"custom_surcharge_tax2":false,"custom_surcharge_tax3":false,"custom_surcharge_tax4":false,"line_items":[{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$981.75","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$46.75","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":981.75,"tax_amount_raw":46.75,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"","tax_rate1":0,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$935.00","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$0.00","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":935,"tax_amount_raw":0,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"GST","tax_rate1":10,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$1,028.50","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$93.50","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":1028.5,"tax_amount_raw":93.5,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"VAT","tax_rate1":17.5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$1,098.63","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$163.63","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":1098.63,"tax_amount_raw":163.63,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"GST","tax_rate1":10,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$1,028.50","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$93.50","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":1028.5,"tax_amount_raw":93.5,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$981.75","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$46.75","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":981.75,"tax_amount_raw":46.75,"product_cost_raw":0}],"reminder1_sent":"","reminder2_sent":"","reminder3_sent":"","reminder_last_sent":"","paid_to_date":"$6,054.13","auto_bill_enabled":false,"client":{"name":"Lowe-Paucek","balance":"38124.670000","payment_balance":"0.000000","credit_balance":"2270.590000","currency":"USD"},"payments":[{"status":"Completed","badge":"
Completed<\/span><\/h6>","amount":"$6,054.13","applied":"$6,054.13","balance":"$0.00","refunded":"$0.00","amount_raw":"6054.130000","applied_raw":"6054.130000","refunded_raw":"0.000000","balance_raw":0,"date":"30\/Sep\/2023","method":"","currency":"USD","exchange_rate":1,"transaction_reference":"Manual entry","is_manual":1,"number":"0008","custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","client":{"name":"Lowe-Paucek","balance":"38124.670000","payment_balance":"0.000000","credit_balance":"2270.590000","currency":"USD"},"paymentables":[{"invoice":"0015","amount_raw":"6054.1300","refunded_raw":"0.0000","net_raw":6054.13,"amount":"$6,054.13","refunded":"$0.00","net":"$6,054.13","is_credit":false,"created_at":"01\/Oct\/2023","updated_at":"01\/Oct\/2023","timestamp":1696151008}]}],"total_tax_map":[{"name":"CA Sales Tax 5%","total":"$141.90","total_raw":141.9}],"line_tax_map":[{"name":"CA Sales Tax 5%","total":"$141.90","total_raw":141.9}]},{"amount":"$3,132.25","amount_raw":"3132.25","balance":"$0.00","balance_raw":"0.000000","number":"0016","discount":0,"po_number":"","date":"17\/Jul\/2023","last_sent_date":"","next_send_date":"","due_date":"","terms":"","public_notes":"","private_notes":"","uses_inclusive_taxes":false,"tax_name1":"","tax_rate1":0,"tax_name2":"","tax_rate2":0,"tax_name3":"CA Sales Tax","tax_rate3":5,"total_taxes":"$327.25","total_taxes_raw":"327.250000","is_amount_discount":true,"footer":"","partial":"0.000000","partial_due_date":"","custom_value1":"1990-05-13","custom_value2":"yes","custom_value3":"","custom_value4":"","custom_surcharge1":0,"custom_surcharge2":0,"custom_surcharge3":0,"custom_surcharge4":0,"exchange_rate":1,"custom_surcharge_tax1":false,"custom_surcharge_tax2":false,"custom_surcharge_tax3":false,"custom_surcharge_tax4":false,"line_items":[{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$981.75","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$46.75","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":981.75,"tax_amount_raw":46.75,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"GST","tax_rate1":10,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$1,028.50","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$93.50","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":1028.5,"tax_amount_raw":93.5,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$981.75","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$46.75","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":981.75,"tax_amount_raw":46.75,"product_cost_raw":0}],"reminder1_sent":"","reminder2_sent":"","reminder3_sent":"","reminder_last_sent":"","paid_to_date":"$3,132.25","auto_bill_enabled":false,"client":{"name":"cypress","balance":"0.000000","payment_balance":"0.000000","credit_balance":"11661.820000","currency":"USD"},"payments":[{"status":"Completed","badge":"
Completed<\/span><\/h6>","amount":"$3,132.25","applied":"$3,132.25","balance":"$0.00","refunded":"$0.00","amount_raw":"3132.250000","applied_raw":"3132.250000","refunded_raw":"0.000000","balance_raw":0,"date":"30\/Sep\/2023","method":"","currency":"USD","exchange_rate":1,"transaction_reference":"Manual entry","is_manual":1,"number":"0009","custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","client":{"name":"cypress","balance":"0.000000","payment_balance":"0.000000","credit_balance":"11661.820000","currency":"USD"},"paymentables":[{"invoice":"0016","amount_raw":"3132.2500","refunded_raw":"0.0000","net_raw":3132.25,"amount":"$3,132.25","refunded":"$0.00","net":"$3,132.25","is_credit":false,"created_at":"01\/Oct\/2023","updated_at":"01\/Oct\/2023","timestamp":1696151008}]}],"total_tax_map":[{"name":"CA Sales Tax 5%","total":"$141.90","total_raw":141.9}],"line_tax_map":[{"name":"CA Sales Tax 5%","total":"$141.90","total_raw":141.9}]},{"amount":"$9,396.77","amount_raw":"9396.77","balance":"$0.00","balance_raw":"0.000000","number":"0017","discount":0,"po_number":"","date":"04\/Sep\/2023","last_sent_date":"","next_send_date":"","due_date":"","terms":"","public_notes":"","private_notes":"","uses_inclusive_taxes":false,"tax_name1":"GST","tax_rate1":10,"tax_name2":"VAT","tax_rate2":17.5,"tax_name3":"CA Sales Tax","tax_rate3":5,"total_taxes":"$2,851.77","total_taxes_raw":"2851.770000","is_amount_discount":true,"footer":"","partial":"0.000000","partial_due_date":"","custom_value1":"1989-04-20","custom_value2":"yes","custom_value3":"","custom_value4":"","custom_surcharge1":0,"custom_surcharge2":0,"custom_surcharge3":0,"custom_surcharge4":0,"exchange_rate":1,"custom_surcharge_tax1":false,"custom_surcharge_tax2":false,"custom_surcharge_tax3":false,"custom_surcharge_tax4":false,"line_items":[{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$981.75","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$46.75","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":981.75,"tax_amount_raw":46.75,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"","tax_rate1":0,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$935.00","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$0.00","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":935,"tax_amount_raw":0,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"VAT","tax_rate1":17.5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$1,098.63","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$163.63","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":1098.63,"tax_amount_raw":163.63,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"GST","tax_rate1":10,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$1,028.50","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$93.50","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":1028.5,"tax_amount_raw":93.5,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"VAT","tax_rate1":17.5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$1,098.63","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$163.63","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":1098.63,"tax_amount_raw":163.63,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"GST","tax_rate1":10,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$1,028.50","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$93.50","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":1028.5,"tax_amount_raw":93.5,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"VAT","tax_rate1":17.5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$1,098.63","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$163.63","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":1098.63,"tax_amount_raw":163.63,"product_cost_raw":0}],"reminder1_sent":"","reminder2_sent":"","reminder3_sent":"","reminder_last_sent":"","paid_to_date":"$9,396.77","auto_bill_enabled":false,"client":{"name":"cypress","balance":"0.000000","payment_balance":"0.000000","credit_balance":"11661.820000","currency":"USD"},"payments":[{"status":"Completed","badge":"
Completed<\/span><\/h6>","amount":"$9,396.77","applied":"$9,396.77","balance":"$0.00","refunded":"$0.00","amount_raw":"9396.770000","applied_raw":"9396.770000","refunded_raw":"0.000000","balance_raw":0,"date":"30\/Sep\/2023","method":"","currency":"USD","exchange_rate":1,"transaction_reference":"Manual entry","is_manual":1,"number":"0010","custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","client":{"name":"cypress","balance":"0.000000","payment_balance":"0.000000","credit_balance":"11661.820000","currency":"USD"},"paymentables":[{"invoice":"0017","amount_raw":"9396.7700","refunded_raw":"0.0000","net_raw":9396.77,"amount":"$9,396.77","refunded":"$0.00","net":"$9,396.77","is_credit":false,"created_at":"01\/Oct\/2023","updated_at":"01\/Oct\/2023","timestamp":1696151008}]}],"total_tax_map":[{"name":"CA Sales Tax 5%","total":"$141.90","total_raw":141.9}],"line_tax_map":[{"name":"CA Sales Tax 5%","total":"$141.90","total_raw":141.9}]},{"amount":"$6,077.51","balance":"$0.00","amount_raw":"6077.51","balance_raw":"0.000000","number":"0019","discount":0,"po_number":"","date":"01\/Aug\/2023","last_sent_date":"","next_send_date":"","due_date":"","terms":"","public_notes":"","private_notes":"","uses_inclusive_taxes":false,"tax_name1":"","tax_rate1":0,"tax_name2":"VAT","tax_rate2":17.5,"tax_name3":"CA Sales Tax","tax_rate3":5,"total_taxes":"$1,402.51","total_taxes_raw":"1402.510000","is_amount_discount":true,"footer":"","partial":"0.000000","partial_due_date":"","custom_value1":"1992-08-20","custom_value2":"no","custom_value3":"","custom_value4":"","custom_surcharge1":0,"custom_surcharge2":0,"custom_surcharge3":0,"custom_surcharge4":0,"exchange_rate":1,"custom_surcharge_tax1":false,"custom_surcharge_tax2":false,"custom_surcharge_tax3":false,"custom_surcharge_tax4":false,"line_items":[{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$981.75","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$46.75","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":981.75,"tax_amount_raw":46.75,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"GST","tax_rate1":10,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$1,028.50","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$93.50","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":1028.5,"tax_amount_raw":93.5,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"VAT","tax_rate1":17.5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$1,098.63","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$163.63","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":1098.63,"tax_amount_raw":163.63,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$981.75","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$46.75","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":981.75,"tax_amount_raw":46.75,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"","tax_rate1":0,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$935.00","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$0.00","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":935,"tax_amount_raw":0,"product_cost_raw":0}],"reminder1_sent":"","reminder2_sent":"","reminder3_sent":"","reminder_last_sent":"","paid_to_date":"$6,077.51","auto_bill_enabled":false,"client":{"name":"cypress","balance":"0.000000","payment_balance":"0.000000","credit_balance":"11661.820000","currency":"USD"},"payments":[{"status":"Refunded","badge":"
Refunded<\/span><\/h6>","amount":"$6,077.51","applied":"$6,077.51","balance":"-$6,077.51","refunded":"$6,077.51","amount_raw":"6077.510000","applied_raw":"6077.510000","refunded_raw":"6077.510000","balance_raw":-6077.51,"date":"30\/Sep\/2023","method":"EuroCard","currency":"USD","exchange_rate":1,"transaction_reference":"Manual entry","is_manual":1,"number":"0001","custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","client":{"name":"cypress","balance":"0.000000","payment_balance":"0.000000","credit_balance":"11661.820000","currency":"USD"},"paymentables":[{"invoice":"0019","amount_raw":"6077.5100","refunded_raw":"6077.5100","net_raw":0,"amount":"$6,077.51","refunded":"$6,077.51","net":"$0.00","is_credit":false,"created_at":"01\/Oct\/2023","updated_at":"01\/Oct\/2023","timestamp":1696150843}]},{"status":"Completed","badge":"
Completed<\/span><\/h6>","amount":"$6,077.51","applied":"$6,077.51","balance":"$0.00","refunded":"$0.00","amount_raw":"6077.510000","applied_raw":"6077.510000","refunded_raw":"0.000000","balance_raw":0,"date":"30\/Sep\/2023","method":"","currency":"USD","exchange_rate":1,"transaction_reference":"Manual entry","is_manual":1,"number":"0011","custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","client":{"name":"cypress","balance":"0.000000","payment_balance":"0.000000","credit_balance":"11661.820000","currency":"USD"},"paymentables":[{"invoice":"0019","amount_raw":"6077.5100","refunded_raw":"0.0000","net_raw":6077.51,"amount":"$6,077.51","refunded":"$0.00","net":"$6,077.51","is_credit":false,"created_at":"01\/Oct\/2023","updated_at":"01\/Oct\/2023","timestamp":1696151008}]}],"total_tax_map":[{"name":"CA Sales Tax 5%","total":"$141.90","total_raw":141.9}],"line_tax_map":[{"name":"CA Sales Tax 5%","total":"$141.90","total_raw":141.9}]},{"amount":"$4,090.64","amount_raw":"4090.64","balance":"$0.00","balance_raw":"0.000000","number":"0020","discount":0,"po_number":"","date":"26\/Aug\/2023","last_sent_date":"","next_send_date":"","due_date":"","terms":"","public_notes":"","private_notes":"","uses_inclusive_taxes":false,"tax_name1":"GST","tax_rate1":10,"tax_name2":"VAT","tax_rate2":17.5,"tax_name3":"CA Sales Tax","tax_rate3":5,"total_taxes":"$1,285.64","total_taxes_raw":"1285.640000","is_amount_discount":true,"footer":"","partial":"0.000000","partial_due_date":"","custom_value1":"1979-06-26","custom_value2":"yes","custom_value3":"","custom_value4":"","custom_surcharge1":0,"custom_surcharge2":0,"custom_surcharge3":0,"custom_surcharge4":0,"exchange_rate":1,"custom_surcharge_tax1":false,"custom_surcharge_tax2":false,"custom_surcharge_tax3":false,"custom_surcharge_tax4":false,"line_items":[{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$981.75","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$46.75","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":981.75,"tax_amount_raw":46.75,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"VAT","tax_rate1":17.5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$1,098.63","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$163.63","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":1098.63,"tax_amount_raw":163.63,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"VAT","tax_rate1":17.5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$1,098.63","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$163.63","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":1098.63,"tax_amount_raw":163.63,"product_cost_raw":0}],"reminder1_sent":"","reminder2_sent":"","reminder3_sent":"","reminder_last_sent":"","paid_to_date":"$4,090.64","auto_bill_enabled":false,"client":{"name":"cypress","balance":"0.000000","payment_balance":"0.000000","credit_balance":"11661.820000","currency":"USD"},"payments":[{"status":"Refunded","badge":"
Refunded<\/span><\/h6>","amount":"$4,090.64","applied":"$4,090.64","balance":"-$4,090.64","refunded":"$4,090.64","amount_raw":"4090.640000","applied_raw":"4090.640000","refunded_raw":"4090.640000","balance_raw":-4090.64,"date":"30\/Sep\/2023","method":"Discover Card","currency":"USD","exchange_rate":1,"transaction_reference":"Manual entry","is_manual":1,"number":"0002","custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","client":{"name":"cypress","balance":"0.000000","payment_balance":"0.000000","credit_balance":"11661.820000","currency":"USD"},"paymentables":[{"invoice":"0020","amount_raw":"4090.6400","refunded_raw":"4090.6400","net_raw":0,"amount":"$4,090.64","refunded":"$4,090.64","net":"$0.00","is_credit":false,"created_at":"01\/Oct\/2023","updated_at":"01\/Oct\/2023","timestamp":1696150843}]},{"status":"Completed","badge":"
Completed<\/span><\/h6>","amount":"$4,090.64","applied":"$4,090.64","balance":"$0.00","refunded":"$0.00","amount_raw":"4090.640000","applied_raw":"4090.640000","refunded_raw":"0.000000","balance_raw":0,"date":"30\/Sep\/2023","method":"","currency":"USD","exchange_rate":1,"transaction_reference":"Manual entry","is_manual":1,"number":"0012","custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","client":{"name":"cypress","balance":"0.000000","payment_balance":"0.000000","credit_balance":"11661.820000","currency":"USD"},"paymentables":[{"invoice":"0020","amount_raw":"4090.6400","refunded_raw":"0.0000","net_raw":4090.64,"amount":"$4,090.64","refunded":"$0.00","net":"$4,090.64","is_credit":false,"created_at":"01\/Oct\/2023","updated_at":"01\/Oct\/2023","timestamp":1696151008}]}],"total_tax_map":[{"name":"CA Sales Tax 5%","total":"$141.90","total_raw":141.9}],"line_tax_map":[{"name":"CA Sales Tax 5%","total":"$141.90","total_raw":141.9}]},{"amount":"$2,197.26","amount_raw":"2197.26","balance":"$0.00","balance_raw":"0.000000","number":"0021","discount":0,"po_number":"","date":"08\/Sep\/2023","last_sent_date":"","next_send_date":"","due_date":"","terms":"","public_notes":"","private_notes":"","uses_inclusive_taxes":false,"tax_name1":"","tax_rate1":0,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"total_taxes":"$327.26","total_taxes_raw":"327.260000","is_amount_discount":true,"footer":"","partial":"0.000000","partial_due_date":"","custom_value1":"1980-11-12","custom_value2":"no","custom_value3":"","custom_value4":"","custom_surcharge1":0,"custom_surcharge2":0,"custom_surcharge3":0,"custom_surcharge4":0,"exchange_rate":1,"custom_surcharge_tax1":false,"custom_surcharge_tax2":false,"custom_surcharge_tax3":false,"custom_surcharge_tax4":false,"line_items":[{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"VAT","tax_rate1":17.5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$1,098.63","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$163.63","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":1098.63,"tax_amount_raw":163.63,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"VAT","tax_rate1":17.5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$1,098.63","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$163.63","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":1098.63,"tax_amount_raw":163.63,"product_cost_raw":0}],"reminder1_sent":"","reminder2_sent":"","reminder3_sent":"","reminder_last_sent":"","paid_to_date":"$2,197.26","auto_bill_enabled":false,"client":{"name":"Jakubowski Group","balance":"28296.170000","payment_balance":"0.000000","credit_balance":"1084.840000","currency":"USD"},"payments":[{"status":"Refunded","badge":"
Refunded<\/span><\/h6>","amount":"$2,197.26","applied":"$2,197.26","balance":"-$2,197.26","refunded":"$2,197.26","amount_raw":"2197.260000","applied_raw":"2197.260000","refunded_raw":"2197.260000","balance_raw":-2197.26,"date":"30\/Sep\/2023","method":"Diners Card","currency":"USD","exchange_rate":1,"transaction_reference":"Manual entry","is_manual":1,"number":"0003","custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","client":{"name":"Jakubowski Group","balance":"28296.170000","payment_balance":"0.000000","credit_balance":"1084.840000","currency":"USD"},"paymentables":[{"invoice":"0021","amount_raw":"2197.2600","refunded_raw":"2197.2600","net_raw":0,"amount":"$2,197.26","refunded":"$2,197.26","net":"$0.00","is_credit":false,"created_at":"01\/Oct\/2023","updated_at":"01\/Oct\/2023","timestamp":1696150843}]},{"status":"Completed","badge":"
Completed<\/span><\/h6>","amount":"$2,197.26","applied":"$2,197.26","balance":"$0.00","refunded":"$0.00","amount_raw":"2197.260000","applied_raw":"2197.260000","refunded_raw":"0.000000","balance_raw":0,"date":"30\/Sep\/2023","method":"","currency":"USD","exchange_rate":1,"transaction_reference":"Manual entry","is_manual":1,"number":"0013","custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","client":{"name":"Jakubowski Group","balance":"28296.170000","payment_balance":"0.000000","credit_balance":"1084.840000","currency":"USD"},"paymentables":[{"invoice":"0021","amount_raw":"2197.2600","refunded_raw":"0.0000","net_raw":2197.26,"amount":"$2,197.26","refunded":"$0.00","net":"$2,197.26","is_credit":false,"created_at":"01\/Oct\/2023","updated_at":"01\/Oct\/2023","timestamp":1696151008}]}],"total_tax_map":[{"name":"CA Sales Tax 5%","total":"$141.90","total_raw":141.9}],"line_tax_map":[{"name":"CA Sales Tax 5%","total":"$141.90","total_raw":141.9}]},{"amount":"$4,955.50","amount_raw":"4955.50","balance":"$66.00","balance_raw":"66.000000","number":"0022","discount":0,"po_number":"","date":"27\/Sep\/2023","last_sent_date":"","next_send_date":"","due_date":"","terms":"","public_notes":"","private_notes":"","uses_inclusive_taxes":false,"tax_name1":"GST","tax_rate1":10,"tax_name2":"VAT","tax_rate2":17.5,"tax_name3":"","tax_rate3":0,"total_taxes":"$1,215.50","total_taxes_raw":"1215.500000","is_amount_discount":true,"footer":"","partial":"0.000000","partial_due_date":"","custom_value1":"1999-08-20","custom_value2":"yes","custom_value3":"","custom_value4":"","custom_surcharge1":0,"custom_surcharge2":0,"custom_surcharge3":0,"custom_surcharge4":0,"exchange_rate":1,"custom_surcharge_tax1":false,"custom_surcharge_tax2":false,"custom_surcharge_tax3":false,"custom_surcharge_tax4":false,"line_items":[{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$981.75","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$46.75","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":981.75,"tax_amount_raw":46.75,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$981.75","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$46.75","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":981.75,"tax_amount_raw":46.75,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$981.75","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$46.75","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":981.75,"tax_amount_raw":46.75,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$981.75","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$46.75","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":981.75,"tax_amount_raw":46.75,"product_cost_raw":0}],"reminder1_sent":"","reminder2_sent":"","reminder3_sent":"","reminder_last_sent":"","paid_to_date":"$4,889.50","auto_bill_enabled":false,"client":{"name":"Jakubowski Group","balance":"28296.170000","payment_balance":"0.000000","credit_balance":"1084.840000","currency":"USD"},"payments":[{"status":"Partially Refunded","badge":"
Partially Refunded<\/span><\/h6>","amount":"$4,955.50","applied":"$4,955.50","balance":"-$66.00","refunded":"$66.00","amount_raw":"4955.500000","applied_raw":"4955.500000","refunded_raw":"66.000000","balance_raw":-66,"date":"30\/Sep\/2023","method":"Maestro","currency":"USD","exchange_rate":1,"transaction_reference":"Manual entry","is_manual":1,"number":"0004","custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","client":{"name":"Jakubowski Group","balance":"28296.170000","payment_balance":"0.000000","credit_balance":"1084.840000","currency":"USD"},"paymentables":[{"invoice":"0022","amount_raw":"4955.5000","refunded_raw":"66.0000","net_raw":4889.5,"amount":"$4,955.50","refunded":"$66.00","net":"$4,889.50","is_credit":false,"created_at":"01\/Oct\/2023","updated_at":"01\/Oct\/2023","timestamp":1696150843}]}],"total_tax_map":[{"name":"CA Sales Tax 5%","total":"$141.90","total_raw":141.9}],"line_tax_map":[{"name":"CA Sales Tax 5%","total":"$141.90","total_raw":141.9}]},{"amount":"$2,290.75","amount_raw":"2290.75","balance":"$34.00","balance_raw":"34.000000","number":"0023","discount":0,"po_number":"","date":"30\/Aug\/2023","last_sent_date":"","next_send_date":"","due_date":"","terms":"","public_notes":"","private_notes":"","uses_inclusive_taxes":false,"tax_name1":"","tax_rate1":0,"tax_name2":"VAT","tax_rate2":17.5,"tax_name3":"CA Sales Tax","tax_rate3":5,"total_taxes":"$420.75","total_taxes_raw":"420.750000","is_amount_discount":true,"footer":"","partial":"0.000000","partial_due_date":"","custom_value1":"2015-12-15","custom_value2":"no","custom_value3":"","custom_value4":"","custom_surcharge1":0,"custom_surcharge2":0,"custom_surcharge3":0,"custom_surcharge4":0,"exchange_rate":1,"custom_surcharge_tax1":false,"custom_surcharge_tax2":false,"custom_surcharge_tax3":false,"custom_surcharge_tax4":false,"line_items":[{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"","tax_rate1":0,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$935.00","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$0.00","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":935,"tax_amount_raw":0,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"","tax_rate1":0,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$935.00","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$0.00","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":935,"tax_amount_raw":0,"product_cost_raw":0}],"reminder1_sent":"","reminder2_sent":"","reminder3_sent":"","reminder_last_sent":"","paid_to_date":"$2,256.75","auto_bill_enabled":false,"client":{"name":"Jakubowski Group","balance":"28296.170000","payment_balance":"0.000000","credit_balance":"1084.840000","currency":"USD"},"payments":[{"status":"Partially Refunded","badge":"
Partially Refunded<\/span><\/h6>","amount":"$2,290.75","applied":"$2,290.75","balance":"-$34.00","refunded":"$34.00","amount_raw":"2290.750000","applied_raw":"2290.750000","refunded_raw":"34.000000","balance_raw":-34,"date":"30\/Sep\/2023","method":"Diners Card","currency":"USD","exchange_rate":1,"transaction_reference":"Manual entry","is_manual":1,"number":"0005","custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","client":{"name":"Jakubowski Group","balance":"28296.170000","payment_balance":"0.000000","credit_balance":"1084.840000","currency":"USD"},"paymentables":[{"invoice":"0023","amount_raw":"2290.7500","refunded_raw":"34.0000","net_raw":2256.75,"amount":"$2,290.75","refunded":"$34.00","net":"$2,256.75","is_credit":false,"created_at":"01\/Oct\/2023","updated_at":"01\/Oct\/2023","timestamp":1696150843}]}],"total_tax_map":[{"name":"CA Sales Tax 5%","total":"$141.90","total_raw":141.9}],"line_tax_map":[{"name":"CA Sales Tax 5%","total":"$141.90","total_raw":141.9}]},{"amount":"$6,802.13","amount_raw":"6802.13","balance":"$444.00","balance_raw":"444.000000","number":"0024","discount":0,"po_number":"","date":"25\/Jul\/2023","last_sent_date":"","next_send_date":"","due_date":"","terms":"","public_notes":"","private_notes":"","uses_inclusive_taxes":false,"tax_name1":"GST","tax_rate1":10,"tax_name2":"","tax_rate2":0,"tax_name3":"CA Sales Tax","tax_rate3":5,"total_taxes":"$1,192.13","total_taxes_raw":"1192.130000","is_amount_discount":true,"footer":"","partial":"0.000000","partial_due_date":"","custom_value1":"1990-07-11","custom_value2":"no","custom_value3":"","custom_value4":"","custom_surcharge1":0,"custom_surcharge2":0,"custom_surcharge3":0,"custom_surcharge4":0,"exchange_rate":1,"custom_surcharge_tax1":false,"custom_surcharge_tax2":false,"custom_surcharge_tax3":false,"custom_surcharge_tax4":false,"line_items":[{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"VAT","tax_rate1":17.5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$1,098.63","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$163.63","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":1098.63,"tax_amount_raw":163.63,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"","tax_rate1":0,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$935.00","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$0.00","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":935,"tax_amount_raw":0,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$981.75","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$46.75","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":981.75,"tax_amount_raw":46.75,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"","tax_rate1":0,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$935.00","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$0.00","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":935,"tax_amount_raw":0,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$981.75","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$46.75","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":981.75,"tax_amount_raw":46.75,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"GST","tax_rate1":10,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$1,028.50","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$93.50","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":1028.5,"tax_amount_raw":93.5,"product_cost_raw":0}],"reminder1_sent":"","reminder2_sent":"","reminder3_sent":"","reminder_last_sent":"","paid_to_date":"$6,358.13","auto_bill_enabled":false,"client":{"name":"Jakubowski Group","balance":"28296.170000","payment_balance":"0.000000","credit_balance":"1084.840000","currency":"USD"},"payments":[{"status":"Partially Refunded","badge":"
Partially Refunded<\/span><\/h6>","amount":"$6,802.13","applied":"$6,802.13","balance":"-$444.00","refunded":"$444.00","amount_raw":"6802.130000","applied_raw":"6802.130000","refunded_raw":"444.000000","balance_raw":-444,"date":"30\/Sep\/2023","method":"Maestro","currency":"USD","exchange_rate":1,"transaction_reference":"Manual entry","is_manual":1,"number":"0006","custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","client":{"name":"Jakubowski Group","balance":"28296.170000","payment_balance":"0.000000","credit_balance":"1084.840000","currency":"USD"},"paymentables":[{"invoice":"0024","amount_raw":"6802.1300","refunded_raw":"444.0000","net_raw":6358.13,"amount":"$6,802.13","refunded":"$444.00","net":"$6,358.13","is_credit":false,"created_at":"01\/Oct\/2023","updated_at":"01\/Oct\/2023","timestamp":1696150843}]}],"total_tax_map":[{"name":"CA Sales Tax 5%","total":"$141.90","total_raw":141.9}],"line_tax_map":[{"name":"CA Sales Tax 5%","total":"$141.90","total_raw":141.9}]},{"amount":"$10,986.26","amount_raw":"10986.26","balance":"$146.26","balance_raw":"146.260000","number":"0025","discount":0,"po_number":"","date":"23\/Jul\/2023","last_sent_date":"","next_send_date":"","due_date":"","terms":"","public_notes":"","private_notes":"","uses_inclusive_taxes":false,"tax_name1":"GST","tax_rate1":10,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"total_taxes":"$1,636.26","total_taxes_raw":"1636.260000","is_amount_discount":true,"footer":"","partial":"0.000000","partial_due_date":"","custom_value1":"1975-02-18","custom_value2":"no","custom_value3":"","custom_value4":"","custom_surcharge1":0,"custom_surcharge2":0,"custom_surcharge3":0,"custom_surcharge4":0,"exchange_rate":1,"custom_surcharge_tax1":false,"custom_surcharge_tax2":false,"custom_surcharge_tax3":false,"custom_surcharge_tax4":false,"line_items":[{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"VAT","tax_rate1":17.5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$1,098.63","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$163.63","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":1098.63,"tax_amount_raw":163.63,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"GST","tax_rate1":10,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$1,028.50","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$93.50","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":1028.5,"tax_amount_raw":93.5,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"","tax_rate1":0,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$935.00","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$0.00","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":935,"tax_amount_raw":0,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"","tax_rate1":0,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$935.00","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$0.00","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":935,"tax_amount_raw":0,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"VAT","tax_rate1":17.5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$1,098.63","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$163.63","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":1098.63,"tax_amount_raw":163.63,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$981.75","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$46.75","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":981.75,"tax_amount_raw":46.75,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$981.75","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$46.75","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":981.75,"tax_amount_raw":46.75,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$981.75","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$46.75","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":981.75,"tax_amount_raw":46.75,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$981.75","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$46.75","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":981.75,"tax_amount_raw":46.75,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"GST","tax_rate1":10,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$1,028.50","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$93.50","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":1028.5,"tax_amount_raw":93.5,"product_cost_raw":0}],"reminder1_sent":"","reminder2_sent":"","reminder3_sent":"","reminder_last_sent":"","paid_to_date":"$10,840.00","auto_bill_enabled":false,"client":{"name":"Jakubowski Group","balance":"28296.170000","payment_balance":"0.000000","credit_balance":"1084.840000","currency":"USD"},"payments":[{"status":"Partially Refunded","badge":"
Partially Refunded<\/span><\/h6>","amount":"$10,986.26","applied":"$10,986.26","balance":"-$146.26","refunded":"$146.26","amount_raw":"10986.260000","applied_raw":"10986.260000","refunded_raw":"146.260000","balance_raw":-146.26000000000022,"date":"30\/Sep\/2023","method":"UnionPay","currency":"USD","exchange_rate":1,"transaction_reference":"Manual entry","is_manual":1,"number":"0007","custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","client":{"name":"Jakubowski Group","balance":"28296.170000","payment_balance":"0.000000","credit_balance":"1084.840000","currency":"USD"},"paymentables":[{"invoice":"0025","amount_raw":"10986.2600","refunded_raw":"146.2600","net_raw":10840,"amount":"$10,986.26","refunded":"$146.26","net":"$10,840.00","is_credit":false,"created_at":"01\/Oct\/2023","updated_at":"01\/Oct\/2023","timestamp":1696150843}]}],"total_tax_map":[{"name":"CA Sales Tax 5%","total":"$141.90","total_raw":141.9}],"line_tax_map":[{"name":"CA Sales Tax 5%","total":"$141.90","total_raw":141.9}]}]'; + public string $invoice_data = '[{"amount":"$6,054.13","balance":"$0.00","amount_raw":"6054.13","balance_raw":"0.000000","number":"0015","discount":1,"po_number":"","date":"20\/Sep\/2023","last_sent_date":"","next_send_date":"","due_date":"","terms":"","public_notes":"","private_notes":"","uses_inclusive_taxes":false,"tax_name1":"","tax_rate1":0,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"total_taxes":"$444.13","total_taxes_raw":"444.130000","is_amount_discount":true,"footer":"","partial":"0.000000","partial_due_date":"","custom_value1":"1984-10-01","custom_value2":"no","custom_value3":"","custom_value4":"","custom_surcharge1":0,"custom_surcharge2":0,"custom_surcharge3":0,"custom_surcharge4":0,"exchange_rate":1,"custom_surcharge_tax1":false,"custom_surcharge_tax2":false,"custom_surcharge_tax3":false,"custom_surcharge_tax4":false,"line_items":[{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$981.75","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"2","product_cost":"$0.00","tax_amount":"$46.75","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":981.75,"tax_amount_raw":46.75,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$981.75","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"2","product_cost":"$0.00","tax_amount":"$46.75","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":981.75,"tax_amount_raw":46.75,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$981.75","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"2","product_cost":"$0.00","tax_amount":"$46.75","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":981.75,"tax_amount_raw":46.75,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$981.75","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$46.75","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":981.75,"tax_amount_raw":46.75,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"","tax_rate1":0,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$935.00","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$0.00","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":935,"tax_amount_raw":0,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"GST","tax_rate1":10,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$1,028.50","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$93.50","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":1028.5,"tax_amount_raw":93.5,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"VAT","tax_rate1":17.5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$1,098.63","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$163.63","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":1098.63,"tax_amount_raw":163.63,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"GST","tax_rate1":10,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$1,028.50","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$93.50","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":1028.5,"tax_amount_raw":93.5,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$981.75","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$46.75","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":981.75,"tax_amount_raw":46.75,"product_cost_raw":0}],"reminder1_sent":"","reminder2_sent":"","reminder3_sent":"","reminder_last_sent":"","paid_to_date":"$6,054.13","auto_bill_enabled":false,"client":{"name":"Lowe-Paucek","balance":"38124.670000","payment_balance":"0.000000","credit_balance":"2270.590000","currency":"USD"},"payments":[{"status":"Completed","badge":"
Completed<\/span><\/h6>","amount":"$6,054.13","applied":"$6,054.13","balance":"$0.00","refunded":"$0.00","amount_raw":"6054.130000","applied_raw":"6054.130000","refunded_raw":"0.000000","balance_raw":0,"date":"30\/Sep\/2023","method":"","currency":"USD","exchange_rate":1,"transaction_reference":"Manual entry","is_manual":1,"number":"0008","custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","client":{"name":"Lowe-Paucek","balance":"38124.670000","payment_balance":"0.000000","credit_balance":"2270.590000","currency":"USD"},"paymentables":[{"invoice":"0015","amount_raw":"6054.1300","refunded_raw":"0.0000","net_raw":6054.13,"amount":"$6,054.13","refunded":"$0.00","net":"$6,054.13","is_credit":false,"created_at":"01\/Oct\/2023","updated_at":"01\/Oct\/2023","timestamp":1696151008}]}],"total_tax_map":[{"name":"CA Sales Tax 5%","total":"$141.90","total_raw":141.9}],"line_tax_map":[{"name":"CA Sales Tax 5%","total":"$141.90","total_raw":141.9}]},{"amount":"$3,132.25","amount_raw":"3132.25","balance":"$0.00","balance_raw":"0.000000","number":"0016","discount":0,"po_number":"","date":"17\/Jul\/2023","last_sent_date":"","next_send_date":"","due_date":"","terms":"","public_notes":"","private_notes":"","uses_inclusive_taxes":false,"tax_name1":"","tax_rate1":0,"tax_name2":"","tax_rate2":0,"tax_name3":"CA Sales Tax","tax_rate3":5,"total_taxes":"$327.25","total_taxes_raw":"327.250000","is_amount_discount":true,"footer":"","partial":"0.000000","partial_due_date":"","custom_value1":"1990-05-13","custom_value2":"yes","custom_value3":"","custom_value4":"","custom_surcharge1":0,"custom_surcharge2":0,"custom_surcharge3":0,"custom_surcharge4":0,"exchange_rate":1,"custom_surcharge_tax1":false,"custom_surcharge_tax2":false,"custom_surcharge_tax3":false,"custom_surcharge_tax4":false,"line_items":[{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$981.75","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$46.75","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":981.75,"tax_amount_raw":46.75,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"GST","tax_rate1":10,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$1,028.50","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$93.50","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":1028.5,"tax_amount_raw":93.5,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$981.75","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$46.75","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":981.75,"tax_amount_raw":46.75,"product_cost_raw":0}],"reminder1_sent":"","reminder2_sent":"","reminder3_sent":"","reminder_last_sent":"","paid_to_date":"$3,132.25","auto_bill_enabled":false,"client":{"name":"cypress","balance":"0.000000","payment_balance":"0.000000","credit_balance":"11661.820000","currency":"USD"},"payments":[{"status":"Completed","badge":"
Completed<\/span><\/h6>","amount":"$3,132.25","applied":"$3,132.25","balance":"$0.00","refunded":"$0.00","amount_raw":"3132.250000","applied_raw":"3132.250000","refunded_raw":"0.000000","balance_raw":0,"date":"30\/Sep\/2023","method":"","currency":"USD","exchange_rate":1,"transaction_reference":"Manual entry","is_manual":1,"number":"0009","custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","client":{"name":"cypress","balance":"0.000000","payment_balance":"0.000000","credit_balance":"11661.820000","currency":"USD"},"paymentables":[{"invoice":"0016","amount_raw":"3132.2500","refunded_raw":"0.0000","net_raw":3132.25,"amount":"$3,132.25","refunded":"$0.00","net":"$3,132.25","is_credit":false,"created_at":"01\/Oct\/2023","updated_at":"01\/Oct\/2023","timestamp":1696151008}]}],"total_tax_map":[{"name":"CA Sales Tax 5%","total":"$141.90","total_raw":141.9}],"line_tax_map":[{"name":"CA Sales Tax 5%","total":"$141.90","total_raw":141.9}]},{"amount":"$9,396.77","amount_raw":"9396.77","balance":"$0.00","balance_raw":"0.000000","number":"0017","discount":0,"po_number":"","date":"04\/Sep\/2023","last_sent_date":"","next_send_date":"","due_date":"","terms":"","public_notes":"","private_notes":"","uses_inclusive_taxes":false,"tax_name1":"GST","tax_rate1":10,"tax_name2":"VAT","tax_rate2":17.5,"tax_name3":"CA Sales Tax","tax_rate3":5,"total_taxes":"$2,851.77","total_taxes_raw":"2851.770000","is_amount_discount":true,"footer":"","partial":"0.000000","partial_due_date":"","custom_value1":"1989-04-20","custom_value2":"yes","custom_value3":"","custom_value4":"","custom_surcharge1":0,"custom_surcharge2":0,"custom_surcharge3":0,"custom_surcharge4":0,"exchange_rate":1,"custom_surcharge_tax1":false,"custom_surcharge_tax2":false,"custom_surcharge_tax3":false,"custom_surcharge_tax4":false,"line_items":[{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$981.75","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$46.75","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":981.75,"tax_amount_raw":46.75,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"","tax_rate1":0,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$935.00","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$0.00","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":935,"tax_amount_raw":0,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"VAT","tax_rate1":17.5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$1,098.63","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$163.63","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":1098.63,"tax_amount_raw":163.63,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"GST","tax_rate1":10,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$1,028.50","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$93.50","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":1028.5,"tax_amount_raw":93.5,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"VAT","tax_rate1":17.5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$1,098.63","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$163.63","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":1098.63,"tax_amount_raw":163.63,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"GST","tax_rate1":10,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$1,028.50","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$93.50","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":1028.5,"tax_amount_raw":93.5,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"VAT","tax_rate1":17.5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$1,098.63","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$163.63","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":1098.63,"tax_amount_raw":163.63,"product_cost_raw":0}],"reminder1_sent":"","reminder2_sent":"","reminder3_sent":"","reminder_last_sent":"","paid_to_date":"$9,396.77","auto_bill_enabled":false,"client":{"name":"cypress","balance":"0.000000","payment_balance":"0.000000","credit_balance":"11661.820000","currency":"USD"},"payments":[{"status":"Completed","badge":"
Completed<\/span><\/h6>","amount":"$9,396.77","applied":"$9,396.77","balance":"$0.00","refunded":"$0.00","amount_raw":"9396.770000","applied_raw":"9396.770000","refunded_raw":"0.000000","balance_raw":0,"date":"30\/Sep\/2023","method":"","currency":"USD","exchange_rate":1,"transaction_reference":"Manual entry","is_manual":1,"number":"0010","custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","client":{"name":"cypress","balance":"0.000000","payment_balance":"0.000000","credit_balance":"11661.820000","currency":"USD"},"paymentables":[{"invoice":"0017","amount_raw":"9396.7700","refunded_raw":"0.0000","net_raw":9396.77,"amount":"$9,396.77","refunded":"$0.00","net":"$9,396.77","is_credit":false,"created_at":"01\/Oct\/2023","updated_at":"01\/Oct\/2023","timestamp":1696151008}]}],"total_tax_map":[{"name":"CA Sales Tax 5%","total":"$141.90","total_raw":141.9}],"line_tax_map":[{"name":"CA Sales Tax 5%","total":"$141.90","total_raw":141.9}]},{"amount":"$6,077.51","balance":"$0.00","amount_raw":"6077.51","balance_raw":"0.000000","number":"0019","discount":0,"po_number":"","date":"01\/Aug\/2023","last_sent_date":"","next_send_date":"","due_date":"","terms":"","public_notes":"","private_notes":"","uses_inclusive_taxes":false,"tax_name1":"","tax_rate1":0,"tax_name2":"VAT","tax_rate2":17.5,"tax_name3":"CA Sales Tax","tax_rate3":5,"total_taxes":"$1,402.51","total_taxes_raw":"1402.510000","is_amount_discount":true,"footer":"","partial":"0.000000","partial_due_date":"","custom_value1":"1992-08-20","custom_value2":"no","custom_value3":"","custom_value4":"","custom_surcharge1":0,"custom_surcharge2":0,"custom_surcharge3":0,"custom_surcharge4":0,"exchange_rate":1,"custom_surcharge_tax1":false,"custom_surcharge_tax2":false,"custom_surcharge_tax3":false,"custom_surcharge_tax4":false,"line_items":[{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$981.75","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$46.75","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":981.75,"tax_amount_raw":46.75,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"GST","tax_rate1":10,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$1,028.50","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$93.50","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":1028.5,"tax_amount_raw":93.5,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"VAT","tax_rate1":17.5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$1,098.63","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$163.63","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":1098.63,"tax_amount_raw":163.63,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$981.75","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$46.75","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":981.75,"tax_amount_raw":46.75,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"","tax_rate1":0,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$935.00","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$0.00","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":935,"tax_amount_raw":0,"product_cost_raw":0}],"reminder1_sent":"","reminder2_sent":"","reminder3_sent":"","reminder_last_sent":"","paid_to_date":"$6,077.51","auto_bill_enabled":false,"client":{"name":"cypress","balance":"0.000000","payment_balance":"0.000000","credit_balance":"11661.820000","currency":"USD"},"payments":[{"status":"Refunded","badge":"
Refunded<\/span><\/h6>","amount":"$6,077.51","applied":"$6,077.51","balance":"-$6,077.51","refunded":"$6,077.51","amount_raw":"6077.510000","applied_raw":"6077.510000","refunded_raw":"6077.510000","balance_raw":-6077.51,"date":"30\/Sep\/2023","method":"EuroCard","currency":"USD","exchange_rate":1,"transaction_reference":"Manual entry","is_manual":1,"number":"0001","custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","client":{"name":"cypress","balance":"0.000000","payment_balance":"0.000000","credit_balance":"11661.820000","currency":"USD"},"paymentables":[{"invoice":"0019","amount_raw":"6077.5100","refunded_raw":"6077.5100","net_raw":0,"amount":"$6,077.51","refunded":"$6,077.51","net":"$0.00","is_credit":false,"created_at":"01\/Oct\/2023","updated_at":"01\/Oct\/2023","timestamp":1696150843}]},{"status":"Completed","badge":"
Completed<\/span><\/h6>","amount":"$6,077.51","applied":"$6,077.51","balance":"$0.00","refunded":"$0.00","amount_raw":"6077.510000","applied_raw":"6077.510000","refunded_raw":"0.000000","balance_raw":0,"date":"30\/Sep\/2023","method":"","currency":"USD","exchange_rate":1,"transaction_reference":"Manual entry","is_manual":1,"number":"0011","custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","client":{"name":"cypress","balance":"0.000000","payment_balance":"0.000000","credit_balance":"11661.820000","currency":"USD"},"paymentables":[{"invoice":"0019","amount_raw":"6077.5100","refunded_raw":"0.0000","net_raw":6077.51,"amount":"$6,077.51","refunded":"$0.00","net":"$6,077.51","is_credit":false,"created_at":"01\/Oct\/2023","updated_at":"01\/Oct\/2023","timestamp":1696151008}]}],"total_tax_map":[{"name":"CA Sales Tax 5%","total":"$141.90","total_raw":141.9}],"line_tax_map":[{"name":"CA Sales Tax 5%","total":"$141.90","total_raw":141.9}]},{"amount":"$4,090.64","amount_raw":"4090.64","balance":"$0.00","balance_raw":"0.000000","number":"0020","discount":0,"po_number":"","date":"26\/Aug\/2023","last_sent_date":"","next_send_date":"","due_date":"","terms":"","public_notes":"","private_notes":"","uses_inclusive_taxes":false,"tax_name1":"GST","tax_rate1":10,"tax_name2":"VAT","tax_rate2":17.5,"tax_name3":"CA Sales Tax","tax_rate3":5,"total_taxes":"$1,285.64","total_taxes_raw":"1285.640000","is_amount_discount":true,"footer":"","partial":"0.000000","partial_due_date":"","custom_value1":"1979-06-26","custom_value2":"yes","custom_value3":"","custom_value4":"","custom_surcharge1":0,"custom_surcharge2":0,"custom_surcharge3":0,"custom_surcharge4":0,"exchange_rate":1,"custom_surcharge_tax1":false,"custom_surcharge_tax2":false,"custom_surcharge_tax3":false,"custom_surcharge_tax4":false,"line_items":[{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$981.75","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$46.75","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":981.75,"tax_amount_raw":46.75,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"VAT","tax_rate1":17.5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$1,098.63","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$163.63","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":1098.63,"tax_amount_raw":163.63,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"VAT","tax_rate1":17.5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$1,098.63","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$163.63","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":1098.63,"tax_amount_raw":163.63,"product_cost_raw":0}],"reminder1_sent":"","reminder2_sent":"","reminder3_sent":"","reminder_last_sent":"","paid_to_date":"$4,090.64","auto_bill_enabled":false,"client":{"name":"cypress","balance":"0.000000","payment_balance":"0.000000","credit_balance":"11661.820000","currency":"USD"},"payments":[{"status":"Refunded","badge":"
Refunded<\/span><\/h6>","amount":"$4,090.64","applied":"$4,090.64","balance":"-$4,090.64","refunded":"$4,090.64","amount_raw":"4090.640000","applied_raw":"4090.640000","refunded_raw":"4090.640000","balance_raw":-4090.64,"date":"30\/Sep\/2023","method":"Discover Card","currency":"USD","exchange_rate":1,"transaction_reference":"Manual entry","is_manual":1,"number":"0002","custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","client":{"name":"cypress","balance":"0.000000","payment_balance":"0.000000","credit_balance":"11661.820000","currency":"USD"},"paymentables":[{"invoice":"0020","amount_raw":"4090.6400","refunded_raw":"4090.6400","net_raw":0,"amount":"$4,090.64","refunded":"$4,090.64","net":"$0.00","is_credit":false,"created_at":"01\/Oct\/2023","updated_at":"01\/Oct\/2023","timestamp":1696150843}]},{"status":"Completed","badge":"
Completed<\/span><\/h6>","amount":"$4,090.64","applied":"$4,090.64","balance":"$0.00","refunded":"$0.00","amount_raw":"4090.640000","applied_raw":"4090.640000","refunded_raw":"0.000000","balance_raw":0,"date":"30\/Sep\/2023","method":"","currency":"USD","exchange_rate":1,"transaction_reference":"Manual entry","is_manual":1,"number":"0012","custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","client":{"name":"cypress","balance":"0.000000","payment_balance":"0.000000","credit_balance":"11661.820000","currency":"USD"},"paymentables":[{"invoice":"0020","amount_raw":"4090.6400","refunded_raw":"0.0000","net_raw":4090.64,"amount":"$4,090.64","refunded":"$0.00","net":"$4,090.64","is_credit":false,"created_at":"01\/Oct\/2023","updated_at":"01\/Oct\/2023","timestamp":1696151008}]}],"total_tax_map":[{"name":"CA Sales Tax 5%","total":"$141.90","total_raw":141.9}],"line_tax_map":[{"name":"CA Sales Tax 5%","total":"$141.90","total_raw":141.9}]},{"amount":"$2,197.26","amount_raw":"2197.26","balance":"$0.00","balance_raw":"0.000000","number":"0021","discount":0,"po_number":"","date":"08\/Sep\/2023","last_sent_date":"","next_send_date":"","due_date":"","terms":"","public_notes":"","private_notes":"","uses_inclusive_taxes":false,"tax_name1":"","tax_rate1":0,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"total_taxes":"$327.26","total_taxes_raw":"327.260000","is_amount_discount":true,"footer":"","partial":"0.000000","partial_due_date":"","custom_value1":"1980-11-12","custom_value2":"no","custom_value3":"","custom_value4":"","custom_surcharge1":0,"custom_surcharge2":0,"custom_surcharge3":0,"custom_surcharge4":0,"exchange_rate":1,"custom_surcharge_tax1":false,"custom_surcharge_tax2":false,"custom_surcharge_tax3":false,"custom_surcharge_tax4":false,"line_items":[{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"VAT","tax_rate1":17.5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$1,098.63","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$163.63","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":1098.63,"tax_amount_raw":163.63,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"VAT","tax_rate1":17.5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$1,098.63","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$163.63","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":1098.63,"tax_amount_raw":163.63,"product_cost_raw":0}],"reminder1_sent":"","reminder2_sent":"","reminder3_sent":"","reminder_last_sent":"","paid_to_date":"$2,197.26","auto_bill_enabled":false,"client":{"name":"Jakubowski Group","balance":"28296.170000","payment_balance":"0.000000","credit_balance":"1084.840000","currency":"USD"},"payments":[{"status":"Refunded","badge":"
Refunded<\/span><\/h6>","amount":"$2,197.26","applied":"$2,197.26","balance":"-$2,197.26","refunded":"$2,197.26","amount_raw":"2197.260000","applied_raw":"2197.260000","refunded_raw":"2197.260000","balance_raw":-2197.26,"date":"30\/Sep\/2023","method":"Diners Card","currency":"USD","exchange_rate":1,"transaction_reference":"Manual entry","is_manual":1,"number":"0003","custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","client":{"name":"Jakubowski Group","balance":"28296.170000","payment_balance":"0.000000","credit_balance":"1084.840000","currency":"USD"},"paymentables":[{"invoice":"0021","amount_raw":"2197.2600","refunded_raw":"2197.2600","net_raw":0,"amount":"$2,197.26","refunded":"$2,197.26","net":"$0.00","is_credit":false,"created_at":"01\/Oct\/2023","updated_at":"01\/Oct\/2023","timestamp":1696150843}]},{"status":"Completed","badge":"
Completed<\/span><\/h6>","amount":"$2,197.26","applied":"$2,197.26","balance":"$0.00","refunded":"$0.00","amount_raw":"2197.260000","applied_raw":"2197.260000","refunded_raw":"0.000000","balance_raw":0,"date":"30\/Sep\/2023","method":"","currency":"USD","exchange_rate":1,"transaction_reference":"Manual entry","is_manual":1,"number":"0013","custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","client":{"name":"Jakubowski Group","balance":"28296.170000","payment_balance":"0.000000","credit_balance":"1084.840000","currency":"USD"},"paymentables":[{"invoice":"0021","amount_raw":"2197.2600","refunded_raw":"0.0000","net_raw":2197.26,"amount":"$2,197.26","refunded":"$0.00","net":"$2,197.26","is_credit":false,"created_at":"01\/Oct\/2023","updated_at":"01\/Oct\/2023","timestamp":1696151008}]}],"total_tax_map":[{"name":"CA Sales Tax 5%","total":"$141.90","total_raw":141.9}],"line_tax_map":[{"name":"CA Sales Tax 5%","total":"$141.90","total_raw":141.9}]},{"amount":"$4,955.50","amount_raw":"4955.50","balance":"$66.00","balance_raw":"66.000000","number":"0022","discount":0,"po_number":"","date":"27\/Sep\/2023","last_sent_date":"","next_send_date":"","due_date":"","terms":"","public_notes":"","private_notes":"","uses_inclusive_taxes":false,"tax_name1":"GST","tax_rate1":10,"tax_name2":"VAT","tax_rate2":17.5,"tax_name3":"","tax_rate3":0,"total_taxes":"$1,215.50","total_taxes_raw":"1215.500000","is_amount_discount":true,"footer":"","partial":"0.000000","partial_due_date":"","custom_value1":"1999-08-20","custom_value2":"yes","custom_value3":"","custom_value4":"","custom_surcharge1":0,"custom_surcharge2":0,"custom_surcharge3":0,"custom_surcharge4":0,"exchange_rate":1,"custom_surcharge_tax1":false,"custom_surcharge_tax2":false,"custom_surcharge_tax3":false,"custom_surcharge_tax4":false,"line_items":[{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$981.75","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$46.75","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":981.75,"tax_amount_raw":46.75,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$981.75","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$46.75","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":981.75,"tax_amount_raw":46.75,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$981.75","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$46.75","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":981.75,"tax_amount_raw":46.75,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$981.75","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$46.75","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":981.75,"tax_amount_raw":46.75,"product_cost_raw":0}],"reminder1_sent":"","reminder2_sent":"","reminder3_sent":"","reminder_last_sent":"","paid_to_date":"$4,889.50","auto_bill_enabled":false,"client":{"name":"Jakubowski Group","balance":"28296.170000","payment_balance":"0.000000","credit_balance":"1084.840000","currency":"USD"},"payments":[{"status":"Partially Refunded","badge":"
Partially Refunded<\/span><\/h6>","amount":"$4,955.50","applied":"$4,955.50","balance":"-$66.00","refunded":"$66.00","amount_raw":"4955.500000","applied_raw":"4955.500000","refunded_raw":"66.000000","balance_raw":-66,"date":"30\/Sep\/2023","method":"Maestro","currency":"USD","exchange_rate":1,"transaction_reference":"Manual entry","is_manual":1,"number":"0004","custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","client":{"name":"Jakubowski Group","balance":"28296.170000","payment_balance":"0.000000","credit_balance":"1084.840000","currency":"USD"},"paymentables":[{"invoice":"0022","amount_raw":"4955.5000","refunded_raw":"66.0000","net_raw":4889.5,"amount":"$4,955.50","refunded":"$66.00","net":"$4,889.50","is_credit":false,"created_at":"01\/Oct\/2023","updated_at":"01\/Oct\/2023","timestamp":1696150843}]}],"total_tax_map":[{"name":"CA Sales Tax 5%","total":"$141.90","total_raw":141.9}],"line_tax_map":[{"name":"CA Sales Tax 5%","total":"$141.90","total_raw":141.9}]},{"amount":"$2,290.75","amount_raw":"2290.75","balance":"$34.00","balance_raw":"34.000000","number":"0023","discount":0,"po_number":"","date":"30\/Aug\/2023","last_sent_date":"","next_send_date":"","due_date":"","terms":"","public_notes":"","private_notes":"","uses_inclusive_taxes":false,"tax_name1":"","tax_rate1":0,"tax_name2":"VAT","tax_rate2":17.5,"tax_name3":"CA Sales Tax","tax_rate3":5,"total_taxes":"$420.75","total_taxes_raw":"420.750000","is_amount_discount":true,"footer":"","partial":"0.000000","partial_due_date":"","custom_value1":"2015-12-15","custom_value2":"no","custom_value3":"","custom_value4":"","custom_surcharge1":0,"custom_surcharge2":0,"custom_surcharge3":0,"custom_surcharge4":0,"exchange_rate":1,"custom_surcharge_tax1":false,"custom_surcharge_tax2":false,"custom_surcharge_tax3":false,"custom_surcharge_tax4":false,"line_items":[{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"","tax_rate1":0,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$935.00","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$0.00","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":935,"tax_amount_raw":0,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"","tax_rate1":0,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$935.00","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$0.00","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":935,"tax_amount_raw":0,"product_cost_raw":0}],"reminder1_sent":"","reminder2_sent":"","reminder3_sent":"","reminder_last_sent":"","paid_to_date":"$2,256.75","auto_bill_enabled":false,"client":{"name":"Jakubowski Group","balance":"28296.170000","payment_balance":"0.000000","credit_balance":"1084.840000","currency":"USD"},"payments":[{"status":"Partially Refunded","badge":"
Partially Refunded<\/span><\/h6>","amount":"$2,290.75","applied":"$2,290.75","balance":"-$34.00","refunded":"$34.00","amount_raw":"2290.750000","applied_raw":"2290.750000","refunded_raw":"34.000000","balance_raw":-34,"date":"30\/Sep\/2023","method":"Diners Card","currency":"USD","exchange_rate":1,"transaction_reference":"Manual entry","is_manual":1,"number":"0005","custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","client":{"name":"Jakubowski Group","balance":"28296.170000","payment_balance":"0.000000","credit_balance":"1084.840000","currency":"USD"},"paymentables":[{"invoice":"0023","amount_raw":"2290.7500","refunded_raw":"34.0000","net_raw":2256.75,"amount":"$2,290.75","refunded":"$34.00","net":"$2,256.75","is_credit":false,"created_at":"01\/Oct\/2023","updated_at":"01\/Oct\/2023","timestamp":1696150843}]}],"total_tax_map":[{"name":"CA Sales Tax 5%","total":"$141.90","total_raw":141.9}],"line_tax_map":[{"name":"CA Sales Tax 5%","total":"$141.90","total_raw":141.9}]},{"amount":"$6,802.13","amount_raw":"6802.13","balance":"$444.00","balance_raw":"444.000000","number":"0024","discount":0,"po_number":"","date":"25\/Jul\/2023","last_sent_date":"","next_send_date":"","due_date":"","terms":"","public_notes":"","private_notes":"","uses_inclusive_taxes":false,"tax_name1":"GST","tax_rate1":10,"tax_name2":"","tax_rate2":0,"tax_name3":"CA Sales Tax","tax_rate3":5,"total_taxes":"$1,192.13","total_taxes_raw":"1192.130000","is_amount_discount":true,"footer":"","partial":"0.000000","partial_due_date":"","custom_value1":"1990-07-11","custom_value2":"no","custom_value3":"","custom_value4":"","custom_surcharge1":0,"custom_surcharge2":0,"custom_surcharge3":0,"custom_surcharge4":0,"exchange_rate":1,"custom_surcharge_tax1":false,"custom_surcharge_tax2":false,"custom_surcharge_tax3":false,"custom_surcharge_tax4":false,"line_items":[{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"VAT","tax_rate1":17.5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$1,098.63","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$163.63","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":1098.63,"tax_amount_raw":163.63,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"","tax_rate1":0,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$935.00","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$0.00","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":935,"tax_amount_raw":0,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$981.75","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$46.75","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":981.75,"tax_amount_raw":46.75,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"","tax_rate1":0,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$935.00","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$0.00","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":935,"tax_amount_raw":0,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$981.75","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$46.75","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":981.75,"tax_amount_raw":46.75,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"GST","tax_rate1":10,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$1,028.50","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$93.50","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":1028.5,"tax_amount_raw":93.5,"product_cost_raw":0}],"reminder1_sent":"","reminder2_sent":"","reminder3_sent":"","reminder_last_sent":"","paid_to_date":"$6,358.13","auto_bill_enabled":false,"client":{"name":"Jakubowski Group","balance":"28296.170000","payment_balance":"0.000000","credit_balance":"1084.840000","currency":"USD"},"payments":[{"status":"Partially Refunded","badge":"
Partially Refunded<\/span><\/h6>","amount":"$6,802.13","applied":"$6,802.13","balance":"-$444.00","refunded":"$444.00","amount_raw":"6802.130000","applied_raw":"6802.130000","refunded_raw":"444.000000","balance_raw":-444,"date":"30\/Sep\/2023","method":"Maestro","currency":"USD","exchange_rate":1,"transaction_reference":"Manual entry","is_manual":1,"number":"0006","custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","client":{"name":"Jakubowski Group","balance":"28296.170000","payment_balance":"0.000000","credit_balance":"1084.840000","currency":"USD"},"paymentables":[{"invoice":"0024","amount_raw":"6802.1300","refunded_raw":"444.0000","net_raw":6358.13,"amount":"$6,802.13","refunded":"$444.00","net":"$6,358.13","is_credit":false,"created_at":"01\/Oct\/2023","updated_at":"01\/Oct\/2023","timestamp":1696150843}]}],"total_tax_map":[{"name":"CA Sales Tax 5%","total":"$141.90","total_raw":141.9}],"line_tax_map":[{"name":"CA Sales Tax 5%","total":"$141.90","total_raw":141.9}]},{"amount":"$10,986.26","amount_raw":"10986.26","balance":"$146.26","balance_raw":"146.260000","number":"0025","discount":0,"po_number":"","date":"23\/Jul\/2023","last_sent_date":"","next_send_date":"","due_date":"","terms":"","public_notes":"","private_notes":"","uses_inclusive_taxes":false,"tax_name1":"GST","tax_rate1":10,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"total_taxes":"$1,636.26","total_taxes_raw":"1636.260000","is_amount_discount":true,"footer":"","partial":"0.000000","partial_due_date":"","custom_value1":"1975-02-18","custom_value2":"no","custom_value3":"","custom_value4":"","custom_surcharge1":0,"custom_surcharge2":0,"custom_surcharge3":0,"custom_surcharge4":0,"exchange_rate":1,"custom_surcharge_tax1":false,"custom_surcharge_tax2":false,"custom_surcharge_tax3":false,"custom_surcharge_tax4":false,"line_items":[{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"VAT","tax_rate1":17.5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$1,098.63","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$163.63","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":1098.63,"tax_amount_raw":163.63,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"GST","tax_rate1":10,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$1,028.50","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$93.50","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":1028.5,"tax_amount_raw":93.5,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"","tax_rate1":0,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$935.00","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$0.00","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":935,"tax_amount_raw":0,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"","tax_rate1":0,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$935.00","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$0.00","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":935,"tax_amount_raw":0,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"VAT","tax_rate1":17.5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$1,098.63","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$163.63","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":1098.63,"tax_amount_raw":163.63,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$981.75","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$46.75","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":981.75,"tax_amount_raw":46.75,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$981.75","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$46.75","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":981.75,"tax_amount_raw":46.75,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$981.75","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$46.75","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":981.75,"tax_amount_raw":46.75,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$981.75","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$46.75","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":981.75,"tax_amount_raw":46.75,"product_cost_raw":0},{"quantity":1,"cost":"$935.00","product_key":"Et.","notes":"Illum similique.","discount":"$0.00","is_amount_discount":true,"tax_name1":"GST","tax_rate1":10,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"$935.00","gross_line_total":"$1,028.50","custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"78","custom_value3":"Itaque laudantium.","custom_value4":"Qui voluptatem ea a.","type_id":"1","product_cost":"$0.00","tax_amount":"$93.50","date":"","tax_id":"","task_id":"","expense_id":"","cost_raw":935,"discount_raw":0,"line_total_raw":935,"gross_line_total_raw":1028.5,"tax_amount_raw":93.5,"product_cost_raw":0}],"reminder1_sent":"","reminder2_sent":"","reminder3_sent":"","reminder_last_sent":"","paid_to_date":"$10,840.00","auto_bill_enabled":false,"client":{"name":"Jakubowski Group","balance":"28296.170000","payment_balance":"0.000000","credit_balance":"1084.840000","currency":"USD"},"payments":[{"status":"Partially Refunded","badge":"
Partially Refunded<\/span><\/h6>","amount":"$10,986.26","applied":"$10,986.26","balance":"-$146.26","refunded":"$146.26","amount_raw":"10986.260000","applied_raw":"10986.260000","refunded_raw":"146.260000","balance_raw":-146.26000000000022,"date":"30\/Sep\/2023","method":"UnionPay","currency":"USD","exchange_rate":1,"transaction_reference":"Manual entry","is_manual":1,"number":"0007","custom_value1":"","custom_value2":"","custom_value3":"","custom_value4":"","client":{"name":"Jakubowski Group","balance":"28296.170000","payment_balance":"0.000000","credit_balance":"1084.840000","currency":"USD"},"paymentables":[{"invoice":"0025","amount_raw":"10986.2600","refunded_raw":"146.2600","net_raw":10840,"amount":"$10,986.26","refunded":"$146.26","net":"$10,840.00","is_credit":false,"created_at":"01\/Oct\/2023","updated_at":"01\/Oct\/2023","timestamp":1696150843}]}],"total_tax_map":[{"name":"CA Sales Tax 5%","total":"$141.90","total_raw":141.9}],"line_tax_map":[{"name":"CA Sales Tax 5%","total":"$141.90","total_raw":141.9}]}]'; - public string $quote_data = '[{"id":1,"client_id":1,"user_id":1,"assigned_user_id":null,"company_id":1,"status_id":2,"project_id":null,"vendor_id":null,"recurring_id":null,"design_id":2,"invoice_id":null,"number":"0001","discount":1,"is_amount_discount":false,"po_number":"Molestias.","date":"1986-08-02","last_sent_date":null,"due_date":null,"next_send_date":null,"is_deleted":false,"line_items":[{"quantity":1,"cost":637,"product_key":"Nisi.","notes":"Ut ipsa rerum.","discount":0,"is_amount_discount":false,"tax_name1":"VAT","tax_rate1":17.5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"637.00","gross_line_total":747.36,"custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"42","custom_value3":"Maxime dolores.","custom_value4":"Odio consequatur.","type_id":"1","product_cost":0,"tax_amount":110.36,"date":"","tax_id":"","task_id":"","expense_id":""},{"quantity":1,"cost":637,"product_key":"Nisi.","notes":"Ut ipsa rerum.","discount":0,"is_amount_discount":false,"tax_name1":"GST","tax_rate1":10,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"637.00","gross_line_total":700.06,"custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"42","custom_value3":"Maxime dolores.","custom_value4":"Odio consequatur.","type_id":"1","product_cost":0,"tax_amount":63.06,"date":"","tax_id":"","task_id":"","expense_id":""},{"quantity":1,"cost":637,"product_key":"Nisi.","notes":"Ut ipsa rerum.","discount":0,"is_amount_discount":false,"tax_name1":"","tax_rate1":0,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"637.00","gross_line_total":637,"custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"42","custom_value3":"Maxime dolores.","custom_value4":"Odio consequatur.","type_id":"1","product_cost":0,"tax_amount":0,"date":"","tax_id":"","task_id":"","expense_id":""},{"quantity":1,"cost":637,"product_key":"Nisi.","notes":"Ut ipsa rerum.","discount":0,"is_amount_discount":false,"tax_name1":"GST","tax_rate1":10,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"637.00","gross_line_total":700.06,"custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"42","custom_value3":"Maxime dolores.","custom_value4":"Odio consequatur.","type_id":"1","product_cost":0,"tax_amount":63.06,"date":"","tax_id":"","task_id":"","expense_id":""},{"quantity":1,"cost":637,"product_key":"Nisi.","notes":"Ut ipsa rerum.","discount":0,"is_amount_discount":false,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"637.00","gross_line_total":668.53,"custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"42","custom_value3":"Maxime dolores.","custom_value4":"Odio consequatur.","type_id":"1","product_cost":0,"tax_amount":31.53,"date":"","tax_id":"","task_id":"","expense_id":""},{"quantity":1,"cost":637,"product_key":"Nisi.","notes":"Ut ipsa rerum.","discount":0,"is_amount_discount":false,"tax_name1":"GST","tax_rate1":10,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"637.00","gross_line_total":700.06,"custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"42","custom_value3":"Maxime dolores.","custom_value4":"Odio consequatur.","type_id":"1","product_cost":0,"tax_amount":63.06,"date":"","tax_id":"","task_id":"","expense_id":""},{"quantity":1,"cost":637,"product_key":"Nisi.","notes":"Ut ipsa rerum.","discount":0,"is_amount_discount":false,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"637.00","gross_line_total":668.53,"custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"42","custom_value3":"Maxime dolores.","custom_value4":"Odio consequatur.","type_id":"1","product_cost":0,"tax_amount":31.53,"date":"","tax_id":"","task_id":"","expense_id":""}],"backup":null,"footer":null,"public_notes":null,"private_notes":null,"terms":null,"tax_name1":"GST","tax_rate1":"10.000000","tax_name2":"VAT","tax_rate2":"17.500000","tax_name3":"THIRDTAX","tax_rate3":"5.000000","total_taxes":"1797.280000","uses_inclusive_taxes":0,"custom_value1":null,"custom_value2":null,"custom_value3":null,"custom_value4":null,"custom_surcharge1":null,"custom_surcharge2":null,"custom_surcharge3":null,"custom_surcharge4":null,"custom_surcharge_tax1":0,"custom_surcharge_tax2":0,"custom_surcharge_tax3":0,"custom_surcharge_tax4":0,"exchange_rate":"1.000000","amount":"6211.690000","balance":"0.000000","partial":null,"partial_due_date":null,"last_viewed":null,"created_at":1695943654,"updated_at":1695943658,"deleted_at":null,"reminder1_sent":null,"reminder2_sent":null,"reminder3_sent":null,"reminder_last_sent":null,"paid_to_date":"0.000000","subscription_id":null,"hashed_id":"VolejRejNm"},{"id":2,"client_id":1,"user_id":1,"assigned_user_id":null,"company_id":1,"status_id":2,"project_id":null,"vendor_id":null,"recurring_id":null,"design_id":2,"invoice_id":null,"number":"0002","discount":9,"is_amount_discount":true,"po_number":"Omnis.","date":"1988-11-22","last_sent_date":null,"due_date":null,"next_send_date":null,"is_deleted":false,"line_items":[{"quantity":1,"cost":637,"product_key":"Nisi.","notes":"Ut ipsa rerum.","discount":0,"is_amount_discount":true,"tax_name1":"VAT","tax_rate1":17.5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":637,"gross_line_total":738.44,"custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"42","custom_value3":"Maxime dolores.","custom_value4":"Odio consequatur.","type_id":"1","product_cost":0,"tax_amount":101.44,"date":"","tax_id":"","task_id":"","expense_id":""},{"quantity":1,"cost":637,"product_key":"Nisi.","notes":"Ut ipsa rerum.","discount":0,"is_amount_discount":true,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":637,"gross_line_total":665.98,"custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"42","custom_value3":"Maxime dolores.","custom_value4":"Odio consequatur.","type_id":"1","product_cost":0,"tax_amount":28.98,"date":"","tax_id":"","task_id":"","expense_id":""},{"quantity":1,"cost":637,"product_key":"Nisi.","notes":"Ut ipsa rerum.","discount":0,"is_amount_discount":true,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":637,"gross_line_total":665.98,"custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"42","custom_value3":"Maxime dolores.","custom_value4":"Odio consequatur.","type_id":"1","product_cost":0,"tax_amount":28.98,"date":"","tax_id":"","task_id":"","expense_id":""},{"quantity":1,"cost":637,"product_key":"Nisi.","notes":"Ut ipsa rerum.","discount":0,"is_amount_discount":true,"tax_name1":"GST","tax_rate1":10,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":637,"gross_line_total":694.97,"custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"42","custom_value3":"Maxime dolores.","custom_value4":"Odio consequatur.","type_id":"1","product_cost":0,"tax_amount":57.97,"date":"","tax_id":"","task_id":"","expense_id":""},{"quantity":1,"cost":637,"product_key":"Nisi.","notes":"Ut ipsa rerum.","discount":0,"is_amount_discount":true,"tax_name1":"VAT","tax_rate1":17.5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":637,"gross_line_total":738.44,"custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"42","custom_value3":"Maxime dolores.","custom_value4":"Odio consequatur.","type_id":"1","product_cost":0,"tax_amount":101.44,"date":"","tax_id":"","task_id":"","expense_id":""}],"backup":null,"footer":null,"public_notes":null,"private_notes":null,"terms":null,"tax_name1":"GST","tax_rate1":"10.000000","tax_name2":"VAT","tax_rate2":"17.500000","tax_name3":"THIRDTAX","tax_rate3":"5.000000","total_taxes":"1381.560000","uses_inclusive_taxes":0,"custom_value1":null,"custom_value2":null,"custom_value3":null,"custom_value4":null,"custom_surcharge1":null,"custom_surcharge2":null,"custom_surcharge3":null,"custom_surcharge4":null,"custom_surcharge_tax1":0,"custom_surcharge_tax2":0,"custom_surcharge_tax3":0,"custom_surcharge_tax4":0,"exchange_rate":"1.000000","amount":"4557.560000","balance":"0.000000","partial":null,"partial_due_date":null,"last_viewed":null,"created_at":1695943654,"updated_at":1696118643,"deleted_at":null,"reminder1_sent":null,"reminder2_sent":null,"reminder3_sent":null,"reminder_last_sent":null,"paid_to_date":"0.000000","subscription_id":null,"hashed_id":"Wpmbk5ezJn"}]'; + public string $quote_data = '[{"id":1,"client_id":1,"user_id":1,"assigned_user_id":null,"company_id":1,"status_id":2,"project_id":null,"vendor_id":null,"recurring_id":null,"design_id":2,"invoice_id":null,"number":"0001","discount":1,"is_amount_discount":false,"po_number":"Molestias.","date":"1986-08-02","last_sent_date":null,"due_date":null,"next_send_date":null,"is_deleted":false,"line_items":[{"quantity":1,"cost":637,"product_key":"Nisi.","notes":"Ut ipsa rerum.","discount":0,"is_amount_discount":false,"tax_name1":"VAT","tax_rate1":17.5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"637.00","gross_line_total":747.36,"custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"42","custom_value3":"Maxime dolores.","custom_value4":"Odio consequatur.","type_id":"2","product_cost":0,"tax_amount":110.36,"date":"","tax_id":"","task_id":"","expense_id":""},{"quantity":1,"cost":637,"product_key":"Nisi.","notes":"Ut ipsa rerum.","discount":0,"is_amount_discount":false,"tax_name1":"VAT","tax_rate1":17.5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"637.00","gross_line_total":747.36,"custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"42","custom_value3":"Maxime dolores.","custom_value4":"Odio consequatur.","type_id":"2","product_cost":0,"tax_amount":110.36,"date":"","tax_id":"","task_id":"","expense_id":""},{"quantity":1,"cost":637,"product_key":"Nisi.","notes":"Ut ipsa rerum.","discount":0,"is_amount_discount":false,"tax_name1":"VAT","tax_rate1":17.5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"637.00","gross_line_total":747.36,"custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"42","custom_value3":"Maxime dolores.","custom_value4":"Odio consequatur.","type_id":"2","product_cost":0,"tax_amount":110.36,"date":"","tax_id":"","task_id":"","expense_id":""},{"quantity":1,"cost":637,"product_key":"Nisi.","notes":"Ut ipsa rerum.","discount":0,"is_amount_discount":false,"tax_name1":"VAT","tax_rate1":17.5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"637.00","gross_line_total":747.36,"custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"42","custom_value3":"Maxime dolores.","custom_value4":"Odio consequatur.","type_id":"1","product_cost":0,"tax_amount":110.36,"date":"","tax_id":"","task_id":"","expense_id":""},{"quantity":1,"cost":637,"product_key":"Nisi.","notes":"Ut ipsa rerum.","discount":0,"is_amount_discount":false,"tax_name1":"GST","tax_rate1":10,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"637.00","gross_line_total":700.06,"custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"42","custom_value3":"Maxime dolores.","custom_value4":"Odio consequatur.","type_id":"1","product_cost":0,"tax_amount":63.06,"date":"","tax_id":"","task_id":"","expense_id":""},{"quantity":1,"cost":637,"product_key":"Nisi.","notes":"Ut ipsa rerum.","discount":0,"is_amount_discount":false,"tax_name1":"","tax_rate1":0,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"637.00","gross_line_total":637,"custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"42","custom_value3":"Maxime dolores.","custom_value4":"Odio consequatur.","type_id":"1","product_cost":0,"tax_amount":0,"date":"","tax_id":"","task_id":"","expense_id":""},{"quantity":1,"cost":637,"product_key":"Nisi.","notes":"Ut ipsa rerum.","discount":0,"is_amount_discount":false,"tax_name1":"GST","tax_rate1":10,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"637.00","gross_line_total":700.06,"custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"42","custom_value3":"Maxime dolores.","custom_value4":"Odio consequatur.","type_id":"1","product_cost":0,"tax_amount":63.06,"date":"","tax_id":"","task_id":"","expense_id":""},{"quantity":1,"cost":637,"product_key":"Nisi.","notes":"Ut ipsa rerum.","discount":0,"is_amount_discount":false,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"637.00","gross_line_total":668.53,"custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"42","custom_value3":"Maxime dolores.","custom_value4":"Odio consequatur.","type_id":"1","product_cost":0,"tax_amount":31.53,"date":"","tax_id":"","task_id":"","expense_id":""},{"quantity":1,"cost":637,"product_key":"Nisi.","notes":"Ut ipsa rerum.","discount":0,"is_amount_discount":false,"tax_name1":"GST","tax_rate1":10,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"637.00","gross_line_total":700.06,"custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"42","custom_value3":"Maxime dolores.","custom_value4":"Odio consequatur.","type_id":"1","product_cost":0,"tax_amount":63.06,"date":"","tax_id":"","task_id":"","expense_id":""},{"quantity":1,"cost":637,"product_key":"Nisi.","notes":"Ut ipsa rerum.","discount":0,"is_amount_discount":false,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":"637.00","gross_line_total":668.53,"custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"42","custom_value3":"Maxime dolores.","custom_value4":"Odio consequatur.","type_id":"1","product_cost":0,"tax_amount":31.53,"date":"","tax_id":"","task_id":"","expense_id":""}],"backup":null,"footer":null,"public_notes":null,"private_notes":null,"terms":null,"tax_name1":"GST","tax_rate1":"10.000000","tax_name2":"VAT","tax_rate2":"17.500000","tax_name3":"THIRDTAX","tax_rate3":"5.000000","total_taxes":"1797.280000","uses_inclusive_taxes":0,"custom_value1":null,"custom_value2":null,"custom_value3":null,"custom_value4":null,"custom_surcharge1":null,"custom_surcharge2":null,"custom_surcharge3":null,"custom_surcharge4":null,"custom_surcharge_tax1":0,"custom_surcharge_tax2":0,"custom_surcharge_tax3":0,"custom_surcharge_tax4":0,"exchange_rate":"1.000000","amount":"6211.690000","balance":"0.000000","partial":null,"partial_due_date":null,"last_viewed":null,"created_at":1695943654,"updated_at":1695943658,"deleted_at":null,"reminder1_sent":null,"reminder2_sent":null,"reminder3_sent":null,"reminder_last_sent":null,"paid_to_date":"0.000000","subscription_id":null,"hashed_id":"VolejRejNm"},{"id":2,"client_id":1,"user_id":1,"assigned_user_id":null,"company_id":1,"status_id":2,"project_id":null,"vendor_id":null,"recurring_id":null,"design_id":2,"invoice_id":null,"number":"0002","discount":9,"is_amount_discount":true,"po_number":"Omnis.","date":"1988-11-22","last_sent_date":null,"due_date":null,"next_send_date":null,"is_deleted":false,"line_items":[{"quantity":1,"cost":637,"product_key":"Nisi.","notes":"Ut ipsa rerum.","discount":0,"is_amount_discount":true,"tax_name1":"VAT","tax_rate1":17.5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":637,"gross_line_total":738.44,"custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"42","custom_value3":"Maxime dolores.","custom_value4":"Odio consequatur.","type_id":"1","product_cost":0,"tax_amount":101.44,"date":"","tax_id":"","task_id":"","expense_id":""},{"quantity":1,"cost":637,"product_key":"Nisi.","notes":"Ut ipsa rerum.","discount":0,"is_amount_discount":true,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":637,"gross_line_total":665.98,"custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"42","custom_value3":"Maxime dolores.","custom_value4":"Odio consequatur.","type_id":"1","product_cost":0,"tax_amount":28.98,"date":"","tax_id":"","task_id":"","expense_id":""},{"quantity":1,"cost":637,"product_key":"Nisi.","notes":"Ut ipsa rerum.","discount":0,"is_amount_discount":true,"tax_name1":"Sales Tax","tax_rate1":5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":637,"gross_line_total":665.98,"custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"42","custom_value3":"Maxime dolores.","custom_value4":"Odio consequatur.","type_id":"1","product_cost":0,"tax_amount":28.98,"date":"","tax_id":"","task_id":"","expense_id":""},{"quantity":1,"cost":637,"product_key":"Nisi.","notes":"Ut ipsa rerum.","discount":0,"is_amount_discount":true,"tax_name1":"GST","tax_rate1":10,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":637,"gross_line_total":694.97,"custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"42","custom_value3":"Maxime dolores.","custom_value4":"Odio consequatur.","type_id":"1","product_cost":0,"tax_amount":57.97,"date":"","tax_id":"","task_id":"","expense_id":""},{"quantity":1,"cost":637,"product_key":"Nisi.","notes":"Ut ipsa rerum.","discount":0,"is_amount_discount":true,"tax_name1":"VAT","tax_rate1":17.5,"tax_name2":"","tax_rate2":0,"tax_name3":"","tax_rate3":0,"sort_id":0,"line_total":637,"gross_line_total":738.44,"custom_value1":"https:\/\/picsum.photos\/200","custom_value2":"42","custom_value3":"Maxime dolores.","custom_value4":"Odio consequatur.","type_id":"1","product_cost":0,"tax_amount":101.44,"date":"","tax_id":"","task_id":"","expense_id":""}],"backup":null,"footer":null,"public_notes":null,"private_notes":null,"terms":null,"tax_name1":"GST","tax_rate1":"10.000000","tax_name2":"VAT","tax_rate2":"17.500000","tax_name3":"THIRDTAX","tax_rate3":"5.000000","total_taxes":"1381.560000","uses_inclusive_taxes":0,"custom_value1":null,"custom_value2":null,"custom_value3":null,"custom_value4":null,"custom_surcharge1":null,"custom_surcharge2":null,"custom_surcharge3":null,"custom_surcharge4":null,"custom_surcharge_tax1":0,"custom_surcharge_tax2":0,"custom_surcharge_tax3":0,"custom_surcharge_tax4":0,"exchange_rate":"1.000000","amount":"4557.560000","balance":"0.000000","partial":null,"partial_due_date":null,"last_viewed":null,"created_at":1695943654,"updated_at":1696118643,"deleted_at":null,"reminder1_sent":null,"reminder2_sent":null,"reminder3_sent":null,"reminder_last_sent":null,"paid_to_date":"0.000000","subscription_id":null,"hashed_id":"Wpmbk5ezJn"}]'; public function __construct(public Company $company) { diff --git a/app/Services/Template/TemplateService.php b/app/Services/Template/TemplateService.php index dd578ca6ee17..c4894b674dd9 100644 --- a/app/Services/Template/TemplateService.php +++ b/app/Services/Template/TemplateService.php @@ -221,6 +221,7 @@ class TemplateService $this->entity = $this->company->invoices()->first() ?? $this->company->quotes()->first(); $this->data = $tm->engines; + $this->variables = $tm->variables[0]; $this->twig->addGlobal('currency_code', $this->company->currency()->code); $this->twig->addGlobal('show_credits', true); @@ -979,6 +980,7 @@ class TemplateService return [ 'name' => $user->present()->name(), 'email' => $user->email, + 'signature' => $user->signature ?? '', ]; } diff --git a/app/Utils/HtmlEngine.php b/app/Utils/HtmlEngine.php index aadea2190f25..e39f257e068a 100644 --- a/app/Utils/HtmlEngine.php +++ b/app/Utils/HtmlEngine.php @@ -399,7 +399,9 @@ class HtmlEngine $data['$taxes'] = ['value' => Number::formatMoney($this->entity_calc->getItemTotalTaxes(), $this->client) ?: ' ', 'label' => ctrans('texts.taxes')]; $data['$invoice.taxes'] = &$data['$taxes']; + $data['$user.name'] = ['value' => $this->entity->user->present()->name(), 'label' => ctrans('texts.name')]; + $data['$user.signature'] = ['value' => $this->entity->user->signature ?? '', 'label' => ctrans('texts.signature')]; $data['$user.first_name'] = ['value' => $this->entity->user->first_name, 'label' => ctrans('texts.first_name')]; $data['$user.last_name'] = ['value' => $this->entity->user->last_name, 'label' => ctrans('texts.last_name')]; $data['$created_by_user'] = &$data['$user.name']; @@ -731,6 +733,7 @@ class HtmlEngine $data['$payment.number'] = ['value' => '', 'label' => ctrans('texts.payment_number')]; $data['$payment.transaction_reference'] = ['value' => '', 'label' => ctrans('texts.transaction_reference')]; $data['$payment.refunded'] = ['value' => '', 'label' => ctrans('texts.refund')]; + $data['$gateway_payment_error'] = ['value' => '', 'label' => ctrans('texts.error')]; if ($this->entity_string == 'invoice' && $this->entity->net_payments()->exists()) { $payment_list = '

'; diff --git a/composer.json b/composer.json index 908e8d120e91..4fac873d9d2f 100644 --- a/composer.json +++ b/composer.json @@ -81,7 +81,7 @@ "nelexa/zip": "^4.0", "nordigen/nordigen-php": "^1.1", "nwidart/laravel-modules": "^11.0", - "phpoffice/phpspreadsheet": "^1.29", + "phpoffice/phpspreadsheet": "^2.2", "pragmarx/google2fa": "^8.0", "predis/predis": "^2", "psr/http-message": "^1.0", diff --git a/composer.lock b/composer.lock index 99bd45a9d6b3..4fe7132906fd 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "9e7ea46cfef2848f4eac13cc9c0c679a", + "content-hash": "ffb9ecf55b32b2e829fdfd750cf2416b", "packages": [ { "name": "adrienrn/php-mimetyper", @@ -535,16 +535,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.320.5", + "version": "3.321.1", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "afda5aefd59da90208d2f59427ce81e91535b1f2" + "reference": "f4ad64dffc2665dde6275e6dcc3f653f15c6e57f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/afda5aefd59da90208d2f59427ce81e91535b1f2", - "reference": "afda5aefd59da90208d2f59427ce81e91535b1f2", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/f4ad64dffc2665dde6275e6dcc3f653f15c6e57f", + "reference": "f4ad64dffc2665dde6275e6dcc3f653f15c6e57f", "shasum": "" }, "require": { @@ -627,9 +627,9 @@ "support": { "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.320.5" + "source": "https://github.com/aws/aws-sdk-php/tree/3.321.1" }, - "time": "2024-08-21T18:14:31+00:00" + "time": "2024-08-29T19:10:23+00:00" }, { "name": "bacon/bacon-qr-code", @@ -975,16 +975,16 @@ }, { "name": "checkout/checkout-sdk-php", - "version": "3.2.2", + "version": "3.2.4", "source": { "type": "git", "url": "https://github.com/checkout/checkout-sdk-php.git", - "reference": "ac757648271894e3c30b7bc58ff08ba1b5b84de8" + "reference": "cec8d6a3e0959d89f739041ea3ea605d86af634e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/checkout/checkout-sdk-php/zipball/ac757648271894e3c30b7bc58ff08ba1b5b84de8", - "reference": "ac757648271894e3c30b7bc58ff08ba1b5b84de8", + "url": "https://api.github.com/repos/checkout/checkout-sdk-php/zipball/cec8d6a3e0959d89f739041ea3ea605d86af634e", + "reference": "cec8d6a3e0959d89f739041ea3ea605d86af634e", "shasum": "" }, "require": { @@ -1037,9 +1037,9 @@ ], "support": { "issues": "https://github.com/checkout/checkout-sdk-php/issues", - "source": "https://github.com/checkout/checkout-sdk-php/tree/3.2.2" + "source": "https://github.com/checkout/checkout-sdk-php/tree/3.2.4" }, - "time": "2024-08-02T08:07:53+00:00" + "time": "2024-08-29T07:34:57+00:00" }, { "name": "composer/ca-bundle", @@ -2015,67 +2015,6 @@ }, "time": "2022-08-04T05:24:33+00:00" }, - { - "name": "ezyang/htmlpurifier", - "version": "v4.17.0", - "source": { - "type": "git", - "url": "https://github.com/ezyang/htmlpurifier.git", - "reference": "bbc513d79acf6691fa9cf10f192c90dd2957f18c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/bbc513d79acf6691fa9cf10f192c90dd2957f18c", - "reference": "bbc513d79acf6691fa9cf10f192c90dd2957f18c", - "shasum": "" - }, - "require": { - "php": "~5.6.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0" - }, - "require-dev": { - "cerdic/css-tidy": "^1.7 || ^2.0", - "simpletest/simpletest": "dev-master" - }, - "suggest": { - "cerdic/css-tidy": "If you want to use the filter 'Filter.ExtractStyleBlocks'.", - "ext-bcmath": "Used for unit conversion and imagecrash protection", - "ext-iconv": "Converts text to and from non-UTF-8 encodings", - "ext-tidy": "Used for pretty-printing HTML" - }, - "type": "library", - "autoload": { - "files": [ - "library/HTMLPurifier.composer.php" - ], - "psr-0": { - "HTMLPurifier": "library/" - }, - "exclude-from-classmap": [ - "/library/HTMLPurifier/Language/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-2.1-or-later" - ], - "authors": [ - { - "name": "Edward Z. Yang", - "email": "admin@htmlpurifier.org", - "homepage": "http://ezyang.com" - } - ], - "description": "Standards compliant HTML filter written in PHP", - "homepage": "http://htmlpurifier.org/", - "keywords": [ - "html" - ], - "support": { - "issues": "https://github.com/ezyang/htmlpurifier/issues", - "source": "https://github.com/ezyang/htmlpurifier/tree/v4.17.0" - }, - "time": "2023-11-17T15:01:25+00:00" - }, { "name": "fakerphp/faker", "version": "v1.23.1", @@ -2522,16 +2461,16 @@ }, { "name": "google/apiclient-services", - "version": "v0.369.0", + "version": "v0.370.0", "source": { "type": "git", "url": "https://github.com/googleapis/google-api-php-client-services.git", - "reference": "002f610e4c3acf0636b4fb1f46314a2097e1c8b4" + "reference": "25ad8515701dd832313d0f5f0a828670d60e541a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/002f610e4c3acf0636b4fb1f46314a2097e1c8b4", - "reference": "002f610e4c3acf0636b4fb1f46314a2097e1c8b4", + "url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/25ad8515701dd832313d0f5f0a828670d60e541a", + "reference": "25ad8515701dd832313d0f5f0a828670d60e541a", "shasum": "" }, "require": { @@ -2560,22 +2499,22 @@ ], "support": { "issues": "https://github.com/googleapis/google-api-php-client-services/issues", - "source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.369.0" + "source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.370.0" }, - "time": "2024-08-14T20:31:16+00:00" + "time": "2024-08-26T01:04:18+00:00" }, { "name": "google/auth", - "version": "v1.41.0", + "version": "v1.42.0", "source": { "type": "git", "url": "https://github.com/googleapis/google-auth-library-php.git", - "reference": "1043ea18fe7f5dfbf5b208ce3ee6d6b6ab8cb038" + "reference": "0c25599a91530b5847f129b271c536f75a7563f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/googleapis/google-auth-library-php/zipball/1043ea18fe7f5dfbf5b208ce3ee6d6b6ab8cb038", - "reference": "1043ea18fe7f5dfbf5b208ce3ee6d6b6ab8cb038", + "url": "https://api.github.com/repos/googleapis/google-auth-library-php/zipball/0c25599a91530b5847f129b271c536f75a7563f5", + "reference": "0c25599a91530b5847f129b271c536f75a7563f5", "shasum": "" }, "require": { @@ -2620,9 +2559,9 @@ "support": { "docs": "https://googleapis.github.io/google-auth-library-php/main/", "issues": "https://github.com/googleapis/google-auth-library-php/issues", - "source": "https://github.com/googleapis/google-auth-library-php/tree/v1.41.0" + "source": "https://github.com/googleapis/google-auth-library-php/tree/v1.42.0" }, - "time": "2024-07-10T15:21:07+00:00" + "time": "2024-08-26T18:33:48+00:00" }, { "name": "graham-campbell/result-type", @@ -3999,12 +3938,12 @@ "source": { "type": "git", "url": "https://github.com/invoiceninja/einvoice.git", - "reference": "d4f80316744bbd31245900ec9799a6f66a663ed6" + "reference": "1ec178ec134981629932aae12677e947ee3df091" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/invoiceninja/einvoice/zipball/d4f80316744bbd31245900ec9799a6f66a663ed6", - "reference": "d4f80316744bbd31245900ec9799a6f66a663ed6", + "url": "https://api.github.com/repos/invoiceninja/einvoice/zipball/1ec178ec134981629932aae12677e947ee3df091", + "reference": "1ec178ec134981629932aae12677e947ee3df091", "shasum": "" }, "require": { @@ -4046,7 +3985,7 @@ "source": "https://github.com/invoiceninja/einvoice/tree/main", "issues": "https://github.com/invoiceninja/einvoice/issues" }, - "time": "2024-07-22T02:40:27+00:00" + "time": "2024-08-28T07:20:26+00:00" }, { "name": "invoiceninja/inspector", @@ -8102,16 +8041,16 @@ }, { "name": "phpoffice/phpspreadsheet", - "version": "1.29.0", + "version": "2.2.2", "source": { "type": "git", "url": "https://github.com/PHPOffice/PhpSpreadsheet.git", - "reference": "fde2ccf55eaef7e86021ff1acce26479160a0fa0" + "reference": "ffbcee68069b073bff07a71eb321dcd9f2763513" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/fde2ccf55eaef7e86021ff1acce26479160a0fa0", - "reference": "fde2ccf55eaef7e86021ff1acce26479160a0fa0", + "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/ffbcee68069b073bff07a71eb321dcd9f2763513", + "reference": "ffbcee68069b073bff07a71eb321dcd9f2763513", "shasum": "" }, "require": { @@ -8128,25 +8067,24 @@ "ext-xmlwriter": "*", "ext-zip": "*", "ext-zlib": "*", - "ezyang/htmlpurifier": "^4.15", "maennchen/zipstream-php": "^2.1 || ^3.0", "markbaker/complex": "^3.0", "markbaker/matrix": "^3.0", - "php": "^7.4 || ^8.0", + "php": "^8.1", "psr/http-client": "^1.0", "psr/http-factory": "^1.0", "psr/simple-cache": "^1.0 || ^2.0 || ^3.0" }, "require-dev": { "dealerdirect/phpcodesniffer-composer-installer": "dev-main", - "dompdf/dompdf": "^1.0 || ^2.0", + "dompdf/dompdf": "^2.0 || ^3.0", "friendsofphp/php-cs-fixer": "^3.2", "mitoteam/jpgraph": "^10.3", "mpdf/mpdf": "^8.1.1", "phpcompatibility/php-compatibility": "^9.3", "phpstan/phpstan": "^1.1", "phpstan/phpstan-phpunit": "^1.0", - "phpunit/phpunit": "^8.5 || ^9.0 || ^10.0", + "phpunit/phpunit": "^9.6 || ^10.5", "squizlabs/php_codesniffer": "^3.7", "tecnickcom/tcpdf": "^6.5" }, @@ -8201,9 +8139,9 @@ ], "support": { "issues": "https://github.com/PHPOffice/PhpSpreadsheet/issues", - "source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/1.29.0" + "source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/2.2.2" }, - "time": "2023-06-14T22:48:31+00:00" + "time": "2024-08-08T02:31:26+00:00" }, { "name": "phpoption/phpoption", @@ -8392,16 +8330,16 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "1.29.1", + "version": "1.30.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4" + "reference": "5ceb0e384997db59f38774bf79c2a6134252c08f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/fcaefacf2d5c417e928405b71b400d4ce10daaf4", - "reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/5ceb0e384997db59f38774bf79c2a6134252c08f", + "reference": "5ceb0e384997db59f38774bf79c2a6134252c08f", "shasum": "" }, "require": { @@ -8433,9 +8371,9 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.29.1" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.30.0" }, - "time": "2024-05-31T08:52:43+00:00" + "time": "2024-08-29T09:54:52+00:00" }, { "name": "pragmarx/google2fa", @@ -14284,20 +14222,20 @@ }, { "name": "twig/intl-extra", - "version": "v3.11.0", + "version": "v3.12.0", "source": { "type": "git", "url": "https://github.com/twigphp/intl-extra.git", - "reference": "e9cadd61342e71e45b2f4f0558122433fd7e4566" + "reference": "61e1189333120a475d2b67b93664b8002668fc27" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/intl-extra/zipball/e9cadd61342e71e45b2f4f0558122433fd7e4566", - "reference": "e9cadd61342e71e45b2f4f0558122433fd7e4566", + "url": "https://api.github.com/repos/twigphp/intl-extra/zipball/61e1189333120a475d2b67b93664b8002668fc27", + "reference": "61e1189333120a475d2b67b93664b8002668fc27", "shasum": "" }, "require": { - "php": ">=7.2.5", + "php": ">=8.0.2", "symfony/intl": "^5.4|^6.4|^7.0", "twig/twig": "^3.10" }, @@ -14332,7 +14270,7 @@ "twig" ], "support": { - "source": "https://github.com/twigphp/intl-extra/tree/v3.11.0" + "source": "https://github.com/twigphp/intl-extra/tree/v3.12.0" }, "funding": [ { @@ -14344,28 +14282,27 @@ "type": "tidelift" } ], - "time": "2024-06-21T06:25:01+00:00" + "time": "2024-08-10T10:32:24+00:00" }, { "name": "twig/twig", - "version": "v3.11.0", + "version": "v3.12.0", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "e80fb8ebba85c7341a97a9ebf825d7fd4b77708d" + "reference": "4d19472d4ac1838e0b1f0e029ce1fa4040eb34ea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/e80fb8ebba85c7341a97a9ebf825d7fd4b77708d", - "reference": "e80fb8ebba85c7341a97a9ebf825d7fd4b77708d", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/4d19472d4ac1838e0b1f0e029ce1fa4040eb34ea", + "reference": "4d19472d4ac1838e0b1f0e029ce1fa4040eb34ea", "shasum": "" }, "require": { - "php": ">=7.2.5", + "php": ">=8.0.2", "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-ctype": "^1.8", "symfony/polyfill-mbstring": "^1.3", - "symfony/polyfill-php80": "^1.22", "symfony/polyfill-php81": "^1.29" }, "require-dev": { @@ -14412,7 +14349,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.11.0" + "source": "https://github.com/twigphp/Twig/tree/v3.12.0" }, "funding": [ { @@ -14424,7 +14361,7 @@ "type": "tidelift" } ], - "time": "2024-08-08T16:15:16+00:00" + "time": "2024-08-29T09:51:12+00:00" }, { "name": "twilio/sdk", @@ -15254,16 +15191,16 @@ }, { "name": "composer/pcre", - "version": "3.3.0", + "version": "3.3.1", "source": { "type": "git", "url": "https://github.com/composer/pcre.git", - "reference": "1637e067347a0c40bbb1e3cd786b20dcab556a81" + "reference": "63aaeac21d7e775ff9bc9d45021e1745c97521c4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/pcre/zipball/1637e067347a0c40bbb1e3cd786b20dcab556a81", - "reference": "1637e067347a0c40bbb1e3cd786b20dcab556a81", + "url": "https://api.github.com/repos/composer/pcre/zipball/63aaeac21d7e775ff9bc9d45021e1745c97521c4", + "reference": "63aaeac21d7e775ff9bc9d45021e1745c97521c4", "shasum": "" }, "require": { @@ -15313,7 +15250,7 @@ ], "support": { "issues": "https://github.com/composer/pcre/issues", - "source": "https://github.com/composer/pcre/tree/3.3.0" + "source": "https://github.com/composer/pcre/tree/3.3.1" }, "funding": [ { @@ -15329,7 +15266,7 @@ "type": "tidelift" } ], - "time": "2024-08-19T19:43:53+00:00" + "time": "2024-08-27T18:44:43+00:00" }, { "name": "composer/semver", @@ -15659,16 +15596,16 @@ }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.62.0", + "version": "v3.63.2", "source": { "type": "git", "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", - "reference": "627692f794d35c43483f34b01d94740df2a73507" + "reference": "9d427f3f14984403a6ae9fc726b61765ca0c005e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/627692f794d35c43483f34b01d94740df2a73507", - "reference": "627692f794d35c43483f34b01d94740df2a73507", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/9d427f3f14984403a6ae9fc726b61765ca0c005e", + "reference": "9d427f3f14984403a6ae9fc726b61765ca0c005e", "shasum": "" }, "require": { @@ -15750,7 +15687,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.62.0" + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.63.2" }, "funding": [ { @@ -15758,7 +15695,7 @@ "type": "github" } ], - "time": "2024-08-07T17:03:09+00:00" + "time": "2024-08-28T10:47:21+00:00" }, { "name": "hamcrest/hamcrest-php", @@ -16340,16 +16277,16 @@ }, { "name": "phpmyadmin/sql-parser", - "version": "5.9.1", + "version": "5.10.0", "source": { "type": "git", "url": "https://github.com/phpmyadmin/sql-parser.git", - "reference": "169a9f11f1957ea36607c9b29eac1b48679f1ecc" + "reference": "91d980ab76c3f152481e367f62b921adc38af451" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpmyadmin/sql-parser/zipball/169a9f11f1957ea36607c9b29eac1b48679f1ecc", - "reference": "169a9f11f1957ea36607c9b29eac1b48679f1ecc", + "url": "https://api.github.com/repos/phpmyadmin/sql-parser/zipball/91d980ab76c3f152481e367f62b921adc38af451", + "reference": "91d980ab76c3f152481e367f62b921adc38af451", "shasum": "" }, "require": { @@ -16423,20 +16360,20 @@ "type": "other" } ], - "time": "2024-08-13T19:01:01+00:00" + "time": "2024-08-29T20:56:34+00:00" }, { "name": "phpstan/phpstan", - "version": "1.11.11", + "version": "1.12.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "707c2aed5d8d0075666e673a5e71440c1d01a5a3" + "reference": "384af967d35b2162f69526c7276acadce534d0e1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/707c2aed5d8d0075666e673a5e71440c1d01a5a3", - "reference": "707c2aed5d8d0075666e673a5e71440c1d01a5a3", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/384af967d35b2162f69526c7276acadce534d0e1", + "reference": "384af967d35b2162f69526c7276acadce534d0e1", "shasum": "" }, "require": { @@ -16481,36 +16418,36 @@ "type": "github" } ], - "time": "2024-08-19T14:37:29+00:00" + "time": "2024-08-27T09:18:05+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "10.1.15", + "version": "10.1.16", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "5da8b1728acd1e6ffdf2ff32ffbdfd04307f26ae" + "reference": "7e308268858ed6baedc8704a304727d20bc07c77" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/5da8b1728acd1e6ffdf2ff32ffbdfd04307f26ae", - "reference": "5da8b1728acd1e6ffdf2ff32ffbdfd04307f26ae", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/7e308268858ed6baedc8704a304727d20bc07c77", + "reference": "7e308268858ed6baedc8704a304727d20bc07c77", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.18 || ^5.0", + "nikic/php-parser": "^4.19.1 || ^5.1.0", "php": ">=8.1", - "phpunit/php-file-iterator": "^4.0", - "phpunit/php-text-template": "^3.0", - "sebastian/code-unit-reverse-lookup": "^3.0", - "sebastian/complexity": "^3.0", - "sebastian/environment": "^6.0", - "sebastian/lines-of-code": "^2.0", - "sebastian/version": "^4.0", - "theseer/tokenizer": "^1.2.0" + "phpunit/php-file-iterator": "^4.1.0", + "phpunit/php-text-template": "^3.0.1", + "sebastian/code-unit-reverse-lookup": "^3.0.0", + "sebastian/complexity": "^3.2.0", + "sebastian/environment": "^6.1.0", + "sebastian/lines-of-code": "^2.0.2", + "sebastian/version": "^4.0.1", + "theseer/tokenizer": "^1.2.3" }, "require-dev": { "phpunit/phpunit": "^10.1" @@ -16522,7 +16459,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "10.1-dev" + "dev-main": "10.1.x-dev" } }, "autoload": { @@ -16551,7 +16488,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.15" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.16" }, "funding": [ { @@ -16559,7 +16496,7 @@ "type": "github" } ], - "time": "2024-06-29T08:25:15+00:00" + "time": "2024-08-22T04:31:57+00:00" }, { "name": "phpunit/php-file-iterator", diff --git a/config/livewire.php b/config/livewire.php index 8a810cfdf660..0d2ba89ba2dc 100644 --- a/config/livewire.php +++ b/config/livewire.php @@ -38,7 +38,7 @@ return [ | */ - 'layout' => 'layouts.app', + 'layout' => 'components.layouts.app', /* |--------------------------------------------------------------------------- @@ -74,6 +74,7 @@ return [ 'jpg', 'jpeg', 'mpga', 'webp', 'wma', ], 'max_upload_time' => 5, // Max duration (in minutes) before an upload is invalidated... + 'cleanup' => true, // Should cleanup temporary uploads older than 24 hrs... ], /* @@ -100,7 +101,7 @@ return [ | */ - 'legacy_model_binding' => true, + 'legacy_model_binding' => false, /* |--------------------------------------------------------------------------- diff --git a/config/ninja.php b/config/ninja.php index d152f711c57c..81179044c820 100644 --- a/config/ninja.php +++ b/config/ninja.php @@ -46,6 +46,7 @@ return [ 'preconfigured_install' => env('PRECONFIGURED_INSTALL', false), 'update_secret' => env('UPDATE_SECRET', ''), 'license_key' => env('LICENSE_KEY', false), + 'hosted_ninja_url' => env('HOSTED_NINJA_URL', 'https://invoicing.co'), // Settings used by invoiceninja.com 'disks' => [ 'backup' => env('BACKUP_DISK', 's3'), diff --git a/database/migrations/2024_08_26_055523_add_qb_product_hash.php b/database/migrations/2024_08_26_055523_add_qb_product_hash.php index 89177311e718..5bbd59e8e30c 100644 --- a/database/migrations/2024_08_26_055523_add_qb_product_hash.php +++ b/database/migrations/2024_08_26_055523_add_qb_product_hash.php @@ -14,6 +14,17 @@ return new class extends Migration Schema::table('products', function (Blueprint $table){ $table->string('hash')->nullable(); }); + + Schema::table('companies', function (Blueprint $table){ + $table->bigInteger('legal_entity_id')->nullable(); + }); + + + if($currency = \App\Models\Currency::find(39)) + { + $currency->symbol = 'лв'; + $currency->save(); + } } /** diff --git a/database/seeders/CurrenciesSeeder.php b/database/seeders/CurrenciesSeeder.php index 2ea762c575e7..83f69318659e 100644 --- a/database/seeders/CurrenciesSeeder.php +++ b/database/seeders/CurrenciesSeeder.php @@ -61,7 +61,7 @@ class CurrenciesSeeder extends Seeder ['id' => 36, 'name' => 'Trinidad and Tobago Dollar', 'code' => 'TTD', 'symbol' => 'TT$', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'], ['id' => 37, 'name' => 'East Caribbean Dollar', 'code' => 'XCD', 'symbol' => 'EC$', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'], ['id' => 38, 'name' => 'Ghanaian Cedi', 'code' => 'GHS', 'symbol' => '', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'], - ['id' => 39, 'name' => 'Bulgarian Lev', 'code' => 'BGN', 'symbol' => '', 'precision' => '2', 'thousand_separator' => ' ', 'decimal_separator' => '.'], + ['id' => 39, 'name' => 'Bulgarian Lev', 'code' => 'BGN', 'symbol' => 'лв', 'precision' => '2', 'thousand_separator' => ' ', 'decimal_separator' => '.'], ['id' => 40, 'name' => 'Aruban Florin', 'code' => 'AWG', 'symbol' => 'Afl. ', 'precision' => '2', 'thousand_separator' => ' ', 'decimal_separator' => '.'], ['id' => 41, 'name' => 'Turkish Lira', 'code' => 'TRY', 'symbol' => 'TL ', 'precision' => '2', 'thousand_separator' => '.', 'decimal_separator' => ','], ['id' => 42, 'name' => 'Romanian New Leu', 'code' => 'RON', 'symbol' => '', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'], diff --git a/lang/en/texts.php b/lang/en/texts.php index 55ded895bd16..676eee819cb4 100644 --- a/lang/en/texts.php +++ b/lang/en/texts.php @@ -5321,6 +5321,11 @@ $lang = array( 'applies_to' => 'Applies To', 'accept_purchase_order' => 'Accept Purchase Order', 'round_to_seconds' => 'Round To Seconds', + 'activity_142' => 'Quote :number reminder 1 sent', + 'activity_143' => 'Auto Bill succeeded for invoice :invoice', + 'activity_144' => 'Auto Bill failed for invoice :invoice. :notes', + 'activity_145' => 'EInvoice :invoice for :client was e-delivered. :notes', + ); return $lang; diff --git a/package-lock.json b/package-lock.json index 19ed6616d33e..3c1cb2273643 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,7 +4,6 @@ "requires": true, "packages": { "": { - "name": "invoiceninja", "dependencies": { "@invoiceninja/simple-card": "^0.0.2", "axios": "^0.25", diff --git a/phpstan.neon b/phpstan.neon index 1811c3080b13..aeb4c03e7948 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -37,4 +37,6 @@ parameters: - '#Expression on left side of ?? is not nullable.#' - '#Left side of && is always true.#' - '#Right side of && is always true.#' + - '#is never read, only written.#' + - '#is never written#' \ No newline at end of file diff --git a/public/build/assets/app-234e3402.js b/public/build/assets/app-234e3402.js deleted file mode 100644 index 987442a68737..000000000000 --- 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 `