diff --git a/.github/workflows/react_release.yml b/.github/workflows/react_release.yml index f94ad90e6c63..2c795b37ddc8 100644 --- a/.github/workflows/react_release.yml +++ b/.github/workflows/react_release.yml @@ -49,7 +49,8 @@ jobs: npm i npm run build cp -r dist/* ../public/ - + cp dist/index.html ../resources/views/react/index.blade.php + - name: Prepare JS/CSS assets run: | npm i diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1c78bcbe7608..8204134564c3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -50,7 +50,8 @@ jobs: mkdir -p ../public/react/${{ github.event.release.tag_name }}/ cp -r dist/react/* ../public/react/${{ github.event.release.tag_name }}/ cp -r dist/react/* ../public/react/ - + cp dist/index.html ../resources/views/react/index.blade.php + mkdir -p ../public/tinymce_6.4.2/tinymce/js/ cp -r node_modules/tinymce ../public/tinymce_6.4.2/tinymce/js/ cd .. diff --git a/.gitignore b/.gitignore index 2b9f631c7963..0b3c53481c27 100644 --- a/.gitignore +++ b/.gitignore @@ -39,4 +39,5 @@ public/storage/test.pdf _ide_helper_models.php _ide_helper.php /composer.phar -.tx/ \ No newline at end of file +.tx/ +.phpunit.cache \ No newline at end of file diff --git a/VERSION.txt b/VERSION.txt index a1e5644bcb98..cd30fd94a6c7 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -5.8.39 \ No newline at end of file +5.8.45 \ No newline at end of file diff --git a/app/Console/Commands/ReactBuilder.php b/app/Console/Commands/ReactBuilder.php index 0bc9cc0f0587..f5e7838d51e8 100644 --- a/app/Console/Commands/ReactBuilder.php +++ b/app/Console/Commands/ReactBuilder.php @@ -42,35 +42,35 @@ class ReactBuilder extends Command /** * Execute the console command. * - * @return mixed + * @return void */ public function handle() { - $includes = ''; + // $includes = ''; - $directoryIterator = false; + // $directoryIterator = false; - try { - $directoryIterator = new \RecursiveDirectoryIterator(public_path('react/v'.config('ninja.app_version').'/'), \RecursiveDirectoryIterator::SKIP_DOTS); - } catch (\Exception $e) { - $this->error('React files not found'); - return; - } + // try { + // $directoryIterator = new \RecursiveDirectoryIterator(public_path('react/v'.config('ninja.app_version').'/'), \RecursiveDirectoryIterator::SKIP_DOTS); + // } catch (\Exception $e) { + // $this->error('React files not found'); + // return; + // } - foreach (new \RecursiveIteratorIterator($directoryIterator) as $file) { - if ($file->getExtension() == 'js') { - if (str_contains($file->getFileName(), 'index-')) { - $includes .= ''."\n"; - } else { - $includes .= ''."\n"; - } - } + // foreach (new \RecursiveIteratorIterator($directoryIterator) as $file) { + // if ($file->getExtension() == 'js') { + // if (str_contains($file->getFileName(), 'index-')) { + // $includes .= ''."\n"; + // } else { + // $includes .= ''."\n"; + // } + // } - if (str_contains($file->getFileName(), '.css')) { - $includes .= ''."\n"; - } - } + // if (str_contains($file->getFileName(), '.css')) { + // $includes .= ''."\n"; + // } + // } - file_put_contents(resource_path('views/react/head.blade.php'), $includes); + // file_put_contents(resource_path('views/react/head.blade.php'), $includes); } } diff --git a/app/DataMapper/InvoiceItem.php b/app/DataMapper/InvoiceItem.php index bf7b1513bffa..60d1c0ee4ca4 100644 --- a/app/DataMapper/InvoiceItem.php +++ b/app/DataMapper/InvoiceItem.php @@ -64,7 +64,9 @@ class InvoiceItem public $task_id = ''; public $expense_id = ''; - + + public $unit_code = 'C62'; + public static $casts = [ 'task_id' => 'string', 'expense_id' => 'string', @@ -92,5 +94,6 @@ class InvoiceItem 'custom_value2' => 'string', 'custom_value3' => 'string', 'custom_value4' => 'string', + 'unit_code' => 'string', ]; } diff --git a/app/Factory/SubscriptionFactory.php b/app/Factory/SubscriptionFactory.php index 8395afb10d83..315716b10772 100644 --- a/app/Factory/SubscriptionFactory.php +++ b/app/Factory/SubscriptionFactory.php @@ -11,7 +11,9 @@ namespace App\Factory; +use App\Livewire\BillingPortal\Purchase; use App\Models\Subscription; +use App\Services\Subscription\StepService; class SubscriptionFactory { @@ -20,6 +22,9 @@ class SubscriptionFactory $billing_subscription = new Subscription(); $billing_subscription->company_id = $company_id; $billing_subscription->user_id = $user_id; + $billing_subscription->steps = collect(Purchase::defaultSteps()) + ->map(fn($step) => StepService::mapClassNameToString($step)) + ->implode(','); return $billing_subscription; } diff --git a/app/Filters/TaskFilters.php b/app/Filters/TaskFilters.php index bae9ab882bb0..3356c538e08f 100644 --- a/app/Filters/TaskFilters.php +++ b/app/Filters/TaskFilters.php @@ -150,6 +150,19 @@ class TaskFilters extends QueryFilters return $this->builder->orderBy($sort_col[0], $dir); } + public function user_id(string $user = ''): Builder + { + if (strlen($user) == 0) { + return $this->builder; + } + + return $this->builder->where(function ($query) use ($user) { + $query->where('user_id', $this->decodePrimaryKey($user)) + ->orWhere('assigned_user_id', $this->decodePrimaryKey($user)); + }); + + } + public function task_status(string $value = ''): Builder { if (strlen($value) == 0) { diff --git a/app/Helpers/Subscription/SubscriptionCalculator.php b/app/Helpers/Subscription/SubscriptionCalculator.php deleted file mode 100644 index 4413b0d593a7..000000000000 --- a/app/Helpers/Subscription/SubscriptionCalculator.php +++ /dev/null @@ -1,96 +0,0 @@ -target_subscription = $target_subscription; - $this->invoice = $invoice; - } - - /** - * Tests if the user is currently up - * to date with their payments for - * a given recurring invoice - * - * @return bool - */ - public function isPaidUp(): bool - { - $outstanding_invoices_exist = Invoice::query()->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL]) - ->where('subscription_id', $this->invoice->subscription_id) - ->where('client_id', $this->invoice->client_id) - ->where('balance', '>', 0) - ->exists(); - - return ! $outstanding_invoices_exist; - } - - public function calcUpgradePlan() - { - //set the starting refund amount - $refund_amount = 0; - - $refund_invoice = false; - - //are they paid up to date. - - //yes - calculate refund - if ($this->isPaidUp()) { - $refund_invoice = $this->getRefundInvoice(); - } - - if ($refund_invoice) { - /** @var \App\Models\Subscription $subscription **/ - $subscription = Subscription::find($this->invoice->subscription_id); - $pro_rata = new ProRata(); - - $to_date = $subscription->service()->getNextDateForFrequency(Carbon::parse($refund_invoice->date), $subscription->frequency_id); - - $refund_amount = $pro_rata->refund($refund_invoice->amount, now(), $to_date, $subscription->frequency_id); - - $charge_amount = $pro_rata->charge($this->target_subscription->price, now(), $to_date, $this->target_subscription->frequency_id); - - return $charge_amount - $refund_amount; - } - - //no - return full freight charge. - return $this->target_subscription->price; - } - - public function executeUpgradePlan() - { - } - - private function getRefundInvoice() - { - return Invoice::where('subscription_id', $this->invoice->subscription_id) - ->where('client_id', $this->invoice->client_id) - ->where('is_deleted', 0) - ->orderBy('id', 'desc') - ->first(); - } -} diff --git a/app/Http/Controllers/Auth/ContactRegisterController.php b/app/Http/Controllers/Auth/ContactRegisterController.php index eb942c1780f3..b47dce8e54d4 100644 --- a/app/Http/Controllers/Auth/ContactRegisterController.php +++ b/app/Http/Controllers/Auth/ContactRegisterController.php @@ -11,17 +11,14 @@ namespace App\Http\Controllers\Auth; -use App\Factory\ClientContactFactory; -use App\Factory\ClientFactory; use App\Http\Controllers\Controller; use App\Http\Requests\ClientPortal\RegisterRequest; -use App\Models\Client; +use App\Livewire\BillingPortal\Authentication\ClientRegisterService; use App\Models\Company; use App\Utils\Ninja; use App\Utils\Traits\GeneratesCounter; use Illuminate\Support\Facades\App; use Illuminate\Support\Facades\Auth; -use Illuminate\Support\Facades\Hash; class ContactRegisterController extends Controller { @@ -53,53 +50,16 @@ class ContactRegisterController extends Controller public function register(RegisterRequest $request) { $request->merge(['company' => $request->company()]); + + $service = new ClientRegisterService( + company: $request->company(), + ); - $client = $this->getClient($request->all()); - $client_contact = $this->getClientContact($request->all(), $client); + $client = $service->createClient($request->all()); + $client_contact = $service->createClientContact($request->all(), $client); Auth::guard('contact')->loginUsingId($client_contact->id, true); return redirect()->intended(route('client.dashboard')); } - - private function getClient(array $data) - { - $client = ClientFactory::create($data['company']->id, $data['company']->owner()->id); - - $client->fill($data); - - $client->save(); - - if (isset($data['currency_id'])) { - $settings = $client->settings; - $settings->currency_id = isset($data['currency_id']) ? $data['currency_id'] : $data['company']->settings->currency_id; - $client->settings = $settings; - } - - $client->number = $this->getNextClientNumber($client); - $client->save(); - - if (! array_key_exists('country_id', $data) && strlen($client->company->settings->country_id) > 1) { - $client->update(['country_id' => $client->company->settings->country_id]); - } - - return $client; - } - - public function getClientContact(array $data, Client $client) - { - $client_contact = ClientContactFactory::create($data['company']->id, $data['company']->owner()->id); - $client_contact->fill($data); - - $client_contact->client_id = $client->id; - $client_contact->is_primary = true; - - if (array_key_exists('password', $data)) { - $client_contact->password = Hash::make($data['password']); - } - - $client_contact->save(); - - return $client_contact; - } } diff --git a/app/Http/Controllers/ClientController.php b/app/Http/Controllers/ClientController.php index e5098f1876d0..8321ca1fffff 100644 --- a/app/Http/Controllers/ClientController.php +++ b/app/Http/Controllers/ClientController.php @@ -237,7 +237,7 @@ class ClientController extends BaseController $hash_or_response = $request->boolean('send_email') ? 'email sent' : \Illuminate\Support\Str::uuid(); TemplateAction::dispatch( - $clients->pluck('id')->toArray(), + $clients->pluck('hashed_id')->toArray(), $request->template_id, Client::class, $user->id, @@ -250,6 +250,14 @@ class ClientController extends BaseController return response()->json(['message' => $hash_or_response], 200); } + if($action == 'assign_group' && $user->can('edit', $clients->first())){ + + $this->client_repo->assignGroup($clients, $request->group_settings_id); + + return $this->listResponse(Client::query()->withTrashed()->company()->whereIn('id', $request->ids)); + + } + $clients->each(function ($client) use ($action, $user) { if ($user->can('edit', $client)) { $this->client_repo->{$action}($client); diff --git a/app/Http/Controllers/ClientPortal/PrePaymentController.php b/app/Http/Controllers/ClientPortal/PrePaymentController.php index 643a05aba46d..d2659d566064 100644 --- a/app/Http/Controllers/ClientPortal/PrePaymentController.php +++ b/app/Http/Controllers/ClientPortal/PrePaymentController.php @@ -105,6 +105,13 @@ class PrePaymentController extends Controller return $invoice; }); + + $variables = false; + + if(($invitation = $invoices->first()->invitations()->first() ?? false) && $invoice->client->getSetting('show_accept_invoice_terms')) { + $variables = (new HtmlEngine($invitation))->generateLabelsAndValues(); + } + $data = [ 'settings' => auth()->guard('contact')->user()->client->getMergedSettings(), 'invoices' => $invoices, diff --git a/app/Http/Controllers/ClientPortal/SubscriptionPurchaseController.php b/app/Http/Controllers/ClientPortal/SubscriptionPurchaseController.php index ffc5e517eeaf..f7cdc576b093 100644 --- a/app/Http/Controllers/ClientPortal/SubscriptionPurchaseController.php +++ b/app/Http/Controllers/ClientPortal/SubscriptionPurchaseController.php @@ -75,6 +75,17 @@ class SubscriptionPurchaseController extends Controller ]); } + public function v3(Subscription $subscription, Request $request) + { + // Todo: Prerequirement checks for subscription. + + return view('billing-portal.v3.index', [ + 'subscription' => $subscription, + 'hash' => Str::uuid()->toString(), + 'request_data' => $request->all(), + ]); + } + /** * Set locale for incoming request. * diff --git a/app/Http/Controllers/CompanyGatewayController.php b/app/Http/Controllers/CompanyGatewayController.php index 8d69b3738a1c..fab62b6164c1 100644 --- a/app/Http/Controllers/CompanyGatewayController.php +++ b/app/Http/Controllers/CompanyGatewayController.php @@ -565,9 +565,11 @@ class CompanyGatewayController extends BaseController public function importCustomers(TestCompanyGatewayRequest $request, CompanyGateway $company_gateway) { + // $x = Cache::pull("throttle_polling:import_customers:{$company_gateway->company->company_key}:{$company_gateway->hashed_id}"); + //Throttle here - // if (Cache::get("throttle_polling:import_customers:{$company_gateway->company->company_key}:{$company_gateway->hashed_id}")) - // return response()->json(['message' => ctrans('texts.import_started')], 200); + if (Cache::has("throttle_polling:import_customers:{$company_gateway->company->company_key}:{$company_gateway->hashed_id}")) + return response()->json(['message' => 'Please wait whilst your previous attempts complete.'], 200); dispatch(function () use($company_gateway) { MultiDB::setDb($company_gateway->company->db); diff --git a/app/Http/Controllers/CreditController.php b/app/Http/Controllers/CreditController.php index e0db0722c133..b20285992506 100644 --- a/app/Http/Controllers/CreditController.php +++ b/app/Http/Controllers/CreditController.php @@ -781,7 +781,7 @@ class CreditController extends BaseController $contact = $invitation->contact; $credit = $invitation->credit; - $file = $credit->service()->getEInvoice($contact); + $file = $credit->service()->getECredit($contact); $file_name = $credit->getFileName("xml"); $headers = ['Content-Type' => 'application/xml']; diff --git a/app/Http/Controllers/PurchaseOrderController.php b/app/Http/Controllers/PurchaseOrderController.php index 1682380e02f1..4b5fa3981b3b 100644 --- a/app/Http/Controllers/PurchaseOrderController.php +++ b/app/Http/Controllers/PurchaseOrderController.php @@ -646,7 +646,6 @@ class PurchaseOrderController extends BaseController echo $file; }, $purchase_order->numberFormatter().".pdf", ['Content-Type' => 'application/pdf']); - break; case 'restore': $this->purchase_order_repository->restore($purchase_order); diff --git a/app/Http/Controllers/SubscriptionStepsController.php b/app/Http/Controllers/SubscriptionStepsController.php new file mode 100644 index 000000000000..81243ffbbba4 --- /dev/null +++ b/app/Http/Controllers/SubscriptionStepsController.php @@ -0,0 +1,43 @@ +map(fn($dependency) => [ + 'id' => $dependency['id'], + 'dependencies' => collect($dependency['dependencies']) + ->map(fn($dependency) => Purchase::$dependencies[$dependency]['id']) + ->toArray(), + ]) + ->toArray(); + + return response()->json($dependencies); + } + + public function check(): JsonResponse + { + request()->validate(([ + 'steps' => ['required', new Steps()] + ])); + + return response()->json([], 200); + } +} diff --git a/app/Http/Requests/Client/BulkClientRequest.php b/app/Http/Requests/Client/BulkClientRequest.php index bfe6a91cdde7..dbfad9556e35 100644 --- a/app/Http/Requests/Client/BulkClientRequest.php +++ b/app/Http/Requests/Client/BulkClientRequest.php @@ -35,10 +35,11 @@ class BulkClientRequest extends Request $user = auth()->user(); return [ - 'action' => 'required|string|in:archive,restore,delete,template', + 'action' => 'required|string|in:archive,restore,delete,template,assign_group', 'ids' => ['required','bail','array',Rule::exists('clients', 'id')->where('company_id', $user->company()->id)], 'template' => 'sometimes|string', 'template_id' => 'sometimes|string', + 'group_settings_id' => ['required_if:action,assign_group',Rule::exists('group_settings', 'id')->where('company_id', $user->company()->id)], 'send_email' => 'sometimes|bool' ]; @@ -52,6 +53,10 @@ class BulkClientRequest extends Request $input['ids'] = $this->transformKeys($input['ids']); } + if (isset($input['group_settings_id'])) { + $input['group_settings_id'] = $this->decodePrimaryKey($input['group_settings_id']); + } + $this->replace($input); } } diff --git a/app/Http/Requests/Subscription/StoreSubscriptionRequest.php b/app/Http/Requests/Subscription/StoreSubscriptionRequest.php index 2a358ac37a94..1831366c7414 100644 --- a/app/Http/Requests/Subscription/StoreSubscriptionRequest.php +++ b/app/Http/Requests/Subscription/StoreSubscriptionRequest.php @@ -14,6 +14,7 @@ namespace App\Http\Requests\Subscription; use App\Http\Requests\Request; use App\Models\Account; use App\Models\Subscription; +use App\Rules\Subscriptions\Steps; use Illuminate\Validation\Rule; class StoreSubscriptionRequest extends Request @@ -63,7 +64,8 @@ class StoreSubscriptionRequest extends Request 'registration_required' => 'bail|sometimes|bool', 'optional_recurring_product_ids' => 'bail|sometimes|nullable|string', 'optional_product_ids' => 'bail|sometimes|nullable|string', - 'use_inventory_management' => 'bail|sometimes|bool' + 'use_inventory_management' => 'bail|sometimes|bool', + 'steps' => ['required', new Steps()], ]; return $this->globalRules($rules); diff --git a/app/Http/Requests/Subscription/UpdateSubscriptionRequest.php b/app/Http/Requests/Subscription/UpdateSubscriptionRequest.php index 811d38000c67..c21af7024223 100644 --- a/app/Http/Requests/Subscription/UpdateSubscriptionRequest.php +++ b/app/Http/Requests/Subscription/UpdateSubscriptionRequest.php @@ -12,6 +12,7 @@ namespace App\Http\Requests\Subscription; use App\Http\Requests\Request; +use App\Rules\Subscriptions\Steps; use App\Utils\Traits\ChecksEntityStatus; use Illuminate\Validation\Rule; @@ -65,6 +66,7 @@ class UpdateSubscriptionRequest extends Request 'optional_recurring_product_ids' => 'bail|sometimes|nullable|string', 'optional_product_ids' => 'bail|sometimes|nullable|string', 'use_inventory_management' => 'bail|sometimes|bool', + 'steps' => ['required', new Steps()], ]; return $this->globalRules($rules); diff --git a/app/Jobs/Cron/SubscriptionCron.php b/app/Jobs/Cron/SubscriptionCron.php index 6e29ba088384..a3a5286a3816 100644 --- a/app/Jobs/Cron/SubscriptionCron.php +++ b/app/Jobs/Cron/SubscriptionCron.php @@ -39,62 +39,25 @@ class SubscriptionCron */ public function handle(): void { - nlog('Subscription Cron'); Auth::logout(); if (! config('ninja.db.multi_db_enabled')) { - $invoices = Invoice::where('is_deleted', 0) - ->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL]) - ->where('balance', '>', 0) - ->where('is_proforma', 0) - ->whereDate('due_date', '<=', now()->addDay()->startOfDay()) - ->whereNull('deleted_at') - ->whereNotNull('subscription_id') - ->cursor(); - $invoices->each(function (Invoice $invoice) { - $subscription = $invoice->subscription; + nlog('Subscription Cron '. now()->toDateTimeString()); - $body = [ - 'context' => 'plan_expired', - 'client' => $invoice->client->hashed_id, - 'invoice' => $invoice->hashed_id, - 'subscription' => $subscription->hashed_id, - ]; + $this->timezoneAware(); - $this->sendLoad($subscription, $body); - //This will send the notification daily. - //We'll need to handle this by performing some action on the invoice to either archive it or delete it? - }); + } else { //multiDB environment, need to foreach (MultiDB::$dbs as $db) { MultiDB::setDB($db); - $invoices = Invoice::where('is_deleted', 0) - ->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL]) - ->where('balance', '>', 0) - ->where('is_proforma', 0) - ->whereDate('due_date', '<=', now()->addDay()->startOfDay()) - ->whereNull('deleted_at') - ->whereNotNull('subscription_id') - ->cursor(); + nlog('Subscription Cron for ' . $db . ' ' . now()->toDateTimeString()); - $invoices->each(function (Invoice $invoice) { - $subscription = $invoice->subscription; + $this->timezoneAware(); - $body = [ - 'context' => 'plan_expired', - 'client' => $invoice->client->hashed_id, - 'invoice' => $invoice->hashed_id, - 'subscription' => $subscription->hashed_id, - ]; - - $this->sendLoad($subscription, $body); - //This will send the notification daily. - //We'll need to handle this by performing some action on the invoice to either archive it or delete it? - }); } } } @@ -131,7 +94,7 @@ class SubscriptionCron ->where('is_proforma', 0) ->whereNotNull('subscription_id') ->where('balance', '>', 0) - ->whereDate('due_date', '<=', now()->setTimezone($company->timezone()->name)->addDay()->startOfDay()) + ->whereDate('due_date', '<=', now()->addDay()->startOfDay()) ->cursor() ->each(function (Invoice $invoice) { diff --git a/app/Jobs/Entity/CreateRawPdf.php b/app/Jobs/Entity/CreateRawPdf.php index bb5a37001283..ac4320f1a89d 100644 --- a/app/Jobs/Entity/CreateRawPdf.php +++ b/app/Jobs/Entity/CreateRawPdf.php @@ -88,6 +88,7 @@ class CreateRawPdf 'quote' => $type = 'product', 'credit' => $type = 'product', 'recurring_invoice' => $type = 'product', + default => $type = 'product', }; return $type; diff --git a/app/Jobs/Mail/NinjaMailerJob.php b/app/Jobs/Mail/NinjaMailerJob.php index bff1f3f5aa7c..8ec580d0d4b0 100644 --- a/app/Jobs/Mail/NinjaMailerJob.php +++ b/app/Jobs/Mail/NinjaMailerJob.php @@ -70,9 +70,7 @@ class NinjaMailerJob implements ShouldQueue public function backoff() { - // return [5, 10, 30, 240]; - return [rand(5, 10), rand(30, 40), rand(60, 79), rand(160, 400)]; - + return [rand(5, 29), rand(30, 59), rand(61, 100), rand(180, 500)]; } public function handle() @@ -182,6 +180,11 @@ class NinjaMailerJob implements ShouldQueue $this->fail(); $this->logMailError($e->getMessage(), $this->company->clients()->first()); + + if ($this->nmo->entity) { + $this->entityEmailFailed($message); + } + $this->cleanUpMailers(); return; @@ -195,6 +198,11 @@ class NinjaMailerJob implements ShouldQueue $this->fail(); $this->logMailError($message, $this->company->clients()->first()); + + if ($this->nmo->entity) { + $this->entityEmailFailed($message); + } + $this->cleanUpMailers(); return; @@ -203,7 +211,7 @@ class NinjaMailerJob implements ShouldQueue //only report once, not on all tries if ($this->attempts() == $this->tries) { - /* If the is an entity attached to the message send a failure mailer */ + /* If there is an entity attached to the message send a failure mailer */ if ($this->nmo->entity) { $this->entityEmailFailed($message); } diff --git a/app/Livewire/BillingPortal/Authentication/ClientRegisterService.php b/app/Livewire/BillingPortal/Authentication/ClientRegisterService.php new file mode 100644 index 000000000000..35cea03d6941 --- /dev/null +++ b/app/Livewire/BillingPortal/Authentication/ClientRegisterService.php @@ -0,0 +1,132 @@ +company->client_registration_fields as $field) { + if ($field['visible'] ?? true) { + $rules[$field['key']] = $field['required'] ? ['bail', 'required'] : ['sometimes']; + } + } + + foreach ($rules as $field => $properties) { + if ($field === 'email') { + $rules[$field] = array_merge($rules[$field], ['email:rfc,dns', 'max:191', Rule::unique('client_contacts')->where('company_id', $this->company->id)]); + } + + if ($field === 'current_password' || $field === 'password') { + $rules[$field] = array_merge($rules[$field], ['string', 'min:6', 'confirmed']); + } + } + + if ($this->company->settings->client_portal_terms || $this->company->settings->client_portal_privacy_policy) { + $rules['terms'] = ['required']; + } + + foreach ($this->additional as $field) { + if ($field['visible'] ?? true) { + $rules[$field['key']] = $field['required'] ? ['bail', 'required'] : ['sometimes']; + } + } + + return $rules; + } + + public function createClient(array $data): Client + { + $client = ClientFactory::create($this->company->id, $this->company->owner()->id); + + $client->fill($data); + + $client->save(); + + if (isset($data['currency_id'])) { + $settings = $client->settings; + $settings->currency_id = isset($data['currency_id']) ? $data['currency_id'] : $this->company->settings->currency_id; + $client->settings = $settings; + } + + $client->number = $this->getNextClientNumber($client); + $client->save(); + + if (!array_key_exists('country_id', $data) && strlen($client->company->settings->country_id) > 1) { + $client->update(['country_id' => $client->company->settings->country_id]); + } + + return $client; + } + + public function createClientContact(array $data, Client $client): ClientContact + { + $client_contact = ClientContactFactory::create($this->company->id, $this->company->owner()->id); + $client_contact->fill($data); + + $client_contact->client_id = $client->id; + $client_contact->is_primary = true; + + if (array_key_exists('password', $data)) { + $client_contact->password = Hash::make($data['password']); + } + + $client_contact->save(); + + return $client_contact; + } + + public static function mappings(): array + { + return [ + 'contact_first_name' => 'first_name', + 'contact_last_name' => 'last_name', + 'contact_email' => 'email', + 'client_phone' => 'phone', + 'client_city' => 'city', + 'client_address_line_1' => 'address1', + 'client_address_line_2' => 'address2', + 'client_state' => 'state', + 'client_country_id' => 'country_id', + 'client_postal_code' => 'postal_code', + 'client_shipping_postal_code' => 'shipping_postal_code', + 'client_shipping_address_line_1' => 'shipping_address1', + 'client_shipping_city' => 'shipping_city', + 'client_shipping_state' => 'shipping_state', + 'client_shipping_country_id' => 'shipping_country_id', + 'client_custom_value1' => 'custom_value1', + 'client_custom_value2' => 'custom_value2', + 'client_custom_value3' => 'custom_value3', + 'client_custom_value4' => 'custom_value4', + ]; + } +} diff --git a/app/Livewire/BillingPortal/Authentication/Login.php b/app/Livewire/BillingPortal/Authentication/Login.php new file mode 100644 index 000000000000..3c24baae9562 --- /dev/null +++ b/app/Livewire/BillingPortal/Authentication/Login.php @@ -0,0 +1,174 @@ + false, // Use as preference. E-mail/password or OTP. + 'login_form' => false, + 'otp_form' => false, + 'initial_completed' => false, + ]; + + public function initial() + { + $this->validateOnly('email', ['email' => 'required|bail|email:rfc|email']); + + $contact = ClientContact::where('email', $this->email) + ->where('company_id', $this->subscription->company_id) + ->first(); + + if ($contact === null) { + $this->addError('email', ctrans('texts.checkout_only_for_existing_customers')); + + return; + } + + $this->state['initial_completed'] = true; + + if ($this->state['otp']) { + return $this->withOtp(); + } + + return $this->withPassword(); + } + + public function withPassword() + { + $contact = ClientContact::where('email', $this->email) + ->where('company_id', $this->subscription->company_id) + ->first(); + + if ($contact) { + return $this->state['login_form'] = true; + } + + $this->state['login_form'] = false; + + $contact = $this->createClientContact(); + + auth()->guard('contact')->loginUsingId($contact->id, true); + + $this->dispatch('purchase.context', property: 'contact', value: $contact); + $this->dispatch('purchase.next'); + } + + public function withOtp() + { + $code = rand(100000, 999999); + $email_hash = "subscriptions:otp:{$this->email}"; + + Cache::put($email_hash, $code, 600); + + $cc = new ClientContact(); + $cc->email = $this->email; + + $nmo = new NinjaMailerObject(); + $nmo->mailable = new OtpCode($this->subscription->company, $this->context['contact'] ?? null, $code); + $nmo->company = $this->subscription->company; + $nmo->settings = $this->subscription->company->settings; + $nmo->to_user = $cc; + + NinjaMailerJob::dispatch($nmo); + + if (app()->environment('local')) { + session()->flash('message', "[dev]: Your OTP is: {$code}"); + } + + $this->state['otp_form'] = true; + } + + public function handleOtp() + { + $this->validate([ + 'otp' => 'required|numeric|digits:6 ', + 'email' => 'required|bail|email:rfc|exists:client_contacts,email', + ]); + + $code = Cache::get("subscriptions:otp:{$this->email}"); + + if ($this->otp != $code) { //loose comparison prevents edge cases + $errors = $this->getErrorBag(); + $errors->add('otp', ctrans('texts.invalid_code')); + + return; + } + + $contact = ClientContact::where('email', $this->email) + ->where('company_id', $this->subscription->company_id) + ->first(); + + if ($contact) { + auth()->guard('contact')->loginUsingId($contact->id, true); + + $this->dispatch('purchase.context', property: 'contact', value: $contact); + $this->dispatch('purchase.next'); + + return; + } + } + + public function handlePassword() + { + $this->validate([ + 'email' => 'required|bail|email:rfc', + 'password' => 'required', + ]); + + $attempt = auth()->guard('contact')->attempt([ + 'email' => $this->email, + 'password' => $this->password, + 'company_id' => $this->subscription->company_id, + ]); + + if ($attempt) { + + $this->dispatch('purchase.context', property: 'contact', value: auth()->guard('contact')->user()); + $this->dispatch('purchase.next'); + } + + session()->flash('message', 'These credentials do not match our records.'); + } + + public function mount() + { + if (auth()->guard('contact')->check()) { + $this->dispatch('purchase.context', property: 'contact', value: auth()->guard('contact')->user()); + $this->dispatch('purchase.next'); + } + } + + public function render(): \Illuminate\View\View + { + return view('billing-portal.v3.authentication.login'); + } +} \ No newline at end of file diff --git a/app/Livewire/BillingPortal/Authentication/Register.php b/app/Livewire/BillingPortal/Authentication/Register.php new file mode 100644 index 000000000000..43c5631b5f47 --- /dev/null +++ b/app/Livewire/BillingPortal/Authentication/Register.php @@ -0,0 +1,154 @@ + false, + 'register_form' => false, + ]; + + public array $register_fields = []; + + public array $additional_fields = []; + + public function initial(): void + { + $this->validateOnly('email', ['email' => 'required|bail|email:rfc']); + + $contact = ClientContact::where('email', $this->email) + ->where('company_id', $this->subscription->company_id) + ->first(); + + if ($contact) { + $this->addError('email', ctrans('texts.checkout_only_for_new_customers')); + + return; + } + + $this->state['initial_completed'] = true; + + $this->registerForm(); + } + + public function register(array $data) + { + $service = new ClientRegisterService( + company: $this->subscription->company, + additional: $this->additional_fields, + ); + + $rules = $service->rules(); + + $data = Validator::make($data, $rules)->validate(); + + $client = $service->createClient($data); + $contact = $service->createClientContact($data, $client); + + auth()->guard('contact')->loginUsingId($contact->id, true); + + $this->dispatch('purchase.context', property: 'contact', value: $contact); + $this->dispatch('purchase.next'); + } + + public function registerForm() + { + $count = collect($this->subscription->company->client_registration_fields ?? []) + ->filter(fn($field) => $field['required'] === true || $field['visible'] === true) + ->count(); + + if ($count === 0) { + $service = new ClientRegisterService( + company: $this->subscription->company, + ); + + $client = $service->createClient([]); + $contact = $service->createClientContact(['email' => $this->email], $client); + + auth()->guard('contact')->loginUsingId($contact->id, true); + + $this->dispatch('purchase.context', property: 'contact', value: $contact); + $this->dispatch('purchase.next'); + + return; + } + + $this->register_fields = [...collect($this->subscription->company->client_registration_fields ?? [])->toArray()]; + + $first_gateway = collect($this->subscription->company->company_gateways) + ->sortBy('sort_order') + ->first(); + + $mappings = ClientRegisterService::mappings(); + + collect($first_gateway->driver()->getClientRequiredFields() ?? []) + ->each(function ($field) use ($mappings) { + $mapping = $mappings[$field['name']] ?? null; + + if ($mapping === null) { + return; + } + + $i = collect($this->register_fields)->search(fn ($field) => $field['key'] == $mapping); + + if ($i !== false) { + $this->register_fields[$i]['visible'] = true; + $this->register_fields[$i]['required'] = true; + + + $this->additional_fields[] = $this->register_fields[$i]; + } else { + $field = [ + 'key' => $mapping, + 'required' => true, + 'visible' => true, + ]; + + $this->register_fields[] = $field; + $this->additional_fields[] = $field; + } + }) + ->toArray(); + + return $this->state['register_form'] = true; + } + + public function mount() + { + if (auth()->guard('contact')->check()) { + $this->dispatch('purchase.context', property: 'contact', value: auth()->guard('contact')->user()); + $this->dispatch('purchase.next'); + } + } + + public function render() + { + return view('billing-portal.v3.authentication.register'); + } +} diff --git a/app/Livewire/BillingPortal/Authentication/RegisterOrLogin.php b/app/Livewire/BillingPortal/Authentication/RegisterOrLogin.php new file mode 100644 index 000000000000..f3d84177507d --- /dev/null +++ b/app/Livewire/BillingPortal/Authentication/RegisterOrLogin.php @@ -0,0 +1,261 @@ + false, // Use as preference. E-mail/password or OTP. + 'login_form' => false, + 'otp_form' => false, + 'register_form' => false, + 'initial_completed' => false, + ]; + + public array $register_fields = []; + + public array $additional_fields = []; + + public function initial() + { + $this->validateOnly('email', ['email' => 'required|bail|email:rfc']); + + $this->state['initial_completed'] = true; + + if ($this->state['otp']) { + return $this->withOtp(); + } + + return $this->withPassword(); + } + + public function withPassword() + { + $contact = ClientContact::where('email', $this->email) + ->where('company_id', $this->subscription->company_id) + ->first(); + + if ($contact) { + return $this->state['login_form'] = true; + } + + $this->state['login_form'] = false; + $this->registerForm(); + } + + public function handlePassword() + { + $this->validate([ + 'email' => 'required|bail|email:rfc', + 'password' => 'required', + ]); + + $attempt = auth()->guard('contact')->attempt([ + 'email' => $this->email, + 'password' => $this->password, + 'company_id' => $this->subscription->company_id, + ]); + + if ($attempt) { + $this->dispatch('purchase.next'); + } + + session()->flash('message', 'These credentials do not match our records.'); + } + + public function withOtp(): void + { + $contact = ClientContact::where('email', $this->email) + ->where('company_id', $this->subscription->company_id) + ->first(); + + if ($contact === null) { + $this->registerForm(); + + return; + } + + $code = rand(100000, 999999); + $email_hash = "subscriptions:otp:{$this->email}"; + + Cache::put($email_hash, $code, 600); + + $cc = new ClientContact(); + $cc->email = $this->email; + + $nmo = new NinjaMailerObject(); + $nmo->mailable = new OtpCode($this->subscription->company, $this->context['contact'] ?? null, $code); + $nmo->company = $this->subscription->company; + $nmo->settings = $this->subscription->company->settings; + $nmo->to_user = $cc; + + NinjaMailerJob::dispatch($nmo); + + if (app()->environment('local')) { + session()->flash('message', "[dev]: Your OTP is: {$code}"); + } + + $this->state['otp_form'] = true; + } + + public function handleOtp(): void + { + $this->validate([ + 'otp' => 'required|numeric|digits:6', + ]); + + $code = Cache::get("subscriptions:otp:{$this->email}"); + + if ($this->otp != $code) { //loose comparison prevents edge cases + $errors = $this->getErrorBag(); + $errors->add('otp', ctrans('texts.invalid_code')); + + return; + } + + $contact = ClientContact::where('email', $this->email) + ->where('company_id', $this->subscription->company_id) + ->first(); + + if ($contact) { + auth()->guard('contact')->loginUsingId($contact->id, true); + + $this->dispatch('purchase.context', property: 'contact', value: $contact); + $this->dispatch('purchase.next'); + + return; + } + + $this->state['otp_form'] = false; + $this->registerForm(); + } + + public function register(array $data): void + { + $service = new ClientRegisterService( + company: $this->subscription->company, + additional: $this->additional_fields, + ); + + $rules = $service->rules(); + $data = Validator::make($data, $rules)->validate(); + + $client = $service->createClient($data); + $contact = $service->createClientContact($data, $client); + + auth()->guard('contact')->loginUsingId($contact->id, true); + + $this->dispatch('purchase.context', property: 'contact', value: $contact); + $this->dispatch('purchase.next'); + } + + public function registerForm() + { + $count = collect($this->subscription->company->client_registration_fields ?? []) + ->filter(fn($field) => $field['required'] === true || $field['visible'] === true) + ->count(); + + if ($count === 0) { + $service = new ClientRegisterService( + company: $this->subscription->company, + ); + + $client = $service->createClient([]); + $contact = $service->createClientContact(['email' => $this->email], $client); + + auth()->guard('contact')->loginUsingId($contact->id, true); + + $this->dispatch('purchase.context', property: 'contact', value: $contact); + $this->dispatch('purchase.next'); + + return; + } + + $this->register_fields = [...collect($this->subscription->company->client_registration_fields ?? [])->toArray()]; + + $first_gateway = collect($this->subscription->company->company_gateways) + ->sortBy('sort_order') + ->first(); + + $mappings = ClientRegisterService::mappings(); + + collect($first_gateway->driver()->getClientRequiredFields() ?? []) + ->each(function ($field) use ($mappings) { + $mapping = $mappings[$field['name']] ?? null; + + if ($mapping === null) { + return; + } + + $i = collect($this->register_fields)->search(fn ($field) => $field['key'] == $mapping); + + if ($i !== false) { + $this->register_fields[$i]['visible'] = true; + $this->register_fields[$i]['required'] = true; + + + $this->additional_fields[] = $this->register_fields[$i]; + } else { + $field = [ + 'key' => $mapping, + 'required' => true, + 'visible' => true, + ]; + + $this->register_fields[] = $field; + $this->additional_fields[] = $field; + } + }) + ->toArray(); + + return $this->state['register_form'] = true; + } + + public function mount() + { + if (auth()->guard('contact')->check()) { + $this->dispatch('purchase.context', property: 'contact', value: auth()->guard('contact')->user()); + $this->dispatch('purchase.next'); + + return; + } + } + + public function render() + { + $countries = Cache::get('countries'); + + return view('billing-portal.v3.authentication.register-or-login', [ + 'countries' => $countries, + ]); + } +} diff --git a/app/Livewire/BillingPortal/Cart/Cart.php b/app/Livewire/BillingPortal/Cart/Cart.php new file mode 100644 index 000000000000..f8fae332df76 --- /dev/null +++ b/app/Livewire/BillingPortal/Cart/Cart.php @@ -0,0 +1,44 @@ +dispatch('purchase.next'); + } + + public function showOptionalProductsLabel() + { + $optional = [ + ...$this->context['bundle']['optional_recurring_products'] ?? [], + ...$this->context['bundle']['optional_one_time_products'] ?? [], + ]; + + return count($optional) > 0; + } + + public function render() + { + return view('billing-portal.v3.cart.cart'); + } +} diff --git a/app/Livewire/BillingPortal/Cart/OneTimeProducts.php b/app/Livewire/BillingPortal/Cart/OneTimeProducts.php new file mode 100644 index 000000000000..f6c538037dce --- /dev/null +++ b/app/Livewire/BillingPortal/Cart/OneTimeProducts.php @@ -0,0 +1,33 @@ +dispatch('purchase.context', property: "bundle.one_time_products.{$id}.quantity", value: $value); + } + + public function render() + { + return view('billing-portal.v3.cart.one-time-products'); + } +} diff --git a/app/Livewire/BillingPortal/Cart/OptionalOneTimeProducts.php b/app/Livewire/BillingPortal/Cart/OptionalOneTimeProducts.php new file mode 100644 index 000000000000..22350ee06b69 --- /dev/null +++ b/app/Livewire/BillingPortal/Cart/OptionalOneTimeProducts.php @@ -0,0 +1,33 @@ +dispatch('purchase.context', property: "bundle.optional_one_time_products.{$id}.quantity", value: $value); + } + + public function render(): \Illuminate\View\View + { + return view('billing-portal.v3.cart.optional-one-time-products'); + } +} diff --git a/app/Livewire/BillingPortal/Cart/OptionalRecurringProducts.php b/app/Livewire/BillingPortal/Cart/OptionalRecurringProducts.php new file mode 100644 index 000000000000..9193ba59ae7c --- /dev/null +++ b/app/Livewire/BillingPortal/Cart/OptionalRecurringProducts.php @@ -0,0 +1,35 @@ +dispatch('purchase.context', property: "bundle.optional_recurring_products.{$id}.quantity", value: $value); + + } + + public function render(): \Illuminate\View\View + { + return view('billing-portal.v3.cart.optional-recurring-products'); + } +} diff --git a/app/Livewire/BillingPortal/Cart/RecurringProducts.php b/app/Livewire/BillingPortal/Cart/RecurringProducts.php new file mode 100644 index 000000000000..d57bc9ede43e --- /dev/null +++ b/app/Livewire/BillingPortal/Cart/RecurringProducts.php @@ -0,0 +1,33 @@ +dispatch('purchase.context', property: "bundle.recurring_products.{$id}.quantity", value: $value); + } + + public function render(): \Illuminate\View\View + { + return view('billing-portal.v3.cart.recurring-products'); + } +} diff --git a/app/Livewire/BillingPortal/Example.php b/app/Livewire/BillingPortal/Example.php new file mode 100644 index 000000000000..00cdba32fe2e --- /dev/null +++ b/app/Livewire/BillingPortal/Example.php @@ -0,0 +1,33 @@ +dispatch('purchase.context', property: 'quantity', value: 1); + $this->dispatch('purchase.next'); + } + + public function render() + { + return <<<'HTML' +
This is step after auth. Currently logged in user is {{ $context['contact']['email'] }}.
+ HTML; + } +} diff --git a/app/Livewire/BillingPortal/Payments/Methods.php b/app/Livewire/BillingPortal/Payments/Methods.php new file mode 100644 index 000000000000..d467b0d85aa5 --- /dev/null +++ b/app/Livewire/BillingPortal/Payments/Methods.php @@ -0,0 +1,82 @@ +context['products'])->sum('total_raw'); + + $methods = auth()->guard('contact')->user()->client->service()->getPaymentMethods( + $total, + ); + + $this->methods = $methods; + } + + public function handleSelect(string $company_gateway_id, string $gateway_type_id) + { + /** @var \App\Models\ClientContact $contact */ + $contact = auth()->guard('contact')->user(); + + $this->dispatch('purchase.context', property: 'client_id', value: $contact->client->hashed_id); + + $this->context['client_id'] = $contact->client->hashed_id; + + $invoice = $this->subscription + ->calc() + ->buildPurchaseInvoice($this->context) + ->service() + ->markSent() + ->fillDefaults() + ->adjustInventory() + ->save(); + + Cache::put($this->context['hash'], [ + 'subscription_id' => $this->subscription->hashed_id, + 'email' => $contact->email, + 'client_id' => $contact->client->hashed_id, + 'invoice_id' => $invoice->hashed_id, + 'context' => 'purchase', + 'campaign' => $this->context['campaign'], + 'bundle' => $this->context['bundle'], + ], now()->addMinutes(60)); + + $payable_amount = $invoice->partial > 0 + ? \App\Utils\Number::formatValue($invoice->partial, $invoice->client->currency()) + : \App\Utils\Number::formatValue($invoice->balance, $invoice->client->currency()); + + $this->dispatch('purchase.context', property: 'form.company_gateway_id', value: $company_gateway_id); + $this->dispatch('purchase.context', property: 'form.payment_method_id', value: $gateway_type_id); + $this->dispatch('purchase.context', property: 'form.invoice_hashed_id', value: $invoice->hashed_id); + $this->dispatch('purchase.context', property: 'form.payable_amount', value: $payable_amount); + + $this->dispatch('purchase.next'); + } + + public function render() + { + return view('billing-portal.v3.payments.methods'); + } +} diff --git a/app/Livewire/BillingPortal/Purchase.php b/app/Livewire/BillingPortal/Purchase.php new file mode 100644 index 000000000000..bcad791b4ff2 --- /dev/null +++ b/app/Livewire/BillingPortal/Purchase.php @@ -0,0 +1,169 @@ + [ + 'id' => 'auth.login', + 'dependencies' => [], + ], + RegisterOrLogin::class => [ + 'id' => 'auth.login-or-register', + 'dependencies' => [], + ], + Register::class => [ + 'id' => 'auth.register', + 'dependencies' => [], + ], + Cart::class => [ + 'id' => 'cart', + 'dependencies' => [], + ], + ]; + + public array $steps = []; + + public array $context = []; + + #[On('purchase.context')] + public function handleContext(string $property, $value): self + { + $clone = $this->context; + + data_set($this->context, $property, $value); + + // The following may not be needed, as we can pass arround $context. + // cache()->set($this->hash, $this->context); + + if ($clone !== $this->context) { + $this->id = Str::uuid(); + } + + return $this; + } + + #[On('purchase.next')] + public function handleNext(): void + { + if (count($this->steps) >= 1 && $this->step < count($this->steps) - 1) { + $this->step++; + $this->id = Str::uuid(); + } + } + + #[On('purchase.forward')] + public function handleForward(string $component): void + { + $this->step = array_search($component, $this->steps); + + $this->id = Str::uuid(); + } + + #[Computed()] + public function component(): string + { + return $this->steps[$this->step]; + } + + #[Computed()] + public function componentUniqueId(): string + { + return "purchase-{$this->id}"; + } + + #[Computed()] + public function summaryUniqueId(): string + { + return "summary-{$this->id}"; + } + + public static function defaultSteps() + { + return [ + Cart::class, + RegisterOrLogin::class, + ]; + } + + public function mount() + { + $classes = collect(self::$dependencies)->mapWithKeys(fn($dependency, $class) => [$dependency['id'] => $class])->toArray(); + + if ($this->subscription->steps) { + $steps = collect(explode(',', $this->subscription->steps)) + ->map(fn($step) => $classes[$step]) + ->toArray(); + + $this->steps = [ + Setup::class, + ...$steps, + Methods::class, + RFF::class, + Submit::class, + ]; + } else { + $this->steps = [ + Setup::class, + ...self::defaultSteps(), + Methods::class, + RFF::class, + Submit::class, + ]; + } + + $this->id = Str::uuid(); + + MultiDB::setDb($this->db); + + $this + ->handleContext('hash', $this->hash) + ->handleContext('quantity', 1) + ->handleContext('request_data', $this->request_data) + ->handleContext('campaign', $this->campaign); + } + + public function render() + { + return view('billing-portal.v3.purchase'); + } +} diff --git a/app/Livewire/BillingPortal/RFF.php b/app/Livewire/BillingPortal/RFF.php new file mode 100644 index 000000000000..38b36f868108 --- /dev/null +++ b/app/Livewire/BillingPortal/RFF.php @@ -0,0 +1,83 @@ +dispatch('purchase.context', property: 'contact', value: auth()->guard('contact')->user()); + + $this->dispatch('purchase.next'); + } + + public function handleSubmit() + { + $data = $this->validate([ + 'contact_first_name' => 'required', + 'contact_last_name' => 'required', + 'contact_email' => 'required|email:rfc', + ]); + + $contact = auth()->guard('contact'); + + $contact->user()->update([ + 'first_name' => $data['contact_first_name'], + 'last_name' => $data['contact_last_name'], + 'email' => $data['contact_email'], + ]); + + $this->dispatch('purchase.context', property: 'contact', value: auth()->guard('contact')->user()); + + $this->dispatch('purchase.next'); + } + + public function mount(): void + { + $this->contact_first_name = $this->context['contact']['first_name'] ?? ''; + $this->contact_last_name = $this->context['contact']['last_name'] ?? ''; + $this->contact_email = $this->context['contact']['email'] ?? ''; + } + + public function render() + { + $gateway = CompanyGateway::find($this->context['form']['company_gateway_id']); + $countries = Cache::get('countries'); + + if ($gateway === null) { + return view('billing-portal.v3.rff-basic'); + } + + return view('billing-portal.v3.rff', [ + 'gateway' => $gateway->driver( + auth()->guard('contact')->user()->client + ), + 'countries' => $countries, + 'company' => $gateway->company, + ]); + } +} diff --git a/app/Livewire/BillingPortal/Setup.php b/app/Livewire/BillingPortal/Setup.php new file mode 100644 index 000000000000..bee2f4c21419 --- /dev/null +++ b/app/Livewire/BillingPortal/Setup.php @@ -0,0 +1,33 @@ +dispatch('purchase.context', property: 'quantity', value: 1); + $this->dispatch('purchase.next'); + } + + public function render() + { + return <<<'HTML' + + HTML; + } +} diff --git a/app/Livewire/BillingPortal/Submit.php b/app/Livewire/BillingPortal/Submit.php new file mode 100644 index 000000000000..a1324f96a3c1 --- /dev/null +++ b/app/Livewire/BillingPortal/Submit.php @@ -0,0 +1,76 @@ + 'hidden', + // 'hash' => $this->context['hash'], + // 'action' => 'payment', + // 'invoices' => [ + // $this->context['form']['invoice_hashed_id'], + // ], + // 'payable_invoices' => [ + // [ + // 'amount' => $this->context['form']['payable_amount'], + // 'invoice_id' => $this->context['form']['invoice_hashed_id'], + // ], + // ], + // 'company_gateway_id' => $this->context['form']['company_gateway_id'], + // 'payment_method_id' => $this->context['form']['payment_method_id'], + // 'contact_first_name' => $this->context['contact']['first_name'], + // 'contact_last_name' => $this->context['contact']['last_name'], + // 'contact_email' => $this->context['contact']['email'], + // ]); + + // return redirect((new InstantPayment($request))->run()); + // dd($this->context); + + nlog($this->context); + + $this->dispatch( + 'purchase.submit', + invoice_hashed_id: $this->context['form']['invoice_hashed_id'], + payable_amount: $this->context['form']['payable_amount'], + company_gateway_id: $this->context['form']['company_gateway_id'], + payment_method_id: $this->context['form']['payment_method_id'], + contact_first_name: $this->context['contact']['first_name'], + contact_last_name: $this->context['contact']['last_name'], + contact_email: $this->context['contact']['email'], + ); + } + + public function render() + { + + return <<<'HTML' + + + + + HTML; + } +} diff --git a/app/Livewire/BillingPortal/Summary.php b/app/Livewire/BillingPortal/Summary.php new file mode 100644 index 000000000000..25e7c86a7684 --- /dev/null +++ b/app/Livewire/BillingPortal/Summary.php @@ -0,0 +1,188 @@ +context['bundle'] ?? [ + 'recurring_products' => [], + 'optional_recurring_products' => [], + 'one_time_products' => [], + 'optional_one_time_products' => [], + ]; + + foreach ($this->subscription->service()->recurring_products() as $key => $product) { + $bundle['recurring_products'][$product->hashed_id] = [ + 'product' => $product, + 'quantity' => $bundle['recurring_products'][$product->hashed_id]['quantity'] ?? 1, + 'notes' => $product->markdownNotes(), + ]; + $bundle['recurring_products'][$product->hashed_id]['product']['is_recurring'] = true; + } + + foreach ($this->subscription->service()->products() as $key => $product) { + $bundle['one_time_products'][$product->hashed_id] = [ + 'product' => $product, + 'quantity' => $bundle['one_time_products'][$product->hashed_id]['quantity'] ?? 1, + 'notes' => $product->markdownNotes(), + ]; + $bundle['one_time_products'][$product->hashed_id]['product']['is_recurring'] = false; + } + + foreach ($this->subscription->service()->optional_recurring_products() as $key => $product) { + $bundle['optional_recurring_products'][$product->hashed_id] = [ + 'product' => $product, + 'quantity' => $bundle['optional_recurring_products'][$product->hashed_id]['quantity'] ?? 0, + 'notes' => $product->markdownNotes(), + ]; + $bundle['optional_recurring_products'][$product->hashed_id]['product']['is_recurring'] = true; + } + + foreach ($this->subscription->service()->optional_products() as $key => $product) { + $bundle['optional_one_time_products'][$product->hashed_id] = [ + 'product' => $product, + 'quantity' => $bundle['optional_one_time_products'][$product->hashed_id]['quantity'] ?? 0, + 'notes' => $product->markdownNotes(), + ]; + $bundle['optional_one_time_products'][$product->hashed_id]['product']['is_recurring'] = false; + } + + $this->dispatch('purchase.context', property: 'bundle', value: $bundle); + } + + public function oneTimePurchasesTotal(bool $raw = false) + { + if (isset($this->context['bundle']['recurring_products']) === false) { + return 0; + } + + $one_time = collect($this->context['bundle']['one_time_products'])->sum(function ($item) { + return $item['product']['price'] * $item['quantity']; + }); + + $one_time_optional = collect($this->context['bundle']['optional_one_time_products'])->sum(function ($item) { + return $item['product']['price'] * $item['quantity']; + }); + + if ($raw) { + return $one_time + $one_time_optional; + } + + return Number::formatMoney($one_time + $one_time_optional, $this->subscription->company); + + } + + public function recurringPurchasesTotal(bool $raw = false) + { + if (isset($this->context['bundle']['recurring_products']) === false) { + return 0; + } + + $recurring = collect($this->context['bundle']['recurring_products'])->sum(function ($item) { + return $item['product']['price'] * $item['quantity']; + }); + + $recurring_optional = collect($this->context['bundle']['optional_recurring_products'])->sum(function ($item) { + return $item['product']['price'] * $item['quantity']; + }); + + if ($raw) { + return $recurring + $recurring_optional; + } + + return \sprintf( + '%s/%s', + Number::formatMoney($recurring + $recurring_optional, $this->subscription->company), + RecurringInvoice::frequencyForKey($this->subscription->frequency_id) + ); + } + + #[Computed()] + public function total() + { + return Number::formatMoney( + collect([ + $this->oneTimePurchasesTotal(raw: true), + $this->recurringPurchasesTotal(raw: true), + ])->sum(), + $this->subscription->company + ); + } + + public function items() + { + if (isset($this->context['bundle']) === false) { + return []; + } + + $products = []; + + foreach ($this->context['bundle']['recurring_products'] as $key => $item) { + $products[] = [ + 'product_key' => $item['product']['product_key'], + 'quantity' => $item['quantity'], + 'total_raw' => $item['product']['price'] * $item['quantity'], + 'total' => Number::formatMoney($item['product']['price'] * $item['quantity'], $this->subscription->company) . ' / ' . RecurringInvoice::frequencyForKey($this->subscription->frequency_id), + ]; + } + + foreach ($this->context['bundle']['optional_recurring_products'] as $key => $item) { + $products[] = [ + 'product_key' => $item['product']['product_key'], + 'quantity' => $item['quantity'], + 'total_raw' => $item['product']['price'] * $item['quantity'], + 'total' => Number::formatMoney($item['product']['price'] * $item['quantity'], $this->subscription->company) . ' / ' . RecurringInvoice::frequencyForKey($this->subscription->frequency_id), + ]; + } + + foreach ($this->context['bundle']['one_time_products'] as $key => $item) { + $products[] = [ + 'product_key' => $item['product']['product_key'], + 'quantity' => $item['quantity'], + 'total_raw' => $item['product']['price'] * $item['quantity'], + 'total' => Number::formatMoney($item['product']['price'] * $item['quantity'], $this->subscription->company), + ]; + } + + foreach ($this->context['bundle']['optional_one_time_products'] as $key => $item) { + $products[] = [ + 'product_key' => $item['product']['product_key'], + 'quantity' => $item['quantity'], + 'total_raw' => $item['product']['price'] * $item['quantity'], + 'total' => Number::formatMoney($item['product']['price'] * $item['quantity'], $this->subscription->company), + ]; + } + + $this->dispatch('purchase.context', property: 'products', value: $products); + + return $products; + } + + public function render() + { + return view('billing-portal.v3.summary'); + } +} diff --git a/app/Livewire/RequiredClientInfo.php b/app/Livewire/RequiredClientInfo.php index 5daabf4b29a3..b174a87cf8fd 100644 --- a/app/Livewire/RequiredClientInfo.php +++ b/app/Livewire/RequiredClientInfo.php @@ -12,7 +12,6 @@ namespace App\Livewire; -use App\Models\Client; use App\Models\Invoice; use Livewire\Component; use App\Libraries\MultiDB; @@ -186,6 +185,8 @@ class RequiredClientInfo extends Component public $company_gateway_id; + public bool $form_only = false; + public $db; public function mount() @@ -222,7 +223,7 @@ class RequiredClientInfo extends Component $this->show_form = true; $hash = Cache::get(request()->input('hash')); - + /** @var \App\Models\Invoice $invoice */ $invoice = Invoice::find($this->decodePrimaryKey($hash['invoice_id'])); @@ -232,6 +233,15 @@ class RequiredClientInfo extends Component count($this->fields) > 0 || $this->show_terms ? $this->checkFields() : $this->show_form = false; + + if (request()->query('source') === 'subscriptions') { + $this->show_form = false; + + $this->dispatch( + 'passed-required-fields-check', + client_postal_code: $this->contact->client->postal_code + ); + } } #[Computed] @@ -240,7 +250,7 @@ class RequiredClientInfo extends Component MultiDB::setDb($this->db); return ClientContact::withTrashed()->find($this->contact_id); - + } #[Computed] @@ -259,7 +269,7 @@ class RequiredClientInfo extends Component public function handleSubmit(array $data): bool { - + MultiDB::setDb($this->db); $contact = ClientContact::withTrashed()->find($this->contact_id); @@ -367,7 +377,6 @@ $_contact->push(); public function checkFields() { - MultiDB::setDb($this->db); $_contact = ClientContact::withTrashed()->find($this->contact_id); @@ -375,7 +384,10 @@ $_contact->push(); $_field = $this->mappings[$field['name']]; if (Str::startsWith($field['name'], 'client_')) { - if (empty($_contact->client->{$_field}) || is_null($_contact->client->{$_field}) || in_array($_field, $this->client_address_array)) { + if (empty($_contact->client->{$_field}) + || is_null($_contact->client->{$_field}) + // || in_array($_field, $this->client_address_array) + ) { $this->show_form = true; } else { $this->fields[$index]['filled'] = true; @@ -390,6 +402,17 @@ $_contact->push(); } } } + + $left = collect($this->fields) + ->filter(fn ($field) => !array_key_exists('filled', $field)) + ->count(); + + if ($left === 0) { + $this->dispatch( + 'passed-required-fields-check', + client_postal_code: $this->contact->client->postal_code + ); + } } public function showCopyBillingCheckbox(): bool diff --git a/app/Mail/Subscription/OtpCode.php b/app/Mail/Subscription/OtpCode.php index 28fd20fe72e7..f6cafb778388 100644 --- a/app/Mail/Subscription/OtpCode.php +++ b/app/Mail/Subscription/OtpCode.php @@ -58,6 +58,8 @@ class OtpCode extends Mailable 'title' => ctrans('texts.otp_code_subject'), 'content' => ctrans('texts.otp_code_body', ['code' => $this->code]), 'whitelabel' => $this->company->account->isPaid(), + 'url' => 'xx', + 'button' => false, 'template' => $this->company->account->isPremium() ? 'email.template.admin_premium' : 'email.template.admin', ]); } diff --git a/app/Models/Account.php b/app/Models/Account.php index adf95c62086f..c2e099bf8366 100644 --- a/app/Models/Account.php +++ b/app/Models/Account.php @@ -291,7 +291,7 @@ class Account extends BaseModel public function isPaid(): bool { - return Ninja::isNinja() ? ($this->isPaidHostedClient() && !$this->isTrial()) : $this->hasFeature(self::FEATURE_WHITE_LABEL); + return Ninja::isNinja() ? $this->isPaidHostedClient() : $this->hasFeature(self::FEATURE_WHITE_LABEL); } public function isPremium(): bool diff --git a/app/Models/Expense.php b/app/Models/Expense.php index 95be95a9123f..126e405ed03b 100644 --- a/app/Models/Expense.php +++ b/app/Models/Expense.php @@ -190,7 +190,7 @@ class Expense extends BaseModel public function purchase_order() { - return $this->hasOne(PurchaseOrder::class); + return $this->hasOne(PurchaseOrder::class)->withTrashed(); } public function translate_entity() diff --git a/app/Models/Product.php b/app/Models/Product.php index e4736a0f7ca7..55ffa44e0de3 100644 --- a/app/Models/Product.php +++ b/app/Models/Product.php @@ -99,6 +99,64 @@ class Product extends BaseModel 'tax_id', ]; + public array $ubl_tax_map = [ + self::PRODUCT_TYPE_REVERSE_TAX => 'AE', // VAT_REVERSE_CHARGE = + self::PRODUCT_TYPE_EXEMPT => 'E', // EXEMPT_FROM_TAX = + self::PRODUCT_TYPE_PHYSICAL => 'S', // STANDARD_RATE = + self::PRODUCT_TYPE_ZERO_RATED => 'Z', // ZERO_RATED_GOODS = + // self::PRODUCT_TYPE_ZERO_RATED => 'G', // FREE_EXPORT_ITEM = + // self::PRODUCT_TYPE_ZERO_RATED => 'O', // OUTSIDE_TAX_SCOPE = + // self::PRODUCT_TYPE_EXEMPT => 'K', // EEA_GOODS_AND_SERVICES = + // self::PRODUCT_TYPE_PHYSICAL => 'L', // CANARY_ISLANDS_INDIRECT_TAX = + // self::PRODUCT_TYPE_PHYSICAL => 'M', // CEUTA_AND_MELILLA = + // self::PRODUCT_TYPE_PHYSICAL => 'B', // TRANSFERRED_VAT_ITALY = + // self::PRODUCT_TYPE_PHYSICAL => 'A', // MIXED_TAX_RATE = + self::PRODUCT_TYPE_REDUCED_TAX => 'AA', // LOWER_RATE = + // self::PRODUCT_TYPE_PHYSICAL => 'AB', // EXEMPT_FOR_RESALE = + // self::PRODUCT_TYPE_PHYSICAL => 'AC', // VAT_NOT_NOW_DUE = + // self::PRODUCT_TYPE_PHYSICAL => 'AD', // VAT_DUE_PREVIOUS_INVOICE = + // self::PRODUCT_TYPE_PHYSICAL => 'B', // TRANSFERRED_VAT = + // self::PRODUCT_TYPE_PHYSICAL => 'C', // DUTY_PAID_BY_SUPPLIER = + // self::PRODUCT_TYPE_PHYSICAL => 'D', // VAT_MARGIN_SCHEME_TRAVEL_AGENTS = + // self::PRODUCT_TYPE_PHYSICAL => 'F', // VAT_MARGIN_SCHEME_SECOND_HAND_GOODS = + // self::PRODUCT_TYPE_PHYSICAL => 'H', // HIGHER_RATE = + // self::PRODUCT_TYPE_PHYSICAL => 'I', // VAT_MARGIN_SCHEME_WORKS_OF_ART = + // self::PRODUCT_TYPE_PHYSICAL => 'J', // VAT_MARGIN_SCHEME_COLLECTORS_ITEMS = + // self::PRODUCT_TYPE_PHYSICAL => 'K', // VAT_EXEMPT_EEA_INTRA_COMMUNITY = + // self::PRODUCT_TYPE_PHYSICAL => 'L', // CANARY_ISLANDS_TAX = + // self::PRODUCT_TYPE_PHYSICAL => 'M', // TAX_CEUTA_MELILLA = + // self::PRODUCT_TYPE_PHYSICAL => 'O', // SERVICES_OUTSIDE_SCOPE = + ]; + + public array $ubl_tax_translations = [ + 'texts.reverse_tax' => 'AE', // VAT_REVERSE_CHARGE + 'texts.tax_exempt' => 'E', // EXEMPT_FROM_TAX + 'texts.physical_goods' => 'S', // STANDARD_RATE + 'texts.zero_rated' => 'Z', // ZERO_RATED_GOODS + 'ubl.vat_exempt_eea_intra_community' => 'K', // VAT_EXEMPT_EEA_INTRA_COMMUNITY + 'ubl.free_export_item' => 'G', // FREE_EXPORT_ITEM + 'ubl.outside_tax_scope' => 'O', // OUTSIDE_TAX_SCOPE + 'ubl.eea_goods_and_services' => 'K', // EEA_GOODS_AND_SERVICES + 'ubl.canary_islands_indirect_tax' => 'L', // CANARY_ISLANDS_INDIRECT_TAX + 'ubl.ceuta_and_melilla' => 'M', // CEUTA_AND_MELILLA + 'ubl.transferred_vat_italy' => 'B', // TRANSFERRED_VAT_ITALY + 'ubl.mixed_tax_rate' => 'A', // MIXED_TAX_RATE + 'ubl.lower_rate' => 'AA', // LOWER_RATE + 'ubl.exempt_for_resale' => 'AB', // EXEMPT_FOR_RESALE + 'ubl.vat_not_now_due' => 'AC', // VAT_NOT_NOW_DUE + 'ubl.vat_due_previous_invoice' => 'AD', // VAT_DUE_PREVIOUS_INVOICE + 'ubl.transferred_vat' => 'B', // TRANSFERRED_VAT + 'ubl.duty_paid_by_supplier' => 'C', // DUTY_PAID_BY_SUPPLIER + 'ubl.vat_margin_scheme_travel_agents' => 'D', // VAT_MARGIN_SCHEME_TRAVEL_AGENTS + 'ubl.vat_margin_scheme_second_hand_goods' => 'F', // VAT_MARGIN_SCHEME_SECOND_HAND_GOODS + 'ubl.higher_rate' => 'H', // HIGHER_RATE + 'ubl.vat_margin_scheme_works_of_art' => 'I', // VAT_MARGIN_SCHEME_WORKS_OF_ART + 'ubl.vat_margin_scheme_collectors_items' => 'J', // VAT_MARGIN_SCHEME_COLLECTORS_ITEMS + 'ubl.canary_islands_tax' => 'L', // CANARY_ISLANDS_TAX + 'ubl.tax_ceuta_melilla' => 'M', // TAX_CEUTA_MELILLA + 'ubl.services_outside_scope' => 'O', // SERVICES_OUTSIDE_SCOPE + ]; + protected $touches = []; public function getEntityType() @@ -148,6 +206,20 @@ class Product extends BaseModel return $converter->convert($this->notes ?? ''); } + public static function markdownHelp(string $notes = '') + { + + $converter = new CommonMarkConverter([ + 'allow_unsafe_links' => false, + 'renderer' => [ + 'soft_break' => '
', + ], + ]); + + return $converter->convert($notes); + + } + public function portalUrl($use_react_url): string { return $use_react_url ? config('ninja.react_url') . "/#/products/{$this->hashed_id}/edit" : config('ninja.app_url'); diff --git a/app/Models/PurchaseOrder.php b/app/Models/PurchaseOrder.php index 3cc2b0e0de3b..284c211f56b5 100644 --- a/app/Models/PurchaseOrder.php +++ b/app/Models/PurchaseOrder.php @@ -265,7 +265,7 @@ class PurchaseOrder extends BaseModel public function expense(): \Illuminate\Database\Eloquent\Relations\BelongsTo { - return $this->belongsTo(Expense::class); + return $this->belongsTo(Expense::class)->withTrashed(); } public function user(): \Illuminate\Database\Eloquent\Relations\BelongsTo diff --git a/app/Models/Subscription.php b/app/Models/Subscription.php index 132b57cfe6e3..51a577c1c699 100644 --- a/app/Models/Subscription.php +++ b/app/Models/Subscription.php @@ -12,6 +12,7 @@ namespace App\Models; use App\Services\Subscription\PaymentLinkService; +use App\Services\Subscription\SubscriptionCalculator; use App\Services\Subscription\SubscriptionService; use App\Services\Subscription\SubscriptionStatus; use Illuminate\Database\Eloquent\Factories\HasFactory; @@ -115,6 +116,7 @@ class Subscription extends BaseModel 'optional_product_ids', 'optional_recurring_product_ids', 'use_inventory_management', + 'steps', ]; protected $casts = [ @@ -146,6 +148,11 @@ class Subscription extends BaseModel return (new SubscriptionStatus($this, $recurring_invoice))->run(); } + public function calc(): SubscriptionCalculator + { + return new SubscriptionCalculator($this); + } + public function company(): \Illuminate\Database\Eloquent\Relations\BelongsTo { return $this->belongsTo(Company::class); diff --git a/app/PaymentDrivers/Authorize/AuthorizeCustomer.php b/app/PaymentDrivers/Authorize/AuthorizeCustomer.php index a9fd927294da..9a4d2f5765b1 100644 --- a/app/PaymentDrivers/Authorize/AuthorizeCustomer.php +++ b/app/PaymentDrivers/Authorize/AuthorizeCustomer.php @@ -103,7 +103,7 @@ class AuthorizeCustomer } else { // nlog("creating client"); - $first_payment_profile = $profile['payment_profiles'][0]; + $first_payment_profile = &$profile['payment_profiles'][0]; if (! $first_payment_profile) { continue; diff --git a/app/PaymentDrivers/Authorize/AuthorizePaymentMethod.php b/app/PaymentDrivers/Authorize/AuthorizePaymentMethod.php index 22eac01927a0..07b7ea7516f5 100644 --- a/app/PaymentDrivers/Authorize/AuthorizePaymentMethod.php +++ b/app/PaymentDrivers/Authorize/AuthorizePaymentMethod.php @@ -101,9 +101,10 @@ class AuthorizePaymentMethod $gateway_customer_reference = (new AuthorizeCreateCustomer($this->authorize, $this->authorize->client))->create($data); $payment_profile = $this->addPaymentMethodToClient($gateway_customer_reference, $data); - $this->createClientGatewayToken($payment_profile, $gateway_customer_reference); } + $this->createClientGatewayToken($payment_profile, $gateway_customer_reference); + return redirect()->route('client.payment_methods.index'); } @@ -168,6 +169,9 @@ class AuthorizePaymentMethod $billto->setCity(substr($this->authorize->client->city, 0, 40)); $billto->setState(substr($this->authorize->client->state, 0, 40)); $billto->setZip(substr($this->authorize->client->postal_code, 0, 20)); + + if(isset($contact->email) && str_contains($contact->email, '@')) + $billto->setEmail($contact->email); if ($this->authorize->client->country_id) { $billto->setCountry($this->authorize->client->country->name); @@ -179,7 +183,7 @@ class AuthorizePaymentMethod // Create a new Customer Payment Profile object $paymentprofile = new CustomerPaymentProfileType(); $paymentprofile->setCustomerType('individual'); - + if ($billto) { $paymentprofile->setBillTo($billto); } diff --git a/app/PaymentDrivers/AuthorizePaymentDriver.php b/app/PaymentDrivers/AuthorizePaymentDriver.php index 87c74fdb9209..0e8c820d133f 100644 --- a/app/PaymentDrivers/AuthorizePaymentDriver.php +++ b/app/PaymentDrivers/AuthorizePaymentDriver.php @@ -195,6 +195,8 @@ class AuthorizePaymentDriver extends BaseDriver { $this->init(); + nlog("starting import auth.net"); + return (new AuthorizeCustomer($this))->importCustomers(); } diff --git a/app/PaymentDrivers/StripePaymentDriver.php b/app/PaymentDrivers/StripePaymentDriver.php index 720155cab594..a7181a4b680c 100644 --- a/app/PaymentDrivers/StripePaymentDriver.php +++ b/app/PaymentDrivers/StripePaymentDriver.php @@ -387,7 +387,6 @@ class StripePaymentDriver extends BaseDriver $fields[] = ['name' => 'client_custom_value4', 'label' => $this->helpers->makeCustomField($this->client->company->custom_fields, 'client4'), 'type' => 'text', 'validation' => 'required']; } - return $fields; } diff --git a/app/Repositories/ActivityRepository.php b/app/Repositories/ActivityRepository.php index 35465a3acf7a..09c530d7ad1b 100644 --- a/app/Repositories/ActivityRepository.php +++ b/app/Repositories/ActivityRepository.php @@ -41,7 +41,7 @@ class ActivityRepository extends BaseRepository * Save the Activity. * * @param \stdClass $fields The fields - * @param \App\Models\Invoice | \App\Models\Quote | \App\Models\Credit | \App\Models\PurchaseOrder $entity + * @param \App\Models\Invoice | \App\Models\Quote | \App\Models\Credit | \App\Models\PurchaseOrder | \App\Models\Expense $entity * @param array $event_vars */ public function save($fields, $entity, $event_vars) @@ -72,7 +72,7 @@ class ActivityRepository extends BaseRepository /** * Creates a backup. * - * @param \App\Models\Invoice | \App\Models\Quote | \App\Models\Credit | \App\Models\PurchaseOrder $entity + * @param \App\Models\Invoice | \App\Models\Quote | \App\Models\Credit | \App\Models\PurchaseOrder | \App\Models\Expense $entity * @param \App\Models\Activity $activity The activity */ public function createBackup($entity, $activity) diff --git a/app/Repositories/ClientRepository.php b/app/Repositories/ClientRepository.php index f7ec59ce7fba..3083a2314df9 100644 --- a/app/Repositories/ClientRepository.php +++ b/app/Repositories/ClientRepository.php @@ -126,6 +126,21 @@ class ClientRepository extends BaseRepository ClientFactory::create($user->company()->id, $user->id) ); } + + /** + * Bulk assign clients to a group. + * + * @param mixed $clients + * @param mixed $group_settings_id + * @return void + */ + public function assignGroup($clients, $group_settings_id): void + { + Client::query() + ->company() + ->whereIn('id', $clients->pluck('id')) + ->update(['group_settings_id' => $group_settings_id]); + } public function purge($client) { diff --git a/app/Repositories/ExpenseRepository.php b/app/Repositories/ExpenseRepository.php index 5b87af81466d..b9d125045fff 100644 --- a/app/Repositories/ExpenseRepository.php +++ b/app/Repositories/ExpenseRepository.php @@ -46,10 +46,12 @@ class ExpenseRepository extends BaseRepository /** @var \App\Models\User $user */ $user = auth()->user(); - if(isset($data['payment_date']) && $data['payment_date'] == $expense->payment_date) { + $payment_date = &$data['payment_date']; + $vendor_id = &$data['vendor_id']; + + if($payment_date && $payment_date == $expense->payment_date) { //do nothing - } elseif(isset($data['payment_date']) && strlen($data['payment_date']) > 1 && $user->company()->notify_vendor_when_paid && (isset($data['vendor_id']) || $expense->vendor_id)) { - nlog("ping"); + } elseif($payment_date && strlen($payment_date) > 1 && $user->company()->notify_vendor_when_paid && ($vendor_id || $expense->vendor_id)) { $this->notify_vendor = true; } @@ -73,6 +75,13 @@ class ExpenseRepository extends BaseRepository VendorExpenseNotify::dispatch($expense, $expense->company->db); } + if($payment_date && strlen($payment_date) > 1 && $expense->purchase_order) { + $purchase_order = $expense->purchase_order; + $purchase_order->balance = round($purchase_order->amount - $expense->amount, 2); + $purchase_order->paid_to_date = $expense->amount; + $purchase_order->save(); + } + return $expense; } diff --git a/app/Repositories/SubscriptionRepository.php b/app/Repositories/SubscriptionRepository.php index f59992211c89..d8780746ccf3 100644 --- a/app/Repositories/SubscriptionRepository.php +++ b/app/Repositories/SubscriptionRepository.php @@ -118,15 +118,60 @@ class SubscriptionRepository extends BaseRepository return $line_items; } + + /** + * ConvertV3Bundle + * + * Removing the nested keys of the items array + * + * @param array $bundle + * @return array + */ + private function convertV3Bundle($bundle): array + { + if(is_object($bundle)) + $bundle = json_decode(json_encode($bundle),1); + + $items = []; + + foreach($bundle['recurring_products'] as $key => $value) { + + $line_item = new \stdClass; + $line_item->product_key = $value['product']['product_key']; + $line_item->qty = (float) $value['quantity']; + $line_item->unit_cost = (float) $value['product']['price']; + $line_item->description = $value['product']['notes']; + $line_item->is_recurring = $value['product']['is_recurring'] ?? false; + $items[] = $line_item; + } + + foreach($bundle['recurring_products'] as $key => $value) { + + $line_item = new \stdClass; + $line_item->product_key = $value['product']['product_key']; + $line_item->qty = (float) $value['quantity']; + $line_item->unit_cost = (float) $value['product']['price']; + $line_item->description = $value['product']['notes']; + $line_item->is_recurring = $value['product']['is_recurring'] ?? false; + + } + + return $items; + + } public function generateBundleLineItems($bundle, $is_recurring = false, $is_credit = false) { + + if(isset($bundle->recurring_products)) + $bundle = $this->convertV3Bundle($bundle); + $multiplier = $is_credit ? -1 : 1; $line_items = []; $line_items = collect($bundle)->filter(function ($item) { - return $item->is_recurring; + return $item->is_recurring ?? false; })->map(function ($item) { $line_item = new InvoiceItem(); $line_item->product_key = $item->product_key; diff --git a/app/Rules/Subscriptions/Steps.php b/app/Rules/Subscriptions/Steps.php new file mode 100644 index 000000000000..3273bc2c3e80 --- /dev/null +++ b/app/Rules/Subscriptions/Steps.php @@ -0,0 +1,26 @@ + 0) { + $fail($errors[0]); + } + } +} diff --git a/app/Services/Client/Statement.php b/app/Services/Client/Statement.php index 163718ea6dbf..55e61356dbe7 100644 --- a/app/Services/Client/Statement.php +++ b/app/Services/Client/Statement.php @@ -63,8 +63,10 @@ class Statement $variables = []; $variables = $html->generateLabelsAndValues(); + + $option_template = &$this->options['template']; - if($this->client->getSetting('statement_design_id') != '') { + if($this->client->getSetting('statement_design_id') != '' || $option_template && $option_template != '') { $variables['values']['$start_date'] = $this->translateDate($this->options['start_date'], $this->client->date_format(), $this->client->locale()); $variables['values']['$end_date'] = $this->translateDate($this->options['end_date'], $this->client->date_format(), $this->client->locale()); diff --git a/app/Services/ClientPortal/InstantPayment.php b/app/Services/ClientPortal/InstantPayment.php index 3ff5cd2c7758..f9e4a9476d06 100644 --- a/app/Services/ClientPortal/InstantPayment.php +++ b/app/Services/ClientPortal/InstantPayment.php @@ -44,6 +44,9 @@ class InstantPayment public function run() { + nlog($this->request->all()); + + /** @var \App\Models\ClientContact $cc */ $cc = auth()->guard('contact')->user(); @@ -69,6 +72,9 @@ class InstantPayment * ['invoice_id' => xxx, 'amount' => 22.00] */ $payable_invoices = collect($this->request->payable_invoices); + + nlog($payable_invoices); + $invoices = Invoice::query()->whereIn('id', $this->transformKeys($payable_invoices->pluck('invoice_id')->toArray()))->withTrashed()->get(); $invoices->each(function ($invoice) { diff --git a/app/Services/Credit/CreditService.php b/app/Services/Credit/CreditService.php index 77409f913e37..ea3643de39ac 100644 --- a/app/Services/Credit/CreditService.php +++ b/app/Services/Credit/CreditService.php @@ -43,6 +43,11 @@ class CreditService return (new CreateEDocument($this->credit))->handle(); } + public function getEDocument($contact = null) + { + return $this->getECredit($contact); + } + /** * Applies the invoice number. * @return $this InvoiceService object diff --git a/app/Services/EDocument/Samples/ro.xml b/app/Services/EDocument/Samples/ro.xml new file mode 100644 index 000000000000..cc2d5e8136b1 --- /dev/null +++ b/app/Services/EDocument/Samples/ro.xml @@ -0,0 +1,119 @@ + + + 2.1 + urn:cen.eu:en16931:2017#compliant#urn:efactura.mfinante.ro:CIUS-RO:1.0.1 + ABC 0020 + 2024-01-01 + 2024-01-15 + 384 + RON + RON + + + + 234234234 + + + This can be the full address , not just the street and street nr. + SECTOR2 + RO-B + + RO + + + + RO234234234 + + VAT + + + + Some Copany Name + J40/2222/2009 + + + Someone + 88282819832 + some@email.com + + + + + + + 646546549 + + + This can be the full address , not just the street and street nr. + SECTOR3 + RO-B + + RO + + + + Some Comapny + 646546549 + + + Someone + + some@email.com + + + + + 42 + + some account nr + Bank name + + + + 63.65 + + 335.00 + 63.65 + + S // this is a speciffic identifier for the VAT type + 19 + + VAT + + + + + + 335.00 + 335.00 + 398.65 + 0.00 + 398.65 + + + 1 + 1 // unitcode + is a speciffic identifier for the type of product + 335.00 + + Some Description + Some product + + S // this is a speciffic identifier for the VAT type + 19 + + VAT + + + + + 335 + + + \ No newline at end of file diff --git a/app/Services/EDocument/Standards/RoEInvoice.php b/app/Services/EDocument/Standards/RoEInvoice.php index d9945e9834df..d9679aa27150 100644 --- a/app/Services/EDocument/Standards/RoEInvoice.php +++ b/app/Services/EDocument/Standards/RoEInvoice.php @@ -31,6 +31,7 @@ use CleverIt\UBL\Invoice\TaxCategory; use CleverIt\UBL\Invoice\TaxScheme; use CleverIt\UBL\Invoice\TaxSubTotal; use CleverIt\UBL\Invoice\TaxTotal; +use App\Models\Product; class RoEInvoice extends AbstractService { @@ -65,10 +66,10 @@ class RoEInvoice extends AbstractService $ubl_invoice = new UBLInvoice(); // invoice - $ubl_invoice->setId($invoice->custom_value1 . ' ' . $invoice->number); + $ubl_invoice->setId($invoice->number); $ubl_invoice->setIssueDate(date_create($invoice->date)); $ubl_invoice->setDueDate(date_create($invoice->due_date)); - $ubl_invoice->setInvoiceTypeCode(explode('-', $invoice->custom_value3)[0]); + $ubl_invoice->setInvoiceTypeCode("380"); $ubl_invoice->setDocumentCurrencyCode($invoice->client->getCurrencyCode()); $ubl_invoice->setTaxCurrencyCode($invoice->client->getCurrencyCode()); @@ -130,7 +131,7 @@ class RoEInvoice extends AbstractService ->setTaxAmount($invoicing_data->getItemTotalTaxes()) ->setTaxableAmount($taxable) ->setTaxCategory((new TaxCategory()) - ->setId(explode('-', $company->settings->custom_value3)[0]) + ->setId("S") ->setPercent($taxRatePercent) ->setTaxScheme(($taxNameScheme === 'TVA') ? 'VAT' : $taxNameScheme))); $ubl_invoice->setTaxTotal($taxtotal); @@ -212,29 +213,29 @@ class RoEInvoice extends AbstractService { if (strlen($item->tax_name1) > 1) { $classifiedTaxCategory = (new ClassifiedTaxCategory()) - ->setId(explode('-', $item->custom_value4)[0]) + ->setId($this->resolveTaxCode($item->tax_id ?? 1)) ->setPercent($item->tax_rate1) ->setTaxScheme(($item->tax_name1 === 'TVA') ? 'VAT' : $item->tax_name1); } elseif (strlen($item->tax_name2) > 1) { $classifiedTaxCategory = (new ClassifiedTaxCategory()) - ->setId(explode('-', $item->custom_value4)[0]) + ->setId($this->resolveTaxCode($item->tax_id ?? 1)) ->setPercent($item->tax_rate2) ->setTaxScheme(($item->tax_name2 === 'TVA') ? 'VAT' : $item->tax_name2); } elseif (strlen($item->tax_name3) > 1) { $classifiedTaxCategory = (new ClassifiedTaxCategory()) - ->setId(explode('-', $item->custom_value4)[0]) + ->setId($this->resolveTaxCode($item->tax_id ?? 1)) ->setPercent($item->tax_rate3) ->setTaxScheme(($item->tax_name3 === 'TVA') ? 'VAT' : $item->tax_name3); } $invoiceLine = (new InvoiceLine()) ->setId($index + 1) ->setInvoicedQuantity($item->quantity) - ->setUnitCode($item->custom_value3) + ->setUnitCode($item->unit_code ?? 'C62') ->setLineExtensionAmount($item->line_total) ->setItem((new Item()) ->setName($item->product_key) ->setDescription($item->notes) - ->setClassifiedTaxCategory($classifiedTaxCategory)) + ->setClassifiedTaxCategory([$classifiedTaxCategory])) ->setPrice((new Price()) ->setPriceAmount($this->costWithDiscount($item))); @@ -365,6 +366,26 @@ class RoEInvoice extends AbstractService } } + private function resolveTaxCode($tax_id) + { + $code = $tax_id; + + match($tax_id){ + Product::PRODUCT_TYPE_REVERSE_TAX => $code = 'AE', // VAT_REVERSE_CHARGE = + Product::PRODUCT_TYPE_EXEMPT => $code = 'E', // EXEMPT_FROM_TAX = + Product::PRODUCT_TYPE_PHYSICAL => $code = 'S', // STANDARD_RATE = + Product::PRODUCT_TYPE_ZERO_RATED => $code = 'Z', // ZERO_RATED_GOODS = + Product::PRODUCT_TYPE_REDUCED_TAX => $code = 'AA', // LOWER_RATE = + Product::PRODUCT_TYPE_SERVICE => $code = 'S', // STANDARD_RATE = + Product::PRODUCT_TYPE_DIGITAL => $code = 'S', // STANDARD_RATE = + Product::PRODUCT_TYPE_SHIPPING => $code = 'S', // STANDARD_RATE = + Product::PRODUCT_TYPE_OVERRIDE_TAX => $code = 'S', // STANDARD_RATE = + default => $code = 'S', + }; + + return $code; + } + public function generateXml(): string { $ubl_invoice = $this->run(); // Call the existing handle method to get the UBLInvoice diff --git a/app/Services/Email/Email.php b/app/Services/Email/Email.php index c07d34515a0f..96faccf0d576 100644 --- a/app/Services/Email/Email.php +++ b/app/Services/Email/Email.php @@ -93,7 +93,7 @@ class Email implements ShouldQueue */ public function backoff() { - return [rand(10, 20), rand(30, 45), rand(60, 79), rand(160, 400)]; + return [rand(5, 29), rand(30, 59), rand(61, 100), rand(180, 500)]; } /** @@ -314,6 +314,8 @@ class Email implements ShouldQueue $this->logMailError($e->getMessage(), $this->company->clients()->first()); $this->cleanUpMailers(); +$this->entityEmailFailed($message); + return; } @@ -329,6 +331,8 @@ class Email implements ShouldQueue $this->logMailError($message, $this->company->clients()->first()); $this->cleanUpMailers(); + $this->entityEmailFailed($message); + return; } @@ -343,11 +347,12 @@ class Email implements ShouldQueue if ($message_body && property_exists($message_body, 'Message')) { $message = $message_body->Message; - nlog($message); } $this->fail(); + $this->entityEmailFailed($message); $this->cleanUpMailers(); + return; } diff --git a/app/Services/Email/EmailDefaults.php b/app/Services/Email/EmailDefaults.php index 5346c0636fe6..7586e991f888 100644 --- a/app/Services/Email/EmailDefaults.php +++ b/app/Services/Email/EmailDefaults.php @@ -301,7 +301,7 @@ class EmailDefaults $documents = []; /* Return early if the user cannot attach documents */ - if (!$this->email->company->account->hasFeature(Account::FEATURE_PDF_ATTACHMENT) || $this->email->email_object->email_template_subject == 'email_subject_statement') { + if (!$this->email->email_object->invitation || !$this->email->company->account->hasFeature(Account::FEATURE_PDF_ATTACHMENT) || $this->email->email_object->email_template_subject == 'email_subject_statement') { return $this; } @@ -320,8 +320,8 @@ class EmailDefaults } } /** E-Invoice xml file */ - if ($this->email->email_object->settings->enable_e_invoice && ! $this->email->email_object->entity instanceof PurchaseOrder) { - $xml_string = $this->email->email_object->entity->service()->getEInvoice(); + if ($this->email->email_object->settings->enable_e_invoice) { + $xml_string = $this->email->email_object->entity->service()->getEDocument(); if($xml_string) { $this->email->email_object->attachments = array_merge($this->email->email_object->attachments, [['file' => base64_encode($xml_string), 'name' => explode(".", $this->email->email_object->entity->getFileName('xml'))[0]."-e_invoice.xml"]]); diff --git a/app/Services/Invoice/GenerateDeliveryNote.php b/app/Services/Invoice/GenerateDeliveryNote.php index c8a3a85b615f..ee4ab5e83cce 100644 --- a/app/Services/Invoice/GenerateDeliveryNote.php +++ b/app/Services/Invoice/GenerateDeliveryNote.php @@ -49,7 +49,9 @@ class GenerateDeliveryNote if($design && $design->is_template) { $ts = new TemplateService($design); - $pdf = $ts->build([ + + $pdf = $ts->setCompany($this->invoice->company) + ->build([ 'invoices' => collect([$this->invoice]), ])->getPdf(); @@ -62,8 +64,8 @@ class GenerateDeliveryNote : $this->decodePrimaryKey($this->invoice->client->getSetting('invoice_design_id')); $invitation = $this->invoice->invitations->first(); - // $file_path = sprintf('%s%s_delivery_note.pdf', $this->invoice->client->invoice_filepath($invitation), $this->invoice->number); - $file_path = sprintf('%sdelivery_note.pdf', $this->invoice->client->invoice_filepath($invitation)); + + // return (new \App\Services\Pdf\PdfService($invitation, 'delivery_note'))->boot()->getPdf(); if (config('ninja.phantomjs_pdf_generation') || config('ninja.pdf_generator') == 'phantom') { return (new Phantom())->generate($this->invoice->invitations->first()); @@ -79,6 +81,9 @@ class GenerateDeliveryNote $template = new PdfMakerDesign(strtolower($design->name)); } + $variables = $html->generateLabelsAndValues(); + $variables['labels']['$entity_label']= ctrans('texts.delivery_note'); + $state = [ 'template' => $template->elements([ 'client' => $this->invoice->client, @@ -86,7 +91,7 @@ class GenerateDeliveryNote 'pdf_variables' => (array) $this->invoice->company->settings->pdf_variables, 'contact' => $this->contact, ], 'delivery_note'), - 'variables' => $html->generateLabelsAndValues(), + 'variables' => $variables, 'options' => [ 'client' => $this->invoice->client, 'entity' => $this->invoice, @@ -111,12 +116,10 @@ class GenerateDeliveryNote info($maker->getCompiledHTML()); } - return $pdf; - // Storage::disk($this->disk)->put($file_path, $pdf); - $maker = null; $state = null; - // return $file_path; + return $pdf; + } } diff --git a/app/Services/Invoice/InvoiceService.php b/app/Services/Invoice/InvoiceService.php index 9378593f1208..776636bd0326 100644 --- a/app/Services/Invoice/InvoiceService.php +++ b/app/Services/Invoice/InvoiceService.php @@ -204,6 +204,11 @@ class InvoiceService return (new CreateEDocument($this->invoice))->handle(); } + public function getEDocument($contact = null) + { + return $this->getEInvoice($contact); + } + public function sendEmail($contact = null) { $send_email = new SendEmail($this->invoice, null, $contact); diff --git a/app/Services/PdfMaker/PdfMaker.php b/app/Services/PdfMaker/PdfMaker.php index f7b8718e80af..75c2ee647025 100644 --- a/app/Services/PdfMaker/PdfMaker.php +++ b/app/Services/PdfMaker/PdfMaker.php @@ -141,7 +141,6 @@ class PdfMaker { $html = $this->document->saveHTML(); - // nlog($html); return str_replace('%24', '$', $html); } } diff --git a/app/Services/PurchaseOrder/PurchaseOrderService.php b/app/Services/PurchaseOrder/PurchaseOrderService.php index 686329599f62..76601307b613 100644 --- a/app/Services/PurchaseOrder/PurchaseOrderService.php +++ b/app/Services/PurchaseOrder/PurchaseOrderService.php @@ -82,6 +82,11 @@ class PurchaseOrderService { return (new CreateEDocument($this->purchase_order))->handle(); } + public function getEDocument($contact = null) + { + return $this->getEPurchaseOrder($contact); + } + public function deleteEPurchaseOrder() { $this->purchase_order->load('invitations'); diff --git a/app/Services/Quote/QuoteService.php b/app/Services/Quote/QuoteService.php index f2ee47666a67..f8080e775932 100644 --- a/app/Services/Quote/QuoteService.php +++ b/app/Services/Quote/QuoteService.php @@ -78,6 +78,11 @@ class QuoteService return (new CreateEDocument($this->quote))->handle(); } + public function getEDocument($contact = null) + { + return $this->getEQuote($contact); + } + public function sendEmail($contact = null): self { $send_email = new SendEmail($this->quote, null, $contact); diff --git a/app/Services/Subscription/StepService.php b/app/Services/Subscription/StepService.php new file mode 100644 index 000000000000..84ed67ecf965 --- /dev/null +++ b/app/Services/Subscription/StepService.php @@ -0,0 +1,70 @@ +mapWithKeys(fn($dependency, $class) => [$dependency['id'] => $class])->toArray(); + + return array_map(fn($step) => $classes[$step], explode(',', $steps)); + } + + public static function check(array $steps): array + { + $dependencies = Purchase::$dependencies; + $step_order = array_flip($steps); + $errors = []; + + foreach ($steps as $step) { + $dependent = $dependencies[$step]['dependencies'] ?? []; + + if (!empty($dependent) && !array_intersect($dependent, $steps)) { + $errors[] = ctrans('texts.step_dependency_fail', [ + 'step' => ctrans('texts.' . self::mapClassNameToString($step)), + 'dependencies' => implode(', ', array_map(fn($dependency) => ctrans('texts.' . self::mapClassNameToString($dependency)), $dependent)), + ]); + } + + foreach ($dependent as $dependency) { + if (in_array($dependency, $steps) && $step_order[$dependency] > $step_order[$step]) { + $errors[] = ctrans('texts.step_dependency_order_fail', [ + 'step' => ctrans('texts.' . self::mapClassNameToString($step)), + 'dependency' => implode(', ', array_map(fn($dependency) => ctrans('texts.' . self::mapClassNameToString($dependency)), $dependent)), + ]); + } + } + } + + $auth = collect($dependencies) + ->filter(fn ($dependency) => str_starts_with($dependency['id'], 'auth.')) + ->keys() + ->toArray(); + + if (count(array_intersect($auth, $steps)) === 0) { + $errors[] = ctrans('texts.step_authentication_fail'); + } + + return $errors; + } + + public static function mapClassNameToString(string $class): string + { + $classes = collect(Purchase::$dependencies)->mapWithKeys(fn($dependency, $class) => [$class => $dependency['id']])->toArray(); + + return $classes[$class]; + } +} \ No newline at end of file diff --git a/app/Services/Subscription/SubscriptionCalculator.php b/app/Services/Subscription/SubscriptionCalculator.php new file mode 100644 index 000000000000..ad730d1677d4 --- /dev/null +++ b/app/Services/Subscription/SubscriptionCalculator.php @@ -0,0 +1,204 @@ +subscription->company_id, $this->subscription->user_id); + $invoice->subscription_id = $this->subscription->id; + $invoice->client_id = $this->decodePrimaryKey($context['client_id']); + $invoice->is_proforma = true; + $invoice->number = "####" . ctrans('texts.subscription') . "_" . now()->format('Y-m-d') . "_" . rand(0, 100000); + $invoice->line_items = $this->buildItems($context); + + if(isset($context['valid_coupon']) && $context['valid_coupon']) { + $invoice->discount = $this->subscription->promo_discount; + $invoice->is_amount_discount = $this->subscription->is_amount_discount; + } + + return $invoice_repo->save([], $invoice); + + } + + /** + * Build Line Items + * + * @param array $context + * + * @return array + */ + private function buildItems(array $context): array + { + + $bundle = $context['bundle']; + + $recurring = array_merge(isset($bundle['recurring_products']) ? $bundle['recurring_products'] : [], isset($bundle['optional_recurring_products']) ? $bundle['optional_recurring_products'] : []); + $one_time = array_merge(isset($bundle['one_time_products']) ? $bundle['one_time_products'] : [], isset($bundle['optional_one_time_products']) ? $bundle['optional_one_time_products'] : []); + + $items = []; + + foreach($recurring as $item) { + + if($item['quantity'] < 1) + continue; + + $line_item = new InvoiceItem(); + $line_item->product_key = $item['product']['product_key']; + $line_item->quantity = (float) $item['quantity']; + $line_item->cost = (float) $item['product']['price']; + $line_item->notes = $item['product']['notes']; + $line_item->tax_id = $item['product']['tax_id'] ?? '1'; + $items[] = $line_item; + + } + + foreach($one_time as $item) { + + if($item['quantity'] < 1) { + continue; + } + + $line_item = new InvoiceItem(); + $line_item->product_key = $item['product']['product_key']; + $line_item->quantity = (float) $item['quantity']; + $line_item->cost = (float) $item['product']['price']; + $line_item->notes = $item['product']['notes']; + $line_item->tax_id = $item['product']['tax_id'] ?? '1'; + $items[] = $line_item; + + } + + return $items; + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + /** + * Tests if the user is currently up + * to date with their payments for + * a given recurring invoice + * + * @return bool + */ + public function isPaidUp(Invoice $invoice): bool + { + $outstanding_invoices_exist = Invoice::query()->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL]) + ->where('subscription_id', $invoice->subscription_id) + ->where('client_id', $invoice->client_id) + ->where('balance', '>', 0) + ->exists(); + + return ! $outstanding_invoices_exist; + } + + public function calcUpgradePlan(Invoice $invoice) + { + //set the starting refund amount + $refund_amount = 0; + + $refund_invoice = false; + + //are they paid up to date. + + //yes - calculate refund + if ($this->isPaidUp($invoice)) { + $refund_invoice = $this->getRefundInvoice($invoice); + } + + if ($refund_invoice) { + /** @var \App\Models\Subscription $subscription **/ + $subscription = Subscription::find($invoice->subscription_id); + $pro_rata = new ProRata(); + + $to_date = $subscription->service()->getNextDateForFrequency(Carbon::parse($refund_invoice->date), $subscription->frequency_id); + + $refund_amount = $pro_rata->refund($refund_invoice->amount, now(), $to_date, $subscription->frequency_id); + + $charge_amount = $pro_rata->charge($this->subscription->price, now(), $to_date, $this->subscription->frequency_id); + + return $charge_amount - $refund_amount; + } + + //no - return full freight charge. + return $this->subscription->price; + } + + public function executeUpgradePlan() {} + + private function getRefundInvoice(Invoice $invoice) + { + return Invoice::where('subscription_id', $invoice->subscription_id) + ->where('client_id', $invoice->client_id) + ->where('is_deleted', 0) + ->orderBy('id', 'desc') + ->first(); + } +} diff --git a/app/Services/Template/TemplateAction.php b/app/Services/Template/TemplateAction.php index c418d94a132f..538320fa9564 100644 --- a/app/Services/Template/TemplateAction.php +++ b/app/Services/Template/TemplateAction.php @@ -11,33 +11,34 @@ namespace App\Services\Template; -use App\Libraries\MultiDB; +use App\Models\Task; +use App\Models\User; +use App\Models\Quote; use App\Models\Client; -use App\Models\Company; use App\Models\Credit; use App\Models\Design; +use App\Models\Vendor; +use App\Models\Company; use App\Models\Expense; use App\Models\Invoice; use App\Models\Payment; use App\Models\Product; use App\Models\Project; +use App\Libraries\MultiDB; use App\Models\PurchaseOrder; -use App\Models\Quote; +use Illuminate\Bus\Queueable; +use App\Utils\Traits\MakesHash; use App\Models\RecurringInvoice; -use App\Models\Task; -use App\Models\User; -use App\Models\Vendor; use App\Services\Email\AdminEmail; use App\Services\Email\EmailObject; -use App\Utils\Traits\MakesHash; -use Illuminate\Bus\Queueable; -use Illuminate\Contracts\Queue\ShouldQueue; -use Illuminate\Foundation\Bus\Dispatchable; +use App\Services\PdfMaker\PdfMerge; use Illuminate\Mail\Mailables\Address; -use Illuminate\Queue\InteractsWithQueue; -use Illuminate\Queue\Middleware\WithoutOverlapping; use Illuminate\Queue\SerializesModels; use Illuminate\Support\Facades\Storage; +use Illuminate\Queue\InteractsWithQueue; +use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Foundation\Bus\Dispatchable; +use Illuminate\Queue\Middleware\WithoutOverlapping; class TemplateAction implements ShouldQueue { @@ -110,10 +111,44 @@ class TemplateAction implements ShouldQueue /** Set a global currency_code */ $first_entity = $result->first(); - if($first_entity->client) - $currency_code = $first_entity->client->currency()->code; - elseif($first_entity instanceof Client) + + /** Lets be clever and sniff out Statements */ + if($first_entity instanceof Client && stripos(json_encode($template->design), '##statement##') !== false) { + + $options = [ + 'show_payments_table' => true, + 'show_aging_table' => true, + 'status' => 'all', + 'show_credits_table' => false, + 'template' => $this->template, + ]; + + $pdfs = []; + + foreach($result as $client) { + $pdfs[] = $client->service()->statement($options); + } + + if(count($pdfs) == 1) { + $pdf = $pdfs[0]; + } else { + $pdf = (new PdfMerge($pdfs))->run(); + } + + if($this->send_email) { + $this->sendEmail($pdf, $template); + } else { + $filename = "templates/{$this->hash}.pdf"; + Storage::disk(config('filesystems.default'))->put($filename, $pdf); + return $pdf; + } + + } + + if($first_entity instanceof Client) $currency_code = $first_entity->currency()->code; + elseif($first_entity->client) + $currency_code = $first_entity->client->currency()->code; else $currency_code = $this->company->currency()->code; diff --git a/app/Services/Template/TemplateMock.php b/app/Services/Template/TemplateMock.php index c921b350a4ac..be71b27677bd 100644 --- a/app/Services/Template/TemplateMock.php +++ b/app/Services/Template/TemplateMock.php @@ -31,9 +31,9 @@ class TemplateMock public string $project_data = '[{"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":[{"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":[],"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"}},{"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":[],"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"}},{"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":[],"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"}}],"client":{"name":"Hoeger, Hahn and Cole","balance":"0.000000","payment_balance":"0.000000","credit_balance":"1022.550000","vat_number":"VAT123"},"user":{"name":"Laron Weissnat Danika Flatley","email":"small@example.com"}},{"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":[{"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":[],"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","vat_number":"VAT123"}},{"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":[],"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","vat_number":"VAT123"}}],"client":{"name":"cypress","balance":"13866.150000","payment_balance":"0.000000","credit_balance":"1013.630000","vat_number":"VAT123"},"user":{"name":"Laron Weissnat Danika Flatley","email":"small@example.com"}},{"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":[{"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":[],"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","vat_number":"VAT123"}},{"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":[],"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","vat_number":"VAT123"}},{"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":[],"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","vat_number":"VAT123"}},{"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":[],"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","vat_number":"VAT123"}}],"client":{"name":"Walsh-Considine","balance":"0.000000","payment_balance":"0.000000","credit_balance":"1960.450000","vat_number":"VAT123"},"user":{"name":"Laron Weissnat Danika Flatley","email":"small@example.com"}},{"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":[{"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":[],"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","vat_number":"VAT123"}},{"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":[],"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","vat_number":"VAT123"}},{"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":[],"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","vat_number":"VAT123"}}],"client":{"name":"Walsh-Considine","balance":"0.000000","payment_balance":"0.000000","credit_balance":"1960.450000","vat_number":"VAT123"},"user":{"name":"Laron Weissnat Danika Flatley","email":"small@example.com"}},{"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":[{"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":[],"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","vat_number":"VAT123"}},{"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":[],"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","vat_number":"VAT123"}}],"client":{"name":"Medhurst Inc","balance":"37633.780000","payment_balance":"0.000000","credit_balance":"1025.100000","vat_number":"VAT123"},"user":{"name":"Laron Weissnat Danika Flatley","email":"small@example.com"}}]'; - 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"}},{"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"},"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"}},{"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"},"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"}},{"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"},"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"}},{"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"}},{"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"},"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"}},{"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"},"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"}},{"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"}},{"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"}},{"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"},"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"}},{"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"},"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"}},{"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"}},{"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"},"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"}},{"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"},"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"}}]'; + 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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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"},"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":"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"}]'; diff --git a/app/Services/Template/TemplateService.php b/app/Services/Template/TemplateService.php index 4dcf064c63c6..0062bafac5e1 100644 --- a/app/Services/Template/TemplateService.php +++ b/app/Services/Template/TemplateService.php @@ -552,6 +552,7 @@ class TemplateService 'payment_balance' => $invoice->client->payment_balance, 'credit_balance' => $invoice->client->credit_balance, 'vat_number' => $invoice->client->vat_number ?? '', + 'currency' => $invoice->client->currency()->code ?? 'USD', ], 'payments' => $payments, 'total_tax_map' => $invoice->calc()->getTotalTaxMap(), @@ -655,7 +656,7 @@ class TemplateService 'amount_raw' => $payment->amount, 'applied_raw' => $payment->applied, 'refunded_raw' => $payment->refunded, - 'balance_raw' => ($payment->amount - $payment->refunded - $payment->applied), + 'balance_raw' => ($payment->amount - $payment->applied), 'date' => $this->translateDate($payment->date, $payment->client->date_format(), $payment->client->locale()), 'method' => $payment->translatedType(), 'currency' => $payment->currency->code ?? $this->company->currency()->code, @@ -675,6 +676,7 @@ class TemplateService 'payment_balance' => $payment->client->payment_balance, 'credit_balance' => $payment->client->credit_balance, 'vat_number' => $payment->client->vat_number ?? '', + 'currency' => $payment->client->currency()->code ?? 'USD', ], 'paymentables' => $pivot, 'refund_activity' => $this->getPaymentRefundActivity($payment), @@ -755,6 +757,7 @@ class TemplateService 'payment_balance' => $quote->client->payment_balance, 'credit_balance' => $quote->client->credit_balance, 'vat_number' => $quote->client->vat_number ?? '', + 'currency' => $quote->client->currency()->code ?? 'USD', ], 'status_id' => $quote->status_id, 'status' => Quote::stringStatus($quote->status_id), @@ -874,6 +877,7 @@ class TemplateService 'payment_balance' => $credit->client->payment_balance, 'credit_balance' => $credit->client->credit_balance, 'vat_number' => $credit->client->vat_number ?? '', + 'currency' => $credit->client->currency()->code ?? 'USD', ], 'payments' => [], 'total_tax_map' => $credit->calc()->getTotalTaxMap(), @@ -938,6 +942,7 @@ class TemplateService 'payment_balance' => $task->client->payment_balance, 'credit_balance' => $task->client->credit_balance, 'vat_number' => $task->client->vat_number ?? '', + 'currency' => $task->client->currency()->code ?? 'USD', ] : [], ]; @@ -999,6 +1004,7 @@ class TemplateService 'payment_balance' => $project->client->payment_balance, 'credit_balance' => $project->client->credit_balance, 'vat_number' => $project->client->vat_number ?? '', + 'currency' => $project->client->currency()->code ?? 'USD', ] : [], 'user' => $this->userInfo($project->user) ]; @@ -1019,6 +1025,7 @@ class TemplateService 'vendor' => $purchase_order->vendor ? [ 'name' => $purchase_order->vendor->present()->name(), 'vat_number' => $purchase_order->vendor->vat_number ?? '', + 'currency' => $purchase_order->vendor->currency()->code ?? 'USD', ] : [], 'amount' => (float)$purchase_order->amount, 'balance' => (float)$purchase_order->balance, @@ -1030,6 +1037,7 @@ class TemplateService 'vat_number' => $purchase_order->client->vat_number ?? '', 'address' => $purchase_order->client->present()->address(), 'shipping_address' => $purchase_order->client->present()->shipping_address(), + 'currency' => $purchase_order->client->currency()->code ?? 'USD', ] : [], 'status_id' => (string)($purchase_order->status_id ?: 1), 'status' => PurchaseOrder::stringStatus($purchase_order->status_id ?? 1), diff --git a/app/Transformers/SubscriptionTransformer.php b/app/Transformers/SubscriptionTransformer.php index f06537d2421f..c2e50eb16e15 100644 --- a/app/Transformers/SubscriptionTransformer.php +++ b/app/Transformers/SubscriptionTransformer.php @@ -72,6 +72,7 @@ class SubscriptionTransformer extends EntityTransformer 'optional_recurring_product_ids' => (string)$subscription->optional_recurring_product_ids, 'optional_product_ids' => (string) $subscription->optional_product_ids, 'registration_required' => (bool) $subscription->registration_required, + 'steps' => $subscription->steps, ]; } } diff --git a/app/Utils/HtmlEngine.php b/app/Utils/HtmlEngine.php index 36abc81f784f..3e4f9b1c79d5 100644 --- a/app/Utils/HtmlEngine.php +++ b/app/Utils/HtmlEngine.php @@ -145,7 +145,7 @@ class HtmlEngine $data['$from'] = ['value' => '', 'label' => ctrans('texts.from')]; $data['$to'] = ['value' => '', 'label' => ctrans('texts.to')]; $data['$shipping'] = ['value' => '', 'label' => ctrans('texts.ship_to')]; - + $data['$ship_to'] = &$data['$shipping']; $data['$total_tax_labels'] = ['value' => $this->totalTaxLabels(), 'label' => ctrans('texts.taxes')]; $data['$total_tax_values'] = ['value' => $this->totalTaxValues(), 'label' => ctrans('texts.taxes')]; $data['$line_tax_labels'] = ['value' => $this->lineTaxLabels(), 'label' => ctrans('texts.taxes')]; @@ -154,7 +154,6 @@ class HtmlEngine $data['$status_logo'] = ['value' => ' ', 'label' => ' ']; $data['$delivery_note'] = ['value' => ' ', 'label' => ctrans('texts.delivery_note')]; $data['$receipt'] = ['value' => ' ', 'label' => ctrans('texts.receipt')]; - $data['$shipping'] = ['value' => ' ', 'label' => ctrans('texts.ship_to')]; $data['$invoice.date'] = &$data['$date']; $data['$invoiceDate'] = &$data['$date']; @@ -661,7 +660,6 @@ class HtmlEngine $data['$thanks'] = ['value' => '', 'label' => ctrans('texts.thanks')]; $data['$from'] = ['value' => '', 'label' => ctrans('texts.from')]; $data['$to'] = ['value' => '', 'label' => ctrans('texts.to')]; - $data['$shipping'] = ['value' => '', 'label' => ctrans('texts.ship_to')]; $data['$details'] = ['value' => '', 'label' => ctrans('texts.details')]; diff --git a/app/Utils/Traits/SubscriptionHooker.php b/app/Utils/Traits/SubscriptionHooker.php index ee286a949423..fdacaca9dc26 100644 --- a/app/Utils/Traits/SubscriptionHooker.php +++ b/app/Utils/Traits/SubscriptionHooker.php @@ -48,7 +48,11 @@ trait SubscriptionHooker RequestOptions::JSON => ['body' => $body], RequestOptions::ALLOW_REDIRECTS => false, ]); - return array_merge($body, json_decode($response->getBody(), true)); + if($response_body = json_decode($response->getBody(), true)) + return array_merge($body, $response_body); + + return array_merge($body, ['message' => 'Success', 'status_code' => 200]); + } catch (ClientException $e) { $message = $e->getMessage(); diff --git a/config/ninja.php b/config/ninja.php index 94933bce3b59..e07134b15e17 100644 --- a/config/ninja.php +++ b/config/ninja.php @@ -17,8 +17,8 @@ return [ 'require_https' => env('REQUIRE_HTTPS', true), 'app_url' => rtrim(env('APP_URL', ''), '/'), 'app_domain' => env('APP_DOMAIN', 'invoicing.co'), - 'app_version' => env('APP_VERSION', '5.8.39'), - 'app_tag' => env('APP_TAG', '5.8.39'), + 'app_version' => env('APP_VERSION', '5.8.45'), + 'app_tag' => env('APP_TAG', '5.8.45'), 'minimum_client_version' => '5.0.16', 'terms_version' => '1.0.1', 'api_secret' => env('API_SECRET', false), @@ -102,7 +102,6 @@ return [ 'wepay' => env('WEPAY_KEYS', ''), 'braintree' => env('BRAINTREE_KEYS', ''), 'mollie' => env('MOLLIE_KEYS', ''), - 'square' => env('SQUARE_KEYS', ''), ], 'contact' => [ 'email' => env('MAIL_FROM_ADDRESS'), diff --git a/database/factories/SubscriptionFactory.php b/database/factories/SubscriptionFactory.php index 81607dd83bd7..fa1682f10b56 100644 --- a/database/factories/SubscriptionFactory.php +++ b/database/factories/SubscriptionFactory.php @@ -27,6 +27,7 @@ class SubscriptionFactory extends Factory return [ 'frequency_id' => RecurringInvoice::FREQUENCY_MONTHLY, 'name' => $this->faker->company(), + 'steps' => "cart,auth.login-or-register", ]; } } diff --git a/database/migrations/2024_02_28_180250_add_steps_to_subscriptions.php b/database/migrations/2024_02_28_180250_add_steps_to_subscriptions.php new file mode 100644 index 000000000000..04faa15f03f4 --- /dev/null +++ b/database/migrations/2024_02_28_180250_add_steps_to_subscriptions.php @@ -0,0 +1,40 @@ +string('steps')->nullable(); + }); + + $steps = collect(Purchase::defaultSteps()) + ->map(fn ($step) => StepService::mapClassNameToString($step)) + ->implode(','); + + \App\Models\Subscription::query() + ->withTrashed() + ->cursor() + ->each(function ($subscription) use ($steps){ + + $subscription->steps = $steps; + $subscription->save(); + + }); + } +}; diff --git a/lang/en/texts.php b/lang/en/texts.php index 3f6fb79b43a5..86d37b3cb92e 100644 --- a/lang/en/texts.php +++ b/lang/en/texts.php @@ -1173,8 +1173,8 @@ $lang = array( 'invoice_number_padding' => 'Padding', 'preview' => 'Preview', 'list_vendors' => 'List Vendors', - 'add_users_not_supported' => 'Upgrade to the Enterprise plan to add additional users to your account.', - 'enterprise_plan_features' => 'The Enterprise plan adds support for multiple users and file attachments, :link to see the full list of features.', + 'add_users_not_supported' => 'Upgrade to the Enterprise Plan to add additional users to your account.', + 'enterprise_plan_features' => 'The Enterprise Plan adds support for multiple users and file attachments, :link to see the full list of features.', 'return_to_app' => 'Return To App', @@ -1323,7 +1323,7 @@ $lang = array( 'security' => 'Security', 'see_whats_new' => 'See what\'s new in v:version', 'wait_for_upload' => 'Please wait for the document upload to complete.', - 'upgrade_for_permissions' => 'Upgrade to our Enterprise plan to enable permissions.', + 'upgrade_for_permissions' => 'Upgrade to our Enterprise Plan to enable permissions.', 'enable_second_tax_rate' => 'Enable specifying a second tax rate', 'payment_file' => 'Payment File', 'expense_file' => 'Expense File', @@ -2699,7 +2699,7 @@ $lang = array( 'no_assets' => 'No images, drag to upload', 'add_image' => 'Add Image', 'select_image' => 'Select Image', - 'upgrade_to_upload_images' => 'Upgrade to the enterprise plan to upload images', + 'upgrade_to_upload_images' => 'Upgrade to the Enterprise Plan to upload images', 'delete_image' => 'Delete Image', 'delete_image_help' => 'Warning: deleting the image will remove it from all proposals.', 'amount_variable_help' => 'Note: the invoice $amount field will use the partial/deposit field if set otherwise it will use the invoice balance.', @@ -3055,7 +3055,7 @@ $lang = array( 'valid_until_days' => 'Valid Until', 'valid_until_days_help' => 'Automatically sets the Valid Until value on quotes to this many days in the future. Leave blank to disable.', 'usually_pays_in_days' => 'Days', - 'requires_an_enterprise_plan' => 'Requires an enterprise plan', + 'requires_an_enterprise_plan' => 'Requires an Enterprise Plan', 'take_picture' => 'Take Picture', 'upload_file' => 'Upload File', 'new_document' => 'New Document', @@ -3157,7 +3157,7 @@ $lang = array( 'archived_group' => 'Successfully archived group', 'deleted_group' => 'Successfully deleted group', 'restored_group' => 'Successfully restored group', - 'upload_logo' => 'Upload Logo', + 'upload_logo' => 'Upload Your Company Logo', 'uploaded_logo' => 'Successfully uploaded logo', 'saved_settings' => 'Successfully saved settings', 'device_settings' => 'Device Settings', @@ -3979,7 +3979,7 @@ $lang = array( 'notification_credit_bounced_subject' => 'Unable to deliver Credit :invoice', 'save_payment_method_details' => 'Save payment method details', 'new_card' => 'New card', - 'new_bank_account' => 'New bank account', + 'new_bank_account' => 'Add Bank Account', 'company_limit_reached' => 'Limit of :limit companies per account.', 'credits_applied_validation' => 'Total credits applied cannot be MORE than total of invoices', 'credit_number_taken' => 'Credit number already taken', @@ -5198,7 +5198,7 @@ $lang = array( 'nordigen_handler_error_heading_account_config_invalid' => 'Missing Credentials', 'nordigen_handler_error_contents_account_config_invalid' => 'Invalid or missing credentials for Gocardless Bank Account Data. Contact support for help, if this issue persists.', 'nordigen_handler_error_heading_not_available' => 'Not Available', - 'nordigen_handler_error_contents_not_available' => 'Feature unavailable, enterprise plan only.', + 'nordigen_handler_error_contents_not_available' => 'Feature unavailable, Enterprise Plan only.', 'nordigen_handler_error_heading_institution_invalid' => 'Invalid Institution', 'nordigen_handler_error_contents_institution_invalid' => 'The provided institution-id is invalid or no longer valid.', 'nordigen_handler_error_heading_ref_invalid' => 'Invalid Reference', @@ -5244,11 +5244,27 @@ $lang = array( 'user_sales' => 'User Sales', 'iframe_url' => 'iFrame URL', 'user_unsubscribed' => 'User unsubscribed from emails :link', + 'out_of_stock' => 'Out of stock', + 'step_dependency_fail' => 'Component ":step" requires at least one of it\'s dependencies (":dependencies") in the list.', + 'step_dependency_order_fail' => 'Component ":step" depends on ":dependency". Make component(s) order is correct.', + 'step_authentication_fail' => 'You must include at least one of authentication methods.', + 'auth.login' => 'Login', + 'auth.login-or-register' => 'Login or Register', + 'auth.register' => 'Register', + 'cart' => 'Cart', + 'methods' => 'Methods', + 'rff' => 'Required fields form', + 'add_step' => 'Add step', + 'steps' => 'Steps', + 'steps_order_help' => 'The order of the steps is important. The first step should not depend on any other step. The second step should depend on the first step, and so on.', + 'other_steps' => 'Other steps', 'use_available_payments' => 'Use Available Payments', 'test_email_sent' => 'Successfully sent email', 'gateway_type' => 'Gateway Type', 'save_template_body' => 'Would you like to save this import mapping as a template for future use?', 'save_as_template' => 'Save Template Mapping', + 'checkout_only_for_existing_customers' => 'Checkout is enabled only for existing customers. Please login with existing account to checkout.', + 'checkout_only_for_new_customers' => 'Checkout is enabled only for new customers. Please register a new account to checkout.', 'auto_bill_standard_invoices_help' => 'Auto bill standard invoices on the due date', 'auto_bill_on_help' => 'Auto bill on send date OR due date (recurring invoices)', 'use_available_credits_help' => 'Apply any credit balances to payments prior to charging a payment method', @@ -5270,9 +5286,11 @@ $lang = array( 'enable_rappen_rounding_help' => 'Rounds totals to nearest 5', 'duration_words' => 'Duration in words', 'upcoming_recurring_invoices' => 'Upcoming Recurring Invoices', + 'shipping_country_id' => 'Shipping Country', 'show_table_footer' => 'Show table footer', 'show_table_footer_help' => 'Displays the totals in the footer of the table', 'total_invoices' => 'Total Invoices', + 'add_to_group' => 'Add to group', ); return $lang; diff --git a/lang/en/ubl.php b/lang/en/ubl.php new file mode 100644 index 000000000000..3178e5b10cda --- /dev/null +++ b/lang/en/ubl.php @@ -0,0 +1,28 @@ + 'Free export item', + 'outside_tax_scope' => 'Outside tax scope', + 'eea_goods_and_services' => 'EEA goods and services', + 'lower_rate' => 'Lower rate', + 'mixed_tax_rate' => 'Mixed tax rate', + 'higher_rate' => 'Higher rate', + 'canary_islands_indirect_tax' => 'Canary Islands indirect tax', + 'ceuta_and_melilla' => 'Ceuta and Melilla', + 'transferred_vat_italy' => 'Transferred VAT Italy', + 'exempt_for_resale' => 'Exempt for resale', + 'vat_not_now_due' => 'VAT not now due', + 'vat_due_previous_invoice' => 'VAT due previous', + 'transferred_vat' => 'Transferred VAT', + 'duty_paid_by_supplier' => 'Duty paid by supplier', + 'vat_margin_scheme_travel_agents' => 'VAT margin scheme travel agents', + 'vat_margin_scheme_second_hand_goods' => 'VAT margin scheme second hand goods', + 'vat_margin_scheme_works_of_art' => 'VAT margin scheme works of art', + 'vat_margin_scheme_collectors_items' => 'VAT margin scheme collectors items', + 'vat_exempt_eea_intra_community' => 'VAT exempt EEA intra community', + 'canary_islands_tax' => 'Canary Islands tax', + 'tax_ceuta_melilla' => 'Tax Ceuta Melilla', + 'services_outside_scope' => 'Services outside scope', +); + +return $lang; \ No newline at end of file diff --git a/public/build/assets/app-c80ec97e.js b/public/build/assets/app-042e859e.js similarity index 82% rename from public/build/assets/app-c80ec97e.js rename to public/build/assets/app-042e859e.js index 0a8f6cc39988..64e1f2bbeb1f 100644 --- a/public/build/assets/app-c80ec97e.js +++ b/public/build/assets/app-042e859e.js @@ -1,15 +1,15 @@ -import{A as pl}from"./index-08e160a7.js";import{c as Ht,g as hl}from"./_commonjsHelpers-725317a4.js";var gl={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}}},ml=gl,ti={},bn={};Object.defineProperty(bn,"__esModule",{value:!0});bn.clone=void 0;function vl(e){return e?JSON.parse(JSON.stringify(e)):null}bn.clone=vl;var ri={};Object.defineProperty(ri,"__esModule",{value:!0});ri.matches=void 0;function yl(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 bl(e,r){return r=String(r),r.substring(0,e.length)===e.substring(0,r.length)}function _l(e,r){return Array.isArray(r)?yl(e,r[0],r[1]):bl(e,r)}ri.matches=_l;Object.defineProperty(ti,"__esModule",{value:!0});ti.addMatchingCardsToResults=void 0;var wl=bn,xl=ri;function Sl(e,r,n){var a,s;for(a=0;a=s&&(y.matchStrength=s),n.push(y);break}}}ti.addMatchingCardsToResults=Sl;var ni={};Object.defineProperty(ni,"__esModule",{value:!0});ni.isValidInputType=void 0;function El(e){return typeof e=="string"||e instanceof String}ni.isValidInputType=El;var ii={};Object.defineProperty(ii,"__esModule",{value:!0});ii.findBestMatch=void 0;function Ol(e){var r=e.filter(function(n){return n.matchStrength}).length;return r>0&&r===e.length}function Cl(e){return Ol(e)?e.reduce(function(r,n){return!r||Number(r.matchStrength)Ml?pn(!1,!1):Nl.test(e)?pn(!1,!0):pn(!0,!0)}ai.cardholderName=kl;var oi={};function Ll(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 jl=Ll;Object.defineProperty(oi,"__esModule",{value:!0});oi.cardNumber=void 0;var Il=jl,Ga=No;function gr(e,r,n){return{card:e,isPotentiallyValid:r,isValid:n}}function Dl(e,r){r===void 0&&(r={});var n,a,s;if(typeof e!="string"&&typeof e!="number")return gr(null,!1,!1);var l=String(e).replace(/-|\s/g,"");if(!/^\d*$/.test(l))return gr(null,!1,!1);var y=Ga(l);if(y.length===0)return gr(null,!1,!1);if(y.length!==1)return gr(null,!0,!1);var m=y[0];if(r.maxLength&&l.length>r.maxLength)return gr(m,!1,!1);m.type===Ga.types.UNIONPAY&&r.luhnValidateUnionPay!==!0?a=!0:a=Il(l),s=Math.max.apply(null,m.lengths),r.maxLength&&(s=Math.min(r.maxLength,s));for(var L=0;L4)return er(!1,!1);var m=parseInt(e,10),L=Number(String(s).substr(2,2)),q=!1;if(a===2){if(String(s).substr(0,2)===e)return er(!1,!0);n=L===m,q=m>=L&&m<=L+r}else a===4&&(n=s===m,q=m>=s&&m<=s+r);return er(q,q,n)}zr.expirationYear=Fl;var ui={};Object.defineProperty(ui,"__esModule",{value:!0});ui.isArray=void 0;ui.isArray=Array.isArray||function(e){return Object.prototype.toString.call(e)==="[object Array]"};Object.defineProperty(li,"__esModule",{value:!0});li.parseDate=void 0;var Bl=zr,Ul=ui;function Hl(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),Bl.expirationYear(n).isPotentiallyValid?1:2):e.length===5?1:e.length>5?2:1}function ql(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)),Ul.isArray(r))return{month:r[0]||"",year:r.slice(1).join()};var n=Hl(e),a=e.substr(0,n);return{month:a,year:e.substr(a.length)}}li.parseDate=ql;var wn={};Object.defineProperty(wn,"__esModule",{value:!0});wn.expirationMonth=void 0;function hn(e,r,n){return{isValid:e,isPotentiallyValid:r,isValidForThisYear:n||!1}}function Vl(e){var r=new Date().getMonth()+1;if(typeof e!="string")return hn(!1,!1);if(e.replace(/\s/g,"")===""||e==="0")return hn(!1,!0);if(!/^\d*$/.test(e))return hn(!1,!1);var n=parseInt(e,10);if(isNaN(Number(e)))return hn(!1,!1);var a=n>0&&n<13;return hn(a,a,a&&n>=r)}wn.expirationMonth=Vl;var Zi=Ht&&Ht.__assign||function(){return Zi=Object.assign||function(e){for(var r,n=1,a=arguments.length;nr?e[n]:r;return r}function Ir(e,r){return{isValid:e,isPotentiallyValid:r}}function Xl(e,r){return r===void 0&&(r=Mo),r=r instanceof Array?r:[r],typeof e!="string"||!/^\d*$/.test(e)?Ir(!1,!1):Gl(r,e.length)?Ir(!0,!0):e.lengthYl(r)?Ir(!1,!1):Ir(!0,!0)}ci.cvv=Xl;var fi={};Object.defineProperty(fi,"__esModule",{value:!0});fi.postalCode=void 0;var Ql=3;function Wi(e,r){return{isValid:e,isPotentiallyValid:r}}function Zl(e,r){r===void 0&&(r={});var n=r.minLength||Ql;return typeof e!="string"?Wi(!1,!1):e.lengthfunction(){return r||(0,e[Lo(e)[0]])((r={exports:{}}).exports,r),r.exports},yu=(e,r,n,a)=>{if(r&&typeof r=="object"||typeof r=="function")for(let s of Lo(r))!vu.call(e,s)&&s!==n&&ko(e,s,{get:()=>r[s],enumerable:!(a=gu(r,s))||a.enumerable});return e},rt=(e,r,n)=>(n=e!=null?hu(mu(e)):{},yu(r||!e||!e.__esModule?ko(n,"default",{value:e,enumerable:!0}):n,e)),wt=Yt({"../alpine/packages/alpinejs/dist/module.cjs.js"(e,r){var n=Object.create,a=Object.defineProperty,s=Object.getOwnPropertyDescriptor,l=Object.getOwnPropertyNames,y=Object.getPrototypeOf,m=Object.prototype.hasOwnProperty,L=(t,i)=>function(){return i||(0,t[l(t)[0]])((i={exports:{}}).exports,i),i.exports},q=(t,i)=>{for(var o in i)a(t,o,{get:i[o],enumerable:!0})},ce=(t,i,o,c)=>{if(i&&typeof i=="object"||typeof i=="function")for(let p of l(i))!m.call(t,p)&&p!==o&&a(t,p,{get:()=>i[p],enumerable:!(c=s(i,p))||c.enumerable});return t},se=(t,i,o)=>(o=t!=null?n(y(t)):{},ce(i||!t||!t.__esModule?a(o,"default",{value:t,enumerable:!0}):o,t)),K=t=>ce(a({},"__esModule",{value:!0}),t),Y=L({"node_modules/@vue/shared/dist/shared.cjs.js"(t){Object.defineProperty(t,"__esModule",{value:!0});function i(b,W){const ee=Object.create(null),le=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"},p="Infinity,undefined,NaN,isFinite,isNaN,parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,BigInt",d=i(p),g=2;function x(b,W=0,ee=b.length){let le=b.split(/(\r?\n)/);const qe=le.filter((yt,ct)=>ct%2===1);le=le.filter((yt,ct)=>ct%2===0);let tt=0;const vt=[];for(let yt=0;yt=W){for(let ct=yt-g;ct<=yt+g||ee>tt;ct++){if(ct<0||ct>=le.length)continue;const fn=ct+1;vt.push(`${fn}${" ".repeat(Math.max(3-String(fn).length,0))}| ${le[ct]}`);const Lr=le[ct].length,Gn=qe[ct]&&qe[ct].length||0;if(ct===yt){const jr=W-(tt-(Lr+Gn)),Vi=Math.max(1,ee>tt?Lr-jr:ee-W);vt.push(" | "+" ".repeat(jr)+"^".repeat(Vi))}else if(ct>yt){if(ee>tt){const jr=Math.max(Math.min(ee-tt,Lr),1);vt.push(" | "+"^".repeat(jr))}tt+=Lr+Gn}}break}return vt.join(` -`)}var k="itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly",Z=i(k),Me=i(k+",async,autofocus,autoplay,controls,default,defer,disabled,hidden,loop,open,required,reversed,scoped,seamless,checked,muted,multiple,selected"),Qe=/[>/="'\u0009\u000a\u000c\u0020]/,$e={};function Ke(b){if($e.hasOwnProperty(b))return $e[b];const W=Qe.test(b);return W&&console.error(`unsafe attribute name: ${b}`),$e[b]=!W}var At={acceptCharset:"accept-charset",className:"class",htmlFor:"for",httpEquiv:"http-equiv"},Ft=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"),Se=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(Nt(b)){const W={};for(let ee=0;ee{if(ee){const le=ee.split(He);le.length>1&&(W[le[0].trim()]=le[1].trim())}}),W}function Rt(b){let W="";if(!b)return W;for(const ee in b){const le=b[ee],qe=ee.startsWith("--")?ee:Kn(ee);(fr(le)||typeof le=="number"&&Ft(qe))&&(W+=`${qe}:${le};`)}return W}function Bt(b){let W="";if(fr(b))W=b;else if(Nt(b))for(let ee=0;ee]/;function Li(b){const W=""+b,ee=ki.exec(W);if(!ee)return W;let le="",qe,tt,vt=0;for(tt=ee.index;tt||--!>|Or(ee,W))}var In=b=>b==null?"":Ut(b)?JSON.stringify(b,Di,2):String(b),Di=(b,W)=>cr(W)?{[`Map(${W.size})`]:[...W.entries()].reduce((ee,[le,qe])=>(ee[`${le} =>`]=qe,ee),{})}:Mt(W)?{[`Set(${W.size})`]:[...W.values()]}:Ut(W)&&!Nt(W)&&!Hn(W)?String(W):W,$i=["bigInt","optionalChaining","nullishCoalescingOperator"],an=Object.freeze({}),on=Object.freeze([]),sn=()=>{},Cr=()=>!1,Ar=/^on[^a-z]/,Tr=b=>Ar.test(b),Pr=b=>b.startsWith("onUpdate:"),Dn=Object.assign,$n=(b,W)=>{const ee=b.indexOf(W);ee>-1&&b.splice(ee,1)},Fn=Object.prototype.hasOwnProperty,Bn=(b,W)=>Fn.call(b,W),Nt=Array.isArray,cr=b=>dr(b)==="[object Map]",Mt=b=>dr(b)==="[object Set]",ln=b=>b instanceof Date,un=b=>typeof b=="function",fr=b=>typeof b=="string",Fi=b=>typeof b=="symbol",Ut=b=>b!==null&&typeof b=="object",Rr=b=>Ut(b)&&un(b.then)&&un(b.catch),Un=Object.prototype.toString,dr=b=>Un.call(b),Bi=b=>dr(b).slice(8,-1),Hn=b=>dr(b)==="[object Object]",qn=b=>fr(b)&&b!=="NaN"&&b[0]!=="-"&&""+parseInt(b,10)===b,Vn=i(",key,ref,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),pr=b=>{const W=Object.create(null);return ee=>W[ee]||(W[ee]=b(ee))},zn=/-(\w)/g,Wn=pr(b=>b.replace(zn,(W,ee)=>ee?ee.toUpperCase():"")),Ui=/\B([A-Z])/g,Kn=pr(b=>b.replace(Ui,"-$1").toLowerCase()),hr=pr(b=>b.charAt(0).toUpperCase()+b.slice(1)),Hi=pr(b=>b?`on${hr(b)}`:""),cn=(b,W)=>b!==W&&(b===b||W===W),qi=(b,W)=>{for(let ee=0;ee{Object.defineProperty(b,W,{configurable:!0,enumerable:!1,value:ee})},Mr=b=>{const W=parseFloat(b);return isNaN(W)?b:W},kr,Jn=()=>kr||(kr=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});t.EMPTY_ARR=on,t.EMPTY_OBJ=an,t.NO=Cr,t.NOOP=sn,t.PatchFlagNames=o,t.babelParserDefaultPlugins=$i,t.camelize=Wn,t.capitalize=hr,t.def=Nr,t.escapeHtml=Li,t.escapeHtmlComment=ji,t.extend=Dn,t.generateCodeFrame=x,t.getGlobalThis=Jn,t.hasChanged=cn,t.hasOwn=Bn,t.hyphenate=Kn,t.invokeArrayFns=qi,t.isArray=Nt,t.isBooleanAttr=Me,t.isDate=ln,t.isFunction=un,t.isGloballyWhitelisted=d,t.isHTMLTag=Sr,t.isIntegerKey=qn,t.isKnownAttr=Se,t.isMap=cr,t.isModelListener=Pr,t.isNoUnitNumericStyleProp=Ft,t.isObject=Ut,t.isOn=Tr,t.isPlainObject=Hn,t.isPromise=Rr,t.isReservedProp=Vn,t.isSSRSafeAttrName=Ke,t.isSVGTag=Mi,t.isSet=Mt,t.isSpecialBooleanAttr=Z,t.isString=fr,t.isSymbol=Fi,t.isVoidTag=Er,t.looseEqual=Or,t.looseIndexOf=jn,t.makeMap=i,t.normalizeClass=Bt,t.normalizeStyle=Ue,t.objectToString=Un,t.parseStringStyle=mt,t.propsToAttrMap=At,t.remove=$n,t.slotFlagsText=c,t.stringifyStyle=Rt,t.toDisplayString=In,t.toHandlerKey=Hi,t.toNumber=Mr,t.toRawType=Bi,t.toTypeString=dr}}),E=L({"node_modules/@vue/shared/index.js"(t,i){i.exports=Y()}}),v=L({"node_modules/@vue/reactivity/dist/reactivity.cjs.js"(t){Object.defineProperty(t,"__esModule",{value:!0});var i=E(),o=new WeakMap,c=[],p,d=Symbol("iterate"),g=Symbol("Map key iterate");function x(u){return u&&u._isEffect===!0}function k(u,T=i.EMPTY_OBJ){x(u)&&(u=u.raw);const N=Qe(u,T);return T.lazy||N(),N}function Z(u){u.active&&($e(u),u.options.onStop&&u.options.onStop(),u.active=!1)}var Me=0;function Qe(u,T){const N=function(){if(!N.active)return u();if(!c.includes(N)){$e(N);try{return Se(),c.push(N),p=N,u()}finally{c.pop(),Ue(),p=c[c.length-1]}}};return N.id=Me++,N.allowRecurse=!!T.allowRecurse,N._isEffect=!0,N.active=!0,N.raw=u,N.deps=[],N.options=T,N}function $e(u){const{deps:T}=u;if(T.length){for(let N=0;N{ht&&ht.forEach(kt=>{(kt!==p||kt.allowRecurse)&&it.add(kt)})};if(T==="clear")je.forEach(bt);else if(N==="length"&&i.isArray(u))je.forEach((ht,kt)=>{(kt==="length"||kt>=ie)&&bt(ht)});else switch(N!==void 0&&bt(je.get(N)),T){case"add":i.isArray(u)?i.isIntegerKey(N)&&bt(je.get("length")):(bt(je.get(d)),i.isMap(u)&&bt(je.get(g)));break;case"delete":i.isArray(u)||(bt(je.get(d)),i.isMap(u)&&bt(je.get(g)));break;case"set":i.isMap(u)&&bt(je.get(d));break}const dn=ht=>{ht.options.onTrigger&&ht.options.onTrigger({effect:ht,target:u,key:N,type:T,newValue:ie,oldValue:J,oldTarget:me}),ht.options.scheduler?ht.options.scheduler(ht):ht()};it.forEach(dn)}var mt=i.makeMap("__proto__,__v_isRef,__isVue"),Rt=new Set(Object.getOwnPropertyNames(Symbol).map(u=>Symbol[u]).filter(i.isSymbol)),Bt=Er(),xr=Er(!1,!0),rn=Er(!0),nn=Er(!0,!0),Sr=Mi();function Mi(){const u={};return["includes","indexOf","lastIndexOf"].forEach(T=>{u[T]=function(...N){const ie=b(this);for(let me=0,je=this.length;me{u[T]=function(...N){Ft();const ie=b(this)[T].apply(this,N);return Ue(),ie}}),u}function Er(u=!1,T=!1){return function(ie,J,me){if(J==="__v_isReactive")return!u;if(J==="__v_isReadonly")return u;if(J==="__v_raw"&&me===(u?T?Wn:zn:T?pr:Vn).get(ie))return ie;const je=i.isArray(ie);if(!u&&je&&i.hasOwn(Sr,J))return Reflect.get(Sr,J,me);const it=Reflect.get(ie,J,me);return(i.isSymbol(J)?Rt.has(J):mt(J))||(u||Le(ie,"get",J),T)?it:le(it)?!je||!i.isIntegerKey(J)?it.value:it:i.isObject(it)?u?cn(it):hr(it):it}}var ki=Ln(),Li=Ln(!0);function Ln(u=!1){return function(N,ie,J,me){let je=N[ie];if(!u&&(J=b(J),je=b(je),!i.isArray(N)&&le(je)&&!le(J)))return je.value=J,!0;const it=i.isArray(N)&&i.isIntegerKey(ie)?Number(ie)i.isObject(u)?hr(u):u,on=u=>i.isObject(u)?cn(u):u,sn=u=>u,Cr=u=>Reflect.getPrototypeOf(u);function Ar(u,T,N=!1,ie=!1){u=u.__v_raw;const J=b(u),me=b(T);T!==me&&!N&&Le(J,"get",T),!N&&Le(J,"get",me);const{has:je}=Cr(J),it=ie?sn:N?on:an;if(je.call(J,T))return it(u.get(T));if(je.call(J,me))return it(u.get(me));u!==J&&u.get(T)}function Tr(u,T=!1){const N=this.__v_raw,ie=b(N),J=b(u);return u!==J&&!T&&Le(ie,"has",u),!T&&Le(ie,"has",J),u===J?N.has(u):N.has(u)||N.has(J)}function Pr(u,T=!1){return u=u.__v_raw,!T&&Le(b(u),"iterate",d),Reflect.get(u,"size",u)}function Dn(u){u=b(u);const T=b(this);return Cr(T).has.call(T,u)||(T.add(u),He(T,"add",u,u)),this}function $n(u,T){T=b(T);const N=b(this),{has:ie,get:J}=Cr(N);let me=ie.call(N,u);me?qn(N,ie,u):(u=b(u),me=ie.call(N,u));const je=J.call(N,u);return N.set(u,T),me?i.hasChanged(T,je)&&He(N,"set",u,T,je):He(N,"add",u,T),this}function Fn(u){const T=b(this),{has:N,get:ie}=Cr(T);let J=N.call(T,u);J?qn(T,N,u):(u=b(u),J=N.call(T,u));const me=ie?ie.call(T,u):void 0,je=T.delete(u);return J&&He(T,"delete",u,void 0,me),je}function Bn(){const u=b(this),T=u.size!==0,N=i.isMap(u)?new Map(u):new Set(u),ie=u.clear();return T&&He(u,"clear",void 0,void 0,N),ie}function Nt(u,T){return function(ie,J){const me=this,je=me.__v_raw,it=b(je),bt=T?sn:u?on:an;return!u&&Le(it,"iterate",d),je.forEach((dn,ht)=>ie.call(J,bt(dn),bt(ht),me))}}function cr(u,T,N){return function(...ie){const J=this.__v_raw,me=b(J),je=i.isMap(me),it=u==="entries"||u===Symbol.iterator&&je,bt=u==="keys"&&je,dn=J[u](...ie),ht=N?sn:T?on:an;return!T&&Le(me,"iterate",bt?g:d),{next(){const{value:kt,done:zi}=dn.next();return zi?{value:kt,done:zi}:{value:it?[ht(kt[0]),ht(kt[1])]:ht(kt),done:zi}},[Symbol.iterator](){return this}}}}function Mt(u){return function(...T){{const N=T[0]?`on key "${T[0]}" `:"";console.warn(`${i.capitalize(u)} operation ${N}failed: target is readonly.`,b(this))}return u==="delete"?!1:this}}function ln(){const u={get(me){return Ar(this,me)},get size(){return Pr(this)},has:Tr,add:Dn,set:$n,delete:Fn,clear:Bn,forEach:Nt(!1,!1)},T={get(me){return Ar(this,me,!1,!0)},get size(){return Pr(this)},has:Tr,add:Dn,set:$n,delete:Fn,clear:Bn,forEach:Nt(!1,!0)},N={get(me){return Ar(this,me,!0)},get size(){return Pr(this,!0)},has(me){return Tr.call(this,me,!0)},add:Mt("add"),set:Mt("set"),delete:Mt("delete"),clear:Mt("clear"),forEach:Nt(!0,!1)},ie={get(me){return Ar(this,me,!0,!0)},get size(){return Pr(this,!0)},has(me){return Tr.call(this,me,!0)},add:Mt("add"),set:Mt("set"),delete:Mt("delete"),clear:Mt("clear"),forEach:Nt(!0,!0)};return["keys","values","entries",Symbol.iterator].forEach(me=>{u[me]=cr(me,!1,!1),N[me]=cr(me,!0,!1),T[me]=cr(me,!1,!0),ie[me]=cr(me,!0,!0)}),[u,N,T,ie]}var[un,fr,Fi,Ut]=ln();function Rr(u,T){const N=T?u?Ut:Fi:u?fr:un;return(ie,J,me)=>J==="__v_isReactive"?!u:J==="__v_isReadonly"?u:J==="__v_raw"?ie:Reflect.get(i.hasOwn(N,J)&&J in ie?N:ie,J,me)}var Un={get:Rr(!1,!1)},dr={get:Rr(!1,!0)},Bi={get:Rr(!0,!1)},Hn={get:Rr(!0,!0)};function qn(u,T,N){const ie=b(N);if(ie!==N&&T.call(u,ie)){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 Vn=new WeakMap,pr=new WeakMap,zn=new WeakMap,Wn=new WeakMap;function Ui(u){switch(u){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function Kn(u){return u.__v_skip||!Object.isExtensible(u)?0:Ui(i.toRawType(u))}function hr(u){return u&&u.__v_isReadonly?u:Nr(u,!1,jn,Un,Vn)}function Hi(u){return Nr(u,!1,Di,dr,pr)}function cn(u){return Nr(u,!0,In,Bi,zn)}function qi(u){return Nr(u,!0,$i,Hn,Wn)}function Nr(u,T,N,ie,J){if(!i.isObject(u))return console.warn(`value cannot be made reactive: ${String(u)}`),u;if(u.__v_raw&&!(T&&u.__v_isReactive))return u;const me=J.get(u);if(me)return me;const je=Kn(u);if(je===0)return u;const it=new Proxy(u,je===2?ie:N);return J.set(u,it),it}function Mr(u){return kr(u)?Mr(u.__v_raw):!!(u&&u.__v_isReactive)}function kr(u){return!!(u&&u.__v_isReadonly)}function Jn(u){return Mr(u)||kr(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)?hr(u):u;function le(u){return!!(u&&u.__v_isRef===!0)}function qe(u){return yt(u)}function tt(u){return yt(u,!0)}var vt=class{constructor(u,T=!1){this._shallow=T,this.__v_isRef=!0,this._rawValue=T?u:b(u),this._value=T?u:ee(u)}get value(){return Le(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 yt(u,T=!1){return le(u)?u:new vt(u,T)}function ct(u){He(b(u),"set","value",u.value)}function fn(u){return le(u)?u.value:u}var Lr={get:(u,T,N)=>fn(Reflect.get(u,T,N)),set:(u,T,N,ie)=>{const J=u[T];return le(J)&&!le(N)?(J.value=N,!0):Reflect.set(u,T,N,ie)}};function Gn(u){return Mr(u)?u:new Proxy(u,Lr)}var jr=class{constructor(u){this.__v_isRef=!0;const{get:T,set:N}=u(()=>Le(this,"get","value"),()=>He(this,"set","value"));this._get=T,this._set=N}get value(){return this._get()}set value(u){this._set(u)}};function Vi(u){return new jr(u)}function ul(u){Jn(u)||console.warn("toRefs() expects a reactive object but received a plain one.");const T=i.isArray(u)?new Array(u.length):{};for(const N in u)T[N]=Ja(u,N);return T}var cl=class{constructor(u,T){this._object=u,this._key=T,this.__v_isRef=!0}get value(){return this._object[this._key]}set value(u){this._object[this._key]=u}};function Ja(u,T){return le(u[T])?u[T]:new cl(u,T)}var fl=class{constructor(u,T,N){this._setter=T,this._dirty=!0,this.__v_isRef=!0,this.effect=k(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),Le(u,"get","value"),u._value}set value(u){this._setter(u)}};function dl(u){let T,N;return i.isFunction(u)?(T=u,N=()=>{console.warn("Write operation failed: computed value is readonly")}):(T=u.get,N=u.set),new fl(T,N,i.isFunction(u)||!u.set)}t.ITERATE_KEY=d,t.computed=dl,t.customRef=Vi,t.effect=k,t.enableTracking=Se,t.isProxy=Jn,t.isReactive=Mr,t.isReadonly=kr,t.isRef=le,t.markRaw=W,t.pauseTracking=Ft,t.proxyRefs=Gn,t.reactive=hr,t.readonly=cn,t.ref=qe,t.resetTracking=Ue,t.shallowReactive=Hi,t.shallowReadonly=qi,t.shallowRef=tt,t.stop=Z,t.toRaw=b,t.toRef=Ja,t.toRefs=ul,t.track=Le,t.trigger=He,t.triggerRef=ct,t.unref=fn}}),_=L({"node_modules/@vue/reactivity/index.js"(t,i){i.exports=v()}}),O={};q(O,{Alpine:()=>Ka,default:()=>ll}),r.exports=K(O);var R=!1,I=!1,U=[],Re=-1;function D(t){C(t)}function C(t){U.includes(t)||U.push(t),te()}function M(t){let i=U.indexOf(t);i!==-1&&i>Re&&U.splice(i,1)}function te(){!I&&!R&&(R=!0,queueMicrotask(be))}function be(){R=!1,I=!0;for(let t=0;tt.effect(i,{scheduler:o=>{Ge?D(o):o()}}),Je=t.raw}function dt(t){Q=t}function xt(t){let i=()=>{};return[c=>{let p=Q(c);return t._x_effects||(t._x_effects=new Set,t._x_runEffects=()=>{t._x_effects.forEach(d=>d())}),t._x_effects.add(p),i=()=>{p!==void 0&&(t._x_effects.delete(p),Pe(p))},p},()=>{i()}]}function Et(t,i){let o=!0,c,p=Q(()=>{let d=t();JSON.stringify(d),o?c=d:queueMicrotask(()=>{i(d,c),c=d}),o=!1});return()=>Pe(p)}function we(t,i,o={}){t.dispatchEvent(new CustomEvent(i,{detail:o,bubbles:!0,composed:!0,cancelable:!0}))}function ue(t,i){if(typeof ShadowRoot=="function"&&t instanceof ShadowRoot){Array.from(t.children).forEach(p=>ue(p,i));return}let o=!1;if(i(t,()=>o=!0),o)return;let c=t.firstElementChild;for(;c;)ue(c,i),c=c.nextElementSibling}function fe(t,...i){console.warn(`Alpine Warning: ${t}`,...i)}var Ee=!1;function ve(){Ee&&fe("Alpine has already been initialized on this page. Calling Alpine.start() more than once can cause problems."),Ee=!0,document.body||fe("Unable to initialize. Trying to load Alpine before `` is available. Did you forget to add `defer` in Alpine's ` +@endpush diff --git a/resources/views/billing-portal/v3/payments/methods.blade.php b/resources/views/billing-portal/v3/payments/methods.blade.php new file mode 100644 index 000000000000..b2eab9f9f9ab --- /dev/null +++ b/resources/views/billing-portal/v3/payments/methods.blade.php @@ -0,0 +1,11 @@ +
+

{{ ctrans('texts.payment_methods') }}

+ +
+ @foreach($methods as $method) + + @endforeach +
+
diff --git a/resources/views/billing-portal/v3/purchase.blade.php b/resources/views/billing-portal/v3/purchase.blade.php new file mode 100644 index 000000000000..d1c41e441e0e --- /dev/null +++ b/resources/views/billing-portal/v3/purchase.blade.php @@ -0,0 +1,52 @@ +
+
+
+ {{ $subscription->company->present()->name }} + + + +
+ @livewire($this->component, ['context' => $context, 'subscription' => $this->subscription], key($this->componentUniqueId())) +
+
+
+ +
+
+
+
+ @livewire('billing-portal.summary', ['subscription' => $subscription, 'context' => $context], key($this->summaryUniqueId())) +
+
+
+
+ +
+ @csrf + + + + + + + + + + +
+
diff --git a/resources/views/billing-portal/v3/rff-basic.blade.php b/resources/views/billing-portal/v3/rff-basic.blade.php new file mode 100644 index 000000000000..9b1448b6d215 --- /dev/null +++ b/resources/views/billing-portal/v3/rff-basic.blade.php @@ -0,0 +1,46 @@ +
+
+
+ @csrf + + + + + + + + +
+
+
diff --git a/resources/views/billing-portal/v3/rff.blade.php b/resources/views/billing-portal/v3/rff.blade.php new file mode 100644 index 000000000000..0017d27967ac --- /dev/null +++ b/resources/views/billing-portal/v3/rff.blade.php @@ -0,0 +1,15 @@ +
+ @if($errors->any()) +
+
    + @foreach($errors->all() as $error) +
  • {{ $error }}
  • + @endforeach +
+
+ @endif + +
+ @livewire('required-client-info', ['db' => $company->db, 'fields' => method_exists($gateway, 'getClientRequiredFields') ? $gateway->getClientRequiredFields() : [], 'contact_id' => auth()->guard('contact')->user()->id, 'countries' => $countries, 'company_id' => $company->id, 'company_gateway_id' => $gateway->company_gateway ? $gateway->company_gateway->id : $gateway->id, 'form_only' => true]) +
+
diff --git a/resources/views/billing-portal/v3/summary.blade.php b/resources/views/billing-portal/v3/summary.blade.php new file mode 100644 index 000000000000..413571bc47a9 --- /dev/null +++ b/resources/views/billing-portal/v3/summary.blade.php @@ -0,0 +1,35 @@ +
+

{{ ctrans('texts.order') }}

+ + @isset($this->context['bundle']) +
+ @foreach($this->items() as $item) + @if($item['quantity'] > 0) +
+ {{ $item['quantity'] }}x {{ $item['product_key'] }} + {{ $item['total'] }} +
+ @endif + @endforeach +
+ +
+
+ {{ ctrans('texts.one_time_purchases') }} + {{ $this->oneTimePurchasesTotal() }} +
+ +
+ {{ ctrans('texts.recurring_purchases') }} + {{ $this->recurringPurchasesTotal() }} +
+ +
+ {{ ctrans('texts.total') }} + {{ $this->total() }} +
+
+ @endif +
diff --git a/resources/views/pdf-designs/plain.html b/resources/views/pdf-designs/plain.html index a2db2c000911..61def4c09c07 100644 --- a/resources/views/pdf-designs/plain.html +++ b/resources/views/pdf-designs/plain.html @@ -101,7 +101,7 @@ flex-direction: column; line-height: var(--line-height); white-space: nowrap; - border: 1px solid #000; + border: 0px solid #000; } [data-ref="table"] { diff --git a/resources/views/pdf-designs/vertical_statement.html b/resources/views/pdf-designs/vertical_statement.html index 44a82eaf0bf4..4b59658566fa 100644 --- a/resources/views/pdf-designs/vertical_statement.html +++ b/resources/views/pdf-designs/vertical_statement.html @@ -1,3 +1,5 @@ + + @@ -10,7 +12,7 @@ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; font-family: $font_name, Helvetica, sans-serif; - font-size: $font_sizepx; + font-size: $font_size; zoom: 80%; } @@ -22,7 +24,7 @@ table tr td, table tr, th { - font-size: $font_sizepx !important; + font-size: $font_size !important; } table { @@ -63,6 +65,11 @@ break-inside: avoid; } + /* tr.border-bottom td{ + height: 2rem; + border-bottom: 0px dashed $primary_color; +} */ + .container { display: flex; height: 100%; @@ -166,9 +173,17 @@ font-size: 1.3rem; } - #date-range { - padding: 0; + #date-label { + font-size: 1.3rem !important; + font-style: italic; + padding: 0 !important; margin-top: 2rem; + margin-bottom: 5px; + } + + #date-range { + padding: 0 !important; + margin: 0 !important; border: 0px solid #000; font-size: 1.3rem; font-weight: bold; @@ -196,11 +211,12 @@
+

$statement_label $date_label

$start_date - $end_date

-
+
{% if invoices|e %} diff --git a/resources/views/portal/ninja2020/components/livewire/required-client-info.blade.php b/resources/views/portal/ninja2020/components/livewire/required-client-info.blade.php index bda902de7424..fd5b6b8bbf25 100644 --- a/resources/views/portal/ninja2020/components/livewire/required-client-info.blade.php +++ b/resources/views/portal/ninja2020/components/livewire/required-client-info.blade.php @@ -1,14 +1,16 @@ -
-
-
-

- {{ ctrans('texts.required_payment_information') }} -

+
+
+ @unless($form_only) +
+

+ {{ ctrans('texts.required_payment_information') }} +

-

- {{ ctrans('texts.required_payment_information_more') }} -

-
+

+ {{ ctrans('texts.required_payment_information_more') }} +

+
+ @endunless
@foreach($fields as $field) diff --git a/resources/views/templates/delivery_notes/td13.html b/resources/views/templates/delivery_notes/td13.html new file mode 100644 index 000000000000..f095de7a2073 --- /dev/null +++ b/resources/views/templates/delivery_notes/td13.html @@ -0,0 +1,205 @@ + + + + + + + + + + + + + +
+ + + + +
Delivery Note{{ img('$company.logo') }}
+
+ + + + + + + +
+
+
+

Bill To:

+
+
+

$client.name

+
+
+

$client.shipping_address

+
+
+
+
+
+

Ship To:

+
+
+

$client.name

+
+
+

$client.shipping_address

+
+
+
+ + + + + + +
+
+

Order # $invoice.po_number

+
+
+
+

Order Date: $invoice.date

+
+
+ + + {% set invoice = invoices|first %} + + + + + + + + + + {% for item in invoice.line_items|filter(item => item.type_id == 1) %} + + + + + + {% endfor %} + +
Item #DescriptionDelivered
{{ item.product_key }}{{ item.notes }}{{ item.quantity }}
+
+ + +
+

Notes:

+ + $invoice.public_notes +
+
+ + + + \ No newline at end of file diff --git a/resources/views/templates/statements/ts1.html b/resources/views/templates/statements/ts1.html index 86e0992ac07c..b5bbb8256ed9 100644 --- a/resources/views/templates/statements/ts1.html +++ b/resources/views/templates/statements/ts1.html @@ -1,5 +1,5 @@ - + @@ -13,7 +13,7 @@ } @page { - margin: 0 !important; //removes top and bottom default headers + margin: 0 !important; size: $page_size $page_layout; } diff --git a/resources/views/templates/statements/ts2.html b/resources/views/templates/statements/ts2.html index 1ccbd455678e..cbfd6ca5db82 100644 --- a/resources/views/templates/statements/ts2.html +++ b/resources/views/templates/statements/ts2.html @@ -1,5 +1,5 @@ - + diff --git a/resources/views/templates/statements/ts3.html b/resources/views/templates/statements/ts3.html index 943e32418faf..fd9f04962731 100644 --- a/resources/views/templates/statements/ts3.html +++ b/resources/views/templates/statements/ts3.html @@ -1,5 +1,5 @@ - + diff --git a/resources/views/templates/statements/ts4.html b/resources/views/templates/statements/ts4.html new file mode 100644 index 000000000000..d90f68d19c04 --- /dev/null +++ b/resources/views/templates/statements/ts4.html @@ -0,0 +1,216 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ +
+ +
+
+
+
+
+ +
+

$statement_label

+

$start_date - $end_date

+
+ +
+
+ + + + + + + + + + + + + + + + {% for invoice in invoices %} + + + + + + + + + + {% for payment in invoice.payments|filter(payment => payment.is_deleted == false) %} + + {% for pivot in payment.paymentables %} + + + + + + + + + + + {% endfor %} + {% endfor %} + {% endfor%} + +
Doc #DateDue DateTotalTransactionOutstanding
Invoice - {{ invoice.number }} + {{ invoice.date }}{{ invoice.due_date }}{{ + invoice.amount_raw|format_currency(invoice.client.currency) }}{{ + invoice.balance_raw|format_currency(invoice.client.currency) }}
Payment - {{ payment.number }} + {{ payment.date }} + {% if pivot.amount > 0 %} + {{ pivot.amount_raw|format_currency(payment.currency) }} - {{ payment.type.name + }} + {% else %} + ({{ pivot.refunded_raw|format_currency(payment.currency) }}) + {% endif %} + {{ payment.transaction_reference + }}
+ +
+ + + {% if aging and show_aging %} +
+ + + + {% for key, age in aging %} + + {% endfor %} + + + + + {% for key, age in aging %} + + {% endfor %} + + +
{{ key }}
{{ age }}
+
+ {% endif %} +
+ + + + +
+ +
+
+ + + \ No newline at end of file diff --git a/routes/api.php b/routes/api.php index 008fd764546c..ee4a8ab000dd 100644 --- a/routes/api.php +++ b/routes/api.php @@ -10,6 +10,7 @@ | is assigned the "api" middleware group. Enjoy building your API! | */ +use App\Http\Controllers\SubscriptionStepsController; use Illuminate\Support\Facades\Route; use App\Http\Controllers\BaseController; use App\Http\Controllers\BrevoController; @@ -409,7 +410,11 @@ Route::group(['middleware' => ['throttle:api', 'api_db', 'token_auth', 'locale'] Route::post('stripe/verify', [StripeController::class, 'verify'])->middleware('password_protected')->name('stripe.verify'); Route::post('stripe/disconnect/{company_gateway_id}', [StripeController::class, 'disconnect'])->middleware('password_protected')->name('stripe.disconnect'); + Route::get('subscriptions/steps', [SubscriptionStepsController::class, 'index']); + Route::post('subscriptions/steps/check', [SubscriptionStepsController::class, 'check']); + Route::resource('subscriptions', SubscriptionController::class); + Route::post('subscriptions/bulk', [SubscriptionController::class, 'bulk'])->name('subscriptions.bulk'); Route::get('statics', StaticController::class); // Route::post('apple_pay/upload_file','ApplyPayController::class, 'upload'); diff --git a/routes/client.php b/routes/client.php index feeefd1e9fb0..c2d3aff12e08 100644 --- a/routes/client.php +++ b/routes/client.php @@ -120,6 +120,7 @@ Route::get('payments/process/response', [App\Http\Controllers\ClientPortal\Payme Route::get('client/subscriptions/{subscription}/purchase', [App\Http\Controllers\ClientPortal\SubscriptionPurchaseController::class, 'index'])->name('client.subscription.purchase')->middleware('domain_db'); Route::get('client/subscriptions/{subscription}/purchase/v2', [App\Http\Controllers\ClientPortal\SubscriptionPurchaseController::class, 'upgrade'])->name('client.subscription.upgrade')->middleware('domain_db'); +Route::get('client/subscriptions/{subscription}/purchase/v3', [App\Http\Controllers\ClientPortal\SubscriptionPurchaseController::class, 'v3'])->name('client.subscription.v3')->middleware('domain_db'); Route::group(['middleware' => ['invite_db'], 'prefix' => 'client', 'as' => 'client.'], function () { /*Invitation catches*/ diff --git a/tailwind.config.cjs b/tailwind.config.cjs index 7144e9e4413f..00b25740a4c8 100644 --- a/tailwind.config.cjs +++ b/tailwind.config.cjs @@ -7,7 +7,8 @@ module.exports = { './resources/views/email/components/**/*.blade.php', './resources/views/themes/ninja2020/**/*.blade.php', './resources/views/auth/**/*.blade.php', - './resources/views/setup/**/*.blade.php' + './resources/views/setup/**/*.blade.php', + './resources/views/billing-portal/**/*.blade.php', ], theme: { extend: { diff --git a/tests/Feature/ClientTest.php b/tests/Feature/ClientTest.php index e2850a2615df..44514d00f220 100644 --- a/tests/Feature/ClientTest.php +++ b/tests/Feature/ClientTest.php @@ -21,12 +21,15 @@ use App\Models\Currency; use Tests\MockAccountData; use Illuminate\Support\Str; use App\Models\CompanyToken; +use App\Models\GroupSetting; use App\Models\ClientContact; use App\Utils\Traits\MakesHash; +use Tests\Unit\GroupSettingsTest; use App\DataMapper\ClientSettings; use App\DataMapper\CompanySettings; use App\DataMapper\DefaultSettings; use App\Factory\InvoiceItemFactory; +use App\Factory\GroupSettingFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\Session; use Illuminate\Validation\ValidationException; @@ -69,6 +72,45 @@ class ClientTest extends TestCase $this->makeTestData(); } + public function testBulkGroupAssignment() + { + Client::factory()->count(5)->create(['user_id' => $this->user->id, 'company_id' => $this->company->id])->each(function ($c) { + ClientContact::factory()->create([ + 'user_id' => $this->user->id, + 'client_id' => $c->id, + 'company_id' => $this->company->id, + 'is_primary' => 1, + ]); + }); + + $gs = GroupSettingFactory::create($this->company->id, $this->user->id); + $gs->name = 'testtest'; + $gs->save(); + + $ids = Client::where('company_id', $this->company->id)->get()->pluck('hashed_id')->toArray(); + $data = [ + 'action' => 'assign_group', + 'ids' => $ids, + 'group_settings_id' => $gs->hashed_id, + ]; + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->post('/api/v1/clients/bulk', $data); + + $arr = $response->json(); + + Client::query()->whereIn('id', $this->transformKeys($ids))->cursor()->each(function ($c) use ($gs, $arr) { + $this->assertEquals($gs->id, $c->group_settings_id); + }); + + foreach($arr['data'] as $client_response){ + + $this->assertEquals($gs->hashed_id, $client_response['group_settings_id']); + } + } + public function testClientExchangeRateCalculation() { $settings = ClientSettings::defaults(); diff --git a/tests/Feature/SubscriptionApiTest.php b/tests/Feature/SubscriptionApiTest.php index a0fb674d794a..9910f92c69c6 100644 --- a/tests/Feature/SubscriptionApiTest.php +++ b/tests/Feature/SubscriptionApiTest.php @@ -12,13 +12,19 @@ namespace Tests\Feature; use Tests\TestCase; +use App\Models\User; +use App\Models\Client; +use App\Models\Company; use App\Models\Invoice; use App\Models\Product; -use App\Models\RecurringInvoice; use Tests\MockAccountData; use Illuminate\Support\Str; +use App\Models\CompanyToken; use App\Models\Subscription; use App\Utils\Traits\MakesHash; +use App\Models\RecurringInvoice; +use App\DataMapper\CompanySettings; +use App\Factory\CompanyUserFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\Session; use Illuminate\Validation\ValidationException; @@ -51,6 +57,250 @@ class SubscriptionApiTest extends TestCase Model::reguard(); } + public function testSubscriptionCronLocalization() + { + + $settings = CompanySettings::defaults(); + $settings->timezone_id = '50'; //europe/vienna + + $c2 = Company::factory()->create([ + 'account_id' => $this->company->account_id, + 'settings' => $settings + ]); + + $cu = CompanyUserFactory::create($this->user->id, $c2->id, $this->account->id); + $cu->is_owner = true; + $cu->is_admin = true; + $cu->is_locked = true; + $cu->permissions = '["view_client"]'; + $cu->save(); + + $different_company_token = \Illuminate\Support\Str::random(64); + + $company_token = new CompanyToken(); + $company_token->user_id = $this->user->id; + $company_token->company_id = $c2->id; + $company_token->account_id = $c2->account_id; + $company_token->name = 'test token'; + $company_token->token = $different_company_token; + $company_token->is_system = true; + $company_token->save(); + + + $s = Subscription::factory()->create([ + 'company_id' => $c2->id, + 'user_id' => $this->user->id, + ]); + + $client2 = Client::factory()->create([ + 'company_id' => $c2->id, + 'user_id' => $this->user->id, + ]); + + $i = Invoice::factory()->create([ + 'company_id' => $c2->id, + 'user_id' => $this->user->id, + 'subscription_id' => $s->id, + 'due_date' => now()->startOfDay(), + 'client_id' => $client2->id, + 'status_id' => Invoice::STATUS_SENT + ]); + + $settings = CompanySettings::defaults(); + $settings->timezone_id = '110'; //sydney/australia + + $c = Company::factory()->create([ + 'account_id' => $this->company->account_id, + 'settings' => $settings, + ]); + + $cu = CompanyUserFactory::create($this->user->id, $c->id, $this->account->id); + $cu->is_owner = true; + $cu->is_admin = true; + $cu->is_locked = true; + $cu->permissions = '["view_client"]'; + $cu->save(); + + $different_company_token = \Illuminate\Support\Str::random(64); + + $company_token = new CompanyToken(); + $company_token->user_id = $this->user->id; + $company_token->company_id = $c->id; + $company_token->account_id = $c->account_id; + $company_token->name = 'test token'; + $company_token->token = $different_company_token; + $company_token->is_system = true; + $company_token->save(); + + $s1 = Subscription::factory()->create([ + 'company_id' => $c->id, + 'user_id' => $this->user->id, + ]); + + + $client = Client::factory()->create([ + 'company_id' => $c2->id, + 'user_id' => $this->user->id, + ]); + + $i = Invoice::factory()->create([ + 'company_id' => $c->id, + 'user_id' => $this->user->id, + 'subscription_id' => $s1->id, + 'due_date' => now()->startOfDay(), + 'client_id' => $client->id, + 'status_id' => Invoice::STATUS_SENT + ]); + + ////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + $company = Company::find($c->id); //sydney + + $timezone_now = now()->setTimezone($company->timezone()->name); + + $this->assertEquals('Australia/Sydney', $timezone_now->timezoneName); + + $this->travelTo($timezone_now->copy()->startOfDay()->subHour()); + + $i = false; + + //Capture companies within the window of 00:00 and 00:30 + if($timezone_now->gte($timezone_now->copy()->startOfDay()) && $timezone_now->lt($timezone_now->copy()->startOfDay()->addMinutes(30))) { + + $i = Invoice::query() + ->where('company_id', $company->id) + ->whereNull('deleted_at') + ->where('is_deleted', 0) + ->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL]) + ->where('is_proforma', 0) + ->whereNotNull('subscription_id') + ->where('balance', '>', 0) + ->whereDate('due_date', '<=', now()->setTimezone($company->timezone()->name)->addDay()->startOfDay()) + ->get(); + + } + + $this->assertFalse($i); + + $this->travelTo($timezone_now->copy()->startOfDay()); + + if(now()->gte($timezone_now->copy()->startOfDay()) && now()->lt($timezone_now->copy()->startOfDay()->addMinutes(30))) { + + $i = Invoice::query() + ->where('company_id', $company->id) + ->whereNull('deleted_at') + ->where('is_deleted', 0) + ->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL]) + ->where('is_proforma', 0) + ->whereNotNull('subscription_id') + ->whereDate('due_date', '<=', now()->setTimezone($company->timezone()->name)->addDay()->startOfDay()) + ->get(); + + } + + $this->assertEquals(1, $i->count()); + + $i = false; + + $this->travelTo($timezone_now->copy()->startOfDay()->addHours(2)); + + if($timezone_now->gte($timezone_now->copy()->startOfDay()) && $timezone_now->lt($timezone_now->copy()->startOfDay()->addMinutes(30))) { + + $i = Invoice::query() + ->where('company_id', $company->id) + ->whereNull('deleted_at') + ->where('is_deleted', 0) + ->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL]) + ->where('is_proforma', 0) + ->whereNotNull('subscription_id') + ->where('balance', '>', 0) + ->whereDate('due_date', '<=', now()->setTimezone($company->timezone()->name)->addDay()->startOfDay()) + ->get(); + + } + + $this->assertFalse($i); + + $count = Invoice::whereNotNull('subscription_id')->whereIn('company_id', [$c2->id, $c->id])->count(); + + $this->assertEquals(2, $count); + + $this->travelBack(); + //////////////////////////////////////////// vienna ////////////////////////////////////////////////// + + $company = Company::find($c2->id); //vienna + + $timezone_now = now()->setTimezone($company->timezone()->name); + + $this->assertEquals('Europe/Vienna', $timezone_now->timezoneName); + + $this->travelTo($timezone_now->copy()->startOfDay()->subHour()); + + $this->travelTo($timezone_now->copy()->startOfDay()->subHour()); + + $i = false; + + //Capture companies within the window of 00:00 and 00:30 + if($timezone_now->gte($timezone_now->copy()->startOfDay()) && $timezone_now->lt($timezone_now->copy()->startOfDay()->addMinutes(30))) { + + $i = Invoice::query() + ->where('company_id', $company->id) + ->whereNull('deleted_at') + ->where('is_deleted', 0) + ->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL]) + ->where('is_proforma', 0) + ->whereNotNull('subscription_id') + ->where('balance', '>', 0) + ->whereDate('due_date', '<=', now()->setTimezone($company->timezone()->name)->addDay()->startOfDay()) + ->get(); + + } + + $this->assertFalse($i); + + $this->travelTo($timezone_now->copy()->startOfDay()); + + if(now()->gte($timezone_now->copy()->startOfDay()) && now()->lt($timezone_now->copy()->startOfDay()->addMinutes(30))) { + + $i = Invoice::query() + ->where('company_id', $company->id) + ->whereNull('deleted_at') + ->where('is_deleted', 0) + ->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL]) + ->where('is_proforma', 0) + ->whereNotNull('subscription_id') + ->whereDate('due_date', '<=', now()->setTimezone($company->timezone()->name)->addDay()->startOfDay()) + ->get(); + + } + + $this->assertEquals(1, $i->count()); + + $i = false; + + $this->travelTo($timezone_now->copy()->startOfDay()->addHours(2)); + + if($timezone_now->gte($timezone_now->copy()->startOfDay()) && $timezone_now->lt($timezone_now->copy()->startOfDay()->addMinutes(30))) { + + $i = Invoice::query() + ->where('company_id', $company->id) + ->whereNull('deleted_at') + ->where('is_deleted', 0) + ->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL]) + ->where('is_proforma', 0) + ->whereNotNull('subscription_id') + ->where('balance', '>', 0) + ->whereDate('due_date', '<=', now()->setTimezone($company->timezone()->name)->addDay()->startOfDay()) + ->get(); + + } + + $this->assertFalse($i); + + + + } + public function testAssignInvoice() { $i = Invoice::factory() @@ -165,11 +415,12 @@ class SubscriptionApiTest extends TestCase 'company_id' => $this->company->id, 'user_id' => $this->user->id, ]); + $response = $this->withHeaders([ 'X-API-SECRET' => config('ninja.api_secret'), 'X-API-TOKEN' => $this->token, - ])->post('/api/v1/subscriptions', ['product_ids' => $product->hashed_id, 'allow_cancellation' => true, 'name' => Str::random(5)]); + ])->post('/api/v1/subscriptions', ['steps' => "cart,auth.login-or-register",'product_ids' => $product->hashed_id, 'allow_cancellation' => true, 'name' => Str::random(5)]); // nlog($response); $response->assertStatus(200); @@ -184,14 +435,14 @@ class SubscriptionApiTest extends TestCase $response1 = $this ->withHeaders(['X-API-SECRET' => config('ninja.api_secret'), 'X-API-TOKEN' => $this->token]) - ->post('/api/v1/subscriptions', ['product_ids' => $product->hashed_id, 'name' => Str::random(5)]) + ->post('/api/v1/subscriptions', ['steps' => "cart,auth.login-or-register",'product_ids' => $product->hashed_id, 'name' => Str::random(5)]) ->assertStatus(200) ->json(); // try { $response2 = $this ->withHeaders(['X-API-SECRET' => config('ninja.api_secret'), 'X-API-TOKEN' => $this->token]) - ->put('/api/v1/subscriptions/'.$response1['data']['id'], ['allow_cancellation' => true]) + ->put('/api/v1/subscriptions/'.$response1['data']['id'], ['steps' => "cart,auth.login-or-register",'allow_cancellation' => true]) ->assertStatus(200) ->json(); // }catch(ValidationException $e) { diff --git a/tests/Integration/EventTest.php b/tests/Integration/EventTest.php index d6ca4dce5d76..ff8ca0c971eb 100644 --- a/tests/Integration/EventTest.php +++ b/tests/Integration/EventTest.php @@ -796,6 +796,7 @@ class EventTest extends TestCase $data = [ 'name' => $this->faker->firstName, + 'steps' => "cart,auth.login-or-register", ]; $response = $this->withHeaders([ @@ -809,6 +810,7 @@ class EventTest extends TestCase $data = [ 'name' => $this->faker->firstName, + 'steps' => "cart,auth.login-or-register", ]; $response = $this->withHeaders([ @@ -820,6 +822,7 @@ class EventTest extends TestCase $data = [ 'ids' => [$arr['data']['id']], + 'steps' => "cart,auth.login-or-register", ]; $response = $this->withHeaders([ diff --git a/tests/Unit/BillingPortal/DependencyTest.php b/tests/Unit/BillingPortal/DependencyTest.php new file mode 100644 index 000000000000..472d2709b105 --- /dev/null +++ b/tests/Unit/BillingPortal/DependencyTest.php @@ -0,0 +1,106 @@ +markTestSkipped('No Bueno'); + + } + + public function testDependencyOrder() + { + $results = StepService::check([ + RegisterOrLogin::class, + Cart::class, + ]); + + $this->assertCount(1, $results); + + $results = StepService::check([ + RegisterOrLogin::class, + Cart::class, + ]); + + $this->assertCount(0, $results); + + $results = StepService::check([ + RegisterOrLogin::class, + Cart::class, + ]); + + $this->assertCount(0, $results); + } + + public function testSorting() + { + $results = $this->sort([ + Methods::class, + RegisterOrLogin::class, + Cart::class, + ]); + + $this->assertEquals(Purchase::defaultSteps(), $results); + + $results = $this->sort([ + RegisterOrLogin::class, + Methods::class, + Cart::class, + ]); + + $this->assertEquals([ + Setup::class, + RegisterOrLogin::class, + Methods::class, + Cart::class, + Submit::class, + ], $results); + + $results = $this->sort([ + RegisterOrLogin::class, + Cart::class, + ]); + + $this->assertEquals([ + Setup::class, + RegisterOrLogin::class, + Cart::class, + Submit::class, + ], $results); + } + + private function sort(array $dependencies): array + { + $errors = StepService::check($dependencies); + + if (count($errors)) { + return Purchase::defaultSteps(); + } + + return [Setup::class, ...$dependencies, Submit::class]; // Note: Re-index if you're doing any index-based checking/comparision. + } +} diff --git a/tests/Unit/SubscriptionsCalcTest.php b/tests/Unit/SubscriptionsCalcTest.php index 2e8684743c9e..37eef6a040f2 100644 --- a/tests/Unit/SubscriptionsCalcTest.php +++ b/tests/Unit/SubscriptionsCalcTest.php @@ -13,7 +13,6 @@ namespace Tests\Unit; use App\Factory\InvoiceItemFactory; use App\Helpers\Invoice\ProRata; -use App\Helpers\Subscription\SubscriptionCalculator; use App\Models\Invoice; use App\Models\Subscription; use Illuminate\Support\Carbon; @@ -79,13 +78,13 @@ class SubscriptionsCalcTest extends TestCase $this->assertEquals(10, $invoice->amount); $this->assertEquals(10, $invoice->balance); - $sub_calculator = new SubscriptionCalculator($target->fresh(), $invoice->fresh()); + $sub_calculator = $target->calc(); - $this->assertFalse($sub_calculator->isPaidUp()); + $this->assertFalse($sub_calculator->isPaidUp($invoice)); $invoice = $invoice->service()->markPaid()->save(); - $this->assertTrue($sub_calculator->isPaidUp()); + $this->assertTrue($sub_calculator->isPaidUp($invoice)); $this->assertEquals(10, $invoice->amount); $this->assertEquals(0, $invoice->balance);