diff --git a/app/Console/Commands/ReactBuilder.php b/app/Console/Commands/ReactBuilder.php
index 430b16d90542..4bec0cefb5c5 100644
--- a/app/Console/Commands/ReactBuilder.php
+++ b/app/Console/Commands/ReactBuilder.php
@@ -12,6 +12,7 @@
namespace App\Console\Commands;
use Illuminate\Console\Command;
+use Illuminate\Support\Facades\Storage;
class ReactBuilder extends Command
{
@@ -47,6 +48,8 @@ class ReactBuilder extends Command
public function handle()
{
$includes = '';
+
+ Storage::makeDirectory(public_path('react'));
$directoryIterator = new \RecursiveDirectoryIterator(public_path('react'), \RecursiveDirectoryIterator::SKIP_DOTS);
diff --git a/app/Export/CSV/BaseExport.php b/app/Export/CSV/BaseExport.php
index 483c1c0b4a48..21ccedac0b14 100644
--- a/app/Export/CSV/BaseExport.php
+++ b/app/Export/CSV/BaseExport.php
@@ -11,21 +11,29 @@
namespace App\Export\CSV;
+use App\Models\Quote;
use App\Utils\Number;
use App\Models\Client;
-use App\Models\ClientContact;
+use App\Models\Credit;
use App\Utils\Helpers;
use App\Models\Company;
use App\Models\Expense;
use App\Models\Invoice;
use App\Models\Payment;
+use App\Models\Document;
use League\Fractal\Manager;
+use App\Models\ClientContact;
+use App\Models\PurchaseOrder;
+use App\Models\RecurringInvoice;
use Illuminate\Support\Carbon;
use App\Utils\Traits\MakesHash;
use App\Transformers\TaskTransformer;
use App\Transformers\PaymentTransformer;
use Illuminate\Database\Eloquent\Builder;
use League\Fractal\Serializer\ArraySerializer;
+use App\Models\Product;
+use App\Models\Task;
+use App\Models\Vendor;
class BaseExport
{
@@ -57,7 +65,7 @@ class BaseExport
'id_number' => 'vendor.id_number',
'name' => 'vendor.name',
'number' => 'vendor.number',
- 'client_phone' => 'vendor.phone',
+ 'phone' => 'vendor.phone',
'postal_code' => 'vendor.postal_code',
'private_notes' => 'vendor.private_notes',
'public_notes' => 'vendor.public_notes',
@@ -230,8 +238,8 @@ class BaseExport
];
protected array $product_report_keys = [
- 'project' => 'project_id',
- 'vendor' => 'vendor_id',
+ // 'project' => 'project_id',
+ // 'vendor' => 'vendor_id',
'custom_value1' => 'custom_value1',
'custom_value2' => 'custom_value2',
'custom_value3' => 'custom_value3',
@@ -247,6 +255,10 @@ class BaseExport
'tax_name1' => 'tax_name1',
'tax_name2' => 'tax_name2',
'tax_name3' => 'tax_name3',
+ 'image' => 'product_image',
+ 'tax_category' => 'tax_id',
+ 'max_quantity' => 'max_quantity',
+ 'in_stock_quantity' => 'in_stock_quantity',
];
protected array $item_report_keys = [
@@ -645,7 +657,7 @@ class BaseExport
// nlog("searching for {$column}");
$transformed_invoice = false;
- if($transformer instanceof PaymentTransformer) {
+ if($transformer instanceof PaymentTransformer && ($entity->invoices ?? false)) {
$transformed_invoices = $transformer->includeInvoices($entity);
$manager = new Manager();
@@ -667,7 +679,7 @@ class BaseExport
}
- if($transformer instanceof TaskTransformer) {
+ if($transformer instanceof TaskTransformer && ($entity->invoice ?? false)) {
$transformed_invoice = $transformer->includeInvoice($entity);
if(!$transformed_invoice)
@@ -987,6 +999,7 @@ class BaseExport
$key = str_replace('payment.', '', $key);
$key = str_replace('expense.', '', $key);
$key = str_replace('product.', '', $key);
+ $key = str_replace('task.', '', $key);
if(stripos($value, 'custom_value') !== false)
{
@@ -1010,7 +1023,7 @@ class BaseExport
$custom_field_string = strlen($helper->makeCustomField($this->company->custom_fields, $entity)) > 1 ? $helper->makeCustomField($this->company->custom_fields, $entity) : ctrans("texts.{$parts[1]}");
$header[] = ctrans("texts.{$parts[0]}") . " " . $custom_field_string;
}
- elseif(count($parts) == 2 && in_array(substr($original_key, 0, -1), ['credit','quote','invoice','purchase_order','recurring_invoice'])){
+ elseif(count($parts) == 2 && in_array(substr($original_key, 0, -1), ['credit','quote','invoice','purchase_order','recurring_invoice','task'])){
$custom_field_string = strlen($helper->makeCustomField($this->company->custom_fields, "product".substr($original_key,-1))) > 1 ? $helper->makeCustomField($this->company->custom_fields, "product".substr($original_key,-1)) : ctrans("texts.{$parts[1]}");
$header[] = ctrans("texts.{$parts[0]}") . " " . $custom_field_string;
}
@@ -1034,10 +1047,21 @@ class BaseExport
{
$class = get_class($resource);
+ $entity = '';
+
match ($class) {
Invoice::class => $entity = 'invoice',
+ RecurringInvoice::class => $entity = 'recurring_invoice',
+ Quote::class => $entity = 'quote',
+ Credit::class => $entity = 'credit',
Expense::class => $entity = 'expense',
+ Document::class => $entity = 'document',
ClientContact::class => $entity = 'contact',
+ PurchaseOrder::class => $entity = 'purchase_order',
+ Payment::class => $entity = 'payment',
+ Product::class => $entity = 'product',
+ Task::class => $entity = 'task',
+ Vendor::class => $entity = 'vendor',
default => $entity = 'invoice',
};
@@ -1048,6 +1072,17 @@ class BaseExport
$report_keys = explode(".", $value);
$column_key = $value;
+
+ if($value == 'product_image') {
+ $column_key = 'image';
+ $value = 'image';
+ }
+
+ if($value == 'tax_id') {
+ $column_key = 'tax_category';
+ $value = 'tax_category';
+ }
+
$clean_row[$key]['entity'] = $report_keys[0];
$clean_row[$key]['id'] = $report_keys[1] ?? $report_keys[0];
$clean_row[$key]['hashed_id'] = $report_keys[0] == $entity ? null : $resource->{$report_keys[0]}->hashed_id ?? null;
@@ -1057,6 +1092,51 @@ class BaseExport
}
+ nlog($clean_row);
+
+ return $clean_row;
+ }
+
+ public function processItemMetaData(array $row, $resource): array
+ {
+ $class = get_class($resource);
+
+ $entity = '';
+
+ match ($class) {
+ Invoice::class => $entity = 'invoice',
+ Quote::class => $entity = 'quote',
+ Credit::class => $entity = 'credit',
+ Expense::class => $entity = 'expense',
+ Document::class => $entity = 'document',
+ ClientContact::class => $entity = 'contact',
+ PurchaseOrder::class => $entity = 'purchase_order',
+ default => $entity = 'invoice',
+ };
+
+ $clean_row = [];
+
+ foreach (array_values($this->input['report_keys']) as $key => $value) {
+
+ $report_keys = explode(".", $value);
+
+ $column_key = $value;
+
+ if($value == 'type_id' || $value == 'item.type_id')
+ $column_key = 'type';
+
+ if($value == 'tax_id' || $value == 'item.tax_id')
+ $column_key = 'tax_category';
+
+ $clean_row[$key]['entity'] = $report_keys[0];
+ $clean_row[$key]['id'] = $report_keys[1] ?? $report_keys[0];
+ $clean_row[$key]['hashed_id'] = $report_keys[0] == $entity ? null : $resource->{$report_keys[0]}->hashed_id ?? null;
+ $clean_row[$key]['value'] = isset($row[$column_key]) ? $row[$column_key] : $row[$report_keys[1]];
+ $clean_row[$key]['identifier'] = $value;
+ $clean_row[$key]['display_value'] = isset($row[$column_key]) ? $row[$column_key] : $row[$report_keys[1]];
+
+ }
+
return $clean_row;
}
diff --git a/app/Export/CSV/CreditExport.php b/app/Export/CSV/CreditExport.php
index ca0fde8bfed6..2d4cc8447fca 100644
--- a/app/Export/CSV/CreditExport.php
+++ b/app/Export/CSV/CreditExport.php
@@ -19,7 +19,7 @@ use App\Models\Company;
use App\Libraries\MultiDB;
use Illuminate\Support\Facades\App;
use App\Transformers\CreditTransformer;
-use Illuminate\Contracts\Database\Eloquent\Builder;
+use Illuminate\Database\Eloquent\Builder;
class CreditExport extends BaseExport
{
@@ -66,12 +66,12 @@ class CreditExport extends BaseExport
$column_key = $value;
$clean_row[$key]['entity'] = $report_keys[0];
$clean_row[$key]['id'] = $report_keys[1] ?? $report_keys[0];
- $clean_row[$key]['hashed_id'] = $report_keys[0] == 'credit' ? null : $credit->{$report_keys[0]}->hashed_id ?? null;
+ $clean_row[$key]['hashed_id'] = $report_keys[0] == 'credit' ? null : $resource->{$report_keys[0]}->hashed_id ?? null;
$clean_row[$key]['value'] = $row[$column_key];
$clean_row[$key]['identifier'] = $value;
if(in_array($clean_row[$key]['id'], ['paid_to_date','total_taxes','amount', 'balance', 'partial', 'refunded', 'applied','unit_cost','cost','price']))
- $clean_row[$key]['display_value'] = Number::formatMoney($row[$column_key], $credit->client);
+ $clean_row[$key]['display_value'] = Number::formatMoney($row[$column_key], $resource->client);
else
$clean_row[$key]['display_value'] = $row[$column_key];
diff --git a/app/Export/CSV/DocumentExport.php b/app/Export/CSV/DocumentExport.php
index 391fe14050a3..701b1bc3ffe0 100644
--- a/app/Export/CSV/DocumentExport.php
+++ b/app/Export/CSV/DocumentExport.php
@@ -16,7 +16,7 @@ use App\Models\Company;
use App\Models\Document;
use App\Transformers\DocumentTransformer;
use App\Utils\Ninja;
-use Illuminate\Contracts\Database\Eloquent\Builder;
+use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\App;
use League\Csv\Writer;
@@ -62,27 +62,6 @@ class DocumentExport extends BaseExport
return array_merge(['columns' => $header], $report);
}
- private function processMetaData(array $row, Document $document): array
- {
- $clean_row = [];
- foreach (array_values($this->input['report_keys']) as $key => $value) {
-
- $report_keys = explode(".", $value);
-
- $column_key = $value;
- $clean_row[$key]['entity'] = $report_keys[0];
- $clean_row[$key]['id'] = $report_keys[1] ?? $report_keys[0];
- $clean_row[$key]['hashed_id'] = $report_keys[0] == 'document' ? null : $document->{$report_keys[0]}->hashed_id ?? null;
- $clean_row[$key]['value'] = $row[$column_key];
- $clean_row[$key]['identifier'] = $value;
-
- $clean_row[$key]['display_value'] = $row[$column_key];
-
- }
-
- return $clean_row;
- }
-
private function init(): Builder
{
diff --git a/app/Export/CSV/InvoiceExport.php b/app/Export/CSV/InvoiceExport.php
index 4123940a7695..f8cc1cfe9348 100644
--- a/app/Export/CSV/InvoiceExport.php
+++ b/app/Export/CSV/InvoiceExport.php
@@ -20,7 +20,7 @@ use App\Libraries\MultiDB;
use App\Export\CSV\BaseExport;
use Illuminate\Support\Facades\App;
use App\Transformers\InvoiceTransformer;
-use Illuminate\Contracts\Database\Eloquent\Builder;
+use Illuminate\Database\Eloquent\Builder;
class InvoiceExport extends BaseExport
{
@@ -95,7 +95,6 @@ class InvoiceExport extends BaseExport
//insert the header
$this->csv->insertOne($this->buildHeader());
-
$query->cursor()
->each(function ($invoice) {
$this->csv->insertOne($this->buildRow($invoice));
diff --git a/app/Export/CSV/InvoiceItemExport.php b/app/Export/CSV/InvoiceItemExport.php
index 92e85fcd348a..4db01226725d 100644
--- a/app/Export/CSV/InvoiceItemExport.php
+++ b/app/Export/CSV/InvoiceItemExport.php
@@ -16,7 +16,7 @@ use App\Models\Company;
use App\Models\Invoice;
use App\Transformers\InvoiceTransformer;
use App\Utils\Ninja;
-use Illuminate\Contracts\Database\Eloquent\Builder;
+use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\App;
use League\Csv\Writer;
@@ -33,6 +33,8 @@ class InvoiceItemExport extends BaseExport
private array $storage_array = [];
+ private array $storage_item_array = [];
+
private array $decorate_keys = [
'client',
'currency_id',
@@ -62,7 +64,8 @@ class InvoiceItemExport extends BaseExport
$query = Invoice::query()
->withTrashed()
- ->with('client')->where('company_id', $this->company->id)
+ ->with('client')
+ ->where('company_id', $this->company->id)
->where('is_deleted', 0);
$query = $this->addDateRange($query);
@@ -81,16 +84,21 @@ class InvoiceItemExport extends BaseExport
return ['identifier' => $value, 'display_value' => $headerdisplay[$value]];
})->toArray();
- $items = $query->cursor()
- ->map(function ($resource) {
+
+ $query->cursor()
+ ->each(function ($resource) {
$this->iterateItems($resource);
- $row = $this->processMetaData($this->storage_array[0], $resource);
+
+ foreach($this->storage_array as $row) {
+ $this->storage_item_array[] = $this->processItemMetaData($row, $resource);
+ }
+
$this->storage_array = [];
- return $row;
- })->toArray();
-
+
+ });
+
+ return array_merge(['columns' => $header], $this->storage_item_array);
- return array_merge(['columns' => $header], $items);
}
@@ -195,33 +203,4 @@ class InvoiceItemExport extends BaseExport
return $entity;
}
- public function processMetaData(array $row, $resource): array
- {
- $entity = 'invoice';
- $clean_row = [];
-
- foreach (array_values($this->input['report_keys']) as $key => $value) {
-
- $report_keys = explode(".", $value);
-
- $column_key = $value;
-
- if($value == 'type_id' || $value == 'item.type_id')
- $column_key = 'type';
-
- if($value == 'tax_id' || $value == 'item.tax_id')
- $column_key = 'tax_category';
-
- $clean_row[$key]['entity'] = $report_keys[0];
- $clean_row[$key]['id'] = $report_keys[1] ?? $report_keys[0];
- $clean_row[$key]['hashed_id'] = $report_keys[0] == $entity ? null : $resource->{$report_keys[0]}->hashed_id ?? null;
- $clean_row[$key]['value'] = isset($row[$column_key]) ? $row[$column_key] : $row[$report_keys[1]];
- $clean_row[$key]['identifier'] = $value;
- $clean_row[$key]['display_value'] = isset($row[$column_key]) ? $row[$column_key] : $row[$report_keys[1]];
-
- }
-
- return $clean_row;
- }
-
}
diff --git a/app/Export/CSV/PaymentExport.php b/app/Export/CSV/PaymentExport.php
index 930be240b75f..b868bd23ea71 100644
--- a/app/Export/CSV/PaymentExport.php
+++ b/app/Export/CSV/PaymentExport.php
@@ -16,7 +16,7 @@ use App\Models\Company;
use App\Models\Payment;
use App\Transformers\PaymentTransformer;
use App\Utils\Ninja;
-use Illuminate\Contracts\Database\Eloquent\Builder;
+use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\App;
use League\Csv\Writer;
@@ -28,40 +28,6 @@ class PaymentExport extends BaseExport
public Writer $csv;
- // public array $entity_keys = [
- // 'amount' => 'amount',
- // 'applied' => 'applied',
- // 'client' => 'client_id',
- // 'currency' => 'currency_id',
- // 'custom_value1' => 'custom_value1',
- // 'custom_value2' => 'custom_value2',
- // 'custom_value3' => 'custom_value3',
- // 'custom_value4' => 'custom_value4',
- // 'date' => 'date',
- // 'exchange_currency' => 'exchange_currency_id',
- // 'gateway' => 'gateway_type_id',
- // 'number' => 'number',
- // 'private_notes' => 'private_notes',
- // 'project' => 'project_id',
- // 'refunded' => 'refunded',
- // 'status' => 'status_id',
- // 'transaction_reference' => 'transaction_reference',
- // 'type' => 'type_id',
- // 'vendor' => 'vendor_id',
- // 'invoices' => 'invoices',
- // ];
-
- // private array $decorate_keys = [
- // 'vendor',
- // 'status',
- // 'project',
- // 'client',
- // 'currency',
- // 'exchange_currency',
- // 'type',
- // 'invoices',
- // ];
-
public function __construct(Company $company, array $input)
{
$this->company = $company;
@@ -105,12 +71,12 @@ class PaymentExport extends BaseExport
$report = $query->cursor()
->map(function ($resource) {
- return $this->buildRow($resource);
+ $row = $this->buildRow($resource);
+ return $this->processMetaData($row, $resource);
})->toArray();
return array_merge(['columns' => $header], $report);
-
}
public function run()
diff --git a/app/Export/CSV/ProductExport.php b/app/Export/CSV/ProductExport.php
index a4c5bbf7535c..0097040ba622 100644
--- a/app/Export/CSV/ProductExport.php
+++ b/app/Export/CSV/ProductExport.php
@@ -13,11 +13,10 @@ namespace App\Export\CSV;
use App\Libraries\MultiDB;
use App\Models\Company;
-use App\Models\Document;
use App\Models\Product;
use App\Transformers\ProductTransformer;
use App\Utils\Ninja;
-use Illuminate\Contracts\Database\Eloquent\Builder;
+use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\App;
use League\Csv\Writer;
@@ -48,7 +47,8 @@ class ProductExport extends BaseExport
$report = $query->cursor()
->map(function ($resource) {
- return $this->buildRow($resource);
+ $row = $this->buildRow($resource);
+ return $this->processMetaData($row, $resource);
})->toArray();
return array_merge(['columns' => $header], $report);
diff --git a/app/Export/CSV/PurchaseOrderExport.php b/app/Export/CSV/PurchaseOrderExport.php
index ffee39eee336..ed506f61050e 100644
--- a/app/Export/CSV/PurchaseOrderExport.php
+++ b/app/Export/CSV/PurchaseOrderExport.php
@@ -19,7 +19,7 @@ use App\Libraries\MultiDB;
use App\Models\PurchaseOrder;
use Illuminate\Support\Facades\App;
use App\Transformers\PurchaseOrderTransformer;
-use Illuminate\Contracts\Database\Eloquent\Builder;
+use Illuminate\Database\Eloquent\Builder;
class PurchaseOrderExport extends BaseExport
{
@@ -119,7 +119,8 @@ class PurchaseOrderExport extends BaseExport
$report = $query->cursor()
->map(function ($resource) {
- return $this->buildRow($resource);
+ $row = $this->buildRow($resource);
+ return $this->processMetaData($row, $resource);
})->toArray();
return array_merge(['columns' => $header], $report);
diff --git a/app/Export/CSV/PurchaseOrderItemExport.php b/app/Export/CSV/PurchaseOrderItemExport.php
index ec63f8388f14..8859a431ce3b 100644
--- a/app/Export/CSV/PurchaseOrderItemExport.php
+++ b/app/Export/CSV/PurchaseOrderItemExport.php
@@ -11,14 +11,14 @@
namespace App\Export\CSV;
-use App\Libraries\MultiDB;
-use App\Models\Company;
-use App\Models\PurchaseOrder;
-use App\Transformers\PurchaseOrderTransformer;
use App\Utils\Ninja;
-use Illuminate\Contracts\Database\Eloquent\Builder;
-use Illuminate\Support\Facades\App;
use League\Csv\Writer;
+use App\Models\Company;
+use App\Libraries\MultiDB;
+use App\Models\PurchaseOrder;
+use Illuminate\Support\Facades\App;
+use Illuminate\Database\Eloquent\Builder;
+use App\Transformers\PurchaseOrderTransformer;
class PurchaseOrderItemExport extends BaseExport
{
@@ -33,6 +33,8 @@ class PurchaseOrderItemExport extends BaseExport
private array $storage_array = [];
+ private array $storage_item_array = [];
+
public function __construct(Company $company, array $input)
{
$this->company = $company;
@@ -50,7 +52,6 @@ class PurchaseOrderItemExport extends BaseExport
$t->replace(Ninja::transformTranslations($this->company->settings));
if (count($this->input['report_keys']) == 0) {
- // $this->force_keys = true;
$this->input['report_keys'] = array_values($this->mergeItemsKeys('purchase_order_report_keys'));
}
@@ -78,9 +79,16 @@ class PurchaseOrderItemExport extends BaseExport
$query->cursor()
->each(function ($resource) {
$this->iterateItems($resource);
+
+ foreach($this->storage_array as $row) {
+ $this->storage_item_array[] = $this->processItemMetaData($row, $resource);
+ }
+
+ $this->storage_array = [];
+
});
- return array_merge(['columns' => $header], $this->storage_array);
+ return array_merge(['columns' => $header], $this->storage_item_array);
}
public function run()
@@ -113,7 +121,7 @@ class PurchaseOrderItemExport extends BaseExport
foreach ($purchase_order->line_items as $item) {
$item_array = [];
- foreach (array_values($this->input['report_keys']) as $key) { //items iterator produces item array
+ foreach (array_values(array_intersect($this->input['report_keys'], $this->item_report_keys)) as $key) { //items iterator produces item array
if (str_contains($key, "item.")) {
@@ -190,4 +198,5 @@ class PurchaseOrderItemExport extends BaseExport
return $entity;
}
+
}
diff --git a/app/Export/CSV/QuoteExport.php b/app/Export/CSV/QuoteExport.php
index a84becb20eb2..de2813608537 100644
--- a/app/Export/CSV/QuoteExport.php
+++ b/app/Export/CSV/QuoteExport.php
@@ -16,7 +16,7 @@ use App\Models\Company;
use App\Models\Quote;
use App\Transformers\QuoteTransformer;
use App\Utils\Ninja;
-use Illuminate\Contracts\Database\Eloquent\Builder;
+use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\App;
use League\Csv\Writer;
@@ -80,7 +80,8 @@ class QuoteExport extends BaseExport
$report = $query->cursor()
->map(function ($resource) {
- return $this->buildRow($resource);
+ $row = $this->buildRow($resource);
+ return $this->processMetaData($row, $resource);
})->toArray();
return array_merge(['columns' => $header], $report);
diff --git a/app/Export/CSV/QuoteItemExport.php b/app/Export/CSV/QuoteItemExport.php
index a2f78d16ce41..774b50a774b2 100644
--- a/app/Export/CSV/QuoteItemExport.php
+++ b/app/Export/CSV/QuoteItemExport.php
@@ -16,7 +16,7 @@ use App\Models\Company;
use App\Models\Quote;
use App\Transformers\QuoteTransformer;
use App\Utils\Ninja;
-use Illuminate\Contracts\Database\Eloquent\Builder;
+use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\App;
use League\Csv\Writer;
@@ -29,7 +29,8 @@ class QuoteItemExport extends BaseExport
public Writer $csv;
- private array $storage_array;
+ private array $storage_array = [];
+ private array $storage_item_array = [];
private array $decorate_keys = [
'client',
@@ -77,12 +78,20 @@ class QuoteItemExport extends BaseExport
return ['identifier' => $value, 'display_value' => $headerdisplay[$value]];
})->toArray();
- $query->cursor()
- ->each(function ($resource) {
- $this->iterateItems($resource);
- });
-
- return array_merge(['columns' => $header], $this->storage_array);
+ $query->cursor()
+ ->each(function ($resource) {
+ $this->iterateItems($resource);
+
+ foreach($this->storage_array as $row) {
+ $this->storage_item_array[] = $this->processItemMetaData($row, $resource);
+ }
+
+ $this->storage_array = [];
+
+ });
+
+ return array_merge(['columns' => $header], $this->storage_item_array);
+
}
diff --git a/app/Export/CSV/RecurringInvoiceExport.php b/app/Export/CSV/RecurringInvoiceExport.php
index 330f29695c83..06c17eec3ff0 100644
--- a/app/Export/CSV/RecurringInvoiceExport.php
+++ b/app/Export/CSV/RecurringInvoiceExport.php
@@ -16,6 +16,7 @@ use App\Models\Company;
use App\Models\RecurringInvoice;
use App\Transformers\RecurringInvoiceTransformer;
use App\Utils\Ninja;
+use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\App;
use League\Csv\Writer;
@@ -28,55 +29,6 @@ class RecurringInvoiceExport extends BaseExport
public Writer $csv;
- public array $entity_keys = [
- 'amount' => 'amount',
- 'balance' => 'balance',
- 'client' => 'client_id',
- // 'custom_surcharge1' => 'custom_surcharge1',
- // 'custom_surcharge2' => 'custom_surcharge2',
- // 'custom_surcharge3' => 'custom_surcharge3',
- // 'custom_surcharge4' => 'custom_surcharge4',
- 'custom_value1' => 'custom_value1',
- 'custom_value2' => 'custom_value2',
- 'custom_value3' => 'custom_value3',
- 'custom_value4' => 'custom_value4',
- 'date' => 'date',
- 'discount' => 'discount',
- 'due_date' => 'due_date',
- 'exchange_rate' => 'exchange_rate',
- 'footer' => 'footer',
- 'number' => 'number',
- 'paid_to_date' => 'paid_to_date',
- 'partial' => 'partial',
- 'partial_due_date' => 'partial_due_date',
- 'po_number' => 'po_number',
- 'private_notes' => 'private_notes',
- 'public_notes' => 'public_notes',
- 'next_send_date' => 'next_send_date',
- 'status' => 'status_id',
- 'tax_name1' => 'tax_name1',
- 'tax_name2' => 'tax_name2',
- 'tax_name3' => 'tax_name3',
- 'tax_rate1' => 'tax_rate1',
- 'tax_rate2' => 'tax_rate2',
- 'tax_rate3' => 'tax_rate3',
- 'terms' => 'terms',
- 'total_taxes' => 'total_taxes',
- 'currency' => 'currency_id',
- 'vendor' => 'vendor_id',
- 'project' => 'project_id',
- 'frequency_id' => 'frequency_id',
- ];
-
- private array $decorate_keys = [
- 'country',
- 'client',
- 'currency',
- 'status',
- 'vendor',
- 'project',
- ];
-
public function __construct(Company $company, array $input)
{
$this->company = $company;
@@ -84,7 +36,7 @@ class RecurringInvoiceExport extends BaseExport
$this->invoice_transformer = new RecurringInvoiceTransformer();
}
- public function run()
+ public function init(): Builder
{
MultiDB::setDb($this->company->db);
App::forgetInstance('translator');
@@ -92,23 +44,33 @@ class RecurringInvoiceExport extends BaseExport
$t = app('translator');
$t->replace(Ninja::transformTranslations($this->company->settings));
- //load the CSV document from a string
- $this->csv = Writer::createFromString();
-
if (count($this->input['report_keys']) == 0) {
- $this->input['report_keys'] = array_values($this->entity_keys);
+ $this->input['report_keys'] = array_values($this->recurring_invoice_report_keys);
}
- //insert the header
- $this->csv->insertOne($this->buildHeader());
-
$query = RecurringInvoice::query()
->withTrashed()
- ->with('client')->where('company_id', $this->company->id)
+ ->with('client')
+ ->where('company_id', $this->company->id)
->where('is_deleted', 0);
$query = $this->addDateRange($query);
+ return $query;
+
+ }
+
+ public function run()
+ {
+
+ $query = $this->init();
+
+ //load the CSV document from a string
+ $this->csv = Writer::createFromString();
+
+ //insert the header
+ $this->csv->insertOne($this->buildHeader());
+
$query->cursor()
->each(function ($invoice) {
$this->csv->insertOne($this->buildRow($invoice));
@@ -117,6 +79,27 @@ class RecurringInvoiceExport extends BaseExport
return $this->csv->toString();
}
+
+ public function returnJson()
+ {
+ $query = $this->init();
+
+ $headerdisplay = $this->buildHeader();
+
+ $header = collect($this->input['report_keys'])->map(function ($key, $value) use($headerdisplay){
+ return ['identifier' => $value, 'display_value' => $headerdisplay[$value]];
+ })->toArray();
+
+ $report = $query->cursor()
+ ->map(function ($resource) {
+ $row = $this->buildRow($resource);
+ return $this->processMetaData($row, $resource);
+ })->toArray();
+
+ return array_merge(['columns' => $header], $report);
+ }
+
+
private function buildRow(RecurringInvoice $invoice) :array
{
$transformed_invoice = $this->invoice_transformer->transform($invoice);
@@ -124,22 +107,13 @@ class RecurringInvoiceExport extends BaseExport
$entity = [];
foreach (array_values($this->input['report_keys']) as $key) {
- $keyval = array_search($key, $this->entity_keys);
- if(!$keyval) {
- $keyval = array_search(str_replace("recurring_invoice.", "", $key), $this->entity_keys) ?? $key;
- }
+ $parts = explode('.', $key);
- if(!$keyval) {
- $keyval = $key;
- }
-
- if (array_key_exists($key, $transformed_invoice)) {
- $entity[$keyval] = $transformed_invoice[$key];
- } elseif (array_key_exists($keyval, $transformed_invoice)) {
- $entity[$keyval] = $transformed_invoice[$keyval];
+ if (is_array($parts) && $parts[0] == 'recurring_invoice' && array_key_exists($parts[1], $transformed_invoice)) {
+ $entity[$key] = $transformed_invoice[$parts[1]];
} else {
- $entity[$keyval] = $this->resolveKey($keyval, $invoice, $this->invoice_transformer);
+ $entity[$key] = $this->resolveKey($key, $invoice, $this->invoice_transformer);
}
}
@@ -174,7 +148,7 @@ class RecurringInvoiceExport extends BaseExport
}
if (in_array('recurring_invoice.frequency_id', $this->input['report_keys']) || in_array('frequency_id', $this->input['report_keys'])) {
- $entity['frequency_id'] = $invoice->frequencyForKey($invoice->frequency_id);
+ $entity['recurring_invoice.frequency_id'] = $invoice->frequencyForKey($invoice->frequency_id);
}
return $entity;
diff --git a/app/Export/CSV/TaskExport.php b/app/Export/CSV/TaskExport.php
index 387bda902043..30cf6379c02f 100644
--- a/app/Export/CSV/TaskExport.php
+++ b/app/Export/CSV/TaskExport.php
@@ -18,6 +18,7 @@ use App\Models\Task;
use App\Models\Timezone;
use App\Transformers\TaskTransformer;
use App\Utils\Ninja;
+use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\App;
use League\Csv\Writer;
@@ -33,30 +34,9 @@ class TaskExport extends BaseExport
public Writer $csv;
- public array $entity_keys = [
- 'start_date' => 'start_date',
- 'end_date' => 'end_date',
- 'duration' => 'duration',
- 'rate' => 'rate',
- 'number' => 'number',
- 'description' => 'description',
- 'custom_value1' => 'custom_value1',
- 'custom_value2' => 'custom_value2',
- 'custom_value3' => 'custom_value3',
- 'custom_value4' => 'custom_value4',
- 'status' => 'status_id',
- 'project' => 'project_id',
- ];
+ private array $storage_array = [];
- private array $decorate_keys = [
- 'status',
- 'project',
- 'client',
- 'invoice',
- 'start_date',
- 'end_date',
- 'duration',
- ];
+ private array $storage_item_array = [];
public function __construct(Company $company, array $input)
{
@@ -65,7 +45,7 @@ class TaskExport extends BaseExport
$this->entity_transformer = new TaskTransformer();
}
- public function run()
+ public function init(): Builder
{
MultiDB::setDb($this->company->db);
App::forgetInstance('translator');
@@ -74,19 +54,12 @@ class TaskExport extends BaseExport
$t->replace(Ninja::transformTranslations($this->company->settings));
$this->date_format = DateFormat::find($this->company->settings->date_format_id)->format;
-
- //load the CSV document from a string
- $this->csv = Writer::createFromString();
-
ksort($this->entity_keys);
if (count($this->input['report_keys']) == 0) {
- $this->input['report_keys'] = array_values($this->entity_keys);
+ $this->input['report_keys'] = array_values($this->task_report_keys);
}
- //insert the header
- $this->csv->insertOne($this->buildHeader());
-
$query = Task::query()
->withTrashed()
->where('company_id', $this->company->id)
@@ -94,51 +67,86 @@ class TaskExport extends BaseExport
$query = $this->addDateRange($query);
+ return $query;
+
+ }
+
+ public function run()
+ {
+
+ $query = $this->init();
+
+ //load the CSV document from a string
+ $this->csv = Writer::createFromString();
+
+ //insert the header
+ $this->csv->insertOne($this->buildHeader());
+
$query->cursor()
->each(function ($entity) {
$this->buildRow($entity);
});
+ $this->csv->insertAll($this->storage_array);
+
return $this->csv->toString();
}
+
+ public function returnJson()
+ {
+ $query = $this->init();
+
+ $headerdisplay = $this->buildHeader();
+
+ $header = collect($this->input['report_keys'])->map(function ($key, $value) use($headerdisplay){
+ return ['identifier' => $value, 'display_value' => $headerdisplay[$value]];
+ })->toArray();
+
+ $query->cursor()
+ ->each(function ($resource) {
+
+ $this->buildRow($resource);
+
+ foreach($this->storage_array as $row)
+ {
+ $this->storage_item_array[] = $this->processMetaData($row, $resource);
+ }
+
+ $this->storage_array = [];
+ });
+ nlog($this->storage_item_array);
+ return array_merge(['columns' => $header], $this->storage_item_array);
+ }
+
private function buildRow(Task $task)
{
$entity = [];
$transformed_entity = $this->entity_transformer->transform($task);
foreach (array_values($this->input['report_keys']) as $key) {
- $keyval = array_search($key, $this->entity_keys);
- if(!$keyval) {
- $keyval = array_search(str_replace("task.", "", $key), $this->entity_keys) ?? $key;
+ $parts = explode('.', $key);
+
+ if (is_array($parts) && $parts[0] == 'task' && array_key_exists($parts[1], $transformed_entity)) {
+ $entity[$key] = $transformed_entity[$parts[1]];
+ } elseif (array_key_exists($key, $transformed_entity)) {
+ $entity[$key] = $transformed_entity[$key];
+ } else {
+ $entity[$key] = $this->resolveKey($key, $task, $this->entity_transformer);
}
- if(!$keyval) {
- $keyval = $key;
- }
-
- if (array_key_exists($key, $transformed_entity)) {
- $entity[$keyval] = $transformed_entity[$key];
- } elseif (array_key_exists($keyval, $transformed_entity)) {
- $entity[$keyval] = $transformed_entity[$keyval];
- }
- else {
- $entity[$keyval] = $this->resolveKey($keyval, $task, $this->entity_transformer);
- }
}
- $entity['start_date'] = '';
- $entity['end_date'] = '';
- $entity['duration'] = '';
-
+ $entity['task.start_date'] = '';
+ $entity['task.end_date'] = '';
+ $entity['task.duration'] = '';
if (is_null($task->time_log) || (is_array(json_decode($task->time_log, 1)) && count(json_decode($task->time_log, 1)) == 0)) {
- $this->csv->insertOne($entity);
+ $this->storage_array[] = $entity;
} else {
$this->iterateLogs($task, $entity);
}
-
}
@@ -163,41 +171,42 @@ class TaskExport extends BaseExport
foreach ($logs as $key => $item) {
if (in_array('task.start_date', $this->input['report_keys']) || in_array('start_date', $this->input['report_keys'])) {
- $entity['start_date'] = Carbon::createFromTimeStamp($item[0])->setTimezone($timezone_name)->format($date_format_default);
+ $entity['task.start_date'] = Carbon::createFromTimeStamp($item[0])->setTimezone($timezone_name)->format($date_format_default);
}
if ((in_array('task.end_date', $this->input['report_keys']) || in_array('end_date', $this->input['report_keys'])) && $item[1] > 0) {
- $entity['end_date'] = Carbon::createFromTimeStamp($item[1])->setTimezone($timezone_name)->format($date_format_default);
+ $entity['task.end_date'] = Carbon::createFromTimeStamp($item[1])->setTimezone($timezone_name)->format($date_format_default);
}
if ((in_array('task.end_date', $this->input['report_keys']) || in_array('end_date', $this->input['report_keys'])) && $item[1] == 0) {
- $entity['end_date'] = ctrans('texts.is_running');
+ $entity['task.end_date'] = ctrans('texts.is_running');
}
if (in_array('task.duration', $this->input['report_keys']) || in_array('duration', $this->input['report_keys'])) {
- $entity['duration'] = $task->calcDuration();
+ $entity['task.duration'] = $task->calcDuration();
}
$entity = $this->decorateAdvancedFields($task, $entity);
- $this->csv->insertOne($entity);
+ $this->storage_array[] = $entity;
- unset($entity['start_date']);
- unset($entity['end_date']);
- unset($entity['duration']);
+ unset($entity['task.start_date']);
+ unset($entity['task.end_date']);
+ unset($entity['task.duration']);
}
+
}
private function decorateAdvancedFields(Task $task, array $entity) :array
{
- if (in_array('status_id', $this->input['report_keys'])) {
- $entity['status'] = $task->status()->exists() ? $task->status->name : '';
+ if (in_array('task.status_id', $this->input['report_keys'])) {
+ $entity['task.status_id'] = $task->status()->exists() ? $task->status->name : '';
}
- if (in_array('project_id', $this->input['report_keys'])) {
- $entity['project'] = $task->project()->exists() ? $task->project->name : '';
+ if (in_array('task.project_id', $this->input['report_keys'])) {
+ $entity['task.project_id'] = $task->project()->exists() ? $task->project->name : '';
}
-
+
return $entity;
}
}
diff --git a/app/Export/CSV/VendorExport.php b/app/Export/CSV/VendorExport.php
index 011484b054a3..7f35f96e5425 100644
--- a/app/Export/CSV/VendorExport.php
+++ b/app/Export/CSV/VendorExport.php
@@ -17,6 +17,7 @@ use App\Models\Company;
use App\Transformers\VendorContactTransformer;
use App\Transformers\VendorTransformer;
use App\Utils\Ninja;
+use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\App;
use League\Csv\Writer;
@@ -31,42 +32,6 @@ class VendorExport extends BaseExport
public string $date_key = 'created_at';
- public array $entity_keys = [
- 'address1' => 'vendor.address1',
- 'address2' => 'vendor.address2',
- 'city' => 'vendor.city',
- 'country' => 'vendor.country_id',
- 'custom_value1' => 'vendor.custom_value1',
- 'custom_value2' => 'vendor.custom_value2',
- 'custom_value3' => 'vendor.custom_value3',
- 'custom_value4' => 'vendor.custom_value4',
- 'id_number' => 'vendor.id_number',
- 'name' => 'vendor.name',
- 'number' => 'vendor.number',
- 'phone' => 'vendor.phone',
- 'postal_code' => 'vendor.postal_code',
- 'private_notes' => 'vendor.private_notes',
- 'public_notes' => 'vendor.public_notes',
- 'state' => 'vendor.state',
- 'vat_number' => 'vendor.vat_number',
- 'website' => 'vendor.website',
- 'currency' => 'vendor.currency',
- 'first_name' => 'vendor_contact.first_name',
- 'last_name' => 'vendor_contact.last_name',
- 'contact_phone' => 'vendor_contact.phone',
- 'contact_custom_value1' => 'vendor_contact.custom_value1',
- 'contact_custom_value2' => 'vendor_contact.custom_value2',
- 'contact_custom_value3' => 'vendor_contact.custom_value3',
- 'contact_custom_value4' => 'vendor_contact.custom_value4',
- 'email' => 'vendor_contact.email',
- 'status' => 'vendor.status'
- ];
-
- private array $decorate_keys = [
- 'vendor.country_id',
- 'vendor.currency',
- ];
-
public function __construct(Company $company, array $input)
{
$this->company = $company;
@@ -75,8 +40,9 @@ class VendorExport extends BaseExport
$this->contact_transformer = new VendorContactTransformer();
}
- public function run()
+ public function init(): Builder
{
+
MultiDB::setDb($this->company->db);
App::forgetInstance('translator');
App::setLocale($this->company->locale());
@@ -87,19 +53,47 @@ class VendorExport extends BaseExport
$this->csv = Writer::createFromString();
if (count($this->input['report_keys']) == 0) {
- $this->input['report_keys'] = array_values($this->entity_keys);
+ $this->input['report_keys'] = array_values($this->vendor_report_keys);
}
-
- //insert the header
- $this->csv->insertOne($this->buildHeader());
-
+
$query = Vendor::query()->with('contacts')
- ->withTrashed()
- ->where('company_id', $this->company->id)
- ->where('is_deleted', 0);
+ ->withTrashed()
+ ->where('company_id', $this->company->id)
+ ->where('is_deleted', 0);
$query = $this->addDateRange($query);
+ return $query;
+
+ }
+
+ public function returnJson()
+ {
+ $query = $this->init();
+
+ $headerdisplay = $this->buildHeader();
+
+ $header = collect($this->input['report_keys'])->map(function ($key, $value) use($headerdisplay){
+ return ['identifier' => $value, 'display_value' => $headerdisplay[$value]];
+ })->toArray();
+
+ $report = $query->cursor()
+ ->map(function ($resource) {
+ $row = $this->buildRow($resource);
+ return $this->processMetaData($row, $resource);
+ })->toArray();
+
+ return array_merge(['columns' => $header], $report);
+ }
+
+ public function run()
+ {
+
+ $query = $this->init();
+
+ //insert the header
+ $this->csv->insertOne($this->buildHeader());
+
$query->cursor()
->each(function ($vendor) {
$this->csv->insertOne($this->buildRow($vendor));
@@ -110,7 +104,7 @@ class VendorExport extends BaseExport
private function buildRow(Vendor $vendor) :array
{
- $transformed_contact = [];
+ $transformed_contact = false;
$transformed_vendor = $this->vendor_transformer->transform($vendor);
@@ -123,14 +117,12 @@ class VendorExport extends BaseExport
foreach (array_values($this->input['report_keys']) as $key) {
$parts = explode('.', $key);
- $keyval = array_search($key, $this->entity_keys);
-
if (is_array($parts) && $parts[0] == 'vendor' && array_key_exists($parts[1], $transformed_vendor)) {
- $entity[$keyval] = $transformed_vendor[$parts[1]];
- } elseif (is_array($parts) && $parts[0] == 'vendor_contact' && array_key_exists($parts[1], $transformed_contact)) {
- $entity[$keyval] = $transformed_contact[$parts[1]];
+ $entity[$key] = $transformed_vendor[$parts[1]];
+ } elseif (is_array($parts) && $parts[0] == 'vendor_contact' && isset($transformed_contact[$parts[1]])) {
+ $entity[$key] = $transformed_contact[$parts[1]];
} else {
- $entity[$keyval] = '';
+ $entity[$key] = $this->resolveKey($key, $vendor, $this->vendor_transformer);
}
}
diff --git a/app/Helpers/Invoice/InvoiceItemSum.php b/app/Helpers/Invoice/InvoiceItemSum.php
index 57d26d43b9cf..bc368e5f7fa5 100644
--- a/app/Helpers/Invoice/InvoiceItemSum.php
+++ b/app/Helpers/Invoice/InvoiceItemSum.php
@@ -391,16 +391,18 @@ class InvoiceItemSum
{
$this->setGroupedTaxes(collect([]));
- $item_tax = 0;
+
- foreach ($this->line_items as $this->item) {
+ foreach ($this->line_items as $key => $this->item) {
if ($this->item->line_total == 0) {
continue;
}
+
+ $item_tax = 0;
//$amount = $this->item->line_total - ($this->item->line_total * ($this->invoice->discount / $this->sub_total));
- $amount = ($this->sub_total > 0) ? $this->item->line_total - ($this->item->line_total * ($this->invoice->discount / $this->sub_total)) : 0;
-
+ $amount = ($this->sub_total > 0) ? $this->item->line_total - ($this->invoice->discount * ( $this->item->line_total / $this->sub_total)) : 0;
+
$item_tax_rate1_total = $this->calcAmountLineTax($this->item->tax_rate1, $amount);
$item_tax += $item_tax_rate1_total;
@@ -424,9 +426,19 @@ class InvoiceItemSum
if ($item_tax_rate3_total != 0) {
$this->groupTax($this->item->tax_name3, $this->item->tax_rate3, $item_tax_rate3_total);
}
+
+ $this->item->gross_line_total = $this->getLineTotal() + $item_tax;
+ $this->item->tax_amount = $item_tax;
+
+ $this->line_items[$key] = $this->item;
+
+ $this->setTotalTaxes($this->getTotalTaxes() + $item_tax);
+
}
- $this->setTotalTaxes($item_tax);
+
+
+ return $this;
}
/**
diff --git a/app/Helpers/Invoice/InvoiceSum.php b/app/Helpers/Invoice/InvoiceSum.php
index 16687aed0298..3f32ed486f78 100644
--- a/app/Helpers/Invoice/InvoiceSum.php
+++ b/app/Helpers/Invoice/InvoiceSum.php
@@ -308,8 +308,9 @@ class InvoiceSum
public function setTaxMap(): self
{
- if ($this->invoice->is_amount_discount == true) {
+ if ($this->invoice->is_amount_discount) {
$this->invoice_items->calcTaxesWithAmountDiscount();
+ $this->invoice->line_items = $this->invoice_items->getLineItems();
}
$this->tax_map = collect();
@@ -327,8 +328,6 @@ class InvoiceSum
return $value['key'] == $key;
})->sum('total');
- //$total_line_tax -= $this->discount($total_line_tax);
-
$this->tax_map[] = ['name' => $tax_name, 'total' => $total_line_tax];
$this->total_taxes += $total_line_tax;
@@ -377,16 +376,6 @@ class InvoiceSum
public function purgeTaxes(): self
{
- // $this->tax_rate1 = 0;
- // $this->tax_name1 = '';
-
- // $this->tax_rate2 = 0;
- // $this->tax_name2 = '';
-
- // $this->tax_rate3 = 0;
- // $this->tax_name3 = '';
-
- // $this->discount = 0;
$line_items = collect($this->invoice->line_items);
diff --git a/app/Http/Controllers/Reports/InvoiceItemReportController.php b/app/Http/Controllers/Reports/InvoiceItemReportController.php
index dc568dfad629..a124171cc66e 100644
--- a/app/Http/Controllers/Reports/InvoiceItemReportController.php
+++ b/app/Http/Controllers/Reports/InvoiceItemReportController.php
@@ -80,7 +80,6 @@ class InvoiceItemReportController extends BaseController
return response()->json(['message' => $hash], 200);
}
-
$export = new InvoiceItemExport($user->company(), $request->all());
diff --git a/app/Http/Controllers/Reports/QuoteItemReportController.php b/app/Http/Controllers/Reports/QuoteItemReportController.php
index 66fb6c5a5fe1..78295f1ddc7c 100644
--- a/app/Http/Controllers/Reports/QuoteItemReportController.php
+++ b/app/Http/Controllers/Reports/QuoteItemReportController.php
@@ -11,12 +11,13 @@
namespace App\Http\Controllers\Reports;
+use Illuminate\Http\Response;
+use App\Utils\Traits\MakesHash;
+use App\Jobs\Report\SendToAdmin;
+use App\Jobs\Report\PreviewReport;
use App\Export\CSV\QuoteItemExport;
use App\Http\Controllers\BaseController;
use App\Http\Requests\Report\GenericReportRequest;
-use App\Jobs\Report\SendToAdmin;
-use App\Utils\Traits\MakesHash;
-use Illuminate\Http\Response;
class QuoteItemReportController extends BaseController
{
@@ -62,14 +63,26 @@ class QuoteItemReportController extends BaseController
*/
public function __invoke(GenericReportRequest $request)
{
+ /** @var \App\Models\User $user */
+ $user = auth()->user();
+
if ($request->has('send_email') && $request->get('send_email')) {
- SendToAdmin::dispatch(auth()->user()->company(), $request->all(), QuoteItemExport::class, $this->filename);
+ SendToAdmin::dispatch($user->company(), $request->all(), QuoteItemExport::class, $this->filename);
return response()->json(['message' => 'working...'], 200);
}
// expect a list of visible fields, or use the default
- $export = new QuoteItemExport(auth()->user()->company(), $request->all());
+ if($request->has('output') && $request->input('output') == 'json') {
+
+ $hash = \Illuminate\Support\Str::uuid();
+
+ PreviewReport::dispatch($user->company(), $request->all(), QuoteItemExport::class, $hash);
+
+ return response()->json(['message' => $hash], 200);
+ }
+
+ $export = new QuoteItemExport($user->company(), $request->all());
$csv = $export->run();
diff --git a/app/Http/Controllers/Reports/RecurringInvoiceReportController.php b/app/Http/Controllers/Reports/RecurringInvoiceReportController.php
index eaae55bd1351..26eb279106f2 100644
--- a/app/Http/Controllers/Reports/RecurringInvoiceReportController.php
+++ b/app/Http/Controllers/Reports/RecurringInvoiceReportController.php
@@ -11,12 +11,13 @@
namespace App\Http\Controllers\Reports;
-use App\Export\CSV\RecurringInvoiceExport;
-use App\Http\Controllers\BaseController;
-use App\Http\Requests\Report\GenericReportRequest;
-use App\Jobs\Report\SendToAdmin;
-use App\Utils\Traits\MakesHash;
use Illuminate\Http\Response;
+use App\Utils\Traits\MakesHash;
+use App\Jobs\Report\SendToAdmin;
+use App\Jobs\Report\PreviewReport;
+use App\Http\Controllers\BaseController;
+use App\Export\CSV\RecurringInvoiceExport;
+use App\Http\Requests\Report\GenericReportRequest;
class RecurringInvoiceReportController extends BaseController
{
@@ -31,14 +32,26 @@ class RecurringInvoiceReportController extends BaseController
public function __invoke(GenericReportRequest $request)
{
+ /** @var \App\Models\User $user */
+ $user = auth()->user();
+
if ($request->has('send_email') && $request->get('send_email')) {
- SendToAdmin::dispatch(auth()->user()->company(), $request->all(), RecurringInvoiceExport::class, $this->filename);
+ SendToAdmin::dispatch($user->company(), $request->all(), RecurringInvoiceExport::class, $this->filename);
return response()->json(['message' => 'working...'], 200);
}
// expect a list of visible fields, or use the default
- $export = new RecurringInvoiceExport(auth()->user()->company(), $request->all());
+ if($request->has('output') && $request->input('output') == 'json') {
+
+ $hash = \Illuminate\Support\Str::uuid();
+
+ PreviewReport::dispatch($user->company(), $request->all(), RecurringInvoiceExport::class, $hash);
+
+ return response()->json(['message' => $hash], 200);
+ }
+
+ $export = new RecurringInvoiceExport($user->company(), $request->all());
$csv = $export->run();
diff --git a/app/Http/Controllers/Reports/TaskReportController.php b/app/Http/Controllers/Reports/TaskReportController.php
index 5eff880c38de..8339a909bcb0 100644
--- a/app/Http/Controllers/Reports/TaskReportController.php
+++ b/app/Http/Controllers/Reports/TaskReportController.php
@@ -11,12 +11,13 @@
namespace App\Http\Controllers\Reports;
+use Illuminate\Http\Response;
use App\Export\CSV\TaskExport;
+use App\Utils\Traits\MakesHash;
+use App\Jobs\Report\SendToAdmin;
+use App\Jobs\Report\PreviewReport;
use App\Http\Controllers\BaseController;
use App\Http\Requests\Report\GenericReportRequest;
-use App\Jobs\Report\SendToAdmin;
-use App\Utils\Traits\MakesHash;
-use Illuminate\Http\Response;
class TaskReportController extends BaseController
{
@@ -62,14 +63,26 @@ class TaskReportController extends BaseController
*/
public function __invoke(GenericReportRequest $request)
{
+ /** @var \App\Models\User $user */
+ $user = auth()->user();
+
if ($request->has('send_email') && $request->get('send_email')) {
- SendToAdmin::dispatch(auth()->user()->company(), $request->all(), TaskExport::class, $this->filename);
+ SendToAdmin::dispatch($user->company(), $request->all(), TaskExport::class, $this->filename);
return response()->json(['message' => 'working...'], 200);
}
// expect a list of visible fields, or use the default
- $export = new TaskExport(auth()->user()->company(), $request->all());
+ if($request->has('output') && $request->input('output') == 'json') {
+
+ $hash = \Illuminate\Support\Str::uuid();
+
+ PreviewReport::dispatch($user->company(), $request->all(), TaskExport::class, $hash);
+
+ return response()->json(['message' => $hash], 200);
+ }
+
+ $export = new TaskExport($user->company(), $request->all());
$csv = $export->run();
diff --git a/app/Http/Controllers/Reports/VendorReportController.php b/app/Http/Controllers/Reports/VendorReportController.php
index 2494daadb923..bfd0f3b2298e 100644
--- a/app/Http/Controllers/Reports/VendorReportController.php
+++ b/app/Http/Controllers/Reports/VendorReportController.php
@@ -11,11 +11,12 @@
namespace App\Http\Controllers\Reports;
+use App\Utils\Traits\MakesHash;
use App\Export\CSV\VendorExport;
+use App\Jobs\Report\SendToAdmin;
+use App\Jobs\Report\PreviewReport;
use App\Http\Controllers\BaseController;
use App\Http\Requests\Report\GenericReportRequest;
-use App\Jobs\Report\SendToAdmin;
-use App\Utils\Traits\MakesHash;
class VendorReportController extends BaseController
{
@@ -30,14 +31,26 @@ class VendorReportController extends BaseController
public function __invoke(GenericReportRequest $request)
{
+ /** @var \App\Models\User $user */
+ $user = auth()->user();
+
if ($request->has('send_email') && $request->get('send_email')) {
- SendToAdmin::dispatch(auth()->user()->company(), $request->all(), VendorExport::class, $this->filename);
+ SendToAdmin::dispatch($user->company(), $request->all(), VendorExport::class, $this->filename);
return response()->json(['message' => 'working...'], 200);
}
// expect a list of visible fields, or use the default
- $export = new VendorExport(auth()->user()->company(), $request->all());
+ if($request->has('output') && $request->input('output') == 'json') {
+
+ $hash = \Illuminate\Support\Str::uuid();
+
+ PreviewReport::dispatch($user->company(), $request->all(), VendorExport::class, $hash);
+
+ return response()->json(['message' => $hash], 200);
+ }
+
+ $export = new VendorExport($user->company(), $request->all());
$csv = $export->run();
diff --git a/app/Http/Controllers/SearchController.php b/app/Http/Controllers/SearchController.php
index ca694e6103ab..fba7c9529439 100644
--- a/app/Http/Controllers/SearchController.php
+++ b/app/Http/Controllers/SearchController.php
@@ -46,7 +46,8 @@ class SearchController extends Controller
'name' => $client->present()->name(),
'type' => '/client',
'id' => $client->hashed_id,
- 'path' => "/clients/{$client->hashed_id}/edit"
+ 'path' => "/clients/{$client->hashed_id}/edit",
+ 'heading' => ctrans('texts.clients')
];
});
}
@@ -65,7 +66,8 @@ class SearchController extends Controller
'name' => $contact->present()->search_display(),
'type' => '/client_contact',
'id' => $contact->client->hashed_id,
- 'path' => "/clients/{$contact->client->hashed_id}"
+ 'path' => "/clients/{$contact->client->hashed_id}",
+ 'heading' => ctrans('texts.contacts')
];
});
}
@@ -84,7 +86,8 @@ class SearchController extends Controller
'name' => $invoice->client->present()->name() . ' - ' . $invoice->number,
'type' => '/invoice',
'id' => $invoice->hashed_id,
- 'path' => "/clients/{$invoice->hashed_id}/edit"
+ 'path' => "/clients/{$invoice->hashed_id}/edit",
+ 'heading' => ctrans('texts.invoices')
];
});
}
@@ -179,6 +182,7 @@ class SearchController extends Controller
'path' => $value,
'type' => $transkey,
'name' => $translation,
+ 'heading' => ctrans('texts.settings')
];
}
diff --git a/app/PaymentDrivers/CheckoutCom/CreditCard.php b/app/PaymentDrivers/CheckoutCom/CreditCard.php
index 116123e16796..8a0166eb0cdb 100644
--- a/app/PaymentDrivers/CheckoutCom/CreditCard.php
+++ b/app/PaymentDrivers/CheckoutCom/CreditCard.php
@@ -12,25 +12,25 @@
namespace App\PaymentDrivers\CheckoutCom;
-use App\Exceptions\PaymentFailed;
-use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest;
-use App\Jobs\Util\SystemLogger;
-use App\Models\ClientGatewayToken;
-use App\Models\GatewayType;
use App\Models\SystemLog;
-use App\PaymentDrivers\CheckoutComPaymentDriver;
-use App\PaymentDrivers\Common\MethodInterface;
+use Illuminate\View\View;
+use App\Models\GatewayType;
+use Illuminate\Http\Request;
+use App\Jobs\Util\SystemLogger;
use App\Utils\Traits\MakesHash;
+use App\Exceptions\PaymentFailed;
+use App\Models\ClientGatewayToken;
use Checkout\CheckoutApiException;
+use Illuminate\Contracts\View\Factory;
use Checkout\CheckoutArgumentException;
use Checkout\CheckoutAuthorizationException;
-use Checkout\Payments\Four\Request\PaymentRequest;
-use Checkout\Payments\Four\Request\Source\RequestTokenSource;
-use Checkout\Payments\PaymentRequest as PaymentsPaymentRequest;
-use Checkout\Payments\Source\RequestTokenSource as SourceRequestTokenSource;
-use Illuminate\Contracts\View\Factory;
-use Illuminate\Http\Request;
-use Illuminate\View\View;
+use Checkout\Payments\Request\PaymentRequest;
+use App\PaymentDrivers\Common\MethodInterface;
+use App\PaymentDrivers\CheckoutComPaymentDriver;
+use Checkout\Payments\Previous\Source\RequestTokenSource;
+use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest;
+use Checkout\Payments\Previous\PaymentRequest as PreviousPaymentRequest;
+use Checkout\Payments\Request\Source\RequestTokenSource as SourceRequestTokenSource;
class CreditCard implements MethodInterface
{
@@ -67,12 +67,12 @@ class CreditCard implements MethodInterface
if ($this->checkout->is_four_api) {
$token_source = new RequestTokenSource();
$token_source->token = $token;
- $request = new PaymentRequest();
+ $request = new PreviousPaymentRequest();
$request->source = $token_source;
} else {
$token_source = new SourceRequestTokenSource();
$token_source->token = $token;
- $request = new PaymentsPaymentRequest();
+ $request = new PaymentRequest();
$request->source = $token_source;
}
@@ -120,44 +120,24 @@ class CreditCard implements MethodInterface
return redirect()->route('client.payment_methods.show', $payment_method->hashed_id);
}
} catch (CheckoutApiException $e) {
- // API error
- $request_id = $e->request_id ?: '';
- $http_status_code = $e->http_status_code ?: '';
+
$error_details = $e->error_details;
- if (is_array($error_details)) {
+ if (isset($e->error_details['error_codes']) ?? false) {
$error_details = end($e->error_details['error_codes']);
}
+ else {
+ $error_details = $e->getMessage();
+ }
- $human_exception = $error_details ? $error_details : $e->getMessage();
-
- $human_exception = "{$human_exception} - Request ID: {$request_id}";
-
- throw new PaymentFailed($human_exception, $http_status_code);
+ throw new PaymentFailed($error_details, $e->getCode());
} catch (CheckoutArgumentException $e) {
// Bad arguments
-
- $error_details = $e->error_details;
-
- if (is_array($error_details)) {
- $error_details = end($e->error_details['error_codes']);
- }
-
- $human_exception = $error_details ? $error_details : $e->getMessage();
-
- throw new PaymentFailed($human_exception, 422);
+ throw new PaymentFailed($e->getMessage(), $e->getCode());
} catch (CheckoutAuthorizationException $e) {
// Bad Invalid authorization
-
- $error_details = $e->error_details;
-
- if (is_array($error_details)) {
- $error_details = end($e->error_details['error_codes']);
- }
- $human_exception = $error_details ? $error_details : $e->getMessage();
-
- throw new PaymentFailed($human_exception, 401);
+ throw new PaymentFailed("There is a problem with your Checkout Gateway API keys", 401);
}
}
@@ -280,8 +260,6 @@ class CreditCard implements MethodInterface
}
} catch (CheckoutApiException $e) {
// API error
- $request_id = $e->request_id;
- $http_status_code = $e->http_status_code;
$error_details = $e->error_details;
if (is_array($error_details)) {
@@ -293,7 +271,7 @@ class CreditCard implements MethodInterface
$human_exception = $error_details ? new \Exception($error_details, 400) : $e;
SystemLogger::dispatch(
- $human_exception->getMessage(),
+ $e->getMessage(),
SystemLog::CATEGORY_GATEWAY_RESPONSE,
SystemLog::EVENT_GATEWAY_ERROR,
SystemLog::TYPE_CHECKOUT,
@@ -304,19 +282,11 @@ class CreditCard implements MethodInterface
return $this->checkout->processInternallyFailedPayment($this->checkout, $human_exception);
} catch (CheckoutArgumentException $e) {
// Bad arguments
-
- $error_details = $e->error_details;
-
- if (is_array($error_details)) {
- $error_details = end($e->error_details['error_codes']);
- }
$this->checkout->unWindGatewayFees($this->checkout->payment_hash);
- $human_exception = $error_details ? new \Exception($error_details, 400) : $e;
-
SystemLogger::dispatch(
- $human_exception->getMessage(),
+ $e->getMessage(),
SystemLog::CATEGORY_GATEWAY_RESPONSE,
SystemLog::EVENT_GATEWAY_ERROR,
SystemLog::TYPE_CHECKOUT,
@@ -324,23 +294,15 @@ class CreditCard implements MethodInterface
$this->checkout->client->company,
);
- return $this->checkout->processInternallyFailedPayment($this->checkout, $human_exception);
+ return new PaymentFailed($e->getMessage(), $e->getCode());
+ // return $this->checkout->processInternallyFailedPayment($this->checkout, $human_exception);
} catch (CheckoutAuthorizationException $e) {
// Bad Invalid authorization
- $error_details = $e->error_details;
-
- if (is_array($error_details)) {
- $error_details = end($e->error_details['error_codes']);
- }
-
$this->checkout->unWindGatewayFees($this->checkout->payment_hash);
- $human_exception = $error_details ? new \Exception($error_details, 400) : $e;
-
-
SystemLogger::dispatch(
- $human_exception->getMessage(),
+ $e->getMessage(),
SystemLog::CATEGORY_GATEWAY_RESPONSE,
SystemLog::EVENT_GATEWAY_ERROR,
SystemLog::TYPE_CHECKOUT,
@@ -348,7 +310,9 @@ class CreditCard implements MethodInterface
$this->checkout->client->company,
);
- return $this->checkout->processInternallyFailedPayment($this->checkout, $human_exception);
+ return new PaymentFailed("There was a problem communicating with the API credentials for Checkout", $e->getCode());
+
+ // return $this->checkout->processInternallyFailedPayment($this->checkout, $human_exception);
}
}
}
diff --git a/app/PaymentDrivers/CheckoutCom/Utilities.php b/app/PaymentDrivers/CheckoutCom/Utilities.php
index ef37688c305a..860240e0a596 100644
--- a/app/PaymentDrivers/CheckoutCom/Utilities.php
+++ b/app/PaymentDrivers/CheckoutCom/Utilities.php
@@ -94,6 +94,16 @@ trait Utilities
$error_message = 'Error processing payment.';
}
+ if(isset($_payment['actions'][0]['response_summary']) ?? false) {
+ $error_message = $_payment['actions'][0]['response_summary'];
+ }
+
+ if(isset($_payment['actions'][0]['response_code']) ?? false) {
+ $error_code = $_payment['actions'][0]['response_code'];
+ }
+ else
+ $error_code = 400;
+
$this->getParent()->sendFailureMail($error_message);
$message = [
@@ -111,7 +121,7 @@ trait Utilities
);
if ($throw_exception) {
- throw new PaymentFailed($error_message, 500);
+ throw new PaymentFailed($error_message, $error_code);
}
}
diff --git a/app/PaymentDrivers/CheckoutComPaymentDriver.php b/app/PaymentDrivers/CheckoutComPaymentDriver.php
index bfeee03569d9..103220c63d6d 100644
--- a/app/PaymentDrivers/CheckoutComPaymentDriver.php
+++ b/app/PaymentDrivers/CheckoutComPaymentDriver.php
@@ -25,29 +25,28 @@ use App\Models\Payment;
use App\Models\PaymentHash;
use App\Models\PaymentType;
use App\Models\SystemLog;
+use App\PaymentDrivers\CheckoutCom\CheckoutWebhook;
use App\PaymentDrivers\CheckoutCom\CreditCard;
use App\PaymentDrivers\CheckoutCom\Utilities;
-use App\PaymentDrivers\CheckoutCom\CheckoutWebhook;
use App\Utils\Traits\SystemLogTrait;
-use Checkout\CheckoutApi;
use Checkout\CheckoutApiException;
use Checkout\CheckoutArgumentException;
use Checkout\CheckoutAuthorizationException;
-use Checkout\CheckoutDefaultSdk;
-use Checkout\CheckoutFourSdk;
+use Checkout\CheckoutSdk;
use Checkout\Common\Phone;
use Checkout\Customers\CustomerRequest;
-use Checkout\Customers\Four\CustomerRequest as FourCustomerRequest;
use Checkout\Environment;
-use Checkout\Models\Payments\Refund;
-use Checkout\Payments\Four\Request\PaymentRequest;
-use Checkout\Payments\Four\Request\Source\RequestIdSource as SourceRequestIdSource;
-use Checkout\Payments\PaymentRequest as PaymentsPaymentRequest;
+use Checkout\Payments\Previous\PaymentRequest as PreviousPaymentRequest;
+use Checkout\Payments\Previous\Source\RequestIdSource as SourceRequestIdSource;
use Checkout\Payments\RefundRequest;
-use Checkout\Payments\Source\RequestIdSource;
+use Checkout\Payments\Request\PaymentRequest;
+use Checkout\Payments\Request\Source\RequestIdSource;
use Exception;
use Illuminate\Support\Facades\Auth;
+//use Checkout\Customers\Four\CustomerRequest as FourCustomerRequest;
+//use Checkout\Payments\Four\Request\Source\RequestIdSource as SourceRequestIdSource;
+
class CheckoutComPaymentDriver extends BaseDriver
{
use SystemLogTrait, Utilities;
@@ -70,7 +69,7 @@ class CheckoutComPaymentDriver extends BaseDriver
public $is_four_api = false;
/**
- * @var CheckoutApi;
+ * @var CheckoutSdk;
*/
public $gateway;
@@ -117,45 +116,61 @@ class CheckoutComPaymentDriver extends BaseDriver
*/
public function init()
{
- $config = [
- 'secret' => $this->company_gateway->getConfigField('secretApiKey'),
- 'public' => $this->company_gateway->getConfigField('publicApiKey'),
- 'sandbox' => $this->company_gateway->getConfigField('testMode'),
- ];
- if (strlen($config['secret']) <= 38) {
- $this->is_four_api = true;
- $builder = CheckoutFourSdk::staticKeys();
- $builder->setPublicKey($config['public']); // optional, only required for operations related with tokens
- $builder->setSecretKey($config['secret']);
- $builder->setEnvironment($config['sandbox'] ? Environment::sandbox() : Environment::production());
+ if (str_contains($this->company_gateway->getConfigField('secretApiKey'), '-')) {
+
+ $this->is_four_api = true; //was four api, now known as previous.
+
+ $builder = CheckoutSdk::builder()
+ ->previous()
+ ->staticKeys()
+ ->environment($this->company_gateway->getConfigField('testMode') ? Environment::sandbox() : Environment::production())
+ ->publicKey($this->company_gateway->getConfigField('publicApiKey'))
+ ->secretKey($this->company_gateway->getConfigField('secretApiKey'));
+
$this->gateway = $builder->build();
+
} else {
- $builder = CheckoutDefaultSdk::staticKeys();
- $builder->setPublicKey($config['public']); // optional, only required for operations related with tokens
- $builder->setSecretKey($config['secret']);
- $builder->setEnvironment($config['sandbox'] ? Environment::sandbox() : Environment::production());
- $this->gateway = $builder->build();
- }
+
+ $builder = CheckoutSdk::builder()->staticKeys()
+ ->publicKey($this->company_gateway->getConfigField('publicApiKey'))
+ ->secretKey($this->company_gateway->getConfigField('secretApiKey'))
+ ->environment($this->company_gateway->getConfigField('testMode') ? Environment::sandbox() : Environment::production());
+ $this->gateway = $builder->build();
+
+ }
return $this;
}
/**
* Process different view depending on payment type
+ *
* @param int $gateway_type_id The gateway type
- * @return string The view string
+ * @return string The view string
*/
public function viewForType($gateway_type_id)
{
return 'gateways.checkout.credit_card.pay';
}
-
+
+ /**
+ * Authorize View
+ *
+ * @param array $data
+ * @return \Illuminate\View\View
+ */
public function authorizeView($data)
{
return $this->payment_method->authorizeView($data);
}
-
+
+ /**
+ * Authorize Response
+ *
+ * @param array $data
+ * @return \Illuminate\View\View
+ */
public function authorizeResponse($data)
{
return $this->payment_method->authorizeResponse($data);
@@ -165,7 +180,7 @@ class CheckoutComPaymentDriver extends BaseDriver
* Payment View
*
* @param array $data Payment data array
- * @return \Illuminate\View\View
+ * @return \Illuminate\View\View
*/
public function processPaymentView(array $data)
{
@@ -176,13 +191,19 @@ class CheckoutComPaymentDriver extends BaseDriver
* Process the payment response
*
* @param \Illuminate\Http\Request $request The payment request
- * @return \Illuminate\View\View
+ * @return \Illuminate\View\View
*/
public function processPaymentResponse($request)
{
return $this->payment_method->paymentResponse($request);
}
-
+
+ /**
+ * Store PaymentMethod
+ *
+ * @param array $data
+ * @return ?ClientGatewayToken $token
+ */
public function storePaymentMethod(array $data)
{
return $this->storeGatewayToken($data);
@@ -197,7 +218,7 @@ class CheckoutComPaymentDriver extends BaseDriver
$request->amount = $this->convertToCheckoutAmount($amount, $this->client->getCurrencyCode());
try {
- // or, refundPayment("payment_id") for a full refund
+
$response = $this->gateway->getPaymentsClient()->refundPayment($payment->transaction_reference, $request);
return [
@@ -213,7 +234,7 @@ class CheckoutComPaymentDriver extends BaseDriver
} catch (CheckoutArgumentException $e) {
// Bad arguments
- throw new PaymentFailed($e->getMessage(), $e->getCode());
+ // throw new PaymentFailed($e->getMessage(), $e->getCode());
return [
'transaction_reference' => null,
@@ -223,9 +244,8 @@ class CheckoutComPaymentDriver extends BaseDriver
'code' => $e->getCode(),
];
} catch (CheckoutAuthorizationException $e) {
- // Bad Invalid authorization
- throw new PaymentFailed($e->getMessage(), $e->getCode());
+ // throw new PaymentFailed("The was a problem with the Checkout Gateway Credentials.", $e->getCode());
return [
'transaction_reference' => null,
@@ -244,12 +264,9 @@ class CheckoutComPaymentDriver extends BaseDriver
return $response;
} catch (\Exception $e) {
- if ($this->is_four_api) {
- $request = new FourCustomerRequest();
- } else {
- $request = new CustomerRequest();
- }
-
+
+ $request = new CustomerRequest();
+
$phone = new Phone();
// $phone->number = $this->client->present()->phone();
$phone->number = substr(str_pad($this->client->present()->phone(), 6, "0", STR_PAD_RIGHT), 0, 24);
@@ -262,59 +279,45 @@ class CheckoutComPaymentDriver extends BaseDriver
$response = $this->gateway->getCustomersClient()->create($request);
} catch (CheckoutApiException $e) {
// API error
- $request_id = $e->request_id;
- $http_status_code = $e->http_status_code;
$error_details = $e->error_details;
- if (is_array($error_details)) {
+ if (isset($error_details['error_codes']) ?? false) {
$error_details = end($e->error_details['error_codes']);
+ } else {
+ $error_details = $e->getMessage();
}
- $human_exception = $error_details ? new \Exception($error_details, 400) : $e;
-
-
- throw new PaymentFailed($human_exception);
+ throw new PaymentFailed($error_details, 400);
} catch (CheckoutArgumentException $e) {
- // Bad arguments
- $error_details = $e->error_details;
-
- if (is_array($error_details)) {
- $error_details = end($e->error_details['error_codes']);
- }
-
- $human_exception = $error_details ? new \Exception($error_details, 400) : $e;
-
- throw new PaymentFailed($human_exception);
+ throw new PaymentFailed($e->getMessage(), $e->getCode());
} catch (CheckoutAuthorizationException $e) {
// Bad Invalid authorization
-
- $error_details = $e->error_details;
-
- if (is_array($error_details)) {
- $error_details = end($e->error_details['error_codes']);
- }
- $human_exception = $error_details ? new \Exception($error_details, 400) : $e;
-
- throw new PaymentFailed($human_exception);
+ throw new PaymentFailed("Checkout Gateway credentials are invalid", 400);
}
return $response;
}
}
-
+
+ /**
+ * Boots a request for a token payment
+ *
+ * @param string $token
+ * @return PreviousPaymentRequest | PaymentRequest
+ */
public function bootTokenRequest($token)
{
if ($this->is_four_api) {
$token_source = new SourceRequestIdSource();
$token_source->id = $token;
- $request = new PaymentRequest();
+ $request = new PreviousPaymentRequest();
$request->source = $token_source;
} else {
$token_source = new RequestIdSource();
$token_source->id = $token;
- $request = new PaymentsPaymentRequest();
+ $request = new PaymentRequest();
$request->source = $token_source;
}
@@ -325,6 +328,8 @@ class CheckoutComPaymentDriver extends BaseDriver
{
$amount = array_sum(array_column($payment_hash->invoices(), 'amount')) + $payment_hash->fee_total;
$invoice = Invoice::query()->whereIn('id', $this->transformKeys(array_column($payment_hash->invoices(), 'invoice_id')))->withTrashed()->first();
+ $this->client = $invoice->client;
+ $this->payment_hash = $payment_hash;
$this->init();
@@ -340,7 +345,6 @@ class CheckoutComPaymentDriver extends BaseDriver
$request->request->add(['payment_hash' => $payment_hash->hash]);
try {
- // $response = $this->gateway->payments()->request($payment);
$response = $this->gateway->getPaymentsClient()->requestPayment($paymentRequest);
if ($response['status'] == 'Authorized') {
@@ -386,25 +390,27 @@ class CheckoutComPaymentDriver extends BaseDriver
return false;
}
- } catch (Exception | CheckoutApiException $e) {
+ } catch (CheckoutApiException $e) {
+
$this->unWindGatewayFees($payment_hash);
- $message = $e->getMessage();
- $error_details = '';
+ $error_details = $e->error_details;
- if (property_exists($e, 'error_details')) {
- $error_details = $e->error_details;
+ if (isset($error_details['error_codes']) ?? false) {
+ $error_details = end($e->error_details['error_codes']);
+ } else {
+ $error_details = $e->getMessage();
}
-
+
$data = [
'status' => $e->error_details,
'error_type' => '',
'error_code' => $e->getCode(),
'param' => '',
- 'message' => $message,
+ 'message' => $e->getMessage(),
];
- $this->sendFailureMail($message);
+ $this->sendFailureMail($e->getMessage());
SystemLogger::dispatch(
$data,
@@ -425,8 +431,7 @@ class CheckoutComPaymentDriver extends BaseDriver
if($request->header('cko-signature') == hash_hmac('sha256', $webhook_payload, $this->company_gateway->company->company_key)) {
CheckoutWebhook::dispatch($request->all(), $request->company_key, $this->company_gateway->id)->delay(10);
- }
- else {
+ } else {
nlog("Hash Mismatch = {$request->header('cko-signature')} ".hash_hmac('sha256', $webhook_payload, $this->company_gateway->company->company_key));
nlog($request->all());
}
@@ -442,6 +447,7 @@ class CheckoutComPaymentDriver extends BaseDriver
//11-08-2022 check the user is authenticated
if (!Auth::guard('contact')->check()) {
$client = $request->getClient();
+ $this->client = $client;
auth()->guard('contact')->loginUsingId($client->contacts()->first()->id, true);
}
diff --git a/app/Services/Payment/RefundPayment.php b/app/Services/Payment/RefundPayment.php
index 007f1df6efbf..b5b67358abcf 100644
--- a/app/Services/Payment/RefundPayment.php
+++ b/app/Services/Payment/RefundPayment.php
@@ -88,7 +88,7 @@ class RefundPayment
/**
* Process the refund through the gateway.
*
- * @var array $response
+ * $response
* [
* 'transaction_reference' => (string),
* 'transaction_response' => (string),
diff --git a/app/Services/Quote/ConvertQuoteToProject.php b/app/Services/Quote/ConvertQuoteToProject.php
index 6b1b642cd16a..59227fcfc566 100644
--- a/app/Services/Quote/ConvertQuoteToProject.php
+++ b/app/Services/Quote/ConvertQuoteToProject.php
@@ -36,7 +36,7 @@ class ConvertQuoteToProject
});
$project = ProjectFactory::create($this->quote->company_id, $this->quote->user_id);
- $project->name = ctrans('texts.quote_number_short'). " " . $this->quote->number . "[{$this->quote->client->present()->name()}]";
+ $project->name = ctrans('texts.quote_number_short'). " " . $this->quote->number . " [{$this->quote->client->present()->name()}]";
$project->client_id = $this->quote->client_id;
$project->public_notes = $this->quote->public_notes;
$project->private_notes = $this->quote->private_notes;
diff --git a/composer.lock b/composer.lock
index fb13b2f575ac..ba232aa837fc 100644
--- a/composer.lock
+++ b/composer.lock
@@ -525,16 +525,16 @@
},
{
"name": "aws/aws-sdk-php",
- "version": "3.280.2",
+ "version": "3.281.4",
"source": {
"type": "git",
"url": "https://github.com/aws/aws-sdk-php.git",
- "reference": "d68b83b3bc39b70bf33e9b8b5166facbe3e4fe9b"
+ "reference": "c37035bcfb67a9d54f91dae303b3fe8f98ea59f4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/d68b83b3bc39b70bf33e9b8b5166facbe3e4fe9b",
- "reference": "d68b83b3bc39b70bf33e9b8b5166facbe3e4fe9b",
+ "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/c37035bcfb67a9d54f91dae303b3fe8f98ea59f4",
+ "reference": "c37035bcfb67a9d54f91dae303b3fe8f98ea59f4",
"shasum": ""
},
"require": {
@@ -614,9 +614,9 @@
"support": {
"forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80",
"issues": "https://github.com/aws/aws-sdk-php/issues",
- "source": "https://github.com/aws/aws-sdk-php/tree/3.280.2"
+ "source": "https://github.com/aws/aws-sdk-php/tree/3.281.4"
},
- "time": "2023-09-01T18:06:10+00:00"
+ "time": "2023-09-11T18:07:49+00:00"
},
{
"name": "bacon/bacon-qr-code",
@@ -830,16 +830,16 @@
},
{
"name": "checkout/checkout-sdk-php",
- "version": "3.0.13",
+ "version": "3.0.14",
"source": {
"type": "git",
"url": "https://github.com/checkout/checkout-sdk-php.git",
- "reference": "09f50d3df10f99681b535b53c395d2ee1ddab22b"
+ "reference": "e8a34d34abac3fb6e7b2227731eb2e75f6ff036f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/checkout/checkout-sdk-php/zipball/09f50d3df10f99681b535b53c395d2ee1ddab22b",
- "reference": "09f50d3df10f99681b535b53c395d2ee1ddab22b",
+ "url": "https://api.github.com/repos/checkout/checkout-sdk-php/zipball/e8a34d34abac3fb6e7b2227731eb2e75f6ff036f",
+ "reference": "e8a34d34abac3fb6e7b2227731eb2e75f6ff036f",
"shasum": ""
},
"require": {
@@ -892,9 +892,9 @@
],
"support": {
"issues": "https://github.com/checkout/checkout-sdk-php/issues",
- "source": "https://github.com/checkout/checkout-sdk-php/tree/3.0.13"
+ "source": "https://github.com/checkout/checkout-sdk-php/tree/3.0.14"
},
- "time": "2023-06-09T09:09:30+00:00"
+ "time": "2023-09-07T11:00:14+00:00"
},
{
"name": "cleverit/ubl_invoice",
@@ -2586,16 +2586,16 @@
},
{
"name": "google/apiclient-services",
- "version": "v0.314.0",
+ "version": "v0.315.0",
"source": {
"type": "git",
"url": "https://github.com/googleapis/google-api-php-client-services.git",
- "reference": "fe2f7513dc5a4a6cf82715fd0edf7589423d6535"
+ "reference": "9fe675be642888cded64be861891901f092ab72d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/fe2f7513dc5a4a6cf82715fd0edf7589423d6535",
- "reference": "fe2f7513dc5a4a6cf82715fd0edf7589423d6535",
+ "url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/9fe675be642888cded64be861891901f092ab72d",
+ "reference": "9fe675be642888cded64be861891901f092ab72d",
"shasum": ""
},
"require": {
@@ -2624,22 +2624,22 @@
],
"support": {
"issues": "https://github.com/googleapis/google-api-php-client-services/issues",
- "source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.314.0"
+ "source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.315.0"
},
- "time": "2023-09-03T01:04:12+00:00"
+ "time": "2023-09-10T01:10:37+00:00"
},
{
"name": "google/auth",
- "version": "v1.29.1",
+ "version": "v1.30.0",
"source": {
"type": "git",
"url": "https://github.com/googleapis/google-auth-library-php.git",
- "reference": "f199ed635b945e5adfd3c1a203543d8d86aff239"
+ "reference": "6028b072aa444d7edecbed603431322026704627"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/googleapis/google-auth-library-php/zipball/f199ed635b945e5adfd3c1a203543d8d86aff239",
- "reference": "f199ed635b945e5adfd3c1a203543d8d86aff239",
+ "url": "https://api.github.com/repos/googleapis/google-auth-library-php/zipball/6028b072aa444d7edecbed603431322026704627",
+ "reference": "6028b072aa444d7edecbed603431322026704627",
"shasum": ""
},
"require": {
@@ -2682,9 +2682,9 @@
"support": {
"docs": "https://googleapis.github.io/google-auth-library-php/main/",
"issues": "https://github.com/googleapis/google-auth-library-php/issues",
- "source": "https://github.com/googleapis/google-auth-library-php/tree/v1.29.1"
+ "source": "https://github.com/googleapis/google-auth-library-php/tree/v1.30.0"
},
- "time": "2023-08-23T08:49:35+00:00"
+ "time": "2023-09-07T19:13:44+00:00"
},
{
"name": "graham-campbell/result-type",
@@ -4331,16 +4331,16 @@
},
{
"name": "laravel/framework",
- "version": "v10.21.0",
+ "version": "v10.22.0",
"source": {
"type": "git",
"url": "https://github.com/laravel/framework.git",
- "reference": "96b15c7ac382a9adb4a56d40c640e782d669a112"
+ "reference": "9234388a895206d4e1df37342b61adc67e5c5d31"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laravel/framework/zipball/96b15c7ac382a9adb4a56d40c640e782d669a112",
- "reference": "96b15c7ac382a9adb4a56d40c640e782d669a112",
+ "url": "https://api.github.com/repos/laravel/framework/zipball/9234388a895206d4e1df37342b61adc67e5c5d31",
+ "reference": "9234388a895206d4e1df37342b61adc67e5c5d31",
"shasum": ""
},
"require": {
@@ -4527,7 +4527,7 @@
"issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework"
},
- "time": "2023-08-29T13:55:56+00:00"
+ "time": "2023-09-05T13:20:01+00:00"
},
{
"name": "laravel/prompts",
@@ -4700,16 +4700,16 @@
},
{
"name": "laravel/socialite",
- "version": "v5.8.1",
+ "version": "v5.9.0",
"source": {
"type": "git",
"url": "https://github.com/laravel/socialite.git",
- "reference": "9989b4530331597fae811bca240bf4e8f15e804b"
+ "reference": "14acfa3262875f180fba51efe3c7aaa089a9ef24"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laravel/socialite/zipball/9989b4530331597fae811bca240bf4e8f15e804b",
- "reference": "9989b4530331597fae811bca240bf4e8f15e804b",
+ "url": "https://api.github.com/repos/laravel/socialite/zipball/14acfa3262875f180fba51efe3c7aaa089a9ef24",
+ "reference": "14acfa3262875f180fba51efe3c7aaa089a9ef24",
"shasum": ""
},
"require": {
@@ -4766,7 +4766,7 @@
"issues": "https://github.com/laravel/socialite/issues",
"source": "https://github.com/laravel/socialite"
},
- "time": "2023-08-21T13:06:52+00:00"
+ "time": "2023-09-05T15:20:21+00:00"
},
{
"name": "laravel/tinker",
@@ -5315,16 +5315,16 @@
},
{
"name": "league/flysystem",
- "version": "3.15.1",
+ "version": "3.16.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/flysystem.git",
- "reference": "a141d430414fcb8bf797a18716b09f759a385bed"
+ "reference": "4fdf372ca6b63c6e281b1c01a624349ccb757729"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/a141d430414fcb8bf797a18716b09f759a385bed",
- "reference": "a141d430414fcb8bf797a18716b09f759a385bed",
+ "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/4fdf372ca6b63c6e281b1c01a624349ccb757729",
+ "reference": "4fdf372ca6b63c6e281b1c01a624349ccb757729",
"shasum": ""
},
"require": {
@@ -5333,6 +5333,8 @@
"php": "^8.0.2"
},
"conflict": {
+ "async-aws/core": "<1.19.0",
+ "async-aws/s3": "<1.14.0",
"aws/aws-sdk-php": "3.209.31 || 3.210.0",
"guzzlehttp/guzzle": "<7.0",
"guzzlehttp/ringphp": "<1.1.1",
@@ -5352,7 +5354,7 @@
"microsoft/azure-storage-blob": "^1.1",
"phpseclib/phpseclib": "^3.0.14",
"phpstan/phpstan": "^0.12.26",
- "phpunit/phpunit": "^9.5.11",
+ "phpunit/phpunit": "^9.5.11|^10.0",
"sabre/dav": "^4.3.1"
},
"type": "library",
@@ -5387,7 +5389,7 @@
],
"support": {
"issues": "https://github.com/thephpleague/flysystem/issues",
- "source": "https://github.com/thephpleague/flysystem/tree/3.15.1"
+ "source": "https://github.com/thephpleague/flysystem/tree/3.16.0"
},
"funding": [
{
@@ -5399,20 +5401,20 @@
"type": "github"
}
],
- "time": "2023-05-04T09:04:26+00:00"
+ "time": "2023-09-07T19:22:17+00:00"
},
{
"name": "league/flysystem-aws-s3-v3",
- "version": "3.15.0",
+ "version": "3.16.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/flysystem-aws-s3-v3.git",
- "reference": "d8de61ee10b6a607e7996cff388c5a3a663e8c8a"
+ "reference": "ded9ba346bb01cb9cc4cc7f2743c2c0e14d18e1c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/thephpleague/flysystem-aws-s3-v3/zipball/d8de61ee10b6a607e7996cff388c5a3a663e8c8a",
- "reference": "d8de61ee10b6a607e7996cff388c5a3a663e8c8a",
+ "url": "https://api.github.com/repos/thephpleague/flysystem-aws-s3-v3/zipball/ded9ba346bb01cb9cc4cc7f2743c2c0e14d18e1c",
+ "reference": "ded9ba346bb01cb9cc4cc7f2743c2c0e14d18e1c",
"shasum": ""
},
"require": {
@@ -5453,7 +5455,7 @@
],
"support": {
"issues": "https://github.com/thephpleague/flysystem-aws-s3-v3/issues",
- "source": "https://github.com/thephpleague/flysystem-aws-s3-v3/tree/3.15.0"
+ "source": "https://github.com/thephpleague/flysystem-aws-s3-v3/tree/3.16.0"
},
"funding": [
{
@@ -5465,20 +5467,20 @@
"type": "github"
}
],
- "time": "2023-05-02T20:02:14+00:00"
+ "time": "2023-08-30T10:14:57+00:00"
},
{
"name": "league/flysystem-local",
- "version": "3.15.0",
+ "version": "3.16.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/flysystem-local.git",
- "reference": "543f64c397fefdf9cfeac443ffb6beff602796b3"
+ "reference": "ec7383f25642e6fd4bb0c9554fc2311245391781"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/543f64c397fefdf9cfeac443ffb6beff602796b3",
- "reference": "543f64c397fefdf9cfeac443ffb6beff602796b3",
+ "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/ec7383f25642e6fd4bb0c9554fc2311245391781",
+ "reference": "ec7383f25642e6fd4bb0c9554fc2311245391781",
"shasum": ""
},
"require": {
@@ -5513,7 +5515,7 @@
],
"support": {
"issues": "https://github.com/thephpleague/flysystem-local/issues",
- "source": "https://github.com/thephpleague/flysystem-local/tree/3.15.0"
+ "source": "https://github.com/thephpleague/flysystem-local/tree/3.16.0"
},
"funding": [
{
@@ -5525,7 +5527,7 @@
"type": "github"
}
],
- "time": "2023-05-02T20:02:14+00:00"
+ "time": "2023-08-30T10:23:59+00:00"
},
{
"name": "league/fractal",
@@ -5867,16 +5869,16 @@
},
{
"name": "microsoft/microsoft-graph",
- "version": "1.105.0",
+ "version": "1.106.0",
"source": {
"type": "git",
"url": "https://github.com/microsoftgraph/msgraph-sdk-php.git",
- "reference": "d137bb44a1f4ec949c814471ee94265db002fc2c"
+ "reference": "a9f43d74131bb13cb1b5a999101d486b26601b8f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/microsoftgraph/msgraph-sdk-php/zipball/d137bb44a1f4ec949c814471ee94265db002fc2c",
- "reference": "d137bb44a1f4ec949c814471ee94265db002fc2c",
+ "url": "https://api.github.com/repos/microsoftgraph/msgraph-sdk-php/zipball/a9f43d74131bb13cb1b5a999101d486b26601b8f",
+ "reference": "a9f43d74131bb13cb1b5a999101d486b26601b8f",
"shasum": ""
},
"require": {
@@ -5913,9 +5915,9 @@
"homepage": "https://developer.microsoft.com/en-us/graph",
"support": {
"issues": "https://github.com/microsoftgraph/msgraph-sdk-php/issues",
- "source": "https://github.com/microsoftgraph/msgraph-sdk-php/tree/1.105.0"
+ "source": "https://github.com/microsoftgraph/msgraph-sdk-php/tree/1.106.0"
},
- "time": "2023-08-22T13:28:28+00:00"
+ "time": "2023-09-08T06:02:27+00:00"
},
{
"name": "mollie/mollie-api-php",
@@ -6403,16 +6405,16 @@
},
{
"name": "nesbot/carbon",
- "version": "2.69.0",
+ "version": "2.70.0",
"source": {
"type": "git",
"url": "https://github.com/briannesbitt/Carbon.git",
- "reference": "4308217830e4ca445583a37d1bf4aff4153fa81c"
+ "reference": "d3298b38ea8612e5f77d38d1a99438e42f70341d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/4308217830e4ca445583a37d1bf4aff4153fa81c",
- "reference": "4308217830e4ca445583a37d1bf4aff4153fa81c",
+ "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/d3298b38ea8612e5f77d38d1a99438e42f70341d",
+ "reference": "d3298b38ea8612e5f77d38d1a99438e42f70341d",
"shasum": ""
},
"require": {
@@ -6505,7 +6507,7 @@
"type": "tidelift"
}
],
- "time": "2023-08-03T09:00:52+00:00"
+ "time": "2023-09-07T16:43:50+00:00"
},
{
"name": "nette/schema",
@@ -7366,6 +7368,7 @@
"issues": "https://github.com/PayFast/payfast-php-sdk/issues",
"source": "https://github.com/PayFast/payfast-php-sdk/tree/v1.1.4"
},
+ "abandoned": true,
"time": "2022-12-20T10:39:51+00:00"
},
{
@@ -8169,16 +8172,16 @@
},
{
"name": "phpstan/phpdoc-parser",
- "version": "1.23.1",
+ "version": "1.24.0",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpdoc-parser.git",
- "reference": "846ae76eef31c6d7790fac9bc399ecee45160b26"
+ "reference": "3510b0a6274cc42f7219367cb3abfc123ffa09d6"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/846ae76eef31c6d7790fac9bc399ecee45160b26",
- "reference": "846ae76eef31c6d7790fac9bc399ecee45160b26",
+ "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/3510b0a6274cc42f7219367cb3abfc123ffa09d6",
+ "reference": "3510b0a6274cc42f7219367cb3abfc123ffa09d6",
"shasum": ""
},
"require": {
@@ -8210,9 +8213,9 @@
"description": "PHPDoc parser with support for nullable, intersection and generic types",
"support": {
"issues": "https://github.com/phpstan/phpdoc-parser/issues",
- "source": "https://github.com/phpstan/phpdoc-parser/tree/1.23.1"
+ "source": "https://github.com/phpstan/phpdoc-parser/tree/1.24.0"
},
- "time": "2023-08-03T16:32:59+00:00"
+ "time": "2023-09-07T20:46:32+00:00"
},
{
"name": "pragmarx/google2fa",
@@ -9152,16 +9155,16 @@
},
{
"name": "razorpay/razorpay",
- "version": "2.8.6",
+ "version": "2.8.7",
"source": {
"type": "git",
"url": "https://github.com/razorpay/razorpay-php.git",
- "reference": "c151dadbb3d0a64d92574e9789b970196e629cac"
+ "reference": "2180c8c3c39678623f5cb8f639c39a706de14c44"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/razorpay/razorpay-php/zipball/c151dadbb3d0a64d92574e9789b970196e629cac",
- "reference": "c151dadbb3d0a64d92574e9789b970196e629cac",
+ "url": "https://api.github.com/repos/razorpay/razorpay-php/zipball/2180c8c3c39678623f5cb8f639c39a706de14c44",
+ "reference": "2180c8c3c39678623f5cb8f639c39a706de14c44",
"shasum": ""
},
"require": {
@@ -9213,20 +9216,20 @@
"issues": "https://github.com/Razorpay/razorpay-php/issues",
"source": "https://github.com/Razorpay/razorpay-php"
},
- "time": "2023-06-16T10:31:14+00:00"
+ "time": "2023-09-11T08:31:26+00:00"
},
{
"name": "rmccue/requests",
- "version": "v2.0.7",
+ "version": "v2.0.8",
"source": {
"type": "git",
"url": "https://github.com/WordPress/Requests.git",
- "reference": "e14a6f4e7438d3f8da3f2657759e6367b906ee23"
+ "reference": "fae75bcb83d9d00d0e31ee86a472a036f9f91519"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/WordPress/Requests/zipball/e14a6f4e7438d3f8da3f2657759e6367b906ee23",
- "reference": "e14a6f4e7438d3f8da3f2657759e6367b906ee23",
+ "url": "https://api.github.com/repos/WordPress/Requests/zipball/fae75bcb83d9d00d0e31ee86a472a036f9f91519",
+ "reference": "fae75bcb83d9d00d0e31ee86a472a036f9f91519",
"shasum": ""
},
"require": {
@@ -9244,6 +9247,12 @@
"wp-coding-standards/wpcs": "^2.0",
"yoast/phpunit-polyfills": "^1.0.0"
},
+ "suggest": {
+ "art4/requests-psr18-adapter": "For using Requests as a PSR-18 HTTP Client",
+ "ext-curl": "For improved performance",
+ "ext-openssl": "For secure transport support",
+ "ext-zlib": "For improved performance when decompressing encoded streams"
+ },
"type": "library",
"autoload": {
"files": [
@@ -9294,7 +9303,7 @@
"issues": "https://github.com/WordPress/Requests/issues",
"source": "https://github.com/WordPress/Requests"
},
- "time": "2023-06-02T07:35:42+00:00"
+ "time": "2023-09-11T08:27:57+00:00"
},
{
"name": "sabre/uri",
@@ -9583,16 +9592,16 @@
},
{
"name": "sentry/sentry-laravel",
- "version": "3.7.3",
+ "version": "3.8.0",
"source": {
"type": "git",
"url": "https://github.com/getsentry/sentry-laravel.git",
- "reference": "2aee4ad217be8ef04ffcde6e9f7dd17af5a3b0bf"
+ "reference": "c7e7611553f9f90af10ed98dde1a680220f02e4d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/getsentry/sentry-laravel/zipball/2aee4ad217be8ef04ffcde6e9f7dd17af5a3b0bf",
- "reference": "2aee4ad217be8ef04ffcde6e9f7dd17af5a3b0bf",
+ "url": "https://api.github.com/repos/getsentry/sentry-laravel/zipball/c7e7611553f9f90af10ed98dde1a680220f02e4d",
+ "reference": "c7e7611553f9f90af10ed98dde1a680220f02e4d",
"shasum": ""
},
"require": {
@@ -9605,6 +9614,7 @@
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^3.11",
+ "laravel/folio": "^1.0",
"laravel/framework": "^6.0 | ^7.0 | ^8.0 | ^9.0 | ^10.0",
"mockery/mockery": "^1.3",
"orchestra/testbench": "^4.7 | ^5.1 | ^6.0 | ^7.0 | ^8.0",
@@ -9658,7 +9668,7 @@
],
"support": {
"issues": "https://github.com/getsentry/sentry-laravel/issues",
- "source": "https://github.com/getsentry/sentry-laravel/tree/3.7.3"
+ "source": "https://github.com/getsentry/sentry-laravel/tree/3.8.0"
},
"funding": [
{
@@ -9670,7 +9680,7 @@
"type": "custom"
}
],
- "time": "2023-08-03T10:10:23+00:00"
+ "time": "2023-09-05T11:02:34+00:00"
},
{
"name": "setasign/fpdf",
@@ -9906,26 +9916,26 @@
},
{
"name": "socialiteproviders/apple",
- "version": "5.5.2",
+ "version": "5.6.0",
"source": {
"type": "git",
"url": "https://github.com/SocialiteProviders/Apple.git",
- "reference": "82febc9805143d1ebea6c3e66db402d43bf511e1"
+ "reference": "4f0f06e463824f0df6151c768db2fec6610ea055"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/SocialiteProviders/Apple/zipball/82febc9805143d1ebea6c3e66db402d43bf511e1",
- "reference": "82febc9805143d1ebea6c3e66db402d43bf511e1",
+ "url": "https://api.github.com/repos/SocialiteProviders/Apple/zipball/4f0f06e463824f0df6151c768db2fec6610ea055",
+ "reference": "4f0f06e463824f0df6151c768db2fec6610ea055",
"shasum": ""
},
"require": {
"ext-json": "*",
"ext-openssl": "*",
- "firebase/php-jwt": "^6.2",
+ "firebase/php-jwt": "^6.8",
"lcobucci/clock": "^2.0 || ^3.0",
"lcobucci/jwt": "^4.1.5 || ^5.0.0",
- "php": "^7.4 || ^8.0",
- "socialiteproviders/manager": "~4.0"
+ "php": "^8.0",
+ "socialiteproviders/manager": "^4.4"
},
"suggest": {
"ahilmurugesan/socialite-apple-helper": "Automatic Apple client key generation and management."
@@ -9974,7 +9984,7 @@
"issues": "https://github.com/socialiteproviders/providers/issues",
"source": "https://github.com/socialiteproviders/providers"
},
- "time": "2023-05-24T23:29:11+00:00"
+ "time": "2023-09-11T21:59:09+00:00"
},
{
"name": "socialiteproviders/manager",
@@ -15068,16 +15078,16 @@
},
{
"name": "friendsofphp/php-cs-fixer",
- "version": "v3.25.1",
+ "version": "v3.26.1",
"source": {
"type": "git",
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
- "reference": "8e21d69801de6b5ecb0dbe0bcdf967b335b1260b"
+ "reference": "d023ba6684055f6ea1da1352d8a02baca0426983"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/8e21d69801de6b5ecb0dbe0bcdf967b335b1260b",
- "reference": "8e21d69801de6b5ecb0dbe0bcdf967b335b1260b",
+ "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/d023ba6684055f6ea1da1352d8a02baca0426983",
+ "reference": "d023ba6684055f6ea1da1352d8a02baca0426983",
"shasum": ""
},
"require": {
@@ -15151,7 +15161,7 @@
],
"support": {
"issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
- "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.25.1"
+ "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.26.1"
},
"funding": [
{
@@ -15159,7 +15169,7 @@
"type": "github"
}
],
- "time": "2023-09-04T01:22:52+00:00"
+ "time": "2023-09-08T19:09:07+00:00"
},
{
"name": "hamcrest/hamcrest-php",
@@ -15870,16 +15880,16 @@
},
{
"name": "phpstan/phpstan",
- "version": "1.10.32",
+ "version": "1.10.33",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpstan.git",
- "reference": "c47e47d3ab03137c0e121e77c4d2cb58672f6d44"
+ "reference": "03b1cf9f814ba0863c4e9affea49a4d1ed9a2ed1"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpstan/phpstan/zipball/c47e47d3ab03137c0e121e77c4d2cb58672f6d44",
- "reference": "c47e47d3ab03137c0e121e77c4d2cb58672f6d44",
+ "url": "https://api.github.com/repos/phpstan/phpstan/zipball/03b1cf9f814ba0863c4e9affea49a4d1ed9a2ed1",
+ "reference": "03b1cf9f814ba0863c4e9affea49a4d1ed9a2ed1",
"shasum": ""
},
"require": {
@@ -15928,7 +15938,7 @@
"type": "tidelift"
}
],
- "time": "2023-08-24T21:54:50+00:00"
+ "time": "2023-09-04T12:20:53+00:00"
},
{
"name": "phpunit/php-code-coverage",
@@ -16253,16 +16263,16 @@
},
{
"name": "phpunit/phpunit",
- "version": "10.3.2",
+ "version": "10.3.3",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
- "reference": "0dafb1175c366dd274eaa9a625e914451506bcd1"
+ "reference": "241ed4dd0db1c096984e62d414c4e1ac8d5dbff4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/0dafb1175c366dd274eaa9a625e914451506bcd1",
- "reference": "0dafb1175c366dd274eaa9a625e914451506bcd1",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/241ed4dd0db1c096984e62d414c4e1ac8d5dbff4",
+ "reference": "241ed4dd0db1c096984e62d414c4e1ac8d5dbff4",
"shasum": ""
},
"require": {
@@ -16334,7 +16344,7 @@
"support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
"security": "https://github.com/sebastianbergmann/phpunit/security/policy",
- "source": "https://github.com/sebastianbergmann/phpunit/tree/10.3.2"
+ "source": "https://github.com/sebastianbergmann/phpunit/tree/10.3.3"
},
"funding": [
{
@@ -16350,7 +16360,7 @@
"type": "tidelift"
}
],
- "time": "2023-08-15T05:34:23+00:00"
+ "time": "2023-09-05T04:34:51+00:00"
},
{
"name": "sebastian/cli-parser",
@@ -16787,16 +16797,16 @@
},
{
"name": "sebastian/exporter",
- "version": "5.0.0",
+ "version": "5.0.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/exporter.git",
- "reference": "f3ec4bf931c0b31e5b413f5b4fc970a7d03338c0"
+ "reference": "32ff03d078fed1279c4ec9a407d08c5e9febb480"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/f3ec4bf931c0b31e5b413f5b4fc970a7d03338c0",
- "reference": "f3ec4bf931c0b31e5b413f5b4fc970a7d03338c0",
+ "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/32ff03d078fed1279c4ec9a407d08c5e9febb480",
+ "reference": "32ff03d078fed1279c4ec9a407d08c5e9febb480",
"shasum": ""
},
"require": {
@@ -16852,7 +16862,8 @@
],
"support": {
"issues": "https://github.com/sebastianbergmann/exporter/issues",
- "source": "https://github.com/sebastianbergmann/exporter/tree/5.0.0"
+ "security": "https://github.com/sebastianbergmann/exporter/security/policy",
+ "source": "https://github.com/sebastianbergmann/exporter/tree/5.0.1"
},
"funding": [
{
@@ -16860,7 +16871,7 @@
"type": "github"
}
],
- "time": "2023-02-03T07:06:49+00:00"
+ "time": "2023-09-08T04:46:58+00:00"
},
{
"name": "sebastian/global-state",
diff --git a/lang/en/texts.php b/lang/en/texts.php
index c17129c75120..a7f79bf59196 100644
--- a/lang/en/texts.php
+++ b/lang/en/texts.php
@@ -5164,6 +5164,7 @@ $LANG = array(
'trust' => 'Trust',
'charity' => 'Charity',
'government' => 'Government',
+ 'in_stock_quantity' => 'Stock quantity',
);
return $LANG;
diff --git a/resources/views/react/head.blade.php b/resources/views/react/head.blade.php
index fc645e62d397..2a14ac4fa27e 100644
--- a/resources/views/react/head.blade.php
+++ b/resources/views/react/head.blade.php
@@ -1,235 +1,235 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/Feature/Export/ReportCsvGenerationTest.php b/tests/Feature/Export/ReportCsvGenerationTest.php
index 32e264c3e251..f7224d9aa43a 100644
--- a/tests/Feature/Export/ReportCsvGenerationTest.php
+++ b/tests/Feature/Export/ReportCsvGenerationTest.php
@@ -293,17 +293,17 @@ class ReportCsvGenerationTest extends TestCase
])->post('/api/v1/reports/vendors', $data);
$csv = $response->streamedContent();
-
- $this->assertEquals('Vendor 1', $this->getFirstValueByColumn($csv, 'Name'));
- $this->assertEquals('1234', $this->getFirstValueByColumn($csv, 'Number'));
- $this->assertEquals('city', $this->getFirstValueByColumn($csv, 'City'));
- $this->assertEquals('address1', $this->getFirstValueByColumn($csv, 'Street'));
- $this->assertEquals('address2', $this->getFirstValueByColumn($csv, 'Apt/Suite'));
- $this->assertEquals('postal_code', $this->getFirstValueByColumn($csv, 'Postal Code'));
- $this->assertEquals('work_phone', $this->getFirstValueByColumn($csv, 'Phone'));
- $this->assertEquals('private_notes', $this->getFirstValueByColumn($csv, 'Private Notes'));
- $this->assertEquals('public_notes', $this->getFirstValueByColumn($csv, 'Public Notes'));
- $this->assertEquals('website', $this->getFirstValueByColumn($csv, 'Website'));
+nlog($csv);
+ $this->assertEquals('Vendor 1', $this->getFirstValueByColumn($csv, 'Vendor Name'));
+ $this->assertEquals('1234', $this->getFirstValueByColumn($csv, 'Vendor Number'));
+ $this->assertEquals('city', $this->getFirstValueByColumn($csv, 'Vendor City'));
+ $this->assertEquals('address1', $this->getFirstValueByColumn($csv, 'Vendor Street'));
+ $this->assertEquals('address2', $this->getFirstValueByColumn($csv, 'Vendor Apt/Suite'));
+ $this->assertEquals('postal_code', $this->getFirstValueByColumn($csv, 'Vendor Postal Code'));
+ $this->assertEquals('work_phone', $this->getFirstValueByColumn($csv, 'Vendor Phone'));
+ $this->assertEquals('private_notes', $this->getFirstValueByColumn($csv, 'Vendor Private Notes'));
+ $this->assertEquals('public_notes', $this->getFirstValueByColumn($csv, 'Vendor Public Notes'));
+ $this->assertEquals('website', $this->getFirstValueByColumn($csv, 'Vendor Website'));
}
@@ -345,9 +345,9 @@ class ReportCsvGenerationTest extends TestCase
$csv = $response->streamedContent();
- $this->assertEquals('Vendor 1', $this->getFirstValueByColumn($csv, 'Name'));
- $this->assertEquals('1234', $this->getFirstValueByColumn($csv, 'Number'));
- $this->assertEquals('city', $this->getFirstValueByColumn($csv, 'City'));
+ $this->assertEquals('Vendor 1', $this->getFirstValueByColumn($csv, 'Vendor Name'));
+ $this->assertEquals('1234', $this->getFirstValueByColumn($csv, 'Vendor Number'));
+ $this->assertEquals('city', $this->getFirstValueByColumn($csv, 'Vendor City'));
}
@@ -488,14 +488,14 @@ class ReportCsvGenerationTest extends TestCase
$csv = $response->streamedContent();
- $this->assertEquals(3600, $this->getFirstValueByColumn($csv, 'Duration'));
- $this->assertEquals('test', $this->getFirstValueByColumn($csv, 'Description'));
- $this->assertEquals('16/Jul/2023', $this->getFirstValueByColumn($csv, 'Start Date'));
- $this->assertEquals('16/Jul/2023', $this->getFirstValueByColumn($csv, 'End Date'));
- $this->assertEquals('Custom 1', $this->getFirstValueByColumn($csv, 'Custom Value 1'));
- $this->assertEquals('Custom 2', $this->getFirstValueByColumn($csv, 'Custom Value 2'));
- $this->assertEquals('Custom 3', $this->getFirstValueByColumn($csv, 'Custom Value 3'));
- $this->assertEquals('Custom 4', $this->getFirstValueByColumn($csv, 'Custom Value 4'));
+ $this->assertEquals(3600, $this->getFirstValueByColumn($csv, 'Task Duration'));
+ $this->assertEquals('test', $this->getFirstValueByColumn($csv, 'Task Description'));
+ $this->assertEquals('16/Jul/2023', $this->getFirstValueByColumn($csv, 'Task Start Date'));
+ $this->assertEquals('16/Jul/2023', $this->getFirstValueByColumn($csv, 'Task End Date'));
+ $this->assertEquals('Custom 1', $this->getFirstValueByColumn($csv, 'Task Custom Value 1'));
+ $this->assertEquals('Custom 2', $this->getFirstValueByColumn($csv, 'Task Custom Value 2'));
+ $this->assertEquals('Custom 3', $this->getFirstValueByColumn($csv, 'Task Custom Value 3'));
+ $this->assertEquals('Custom 4', $this->getFirstValueByColumn($csv, 'Task Custom Value 4'));
}
@@ -1567,29 +1567,29 @@ class ReportCsvGenerationTest extends TestCase
$csv = $response->streamedContent();
- $this->assertEquals('100', $this->getFirstValueByColumn($csv, 'Amount'));
- $this->assertEquals('50', $this->getFirstValueByColumn($csv, 'Balance'));
- $this->assertEquals('10', $this->getFirstValueByColumn($csv, 'Discount'));
- $this->assertEquals('1234', $this->getFirstValueByColumn($csv, 'PO Number'));
- $this->assertEquals('Public', $this->getFirstValueByColumn($csv, 'Public Notes'));
- $this->assertEquals('Private', $this->getFirstValueByColumn($csv, 'Private Notes'));
- $this->assertEquals('Terms', $this->getFirstValueByColumn($csv, 'Terms'));
- $this->assertEquals('2020-01-01', $this->getFirstValueByColumn($csv, 'Date'));
- $this->assertEquals('2021-01-02', $this->getFirstValueByColumn($csv, 'Due Date'));
- $this->assertEquals('2021-01-03', $this->getFirstValueByColumn($csv, 'Partial Due Date'));
- $this->assertEquals('10', $this->getFirstValueByColumn($csv, 'Partial/Deposit'));
- $this->assertEquals('Custom 1', $this->getFirstValueByColumn($csv, 'Custom Value 1'));
- $this->assertEquals('Custom 2', $this->getFirstValueByColumn($csv, 'Custom Value 2'));
- $this->assertEquals('Custom 3', $this->getFirstValueByColumn($csv, 'Custom Value 3'));
- $this->assertEquals('Custom 4', $this->getFirstValueByColumn($csv, 'Custom Value 4'));
- $this->assertEquals('Footer', $this->getFirstValueByColumn($csv, 'Footer'));
- $this->assertEquals('Tax 1', $this->getFirstValueByColumn($csv, 'Tax Name 1'));
- $this->assertEquals('10', $this->getFirstValueByColumn($csv, 'Tax Rate 1'));
- $this->assertEquals('Tax 2', $this->getFirstValueByColumn($csv, 'Tax Name 2'));
- $this->assertEquals('20', $this->getFirstValueByColumn($csv, 'Tax Rate 2'));
- $this->assertEquals('Tax 3', $this->getFirstValueByColumn($csv, 'Tax Name 3'));
- $this->assertEquals('30', $this->getFirstValueByColumn($csv, 'Tax Rate 3'));
- $this->assertEquals('Daily', $this->getFirstValueByColumn($csv, 'How Often'));
+ $this->assertEquals('100', $this->getFirstValueByColumn($csv, 'Recurring Invoice Amount'));
+ $this->assertEquals('50', $this->getFirstValueByColumn($csv, 'Recurring Invoice Balance'));
+ $this->assertEquals('10', $this->getFirstValueByColumn($csv, 'Recurring Invoice Discount'));
+ $this->assertEquals('1234', $this->getFirstValueByColumn($csv, 'Recurring Invoice PO Number'));
+ $this->assertEquals('Public', $this->getFirstValueByColumn($csv, 'Recurring Invoice Public Notes'));
+ $this->assertEquals('Private', $this->getFirstValueByColumn($csv, 'Recurring Invoice Private Notes'));
+ $this->assertEquals('Terms', $this->getFirstValueByColumn($csv, 'Recurring Invoice Terms'));
+ $this->assertEquals('2020-01-01', $this->getFirstValueByColumn($csv, 'Recurring Invoice Date'));
+ $this->assertEquals('2021-01-02', $this->getFirstValueByColumn($csv, 'Recurring Invoice Due Date'));
+ $this->assertEquals('2021-01-03', $this->getFirstValueByColumn($csv, 'Recurring Invoice Partial Due Date'));
+ $this->assertEquals('10', $this->getFirstValueByColumn($csv, 'Recurring Invoice Partial/Deposit'));
+ $this->assertEquals('Custom 1', $this->getFirstValueByColumn($csv, 'Recurring Invoice Custom Value 1'));
+ $this->assertEquals('Custom 2', $this->getFirstValueByColumn($csv, 'Recurring Invoice Custom Value 2'));
+ $this->assertEquals('Custom 3', $this->getFirstValueByColumn($csv, 'Recurring Invoice Custom Value 3'));
+ $this->assertEquals('Custom 4', $this->getFirstValueByColumn($csv, 'Recurring Invoice Custom Value 4'));
+ $this->assertEquals('Footer', $this->getFirstValueByColumn($csv, 'Recurring Invoice Footer'));
+ $this->assertEquals('Tax 1', $this->getFirstValueByColumn($csv, 'Recurring Invoice Tax Name 1'));
+ $this->assertEquals('10', $this->getFirstValueByColumn($csv, 'Recurring Invoice Tax Rate 1'));
+ $this->assertEquals('Tax 2', $this->getFirstValueByColumn($csv, 'Recurring Invoice Tax Name 2'));
+ $this->assertEquals('20', $this->getFirstValueByColumn($csv, 'Recurring Invoice Tax Rate 2'));
+ $this->assertEquals('Tax 3', $this->getFirstValueByColumn($csv, 'Recurring Invoice Tax Name 3'));
+ $this->assertEquals('30', $this->getFirstValueByColumn($csv, 'Recurring Invoice Tax Rate 3'));
+ $this->assertEquals('Daily', $this->getFirstValueByColumn($csv, 'Recurring Invoice How Often'));
}
diff --git a/tests/Feature/QuoteTest.php b/tests/Feature/QuoteTest.php
index e32f10f8824f..57ebde27b3e6 100644
--- a/tests/Feature/QuoteTest.php
+++ b/tests/Feature/QuoteTest.php
@@ -171,7 +171,7 @@ class QuoteTest extends TestCase
$project = Project::find($this->decodePrimaryKey($res['data'][0]['project_id']));
- $this->assertEquals($project->name, ctrans('texts.quote_number_short') . " " . $this->quote->number);
+ $this->assertEquals($project->name, ctrans('texts.quote_number_short') . " " . $this->quote->number."[{$this->quote->client->present()->name()}]");
}
public function testQuoteList()
diff --git a/tests/Unit/InvoiceTest.php b/tests/Unit/InvoiceTest.php
index 305e1e86704d..49abb228a8e9 100644
--- a/tests/Unit/InvoiceTest.php
+++ b/tests/Unit/InvoiceTest.php
@@ -49,6 +49,58 @@ class InvoiceTest extends TestCase
$this->invoice_calc = new InvoiceSum($this->invoice);
}
+public function testGrossTaxAmountCalcuations()
+ {
+ $invoice = InvoiceFactory::create($this->company->id, $this->user->id);
+ $invoice->client_id = $this->client->id;
+ $invoice->uses_inclusive_taxes = false;
+ $invoice->discount = 14191;
+ $invoice->is_amount_discount = true;
+ $invoice->status_id = 2;
+ $line_items = [];
+
+ $line_item = new InvoiceItem;
+ $line_item->quantity = 1;
+ $line_item->cost = 8000;
+ $line_item->tax_rate1 = 5;
+ $line_item->tax_name1 = 'CA';
+ $line_item->product_key = 'line1';
+ $line_item->notes = 'Test';
+ $line_item->tax_id = 1;
+ $line_items[] = $line_item;
+
+ $line_item = new InvoiceItem;
+ $line_item->quantity = 1;
+ $line_item->cost = 9500;
+ $line_item->tax_rate1 = 5;
+ $line_item->tax_name1 = 'CA';
+ $line_item->product_key = 'line2';
+ $line_item->notes = 'Test';
+ $line_item->tax_id = 1;
+
+ $line_items[] = $line_item;
+
+ $invoice->line_items = $line_items;
+ $invoice->save();
+
+ $calc = $invoice->calc();
+ $invoice = $calc->getInvoice();
+
+ $this->assertEquals(3474.45, $invoice->amount);
+ $this->assertEquals(14191, $invoice->discount);
+ $this->assertEquals(165.45, $invoice->total_taxes);
+
+ $item = collect($invoice->line_items)->firstWhere('product_key', 'line1');
+ $this->assertEquals(75.63, $item->tax_amount);
+ $this->assertEquals(8075.63, $item->gross_line_total);
+
+ $item = collect($invoice->line_items)->firstWhere('product_key', 'line2');
+ $this->assertEquals(89.82, $item->tax_amount);
+ $this->assertEquals(9589.82, $item->gross_line_total);
+
+
+ }
+
public function testTaskRoundingPrecisionThree()
{
$invoice = InvoiceFactory::create($this->company->id, $this->user->id);