Merge pull request #9009 from turbo124/v5-develop

v5.7.56
This commit is contained in:
David Bomba 2023-12-02 15:49:38 +11:00 committed by GitHub
commit c14d73cda4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
52 changed files with 7369 additions and 7096 deletions

View File

@ -1 +1 @@
5.7.55
5.7.56

View File

@ -45,7 +45,7 @@ class EmailReport
/**
* The date range the statement should include
* The date range the report should include
*
* @var string
*/
@ -67,7 +67,45 @@ class EmailReport
*/
public string $end_date = '';
/******************************* Parameters **********************************/
/** @var string $report_name */
public string $report_name = '';
/**
* Optional array of report keys for
* filter the columns of the report
*
* @var array $report_keys
*
* */
public array $report_keys = [];
/** Profit Loss Parameters */
public bool $is_income_billed = true;
public bool $is_expense_billed = true;
public bool $include_tax = true;
/**
* Comma separated string of statuses for filtering the Invoice report
*
* all
* draft
* sent
* paid
* unpaid
* overdue
* viewed
*
* */
public string $status = '';
/**
* Comma separated list of product.product_keys
* to filter the report by
*/
public string $product_key = '';
}

View File

@ -105,8 +105,6 @@ class ActivityExport extends BaseExport
$this->date_format = DateFormat::find($this->company->settings->date_format_id)->format;
// ksort($this->entity_keys);
if (count($this->input['report_keys']) == 0) {
$this->input['report_keys'] = array_values($this->entity_keys);
}
@ -142,8 +140,7 @@ class ActivityExport extends BaseExport
{
$this->csv->insertOne($this->buildActivityRow($activity));
}
private function decorateAdvancedFields(Task $task, array $entity) :array

View File

@ -175,11 +175,15 @@ class ClientExport extends BaseExport
} elseif (is_array($parts) && $parts[0] == 'contact' && array_key_exists($parts[1], $transformed_contact)) {
$entity[$key] = $transformed_contact[$parts[1]];
} else {
$entity[$key] = '';
// nlog($key);
$entity[$key] = $this->decorator->transform($key, $client);
// $entity[$key] = '';
}
}
return $this->decorateAdvancedFields($client, $entity);
return $entity;
// return $this->decorateAdvancedFields($client, $entity);
}
public function processMetaData(array $row, $resource): array

View File

@ -11,16 +11,17 @@
namespace App\Export\CSV;
use App\Libraries\MultiDB;
use App\Models\Client;
use App\Models\ClientContact;
use App\Models\Company;
use App\Transformers\ClientContactTransformer;
use App\Transformers\ClientTransformer;
use App\Utils\Ninja;
use Illuminate\Contracts\Database\Eloquent\Builder;
use Illuminate\Support\Facades\App;
use App\Models\Client;
use League\Csv\Writer;
use App\Models\Company;
use App\Libraries\MultiDB;
use App\Models\ClientContact;
use Illuminate\Support\Facades\App;
use App\Export\Decorators\Decorator;
use App\Transformers\ClientTransformer;
use App\Transformers\ClientContactTransformer;
use Illuminate\Database\Eloquent\Builder;
class ContactExport extends BaseExport
{
@ -29,6 +30,8 @@ class ContactExport extends BaseExport
private ClientContactTransformer $contact_transformer;
private Decorator $decorator;
public Writer $csv;
public string $date_key = 'created_at';
@ -39,6 +42,7 @@ class ContactExport extends BaseExport
$this->input = $input;
$this->client_transformer = new ClientTransformer();
$this->contact_transformer = new ClientContactTransformer();
$this->decorator = new Decorator();
}
private function init(): Builder
@ -119,11 +123,14 @@ class ContactExport extends BaseExport
} elseif ($parts[0] == 'contact' && array_key_exists($parts[1], $transformed_contact)) {
$entity[$key] = $transformed_contact[$parts[1]];
} else {
$entity[$key] = '';
// nlog($key);
$entity[$key] = $this->decorator->transform($key, $contact);
// $entity[$key] = '';
}
}
return $this->decorateAdvancedFields($contact->client, $entity);
return $entity;
// return $this->decorateAdvancedFields($contact->client, $entity);
}
private function decorateAdvancedFields(Client $client, array $entity) :array

View File

@ -11,6 +11,7 @@
namespace App\Export\CSV;
use App\Export\Decorators\Decorator;
use App\Libraries\MultiDB;
use App\Models\Company;
use App\Models\Credit;
@ -26,6 +27,8 @@ class CreditExport extends BaseExport
private CreditTransformer $credit_transformer;
private Decorator $decorator;
public string $date_key = 'created_at';
public Writer $csv;
@ -35,6 +38,7 @@ class CreditExport extends BaseExport
$this->company = $company;
$this->input = $input;
$this->credit_transformer = new CreditTransformer();
$this->decorator = new Decorator();
}
public function returnJson()
@ -143,7 +147,11 @@ class CreditExport extends BaseExport
} elseif(isset($transformed_credit[$searched_credit_key])) {
$entity[$keyval] = $transformed_credit[$searched_credit_key];
} else {
$entity[$keyval] = $this->resolveKey($keyval, $credit, $this->credit_transformer);
// nlog($key);
$entity[$key] = $this->decorator->transform($key, $credit);
// $entity[$key] = '';
// $entity[$keyval] = $this->resolveKey($keyval, $credit, $this->credit_transformer);
}
}

View File

@ -11,12 +11,13 @@
namespace App\Export\CSV;
use App\Export\Decorators\Decorator;
use App\Libraries\MultiDB;
use App\Models\Company;
use App\Models\Expense;
use App\Transformers\ExpenseTransformer;
use App\Utils\Ninja;
use Illuminate\Contracts\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\App;
use League\Csv\Writer;
@ -25,6 +26,8 @@ class ExpenseExport extends BaseExport
private $expense_transformer;
private Decorator $decorator;
public string $date_key = 'date';
public Writer $csv;
@ -34,6 +37,7 @@ class ExpenseExport extends BaseExport
$this->company = $company;
$this->input = $input;
$this->expense_transformer = new ExpenseTransformer();
$this->decorator = new Decorator();
}
@ -102,7 +106,8 @@ class ExpenseExport extends BaseExport
private function buildRow(Expense $expense) :array
{
$transformed_expense = $this->expense_transformer->transform($expense);
$transformed_expense['currency_id'] = $expense->currency ? $expense->currency->code : $expense->company->currency()->code;
$entity = [];
foreach (array_values($this->input['report_keys']) as $key) {
@ -113,12 +118,16 @@ class ExpenseExport extends BaseExport
} elseif (array_key_exists($key, $transformed_expense)) {
$entity[$key] = $transformed_expense[$key];
} else {
$entity[$key] = $this->resolveKey($key, $expense, $this->expense_transformer);
// nlog($key);
$entity[$key] = $this->decorator->transform($key, $expense);
// $entity[$key] = '';
// $entity[$key] = $this->resolveKey($key, $expense, $this->expense_transformer);
}
}
return $this->decorateAdvancedFields($expense, $entity);
return $entity;
// return $this->decorateAdvancedFields($expense, $entity);
}
private function decorateAdvancedFields(Expense $expense, array $entity) :array

View File

@ -11,6 +11,7 @@
namespace App\Export\CSV;
use App\Export\Decorators\Decorator;
use App\Libraries\MultiDB;
use App\Models\Company;
use App\Models\Invoice;
@ -28,11 +29,14 @@ class InvoiceExport extends BaseExport
public Writer $csv;
private Decorator $decorator;
public function __construct(Company $company, array $input)
{
$this->company = $company;
$this->input = $input;
$this->invoice_transformer = new InvoiceTransformer();
$this->decorator = new Decorator();
}
public function init(): Builder
@ -116,12 +120,16 @@ class InvoiceExport extends BaseExport
if (is_array($parts) && $parts[0] == 'invoice' && array_key_exists($parts[1], $transformed_invoice)) {
$entity[$key] = $transformed_invoice[$parts[1]];
} else {
$entity[$key] = $this->resolveKey($key, $invoice, $this->invoice_transformer);
// nlog($key);
$entity[$key] = $this->decorator->transform($key, $invoice);
// $entity[$key] = '';
// $entity[$key] = $this->resolveKey($key, $invoice, $this->invoice_transformer);
}
}
return $this->decorateAdvancedFields($invoice, $entity);
return $entity;
// return $this->decorateAdvancedFields($invoice, $entity);
}
private function decorateAdvancedFields(Invoice $invoice, array $entity) :array

View File

@ -11,6 +11,7 @@
namespace App\Export\CSV;
use App\Export\Decorators\Decorator;
use App\Libraries\MultiDB;
use App\Models\Company;
use App\Models\Invoice;
@ -29,6 +30,8 @@ class InvoiceItemExport extends BaseExport
public Writer $csv;
private Decorator $decorator;
private bool $force_keys = false;
private array $storage_array = [];
@ -46,6 +49,7 @@ class InvoiceItemExport extends BaseExport
$this->company = $company;
$this->input = $input;
$this->invoice_transformer = new InvoiceTransformer();
$this->decorator = new Decorator();
}
public function init(): Builder
@ -186,11 +190,14 @@ class InvoiceItemExport extends BaseExport
} elseif (array_key_exists($key, $transformed_invoice)) {
$entity[$key] = $transformed_invoice[$key];
} else {
$entity[$key] = $this->resolveKey($key, $invoice, $this->invoice_transformer);
// nlog($key);
$entity[$key] = $this->decorator->transform($key, $invoice);
// $entity[$key] = '';
// $entity[$key] = $this->resolveKey($key, $invoice, $this->invoice_transformer);
}
}
return $this->decorateAdvancedFields($invoice, $entity);
return $entity;
// return $this->decorateAdvancedFields($invoice, $entity);
}
private function decorateAdvancedFields(Invoice $invoice, array $entity) :array

View File

@ -118,13 +118,15 @@ class PaymentExport extends BaseExport
$entity[$key] = $transformed_entity[$key];
} else {
// $entity[$key] = $this->decorator->transform($key, $payment);
$entity[$key] = $this->resolveKey($key, $payment, $this->entity_transformer);
// nlog($key);
$entity[$key] = $this->decorator->transform($key, $payment);
// $entity[$key] = $this->resolveKey($key, $payment, $this->entity_transformer);
}
}
return $this->decorateAdvancedFields($payment, $entity);
return $entity;
// return $this->decorateAdvancedFields($payment, $entity);
}
private function decorateAdvancedFields(Payment $payment, array $entity) :array

View File

@ -11,14 +11,15 @@
namespace App\Export\CSV;
use App\Libraries\MultiDB;
use App\Utils\Ninja;
use League\Csv\Writer;
use App\Models\Company;
use App\Models\Product;
use App\Transformers\ProductTransformer;
use App\Utils\Ninja;
use Illuminate\Database\Eloquent\Builder;
use App\Libraries\MultiDB;
use Illuminate\Support\Facades\App;
use League\Csv\Writer;
use App\Export\Decorators\Decorator;
use App\Transformers\ProductTransformer;
use Illuminate\Database\Eloquent\Builder;
class ProductExport extends BaseExport
{
@ -28,11 +29,14 @@ class ProductExport extends BaseExport
public Writer $csv;
private Decorator $decorator;
public function __construct(Company $company, array $input)
{
$this->company = $company;
$this->input = $input;
$this->entity_transformer = new ProductTransformer();
$this->decorator = new Decorator();
}
public function returnJson()
@ -109,11 +113,15 @@ class ProductExport extends BaseExport
if (array_key_exists($key, $transformed_entity)) {
$entity[$keyval] = $transformed_entity[$key];
} else {
$entity[$keyval] = '';
// nlog($key);
$entity[$key] = $this->decorator->transform($key, $product);
// $entity[$key] = '';
}
}
return $this->decorateAdvancedFields($product, $entity);
return $entity;
// return $this->decorateAdvancedFields($product, $entity);
}
private function decorateAdvancedFields(Product $product, array $entity) :array

View File

@ -11,14 +11,15 @@
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\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 App\Export\Decorators\Decorator;
use Illuminate\Database\Eloquent\Builder;
use App\Transformers\PurchaseOrderTransformer;
class PurchaseOrderExport extends BaseExport
{
@ -29,6 +30,8 @@ class PurchaseOrderExport extends BaseExport
public Writer $csv;
private Decorator $decorator;
public array $entity_keys = [
'amount' => 'purchase_order.amount',
'balance' => 'purchase_order.balance',
@ -79,6 +82,7 @@ class PurchaseOrderExport extends BaseExport
$this->company = $company;
$this->input = $input;
$this->purchase_order_transformer = new PurchaseOrderTransformer();
$this->decorator = new Decorator();
}
@ -160,13 +164,17 @@ class PurchaseOrderExport extends BaseExport
if (is_array($parts) && $parts[0] == 'purchase_order' && array_key_exists($parts[1], $transformed_purchase_order)) {
$entity[$key] = $transformed_purchase_order[$parts[1]];
} else {
$entity[$key] = $this->resolveKey($key, $purchase_order, $this->purchase_order_transformer);
// nlog($key);
$entity[$key] = $this->decorator->transform($key, $purchase_order);
// $entity[$key] = '';
// $entity[$key] = $this->resolveKey($key, $purchase_order, $this->purchase_order_transformer);
}
}
return $this->decorateAdvancedFields($purchase_order, $entity);
return $entity;
// return $this->decorateAdvancedFields($purchase_order, $entity);
}
private function decorateAdvancedFields(PurchaseOrder $purchase_order, array $entity) :array

View File

@ -11,6 +11,7 @@
namespace App\Export\CSV;
use App\Export\Decorators\Decorator;
use App\Libraries\MultiDB;
use App\Models\Company;
use App\Models\PurchaseOrder;
@ -29,6 +30,8 @@ class PurchaseOrderItemExport extends BaseExport
public Writer $csv;
private Decorator $decorator;
private bool $force_keys = false;
private array $storage_array = [];
@ -40,6 +43,7 @@ class PurchaseOrderItemExport extends BaseExport
$this->company = $company;
$this->input = $input;
$this->purchase_order_transformer = new PurchaseOrderTransformer();
$this->decorator = new Decorator();
}
private function init(): Builder
@ -171,7 +175,10 @@ class PurchaseOrderItemExport extends BaseExport
} elseif (array_key_exists($key, $transformed_purchase_order)) {
$entity[$key] = $transformed_purchase_order[$key];
} else {
$entity[$key] = $this->resolveKey($key, $purchase_order, $this->purchase_order_transformer);
// nlog($key);
$entity[$key] = $this->decorator->transform($key, $purchase_order);
// $entity[$key] = '';
// $entity[$key] = $this->resolveKey($key, $purchase_order, $this->purchase_order_transformer);
}
}

View File

@ -11,6 +11,7 @@
namespace App\Export\CSV;
use App\Export\Decorators\Decorator;
use App\Libraries\MultiDB;
use App\Models\Company;
use App\Models\Quote;
@ -29,6 +30,8 @@ class QuoteExport extends BaseExport
public Writer $csv;
private Decorator $decorator;
private array $decorate_keys = [
'client',
'currency',
@ -40,6 +43,7 @@ class QuoteExport extends BaseExport
$this->company = $company;
$this->input = $input;
$this->quote_transformer = new QuoteTransformer();
$this->decorator = new Decorator();
}
private function init(): Builder
@ -122,15 +126,17 @@ class QuoteExport extends BaseExport
if (is_array($parts) && $parts[0] == 'quote' && array_key_exists($parts[1], $transformed_invoice)) {
$entity[$key] = $transformed_invoice[$parts[1]];
} else {
$entity[$key] = $this->resolveKey($key, $quote, $this->quote_transformer);
// nlog($key);
$entity[$key] = $this->decorator->transform($key, $quote);
// $entity[$key] = '';
// $entity[$key] = $this->resolveKey($key, $quote, $this->quote_transformer);
}
}
return $this->decorateAdvancedFields($quote, $entity);
return $entity;
// return $this->decorateAdvancedFields($quote, $entity);
}
private function decorateAdvancedFields(Quote $quote, array $entity) :array
{
if (in_array('quote.currency_id', $this->input['report_keys'])) {

View File

@ -11,6 +11,7 @@
namespace App\Export\CSV;
use App\Export\Decorators\Decorator;
use App\Libraries\MultiDB;
use App\Models\Company;
use App\Models\Quote;
@ -29,7 +30,10 @@ class QuoteItemExport extends BaseExport
public Writer $csv;
private Decorator $decorator;
private array $storage_array = [];
private array $storage_item_array = [];
private array $decorate_keys = [
@ -42,6 +46,7 @@ class QuoteItemExport extends BaseExport
$this->company = $company;
$this->input = $input;
$this->quote_transformer = new QuoteTransformer();
$this->decorator = new Decorator;
}
public function init(): Builder
@ -178,12 +183,14 @@ class QuoteItemExport extends BaseExport
} elseif (array_key_exists($key, $transformed_quote)) {
$entity[$key] = $transformed_quote[$key];
} else {
$entity[$key] = $this->resolveKey($key, $quote, $this->quote_transformer);
// nlog($key);
$entity[$key] = $this->decorator->transform($key, $quote);
// $entity[$key] = $this->resolveKey($key, $quote, $this->quote_transformer);
}
}
return $this->decorateAdvancedFields($quote, $entity);
return $entity;
// return $this->decorateAdvancedFields($quote, $entity);
}
private function decorateAdvancedFields(Quote $quote, array $entity) :array
{

View File

@ -11,6 +11,7 @@
namespace App\Export\CSV;
use App\Export\Decorators\Decorator;
use App\Libraries\MultiDB;
use App\Models\Company;
use App\Models\RecurringInvoice;
@ -29,11 +30,14 @@ class RecurringInvoiceExport extends BaseExport
public Writer $csv;
private Decorator $decorator;
public function __construct(Company $company, array $input)
{
$this->company = $company;
$this->input = $input;
$this->invoice_transformer = new RecurringInvoiceTransformer();
$this->decorator = new Decorator();
}
public function init(): Builder
@ -105,6 +109,8 @@ class RecurringInvoiceExport extends BaseExport
private function buildRow(RecurringInvoice $invoice) :array
{
$transformed_invoice = $this->invoice_transformer->transform($invoice);
$transformed_invoice['frequency_id'] = $invoice->frequencyForKey($invoice->frequency_id); //need to inject this here because it is also a valid key
// nlog($transformed_invoice);
$entity = [];
@ -114,13 +120,20 @@ class RecurringInvoiceExport extends BaseExport
if (is_array($parts) && $parts[0] == 'recurring_invoice' && array_key_exists($parts[1], $transformed_invoice)) {
$entity[$key] = $transformed_invoice[$parts[1]];
} else {
$entity[$key] = $this->resolveKey($key, $invoice, $this->invoice_transformer);
} elseif($parts[0] == 'item'){
$entity[$key] = '';
}
else {
// nlog($key);
$entity[$key] = $this->decorator->transform($key, $invoice);
// $entity[$key] = '';
// $entity[$key] = $this->resolveKey($key, $invoice, $this->invoice_transformer);
}
}
return $this->decorateAdvancedFields($invoice, $entity);
// nlog($entity);
return $entity;
// return $this->decorateAdvancedFields($invoice, $entity);
}
private function decorateAdvancedFields(RecurringInvoice $invoice, array $entity) :array

View File

@ -11,6 +11,7 @@
namespace App\Export\CSV;
use App\Export\Decorators\Decorator;
use App\Libraries\MultiDB;
use App\Models\Company;
use App\Models\DateFormat;
@ -34,6 +35,8 @@ class TaskExport extends BaseExport
public Writer $csv;
private Decorator $decorator;
private array $storage_array = [];
private array $storage_item_array = [];
@ -43,6 +46,7 @@ class TaskExport extends BaseExport
$this->company = $company;
$this->input = $input;
$this->entity_transformer = new TaskTransformer();
$this->decorator = new Decorator();
}
public function init(): Builder
@ -133,15 +137,21 @@ class TaskExport extends BaseExport
$entity[$key] = $transformed_entity[$parts[1]];
} elseif (array_key_exists($key, $transformed_entity)) {
$entity[$key] = $transformed_entity[$key];
} elseif (in_array($key, ['task.start_date', 'task.end_date', 'task.duration'])) {
$entity[$key] = '';
} else {
$entity[$key] = $this->resolveKey($key, $task, $this->entity_transformer);
// nlog($key);
$entity[$key] = $this->decorator->transform($key, $task);
// $entity[$key] = $this->resolveKey($key, $task, $this->entity_transformer);
}
// $entity['task.start_date'] = '';
// $entity['task.end_date'] = '';
// $entity['task.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->storage_array[] = $entity;
@ -187,7 +197,7 @@ class TaskExport extends BaseExport
$entity['task.duration'] = $task->calcDuration();
}
$entity = $this->decorateAdvancedFields($task, $entity);
// $entity = $this->decorateAdvancedFields($task, $entity);
$this->storage_array[] = $entity;

View File

@ -11,6 +11,7 @@
namespace App\Export\CSV;
use App\Export\Decorators\Decorator;
use App\Libraries\MultiDB;
use App\Models\Company;
use App\Models\Vendor;
@ -30,6 +31,8 @@ class VendorExport extends BaseExport
public Writer $csv;
private Decorator $decorator;
public string $date_key = 'created_at';
public function __construct(Company $company, array $input)
@ -38,6 +41,7 @@ class VendorExport extends BaseExport
$this->input = $input;
$this->vendor_transformer = new VendorTransformer();
$this->contact_transformer = new VendorContactTransformer();
$this->decorator = new Decorator();
}
public function init(): Builder
@ -122,11 +126,15 @@ class VendorExport extends BaseExport
} elseif (is_array($parts) && $parts[0] == 'vendor_contact' && isset($transformed_contact[$parts[1]])) {
$entity[$key] = $transformed_contact[$parts[1]];
} else {
$entity[$key] = $this->resolveKey($key, $vendor, $this->vendor_transformer);
// nlog($key);
$entity[$key] = $this->decorator->transform($key, $vendor);
// $entity[$key] = $this->resolveKey($key, $vendor, $this->vendor_transformer);
}
}
return $this->decorateAdvancedFields($vendor, $entity);
return $entity;
// return $this->decorateAdvancedFields($vendor, $entity);
}
private function decorateAdvancedFields(Vendor $vendor, array $entity) :array

View File

@ -30,6 +30,9 @@ class ClientDecorator extends Decorator implements DecoratorInterface
if($client && method_exists($this, $key)) {
return $this->{$key}($client);
}
elseif($client && $client->{$key}) {
return $client->{$key};
}
return '';
}
@ -39,11 +42,6 @@ class ClientDecorator extends Decorator implements DecoratorInterface
return $client->present()->name();
}
public function number(Client $client)
{
return $client->number ?? '';
}
public function user(Client $client)
{
return $client->user->present()->name();
@ -54,29 +52,14 @@ class ClientDecorator extends Decorator implements DecoratorInterface
return $client->assigned_user ? $client->user->present()->name() : '';
}
public function balance(Client $client)
{
return $client->balance ?? 0;
}
public function paid_to_date(Client $client)
{
return $client->paid_to_date ?? 0;
}
public function currency_id(Client $client)
{
return $client->currency() ? $client->currency()->code : $client->company->currency()->code;
}
public function website(Client $client)
{
return $client->website ?? '';
}
public function private_notes(Client $client)
{
return $client->private_notes ?? '';
return strip_tags($client->private_notes ?? '');
}
public function industry_id(Client $client)
@ -89,66 +72,11 @@ class ClientDecorator extends Decorator implements DecoratorInterface
return $client->size ? ctrans("texts.size_{$client->size->name}") : '';
}
public function phone(Client $client)
{
return $client->phone ?? '';
}
public function address1(Client $client)
{
return $client->address1 ?? '';
}
public function address2(Client $client)
{
return $client->address2 ?? '';
}
public function city(Client $client)
{
return $client->city ?? '';
}
public function state(Client $client)
{
return $client->state ?? '';
}
public function postal_code(Client $client)
{
return $client->postal_code ?? '';
}
public function country_id(Client $client)
{
return $client->country ? ctrans("texts.country_{$client->country->name}") : '';
}
public function shipping_address1(Client $client)
{
return $client->shipping_address1 ?? '';
}
public function shipping_address2(Client $client)
{
return $client->shipping_address2 ?? '';
}
public function shipping_city(Client $client)
{
return $client->shipping_city ?? '';
}
public function shipping_state(Client $client)
{
return $client->shipping_state ?? '';
}
public function shipping_postal_code(Client $client)
{
return $client->shipping_postal_code ?? '';
}
public function shipping_country_id(Client $client)
{
return $client->shipping_country ? ctrans("texts.country_{$client->shipping_country->name}") : '';
@ -159,49 +87,9 @@ class ClientDecorator extends Decorator implements DecoratorInterface
return $client?->settings?->payment_terms ?? $client->company->settings->payment_terms;
}
public function vat_number(Client $client)
{
return $client->vat_number ?? '';
}
public function id_number(Client $client)
{
return $client->id_number ?? '';
}
public function public_notes(Client $client)
{
return $client->public_notes ?? '';
}
public function custom_value1(Client $client)
{
return $client->custom_value1 ?? '';
}
public function custom_value2(Client $client)
{
return $client->custom_value2 ?? '';
}
public function custom_value3(Client $client)
{
return $client->custom_value3 ?? '';
}
public function custom_value4(Client $client)
{
return $client->custom_value4 ?? '';
}
public function payment_balance(Client $client)
{
return $client->payment_balance ?? 0;
}
public function credit_balance(Client $client)
{
return $client->credit_balance ?? 0;
return strip_tags($client->public_notes ?? '');
}
public function classification(Client $client)

View File

@ -28,42 +28,12 @@ class ContactDecorator implements DecoratorInterface
if($contact && method_exists($this, $key)) {
return $this->{$key}($contact);
}
elseif($contact && $contact->{$key}){
return $contact->{$key};
}
return '';
}
public function phone(ClientContact $contact)
{
return $contact->phone ?? '';
}
public function first_name(ClientContact $contact)
{
return $contact->first_name ?? '';
}
public function last_name(ClientContact $contact)
{
return $contact->last_name ?? '';
}
public function email(ClientContact $contact)
{
return $contact->email ?? '';
}
public function custom_value1(ClientContact $contact)
{
return $contact->custom_value1 ?? '';
}
public function custom_value2(ClientContact $contact)
{
return $contact->custom_value2 ?? '';
}
public function custom_value3(ClientContact $contact)
{
return $contact->custom_value3 ?? '';
}
public function custom_value4(ClientContact $contact)
{
return $contact->custom_value4 ?? '';
}
}

View File

@ -27,32 +27,14 @@ class CreditDecorator implements DecoratorInterface
if($credit && method_exists($this, $key)) {
return $this->{$key}($credit);
} elseif($credit && $credit->{$key}){
return $credit->{$key};
}
return '';
}
public function number(Credit $credit)
{
return $credit->number ?? '';
}
public function amount(Credit $credit)
{
return $credit->amount ?? 0;
}
public function balance(Credit $credit)
{
return $credit->balance ?? 0;
}
public function paid_to_date(Credit $credit)
{
return $credit->paid_to_date ?? 0;
}
public function po_number(Credit $credit)
{
return $credit->po_number ?? '';
}
public function date(Credit $credit)
{
return $credit->date ?? '';
@ -63,7 +45,7 @@ class CreditDecorator implements DecoratorInterface
}
public function terms(Credit $credit)
{
return $credit->terms ?? '';
return strip_tags($credit->terms ?? '');
}
public function discount(Credit $credit)
{

View File

@ -27,40 +27,24 @@ class ExpenseDecorator implements DecoratorInterface
if($expense && method_exists($this, $key)) {
return $this->{$key}($expense);
} elseif($expense && $expense->{$key}) {
return $expense->{$key};
}
return '';
}
public function amount(Expense $expense)
{
return $expense->amount ?? 0;
}
public function category_id(Expense $expense)
{
return $expense->category ? $expense->category->name : '';
}
public function client_id(Expense $expense)
{
return $expense->client ? $expense->client->present()->name() : '';
}
public function custom_value1(Expense $expense)
{
return $expense->custom_value1 ?? '';
}
public function custom_value2(Expense $expense)
{
return $expense->custom_value2 ?? '';
}
public function custom_value3(Expense $expense)
{
return $expense->custom_value3 ?? '';
}
public function custom_value4(Expense $expense)
{
return $expense->custom_value4 ?? '';
}
public function currency_id(Expense $expense)
{
return $expense->currency ? $expense->currency->code : $expense->company->currency()->code;
@ -85,17 +69,14 @@ class ExpenseDecorator implements DecoratorInterface
{
return $expense->payment_date ?? '';
}
public function number(Expense $expense)
{
return $expense->number ?? '';
}
public function payment_type_id(Expense $expense)
{
return $expense->payment_type ? $expense->payment_type->name : '';
}
public function private_notes(Expense $expense)
{
return $expense->private_notes ?? '';
return strip_tags($expense->private_notes ?? '');
}
public function project_id(Expense $expense)
{
@ -103,48 +84,9 @@ class ExpenseDecorator implements DecoratorInterface
}
public function public_notes(Expense $expense)
{
return $expense->public_notes ?? '';
}
public function tax_amount1(Expense $expense)
{
return $expense->tax_amount1 ?? 0;
}
public function tax_amount2(Expense $expense)
{
return $expense->tax_amount2 ?? 0;
}
public function tax_amount3(Expense $expense)
{
return $expense->tax_amount3 ?? 0;
}
public function tax_name1(Expense $expense)
{
return $expense->tax_name1 ?? '';
}
public function tax_name2(Expense $expense)
{
return $expense->tax_name2 ?? '';
}
public function tax_name3(Expense $expense)
{
return $expense->tax_name3 ?? '';
}
public function tax_rate1(Expense $expense)
{
return $expense->tax_rate1 ?? 0;
}
public function tax_rate2(Expense $expense)
{
return $expense->tax_rate2 ?? 0;
}
public function tax_rate3(Expense $expense)
{
return $expense->tax_rate3 ?? 0;
}
public function transaction_reference(Expense $expense)
{
return $expense->transaction_reference ?? '';
return strip_tags($expense->public_notes ?? '');
}
public function vendor_id(Expense $expense)
{
return $expense->vendor ? $expense->vendor->name : '';

View File

@ -23,36 +23,20 @@ class InvoiceDecorator extends Decorator implements DecoratorInterface
$invoice = $entity;
} elseif($entity->invoice) {
$invoice = $entity->invoice;
} elseif($entity->invoices()->exists()) {
$invoice = $entity->invoices()->first();
}
if($invoice && method_exists($this, $key)) {
return $this->{$key}($invoice);
}elseif($invoice && $invoice->{$key}){
return $invoice->{$key};
}
return '';
}
public function number(Invoice $invoice)
{
return $invoice->number ?? '';
}
public function amount(Invoice $invoice)
{
return $invoice->amount ?? 0;
}
public function balance(Invoice $invoice)
{
return $invoice->balance ?? 0;
}
public function paid_to_date(Invoice $invoice)
{
return $invoice->paid_to_date ?? 0;
}
public function po_number(Invoice $invoice)
{
return $invoice->po_number ?? '';
}
public function date(Invoice $invoice)
{
return $invoice->date ?? '';
@ -63,11 +47,11 @@ class InvoiceDecorator extends Decorator implements DecoratorInterface
}
public function terms(Invoice $invoice)
{
return $invoice->terms ?? '';
return strip_tags($invoice->terms ?? '');
}
public function footer(Invoice $invoice)
{
return $invoice->footer ?? '';
return strip_tags($invoice->footer ?? '');
}
public function status(Invoice $invoice)
{
@ -75,7 +59,7 @@ class InvoiceDecorator extends Decorator implements DecoratorInterface
}
public function public_notes(Invoice $invoice)
{
return $invoice->public_notes ?? '';
return strip_tags($invoice->public_notes ?? '');
}
public function private_notes(Invoice $invoice)
{
@ -89,42 +73,13 @@ class InvoiceDecorator extends Decorator implements DecoratorInterface
{
return $invoice->is_amount_discount ? ctrans('texts.yes') : ctrans('texts.no');
}
public function discount(Invoice $invoice)
{
return $invoice->discount ?? 0;
}
public function partial(Invoice $invoice)
{
return $invoice->partial ?? 0;
}
public function partial_due_date(Invoice $invoice)
{
return $invoice->partial_due_date ?? '';
}
public function custom_surcharge1(Invoice $invoice)
{
return $invoice->custom_surcharge1 ?? 0;
}
public function custom_surcharge2(Invoice $invoice)
{
return $invoice->custom_surcharge2 ?? 0;
}
public function custom_surcharge3(Invoice $invoice)
{
return $invoice->custom_surcharge3 ?? 0;
}
public function custom_surcharge4(Invoice $invoice)
{
return $invoice->custom_surcharge4 ?? 0;
}
public function exchange_rate(Invoice $invoice)
{
return $invoice->exchange_rate ?? 0;
}
public function total_taxes(Invoice $invoice)
{
return $invoice->total_taxes ?? 0;
}
public function assigned_user_id(Invoice $invoice)
{
return $invoice->assigned_user ? $invoice->assigned_user->present()->name(): '';
@ -133,46 +88,7 @@ class InvoiceDecorator extends Decorator implements DecoratorInterface
{
return $invoice->user ? $invoice->user->present()->name(): '';
}
public function custom_value1(Invoice $invoice)
{
return $invoice->custom_value1 ?? '';
}
public function custom_value2(Invoice $invoice)
{
return $invoice->custom_value2 ?? '';
}
public function custom_value3(Invoice $invoice)
{
return $invoice->custom_value3 ?? '';
}
public function custom_value4(Invoice $invoice)
{
return $invoice->custom_value4 ?? '';
}
public function tax_name1(Invoice $invoice)
{
return $invoice->tax_name1 ?? '';
}
public function tax_name2(Invoice $invoice)
{
return $invoice->tax_name2 ?? '';
}
public function tax_name3(Invoice $invoice)
{
return $invoice->tax_name3 ?? '';
}
public function tax_rate1(Invoice $invoice)
{
return $invoice->tax_rate1 ?? 0;
}
public function tax_rate2(Invoice $invoice)
{
return $invoice->tax_rate2 ?? 0;
}
public function tax_rate3(Invoice $invoice)
{
return $invoice->tax_rate3 ?? 0;
}
public function recurring_id(Invoice $invoice)
{
return $invoice->recurring_invoice ? $invoice->recurring_invoice->number : '';

View File

@ -26,6 +26,8 @@ class PaymentDecorator extends Decorator implements DecoratorInterface
$payment = $entity;
} elseif($entity->payment) {
$payment = $entity->payment;
} elseif($entity->payments()->exists()) {
$payment = $entity->payments()->first();
}
if($key == 'amount' && (!$entity instanceof Payment)) {
@ -41,6 +43,9 @@ class PaymentDecorator extends Decorator implements DecoratorInterface
if($payment && method_exists($this, $key)) {
return $this->{$key}($payment);
}
elseif($payment && $payment->{$key}){
return $payment->{$key};
}
return '';
}
@ -78,11 +83,6 @@ class PaymentDecorator extends Decorator implements DecoratorInterface
return $payment->exchange_rate ?? 1;
}
public function number(Payment $payment)
{
return $payment->number ?? '';
}
public function method(Payment $payment)
{
return $payment->translatedType();
@ -98,26 +98,6 @@ class PaymentDecorator extends Decorator implements DecoratorInterface
return strip_tags($payment->private_notes) ?? '';
}
public function custom_value1(Payment $payment)
{
return $payment->custom_value1 ?? '';
}
public function custom_value2(Payment $payment)
{
return $payment->custom_value2 ?? '';
}
public function custom_value3(Payment $payment)
{
return $payment->custom_value3 ?? '';
}
public function custom_value4(Payment $payment)
{
return $payment->custom_value4 ?? '';
}
public function user_id(Payment $payment)
{
return $payment->user ? $payment->user->present()->name() : '';

View File

@ -30,8 +30,8 @@ class TaskDecorator extends Decorator implements DecoratorInterface
if($task && method_exists($this, $key)) {
return $this->{$key}($task);
} elseif($task->{$key}) {
return $task->{$key} ?? '';
} elseif($task && $task->{$key}) {
return $task->{$key};
}
return '';

View File

@ -27,7 +27,7 @@ class VendorContactDecorator implements DecoratorInterface
if($contact && method_exists($this, $key)) {
return $this->{$key}($contact);
} elseif($contact->{$key}) {
} elseif($contact && $contact->{$key}) {
return $contact->{$key} ?? '';
}

View File

@ -36,6 +36,7 @@ class TaskFilters extends QueryFilters
return $this->builder->where(function ($query) use ($filter) {
$query->where('description', 'like', '%'.$filter.'%')
->orWhere('time_log', 'like', '%'.$filter.'%')
->orWhere('custom_value1', 'like', '%'.$filter.'%')
->orWhere('custom_value2', 'like', '%'.$filter.'%')
->orWhere('custom_value3', 'like', '%'.$filter.'%')

View File

@ -928,11 +928,9 @@ class BaseController extends Controller
} //allows us to selective display bank integrations back to the user if they can view / create bank transactions but without the bank balance being present in the response
elseif($this->entity_type == TaxRate::class && $user->hasIntersectPermissions(['create_invoice','edit_invoice','create_quote','edit_quote','create_purchase_order','edit_purchase_order'])) {
// need to show tax rates if the user has the ability to create documents.
}
elseif($this->entity_type == ExpenseCategory::class && $user->hasPermission('create_expense')) {
} elseif($this->entity_type == ExpenseCategory::class && $user->hasPermission('create_expense')) {
// need to show expense categories if the user has the ability to create expenses.
}
else {
} else {
$query->where('user_id', '=', $user->id);
}
} elseif (in_array($this->entity_type, [Design::class, GroupSetting::class, PaymentTerm::class, TaskStatus::class])) {

View File

@ -248,7 +248,7 @@ class PreviewController extends BaseController
$company = $user->company();
$design = \App\Models\Design::query()
->where('id', $request_data['design_id'])
->where(function ($q) use ($user){
->where(function ($q) use ($user) {
$q->whereNull('company_id')->orWhere('company_id', $user->companyId());
})
->first();

View File

@ -68,7 +68,7 @@ class SearchController extends Controller
'type' => '/client',
'id' => $contact->client->hashed_id,
'path' => "/clients/{$contact->client->hashed_id}"
];
];
});
}

View File

@ -22,7 +22,10 @@ class ProfitLossRequest extends Request
*/
public function authorize() : bool
{
return auth()->user()->isAdmin();
/** @var \App\Models\User $user */
$user = auth()->user();
return $user->isAdmin();
}
public function rules()

View File

@ -47,7 +47,7 @@ class StoreSchedulerRequest extends Request
'parameters.end_date' => ['bail', 'sometimes', 'date:Y-m-d', 'required_if:parameters.date_rate,custom', 'after_or_equal:parameters.start_date'],
'parameters.entity' => ['bail', 'sometimes', 'string', 'in:invoice,credit,quote,purchase_order'],
'parameters.entity_id' => ['bail', 'sometimes', 'string'],
'parameters.report_name' => ['bail','sometimes', 'string', 'required_if:template,email_report', 'in:ar_detailed,ar_summary,client_balance,tax_summary,profitloss,client_sales,user_sales,product_sales,clients,client_contacts,credits,documents,expenses,invoices,invoice_items,quotes,quote_items,recurring_invoices,payments,products,tasks'],
'parameters.report_name' => ['bail','sometimes', 'string', 'required_if:template,email_report','in:ar_detailed,ar_summary,client_balance,tax_summary,profitloss,client_sales,user_sales,product_sales,clients,client_contacts,credits,documents,expenses,invoices,invoice_items,quotes,quote_items,recurring_invoices,payments,products,tasks'],
'parameters.date_key' => ['bail','sometimes', 'string'],
];

View File

@ -454,7 +454,7 @@ class CompanyExport implements ShouldQueue
nlog("could not create directory");
}
$zip_path = storage_path('backups/'.$file_name);
$zip_path = storage_path('backups/'.\Illuminate\Support\Str::ascii($file_name));
$zip = new \ZipArchive();
if ($zip->open($zip_path, \ZipArchive::CREATE)!==true) {
@ -484,12 +484,12 @@ class CompanyExport implements ShouldQueue
$t = app('translator');
$t->replace(Ninja::transformTranslations($this->company->settings));
$company_reference = Company::find($this->company->id);
// $company_reference = Company::find($this->company->id);
$nmo = new NinjaMailerObject;
$nmo->mailable = new DownloadBackup($url, $company_reference);
$nmo->mailable = new DownloadBackup($url, $this->company->withoutRelations());
$nmo->to_user = $this->user;
$nmo->company = $company_reference;
$nmo->company = $this->company->withoutRelations();
$nmo->settings = $this->company->settings;
(new NinjaMailerJob($nmo, true))->handle();

View File

@ -41,8 +41,9 @@ class VendorExpenseNotify implements ShouldQueue
{
MultiDB::setDB($this->db);
if(!$this->expense->vendor)
if(!$this->expense->vendor) {
return;
}
$this->expense->vendor->contacts->filter(function (VendorContact $contact) {
return $contact->send_email && $contact->email;

View File

@ -139,7 +139,8 @@ class PayPalPPCPPaymentDriver extends BaseDriver
public function init(): self
{
$this->api_endpoint_url = $this->company_gateway->getConfigField('testMode') ? 'https://api-m.sandbox.paypal.com' : 'https://api-m.paypal.com';
// $this->api_endpoint_url = $this->company_gateway->getConfigField('testMode') ? 'https://api-m.sandbox.paypal.com' : 'https://api-m.paypal.com';
$this->api_endpoint_url = 'https://api-m.paypal.com';
$secret = config('ninja.paypal.secret');
$client_id = config('ninja.paypal.client_id');
@ -230,7 +231,7 @@ class PayPalPPCPPaymentDriver extends BaseDriver
$data['funding_source'] = $this->paypal_payment_method;
$data['gateway_type_id'] = $this->gateway_type_id;
$data['merchantId'] = $this->company_gateway->getConfigField('merchantId');
$data['currency'] = $this->client->currency()->code;
// nlog($data['merchantId']);
return render('gateways.paypal.ppcp.pay', $data);

View File

@ -624,8 +624,6 @@ class PdfBuilder
$element['elements'][] = ['element' => 'td', 'content' => $row['$task.cost'], 'properties' => ['data-ref' => 'task_table-task.cost-td']];
} elseif ($cell == '$product.discount' && !$this->service->company->enable_product_discount) {
$element['elements'][] = ['element' => 'td', 'content' => $row['$product.discount'], 'properties' => ['data-ref' => 'product_table-product.discount-td', 'style' => 'display: none;']];
} elseif ($cell == '$product.quantity' && !$this->service->company->enable_product_quantity) {
$element['elements'][] = ['element' => 'td', 'content' => $row['$product.quantity'], 'properties' => ['data-ref' => 'product_table-product.quantity-td', 'style' => 'display: none;']];
} elseif ($cell == '$task.hours') {
$element['elements'][] = ['element' => 'td', 'content' => $row['$task.quantity'], 'properties' => ['data-ref' => 'task_table-task.hours-td']];
} elseif ($cell == '$product.tax_rate1') {
@ -808,8 +806,6 @@ class PdfBuilder
$elements[] = ['element' => 'th', 'content' => $aliases[$column] . '_label', 'properties' => ['data-ref' => "{$type}_table-" . substr($aliases[$column], 1) . '-th', 'hidden' => $this->service->config->settings->hide_empty_columns_on_pdf]];
} elseif ($column == '$product.discount' && !$this->service->company->enable_product_discount) {
$elements[] = ['element' => 'th', 'content' => $column . '_label', 'properties' => ['data-ref' => "{$type}_table-" . substr($column, 1) . '-th', 'style' => 'display: none;']];
} elseif ($column == '$product.quantity' && !$this->service->company->enable_product_quantity) {
$elements[] = ['element' => 'th', 'content' => $column . '_label', 'properties' => ['data-ref' => "{$type}_table-" . substr($column, 1) . '-th', 'style' => 'display: none;']];
} elseif ($column == '$product.tax_rate1') {
$elements[] = ['element' => 'th', 'content' => $column . '_label', 'properties' => ['data-ref' => "{$type}_table-product.tax1-th", 'hidden' => $this->service->config->settings->hide_empty_columns_on_pdf]];
} elseif ($column == '$product.tax_rate2') {

View File

@ -69,9 +69,9 @@ class PdfMock
if(isset($this->request['design_id']) && $design = Design::withTrashed()->find($this->request['design_id'])) {
$pdf_config->design = $design;
$pdf_config->entity_design_id = $design->hashed_id;
}
else
} else {
$pdf_config->design = Design::withTrashed()->find($this->decodePrimaryKey($pdf_config->entity_design_id));
}
$pdf_service->config = $pdf_config;
@ -507,7 +507,7 @@ class PdfMock
'$status_logo' => '<div class="stamp is-paid"> ' . ctrans('texts.paid') .'</div>',
'$show_shipping_address' => $this->settings->show_shipping_address ? 'flex' : 'none',
'$show_shipping_address_block' => $this->settings->show_shipping_address ? 'block' : 'none',
'$show_shipping_address_visibility' => $this->settings->show_shipping_address ? 'visible' : 'hidden',
'$show_shipping_address_visibility' => $this->settings->show_shipping_address ? '1' : '0',
'$start_date' => '31/01/2023',
'$end_date' => '31/12/2023',
'$history' => '',

View File

@ -694,8 +694,6 @@ class Design extends BaseDesign
$elements[] = ['element' => 'th', 'content' => $aliases[$column] . '_label', 'properties' => ['data-ref' => "{$type}_table-" . substr($aliases[$column], 1) . '-th', 'hidden' => $this->settings_object->getSetting('hide_empty_columns_on_pdf')]];
} elseif ($column == '$product.discount' && !$this->company->enable_product_discount) {
$elements[] = ['element' => 'th', 'content' => $column . '_label', 'properties' => ['data-ref' => "{$type}_table-" . substr($column, 1) . '-th', 'style' => 'display: none;']];
} elseif ($column == '$product.quantity' && !$this->company->enable_product_quantity) {
$elements[] = ['element' => 'th', 'content' => $column . '_label', 'properties' => ['data-ref' => "{$type}_table-" . substr($column, 1) . '-th', 'style' => 'display: none;']];
} elseif ($column == '$product.tax_rate1') {
$elements[] = ['element' => 'th', 'content' => $column . '_label', 'properties' => ['data-ref' => "{$type}_table-product.tax1-th", 'hidden' => $this->settings_object->getSetting('hide_empty_columns_on_pdf')]];
} elseif ($column == '$product.tax_rate2') {
@ -801,8 +799,6 @@ class Design extends BaseDesign
$element['elements'][] = ['element' => 'td', 'content' => $row['$task.cost'], 'properties' => ['data-ref' => 'task_table-task.cost-td']];
} elseif ($cell == '$product.discount' && !$this->company->enable_product_discount) {
$element['elements'][] = ['element' => 'td', 'content' => $row['$product.discount'], 'properties' => ['data-ref' => 'product_table-product.discount-td', 'style' => 'display: none;']];
} elseif ($cell == '$product.quantity' && !$this->company->enable_product_quantity) {
$element['elements'][] = ['element' => 'td', 'content' => $row['$product.quantity'], 'properties' => ['data-ref' => 'product_table-product.quantity-td', 'style' => 'display: none;']];
} elseif ($cell == '$task.hours') {
$element['elements'][] = ['element' => 'td', 'content' => $row['$task.quantity'], 'properties' => ['data-ref' => 'task_table-task.hours-td']];
} elseif ($cell == '$product.tax_rate1') {

View File

@ -82,12 +82,11 @@ class PdfMaker
$ts = new TemplateService();
if(isset($this->data['template']['entity'])){
try{
if(isset($this->data['template']['entity'])) {
try {
$entity = $this->data['template']['entity'];
$ts->setCompany($entity->company);
}
catch(\Exception $e){
} catch(\Exception $e) {
}
}

View File

@ -179,11 +179,13 @@ class TemplateService
private function getSettings(): object
{
if($this->settings)
if($this->settings) {
return $this->settings;
}
if($this->client)
if($this->client) {
return $this->client->getMergedSettings();
}
return $this->company->settings;
}

View File

@ -75,6 +75,7 @@
"nwidart/laravel-modules": "^10.0",
"omnipay/paypal": "^3.0",
"payfast/payfast-php-sdk": "^1.1",
"phpoffice/phpspreadsheet": "^1.29",
"pragmarx/google2fa": "^8.0",
"predis/predis": "^2",
"psr/http-message": "^1.0",
@ -172,4 +173,4 @@
},
"minimum-stability": "dev",
"prefer-stable": true
}
}

356
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "a224dafda3997e33733e329b05395f4c",
"content-hash": "00ba47529c0a2ba7ae6bbd1241af1649",
"packages": [
{
"name": "afosto/yaac",
@ -2099,6 +2099,67 @@
},
"time": "2022-08-04T05:24:33+00:00"
},
{
"name": "ezyang/htmlpurifier",
"version": "v4.17.0",
"source": {
"type": "git",
"url": "https://github.com/ezyang/htmlpurifier.git",
"reference": "bbc513d79acf6691fa9cf10f192c90dd2957f18c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/bbc513d79acf6691fa9cf10f192c90dd2957f18c",
"reference": "bbc513d79acf6691fa9cf10f192c90dd2957f18c",
"shasum": ""
},
"require": {
"php": "~5.6.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0"
},
"require-dev": {
"cerdic/css-tidy": "^1.7 || ^2.0",
"simpletest/simpletest": "dev-master"
},
"suggest": {
"cerdic/css-tidy": "If you want to use the filter 'Filter.ExtractStyleBlocks'.",
"ext-bcmath": "Used for unit conversion and imagecrash protection",
"ext-iconv": "Converts text to and from non-UTF-8 encodings",
"ext-tidy": "Used for pretty-printing HTML"
},
"type": "library",
"autoload": {
"files": [
"library/HTMLPurifier.composer.php"
],
"psr-0": {
"HTMLPurifier": "library/"
},
"exclude-from-classmap": [
"/library/HTMLPurifier/Language/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL-2.1-or-later"
],
"authors": [
{
"name": "Edward Z. Yang",
"email": "admin@htmlpurifier.org",
"homepage": "http://ezyang.com"
}
],
"description": "Standards compliant HTML filter written in PHP",
"homepage": "http://htmlpurifier.org/",
"keywords": [
"html"
],
"support": {
"issues": "https://github.com/ezyang/htmlpurifier/issues",
"source": "https://github.com/ezyang/htmlpurifier/tree/v4.17.0"
},
"time": "2023-11-17T15:01:25+00:00"
},
{
"name": "fakerphp/faker",
"version": "v1.23.0",
@ -5777,6 +5838,194 @@
],
"time": "2023-08-11T04:02:34+00:00"
},
{
"name": "maennchen/zipstream-php",
"version": "3.1.0",
"source": {
"type": "git",
"url": "https://github.com/maennchen/ZipStream-PHP.git",
"reference": "b8174494eda667f7d13876b4a7bfef0f62a7c0d1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/maennchen/ZipStream-PHP/zipball/b8174494eda667f7d13876b4a7bfef0f62a7c0d1",
"reference": "b8174494eda667f7d13876b4a7bfef0f62a7c0d1",
"shasum": ""
},
"require": {
"ext-mbstring": "*",
"ext-zlib": "*",
"php-64bit": "^8.1"
},
"require-dev": {
"ext-zip": "*",
"friendsofphp/php-cs-fixer": "^3.16",
"guzzlehttp/guzzle": "^7.5",
"mikey179/vfsstream": "^1.6",
"php-coveralls/php-coveralls": "^2.5",
"phpunit/phpunit": "^10.0",
"vimeo/psalm": "^5.0"
},
"suggest": {
"guzzlehttp/psr7": "^2.4",
"psr/http-message": "^2.0"
},
"type": "library",
"autoload": {
"psr-4": {
"ZipStream\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Paul Duncan",
"email": "pabs@pablotron.org"
},
{
"name": "Jonatan Männchen",
"email": "jonatan@maennchen.ch"
},
{
"name": "Jesse Donat",
"email": "donatj@gmail.com"
},
{
"name": "András Kolesár",
"email": "kolesar@kolesar.hu"
}
],
"description": "ZipStream is a library for dynamically streaming dynamic zip files from PHP without writing to the disk at all on the server.",
"keywords": [
"stream",
"zip"
],
"support": {
"issues": "https://github.com/maennchen/ZipStream-PHP/issues",
"source": "https://github.com/maennchen/ZipStream-PHP/tree/3.1.0"
},
"funding": [
{
"url": "https://github.com/maennchen",
"type": "github"
},
{
"url": "https://opencollective.com/zipstream",
"type": "open_collective"
}
],
"time": "2023-06-21T14:59:35+00:00"
},
{
"name": "markbaker/complex",
"version": "3.0.2",
"source": {
"type": "git",
"url": "https://github.com/MarkBaker/PHPComplex.git",
"reference": "95c56caa1cf5c766ad6d65b6344b807c1e8405b9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/95c56caa1cf5c766ad6d65b6344b807c1e8405b9",
"reference": "95c56caa1cf5c766ad6d65b6344b807c1e8405b9",
"shasum": ""
},
"require": {
"php": "^7.2 || ^8.0"
},
"require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "dev-master",
"phpcompatibility/php-compatibility": "^9.3",
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0",
"squizlabs/php_codesniffer": "^3.7"
},
"type": "library",
"autoload": {
"psr-4": {
"Complex\\": "classes/src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Mark Baker",
"email": "mark@lange.demon.co.uk"
}
],
"description": "PHP Class for working with complex numbers",
"homepage": "https://github.com/MarkBaker/PHPComplex",
"keywords": [
"complex",
"mathematics"
],
"support": {
"issues": "https://github.com/MarkBaker/PHPComplex/issues",
"source": "https://github.com/MarkBaker/PHPComplex/tree/3.0.2"
},
"time": "2022-12-06T16:21:08+00:00"
},
{
"name": "markbaker/matrix",
"version": "3.0.1",
"source": {
"type": "git",
"url": "https://github.com/MarkBaker/PHPMatrix.git",
"reference": "728434227fe21be27ff6d86621a1b13107a2562c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/MarkBaker/PHPMatrix/zipball/728434227fe21be27ff6d86621a1b13107a2562c",
"reference": "728434227fe21be27ff6d86621a1b13107a2562c",
"shasum": ""
},
"require": {
"php": "^7.1 || ^8.0"
},
"require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "dev-master",
"phpcompatibility/php-compatibility": "^9.3",
"phpdocumentor/phpdocumentor": "2.*",
"phploc/phploc": "^4.0",
"phpmd/phpmd": "2.*",
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0",
"sebastian/phpcpd": "^4.0",
"squizlabs/php_codesniffer": "^3.7"
},
"type": "library",
"autoload": {
"psr-4": {
"Matrix\\": "classes/src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Mark Baker",
"email": "mark@demon-angel.eu"
}
],
"description": "PHP Class for working with matrices",
"homepage": "https://github.com/MarkBaker/PHPMatrix",
"keywords": [
"mathematics",
"matrix",
"vector"
],
"support": {
"issues": "https://github.com/MarkBaker/PHPMatrix/issues",
"source": "https://github.com/MarkBaker/PHPMatrix/tree/3.0.1"
},
"time": "2022-12-02T22:17:43+00:00"
},
{
"name": "microsoft/microsoft-graph",
"version": "1.109.0",
@ -7829,6 +8078,111 @@
},
"time": "2023-08-12T11:01:26+00:00"
},
{
"name": "phpoffice/phpspreadsheet",
"version": "1.29.0",
"source": {
"type": "git",
"url": "https://github.com/PHPOffice/PhpSpreadsheet.git",
"reference": "fde2ccf55eaef7e86021ff1acce26479160a0fa0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/fde2ccf55eaef7e86021ff1acce26479160a0fa0",
"reference": "fde2ccf55eaef7e86021ff1acce26479160a0fa0",
"shasum": ""
},
"require": {
"ext-ctype": "*",
"ext-dom": "*",
"ext-fileinfo": "*",
"ext-gd": "*",
"ext-iconv": "*",
"ext-libxml": "*",
"ext-mbstring": "*",
"ext-simplexml": "*",
"ext-xml": "*",
"ext-xmlreader": "*",
"ext-xmlwriter": "*",
"ext-zip": "*",
"ext-zlib": "*",
"ezyang/htmlpurifier": "^4.15",
"maennchen/zipstream-php": "^2.1 || ^3.0",
"markbaker/complex": "^3.0",
"markbaker/matrix": "^3.0",
"php": "^7.4 || ^8.0",
"psr/http-client": "^1.0",
"psr/http-factory": "^1.0",
"psr/simple-cache": "^1.0 || ^2.0 || ^3.0"
},
"require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "dev-main",
"dompdf/dompdf": "^1.0 || ^2.0",
"friendsofphp/php-cs-fixer": "^3.2",
"mitoteam/jpgraph": "^10.3",
"mpdf/mpdf": "^8.1.1",
"phpcompatibility/php-compatibility": "^9.3",
"phpstan/phpstan": "^1.1",
"phpstan/phpstan-phpunit": "^1.0",
"phpunit/phpunit": "^8.5 || ^9.0 || ^10.0",
"squizlabs/php_codesniffer": "^3.7",
"tecnickcom/tcpdf": "^6.5"
},
"suggest": {
"dompdf/dompdf": "Option for rendering PDF with PDF Writer",
"ext-intl": "PHP Internationalization Functions",
"mitoteam/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers",
"mpdf/mpdf": "Option for rendering PDF with PDF Writer",
"tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer"
},
"type": "library",
"autoload": {
"psr-4": {
"PhpOffice\\PhpSpreadsheet\\": "src/PhpSpreadsheet"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Maarten Balliauw",
"homepage": "https://blog.maartenballiauw.be"
},
{
"name": "Mark Baker",
"homepage": "https://markbakeruk.net"
},
{
"name": "Franck Lefevre",
"homepage": "https://rootslabs.net"
},
{
"name": "Erik Tilt"
},
{
"name": "Adrien Crivelli"
}
],
"description": "PHPSpreadsheet - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine",
"homepage": "https://github.com/PHPOffice/PhpSpreadsheet",
"keywords": [
"OpenXML",
"excel",
"gnumeric",
"ods",
"php",
"spreadsheet",
"xls",
"xlsx"
],
"support": {
"issues": "https://github.com/PHPOffice/PhpSpreadsheet/issues",
"source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/1.29.0"
},
"time": "2023-06-14T22:48:31+00:00"
},
{
"name": "phpoption/phpoption",
"version": "1.9.2",

View File

@ -17,8 +17,8 @@ return [
'require_https' => env('REQUIRE_HTTPS', true),
'app_url' => rtrim(env('APP_URL', ''), '/'),
'app_domain' => env('APP_DOMAIN', 'invoicing.co'),
'app_version' => env('APP_VERSION', '5.7.55'),
'app_tag' => env('APP_TAG', '5.7.55'),
'app_version' => env('APP_VERSION', '5.7.56'),
'app_tag' => env('APP_TAG', '5.7.56'),
'minimum_client_version' => '5.0.16',
'terms_version' => '1.0.1',
'api_secret' => env('API_SECRET', false),

View File

@ -14,8 +14,6 @@ return new class extends Migration {
if(!Gateway::find(61) && Ninja::isHosted()) {
$fields = new \stdClass;
$fields->clientId = "";
$fields->secret = "";
$fields->testMode = false;
$paypal = new Gateway;

View File

@ -0,0 +1,29 @@
<?php
use App\Models\Gateway;
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Gateway::whereIn('id', [60, 15])->update(['visible' => 1]);
\Illuminate\Support\Facades\Artisan::call('ninja:design-update');
}
/**
* Reverse the migrations.
*/
public function down(): void
{
//
}
};

View File

@ -5218,6 +5218,7 @@ $lang = array(
'vendor_notification_body' => 'Payment processed for :amount dated :payment_date. <br>[Transaction Reference: :transaction_reference]',
'receipt' => 'Receipt',
'charges' => 'Charges',
'email_report' => 'Email Report',
);
return $lang;

File diff suppressed because it is too large Load Diff

View File

@ -99,4 +99,6 @@
type: string
example: '123456'
readOnly: true
company_user:
$ref: '#/components/schemas/CompanyUser'
type: object

View File

@ -32,7 +32,6 @@
margin-top: 0;
margin-bottom: 0;
size: $page_size $page_layout;
}
p {
@ -44,19 +43,13 @@
display: grid;
grid-template-columns: 1fr 1fr 1fr;
line-height: var(--line-height);
margin-bottom:10px;
margin-bottom: 10px;
}
.client-wrapper{
.client-wrapper {
display: grid;
gap: 10px;
grid-template-columns: 1fr 1fr 1fr;
grid-template-areas: "a b c ";
grid-auto-columns: minmax(0, 1fr);
grid-auto-flow: column;
justify-content:left;
line-height: var(--line-height);
grid-template-columns: 1fr auto 1fr;
border: 0px solid #000;
}
.company-logo {
@ -69,11 +62,18 @@
line-height: var(--line-height);
}
#entity-details {
text-align: left;
#entity-container {
border: 0px solid #000;
width: 100%;
}
#entity-details {
text-align: left;
line-height: var(--line-height) !important;
white-space: nowrap;
border: 0px solid #000;
margin-right: 0;
margin-left: auto;
}
#entity-details>tr,
@ -92,7 +92,8 @@
display: flex;
flex-direction: column;
line-height: var(--line-height);
white-space: nowrap;
/* white-space: nowrap; */
border: 0px solid #000;
}
#shipping-details {
@ -100,6 +101,7 @@
flex-direction: column;
line-height: var(--line-height);
white-space: nowrap;
border: 1px solid #000;
}
[data-ref="table"] {
@ -285,6 +287,13 @@
color: #505050;
}
#logo-container {
margin-right: 0;
margin-left: auto;
text-align: right;
border: 0px solid #000;
}
.pqrcode {}
/** Useful snippets, uncomment to enable. **/
@ -332,16 +341,15 @@
<div class="header-wrapper">
<div id="company-details"></div>
<div id="company-address"></div>
<div>
<img class="company-logo" src="$company.logo" alt="$company.name logo" />
<div id="logo-container">
<img class="company-logo" src="$company.logo" alt="$company.name logo">
</div>
</div>
<div class="client-wrapper">
<div id="client-details"></div>
<div id="vendor-details"></div>
<div id="shipping-details"></div>
<div>
<div id="entity-container">
<table id="entity-details" cellspacing="0" cellpadding="0" dir="$dir"></table>
</div>
</div>

View File

@ -30,26 +30,29 @@
@push('footer')
<script src="https://www.paypal.com/sdk/js?client-id={!! $client_id !!}&merchant-id={!! $merchantId !!}&components=buttons,funding-eligibility&intent=capture" data-partner-attribution-id="invoiceninja_SP_PPCP"></script>
<script src="https://www.paypal.com/sdk/js?client-id={!! $client_id !!}&currency={!! $currency !!}&merchant-id={!! $merchantId !!}&components=buttons,funding-eligibility&intent=capture" data-partner-attribution-id="invoiceninja_SP_PPCP"></script>
<div id="paypal-button-container"></div>
<script>
//&buyer-country=US&currency=USD&enable-funding=venmo
const fundingSource = "{!! $funding_source !!}";
const testMode = {{ $gateway->company_gateway->getConfigField('testMode') }};
const clientId = "{{ $client_id }}";
const sandbox = { sandbox: clientId };
const production = { production: clientId };
const orderId = "{!! $order_id !!}";
paypal.Buttons({
env: testMode ? 'sandbox' : 'production',
env: 'production',
fundingSource: fundingSource,
client: testMode ? sandbox : production,
client: clientId,
createOrder: function(data, actions) {
return orderId;
},
onApprove: function(data, actions) {
var errorDetail = Array.isArray(data.details) && data.details[0];
if (errorDetail && ['INSTRUMENT_DECLINED', 'PAYER_ACTION_REQUIRED'].includes(errorDetail.issue)) {
return actions.restart();
}
return actions.order.capture().then(function(details) {
document.getElementById("gateway_response").value =JSON.stringify( details );
document.getElementById("server_response").submit();

View File

@ -655,7 +655,7 @@ class ReportCsvGenerationTest extends TestCase
$csv = $response->body();
// nlog($csv);
$this->assertEquals(3600, $this->getFirstValueByColumn($csv, 'Task Duration'));
$this->assertEquals('test1', $this->getFirstValueByColumn($csv, 'Task Description'));
$this->assertEquals('16/Jul/2023', $this->getFirstValueByColumn($csv, 'Task Start Date'));
@ -890,6 +890,7 @@ class ReportCsvGenerationTest extends TestCase
$csv = $response->body();
// nlog($csv);
$this->assertEquals(100, $this->getFirstValueByColumn($csv, 'Payment Amount'));
$this->assertEquals(now()->addSeconds($this->company->timezone()->utc_offset)->format('Y-m-d'), $this->getFirstValueByColumn($csv, 'Payment Date'));
@ -1764,7 +1765,7 @@ class ReportCsvGenerationTest extends TestCase
$data = [
'date_range' => 'all',
'report_keys' => ["client.name","invoice.number","invoice.amount","payment.date", "payment.amount"],
'report_keys' => ["client.name","invoice.number","invoice.amount", "payment.date", "payment.amount"],
'send_email' => false,
];
@ -1783,13 +1784,11 @@ class ReportCsvGenerationTest extends TestCase
$csv = $response->body();
$this->assertEquals('bob', $this->getFirstValueByColumn($csv, 'Client Name'));
$this->assertEquals('12345', $this->getFirstValueByColumn($csv, 'Invoice Invoice Number'));
$this->assertEquals(100, $this->getFirstValueByColumn($csv, 'Payment Amount'));
$this->assertEquals(now()->addSeconds($this->company->timezone()->utc_offset)->format('Y-m-d'), $this->getFirstValueByColumn($csv, 'Payment Date'));
}
public function testClientContactCsvGeneration()

View File

@ -0,0 +1,54 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace Tests\Feature\PhpOffice;
use Tests\TestCase;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
class CsvConversionTest extends TestCase
{
protected function setUp(): void
{
parent::setUp();
}
public function testExample()
{
$spreadsheet = new Spreadsheet();
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Csv();
/* Set CSV parsing options */
$reader->setDelimiter(',');
// $reader->setEnclosure('"');
$reader->setSheetIndex(0);
/* Load a CSV file and save as a XLS */
$spreadsheet = $reader->load(base_path().'/tests/Feature/Import/expenses.csv');
$writer = new Xlsx($spreadsheet);
$writer->save(storage_path('/test.xlsx'));
$spreadsheet->disconnectWorksheets();
$this->assertTrue(file_exists(storage_path('/test.xlsx')));
unlink(storage_path('/test.xlsx'));
}
}