mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-06-03 17:54:38 -04:00
Merge branch 'v5-develop' of https://github.com/turbo124/invoiceninja into v5-develop
This commit is contained in:
commit
e7b2afb0be
@ -61,7 +61,7 @@ class MobileLocalization extends Command
|
|||||||
|
|
||||||
private function laravelResources()
|
private function laravelResources()
|
||||||
{
|
{
|
||||||
$resources = $this->getResources();
|
$resources =(array)$this->getResources();
|
||||||
|
|
||||||
if(is_iterable($resources)){
|
if(is_iterable($resources)){
|
||||||
foreach ($resources as $key => $val) {
|
foreach ($resources as $key => $val) {
|
||||||
|
@ -628,11 +628,11 @@ class BaseExport
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(in_array($column, ['client.user_id', 'user_id'])) {
|
if(in_array($column, ['client.user_id', 'user_id'])) {
|
||||||
return $entity->client->user->present()->name();
|
return $entity->client->user ? $entity->client->user->present()->name() : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
if(in_array($column, ['client.assigned_user_id', 'assigned_user_id'])) {
|
if(in_array($column, ['client.assigned_user_id', 'assigned_user_id'])) {
|
||||||
return $entity->client->assigned_user->present()->name();
|
return $entity->client->assigned_user ? $entity->client->assigned_user->present()->name() : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
if(in_array($column, ['client.country_id', 'country_id'])) {
|
if(in_array($column, ['client.country_id', 'country_id'])) {
|
||||||
@ -760,7 +760,7 @@ class BaseExport
|
|||||||
return $transformed_payment[$column];
|
return $transformed_payment[$column];
|
||||||
} elseif (array_key_exists(str_replace("payment.", "", $column), $transformed_payment)) {
|
} elseif (array_key_exists(str_replace("payment.", "", $column), $transformed_payment)) {
|
||||||
return $transformed_payment[$column];
|
return $transformed_payment[$column];
|
||||||
}
|
}
|
||||||
|
|
||||||
// nlog("export: Could not resolve payment key: {$column}");
|
// nlog("export: Could not resolve payment key: {$column}");
|
||||||
|
|
||||||
|
@ -177,6 +177,14 @@ class CreditExport extends BaseExport
|
|||||||
$entity['credit.status'] = $credit->stringStatus($credit->status_id);
|
$entity['credit.status'] = $credit->stringStatus($credit->status_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (in_array('credit.assigned_user_id', $this->input['report_keys'])) {
|
||||||
|
$entity['credit.assigned_user_id'] = $credit->assigned_user ? $credit->assigned_user->present()->name(): '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_array('credit.user_id', $this->input['report_keys'])) {
|
||||||
|
$entity['credit.user_id'] = $credit->user ? $credit->user->present()->name(): '';
|
||||||
|
}
|
||||||
|
|
||||||
return $entity;
|
return $entity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -151,7 +151,15 @@ class InvoiceExport extends BaseExport
|
|||||||
$entity['invoice.auto_bill_enabled'] = $invoice->auto_bill_enabled ? ctrans('texts.yes') : ctrans('texts.no');
|
$entity['invoice.auto_bill_enabled'] = $invoice->auto_bill_enabled ? ctrans('texts.yes') : ctrans('texts.no');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (in_array('invoice.assigned_user_id', $this->input['report_keys'])) {
|
||||||
|
$entity['invoice.assigned_user_id'] = $invoice->assigned_user ? $invoice->assigned_user->present()->name(): '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_array('invoice.user_id', $this->input['report_keys'])) {
|
||||||
|
$entity['invoice.user_id'] = $invoice->user ? $invoice->user->present()->name(): '';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return $entity;
|
return $entity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -227,6 +227,13 @@ class InvoiceItemExport extends BaseExport
|
|||||||
$entity['invoice.recurring_id'] = $invoice->recurring_invoice->number ?? '';
|
$entity['invoice.recurring_id'] = $invoice->recurring_invoice->number ?? '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (in_array('invoice.assigned_user_id', $this->input['report_keys'])) {
|
||||||
|
$entity['invoice.assigned_user_id'] = $invoice->assigned_user ? $invoice->assigned_user->present()->name(): '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_array('invoice.user_id', $this->input['report_keys'])) {
|
||||||
|
$entity['invoice.user_id'] = $invoice->user ? $invoice->user->present()->name(): '';
|
||||||
|
}
|
||||||
|
|
||||||
return $entity;
|
return $entity;
|
||||||
}
|
}
|
||||||
|
@ -167,6 +167,14 @@ class PaymentExport extends BaseExport
|
|||||||
$entity['gateway'] = $payment->gateway_type ? $payment->gateway_type->name : 'Unknown Type';
|
$entity['gateway'] = $payment->gateway_type ? $payment->gateway_type->name : 'Unknown Type';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (in_array('payment.assigned_user_id', $this->input['report_keys'])) {
|
||||||
|
$entity['payment.assigned_user_id'] = $payment->assigned_user ? $payment->assigned_user->present()->name() : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_array('payment.user_id', $this->input['report_keys'])) {
|
||||||
|
$entity['payment.user_id'] = $payment->user ? $payment->user->present()->name() : '';
|
||||||
|
}
|
||||||
|
|
||||||
// $entity['invoices'] = $payment->invoices()->exists() ? $payment->invoices->pluck('number')->implode(',') : '';
|
// $entity['invoices'] = $payment->invoices()->exists() ? $payment->invoices->pluck('number')->implode(',') : '';
|
||||||
|
|
||||||
return $entity;
|
return $entity;
|
||||||
|
@ -149,6 +149,15 @@ class QuoteExport extends BaseExport
|
|||||||
$entity['quote.invoice'] = $quote->invoice ? $quote->invoice->number : '';
|
$entity['quote.invoice'] = $quote->invoice ? $quote->invoice->number : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (in_array('quote.assigned_user_id', $this->input['report_keys'])) {
|
||||||
|
$entity['quote.assigned_user_id'] = $quote->assigned_user ? $quote->assigned_user->present()->name(): '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_array('quote.user_id', $this->input['report_keys'])) {
|
||||||
|
$entity['quote.user_id'] = $quote->user ? $quote->user->present()->name(): '';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return $entity;
|
return $entity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -198,6 +198,16 @@ class QuoteItemExport extends BaseExport
|
|||||||
if (in_array('status_id', $this->input['report_keys'])) {
|
if (in_array('status_id', $this->input['report_keys'])) {
|
||||||
$entity['status'] = $quote->stringStatus($quote->status_id);
|
$entity['status'] = $quote->stringStatus($quote->status_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (in_array('quote.assigned_user_id', $this->input['report_keys'])) {
|
||||||
|
$entity['quote.assigned_user_id'] = $quote->assigned_user ? $quote->assigned_user->present()->name(): '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_array('quote.user_id', $this->input['report_keys'])) {
|
||||||
|
$entity['quote.user_id'] = $quote->user ? $quote->user->present()->name(): '';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return $entity;
|
return $entity;
|
||||||
}
|
}
|
||||||
|
@ -157,6 +157,15 @@ class RecurringInvoiceExport extends BaseExport
|
|||||||
$entity['recurring_invoice.auto_bill_enabled'] = $invoice->auto_bill_enabled ? ctrans('texts.yes') : ctrans('texts.no');
|
$entity['recurring_invoice.auto_bill_enabled'] = $invoice->auto_bill_enabled ? ctrans('texts.yes') : ctrans('texts.no');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (in_array('recurring_invoice.assigned_user_id', $this->input['report_keys'])) {
|
||||||
|
$entity['recurring_invoice.assigned_user_id'] = $invoice->assigned_user ? $invoice->assigned_user->present()->name() : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_array('recurring_invoice.user_id', $this->input['report_keys'])) {
|
||||||
|
$entity['recurring_invoice.user_id'] = $invoice->user ? $invoice->user->present()->name() : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return $entity;
|
return $entity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
20
app/Export/Decorators/ClientDecorator.php
Normal file
20
app/Export/Decorators/ClientDecorator.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Export\Decorators;
|
||||||
|
|
||||||
|
class ClientDecorator implements DecoratorInterface
|
||||||
|
{
|
||||||
|
public function transform(): string
|
||||||
|
{
|
||||||
|
return 'Payment Decorator';
|
||||||
|
}
|
||||||
|
}
|
20
app/Export/Decorators/CreditDecorator.php
Normal file
20
app/Export/Decorators/CreditDecorator.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Export\Decorators;
|
||||||
|
|
||||||
|
class CreditDecorator implements DecoratorInterface
|
||||||
|
{
|
||||||
|
public function transform(): string
|
||||||
|
{
|
||||||
|
return 'Payment Decorator';
|
||||||
|
}
|
||||||
|
}
|
51
app/Export/Decorators/Decorator.php
Normal file
51
app/Export/Decorators/Decorator.php
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Export\Decorators;
|
||||||
|
|
||||||
|
|
||||||
|
use App\Models\Task;
|
||||||
|
use App\Models\Quote;
|
||||||
|
use App\Models\Client;
|
||||||
|
use App\Models\Credit;
|
||||||
|
use App\Models\Vendor;
|
||||||
|
use App\Models\Expense;
|
||||||
|
use App\Models\Invoice;
|
||||||
|
use App\Models\Payment;
|
||||||
|
use App\Models\Product;
|
||||||
|
use App\Models\Project;
|
||||||
|
use App\Models\PurchaseOrder;
|
||||||
|
use App\Models\RecurringInvoice;
|
||||||
|
|
||||||
|
class Decorator {
|
||||||
|
|
||||||
|
public function __invoke(mixed $entity, string $key)
|
||||||
|
{
|
||||||
|
return match($entity){
|
||||||
|
($entity instanceof Client) => $value = (new ClientDecorator($entity, $key))->transform(),
|
||||||
|
($entity instanceof Payment) => $value = (new PaymentDecorator($entity, $key))->transform(),
|
||||||
|
($entity instanceof Invoice) => $value = (new InvoiceDecorator($entity, $key))->transform(),
|
||||||
|
($entity instanceof RecurringInvoice) => $value = (new RecurringInvoiceDecorator($entity, $key))->transform(),
|
||||||
|
($entity instanceof Credit) => $value = (new CreditDecorator($entity, $key))->transform(),
|
||||||
|
($entity instanceof Quote) => $value = (new QuoteDecorator($entity, $key))->transform(),
|
||||||
|
($entity instanceof Task) => $value = (new TaskDecorator($entity, $key))->transform(),
|
||||||
|
($entity instanceof Expense) => $value = (new ExpenseDecorator($entity, $key))->transform(),
|
||||||
|
($entity instanceof Project) => $value = (new ProjectDecorator($entity, $key))->transform(),
|
||||||
|
($entity instanceof Product) => $value = (new ProductDecorator($entity, $key))->transform(),
|
||||||
|
($entity instanceof Vendor) => $value = (new VendorDecorator($entity, $key))->transform(),
|
||||||
|
($entity instanceof PurchaseOrder) => $value = (new PurchaseOrderDecorator($entity, $key))->transform(),
|
||||||
|
default => $value = '',
|
||||||
|
};
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
16
app/Export/Decorators/DecoratorInterface.php
Normal file
16
app/Export/Decorators/DecoratorInterface.php
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Export\Decorators;
|
||||||
|
|
||||||
|
interface DecoratorInterface {
|
||||||
|
public function transform(): string;
|
||||||
|
}
|
20
app/Export/Decorators/ExpenseDecorator.php
Normal file
20
app/Export/Decorators/ExpenseDecorator.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Export\Decorators;
|
||||||
|
|
||||||
|
class ExpenseDecorator implements DecoratorInterface
|
||||||
|
{
|
||||||
|
public function transform(): string
|
||||||
|
{
|
||||||
|
return 'Payment Decorator';
|
||||||
|
}
|
||||||
|
}
|
20
app/Export/Decorators/InvoiceDecorator.php
Normal file
20
app/Export/Decorators/InvoiceDecorator.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Export\Decorators;
|
||||||
|
|
||||||
|
class InvoiceDecorator implements DecoratorInterface
|
||||||
|
{
|
||||||
|
public function transform(): string
|
||||||
|
{
|
||||||
|
return 'Payment Decorator';
|
||||||
|
}
|
||||||
|
}
|
20
app/Export/Decorators/PaymentDecorator.php
Normal file
20
app/Export/Decorators/PaymentDecorator.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Export\Decorators;
|
||||||
|
|
||||||
|
class PaymentDecorator implements DecoratorInterface{
|
||||||
|
|
||||||
|
public function transform(): string
|
||||||
|
{
|
||||||
|
return 'Payment Decorator';
|
||||||
|
}
|
||||||
|
}
|
20
app/Export/Decorators/ProductDecorator.php
Normal file
20
app/Export/Decorators/ProductDecorator.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Export\Decorators;
|
||||||
|
|
||||||
|
class ProductDecorator implements DecoratorInterface
|
||||||
|
{
|
||||||
|
public function transform(): string
|
||||||
|
{
|
||||||
|
return 'Payment Decorator';
|
||||||
|
}
|
||||||
|
}
|
20
app/Export/Decorators/ProjectDecorator.php
Normal file
20
app/Export/Decorators/ProjectDecorator.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Export\Decorators;
|
||||||
|
|
||||||
|
class ProjectDecorator implements DecoratorInterface
|
||||||
|
{
|
||||||
|
public function transform(): string
|
||||||
|
{
|
||||||
|
return 'Payment Decorator';
|
||||||
|
}
|
||||||
|
}
|
20
app/Export/Decorators/PurchaseOrderDecorator.php
Normal file
20
app/Export/Decorators/PurchaseOrderDecorator.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Export\Decorators;
|
||||||
|
|
||||||
|
class PurchaseOrderDecorator implements DecoratorInterface
|
||||||
|
{
|
||||||
|
public function transform(): string
|
||||||
|
{
|
||||||
|
return 'Payment Decorator';
|
||||||
|
}
|
||||||
|
}
|
20
app/Export/Decorators/QuoteDecorator.php
Normal file
20
app/Export/Decorators/QuoteDecorator.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Export\Decorators;
|
||||||
|
|
||||||
|
class QuoteDecorator implements DecoratorInterface
|
||||||
|
{
|
||||||
|
public function transform(): string
|
||||||
|
{
|
||||||
|
return 'Payment Decorator';
|
||||||
|
}
|
||||||
|
}
|
20
app/Export/Decorators/RecurringInvoiceDecorator.php
Normal file
20
app/Export/Decorators/RecurringInvoiceDecorator.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Export\Decorators;
|
||||||
|
|
||||||
|
class RecurringInvoiceDecorator implements DecoratorInterface
|
||||||
|
{
|
||||||
|
public function transform(): string
|
||||||
|
{
|
||||||
|
return 'Payment Decorator';
|
||||||
|
}
|
||||||
|
}
|
20
app/Export/Decorators/TaskDecorator.php
Normal file
20
app/Export/Decorators/TaskDecorator.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Export\Decorators;
|
||||||
|
|
||||||
|
class TaskDecorator implements DecoratorInterface
|
||||||
|
{
|
||||||
|
public function transform(): string
|
||||||
|
{
|
||||||
|
return 'Payment Decorator';
|
||||||
|
}
|
||||||
|
}
|
20
app/Export/Decorators/VendorDecorator.php
Normal file
20
app/Export/Decorators/VendorDecorator.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Export\Decorators;
|
||||||
|
|
||||||
|
class VendorDecorator implements DecoratorInterface
|
||||||
|
{
|
||||||
|
public function transform(): string
|
||||||
|
{
|
||||||
|
return 'Payment Decorator';
|
||||||
|
}
|
||||||
|
}
|
@ -11,13 +11,13 @@
|
|||||||
|
|
||||||
namespace App\Factory;
|
namespace App\Factory;
|
||||||
|
|
||||||
use App\DataMapper\ClientRegistrationFields;
|
|
||||||
use App\DataMapper\CompanySettings;
|
|
||||||
use App\DataMapper\Tax\TaxModel;
|
|
||||||
use App\Libraries\MultiDB;
|
|
||||||
use App\Models\Company;
|
|
||||||
use App\Utils\Ninja;
|
use App\Utils\Ninja;
|
||||||
|
use App\Models\Company;
|
||||||
|
use App\Libraries\MultiDB;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
|
use App\DataMapper\Tax\TaxModel;
|
||||||
|
use App\DataMapper\CompanySettings;
|
||||||
|
use App\DataMapper\ClientRegistrationFields;
|
||||||
|
|
||||||
class CompanyFactory
|
class CompanyFactory
|
||||||
{
|
{
|
||||||
@ -48,7 +48,7 @@ class CompanyFactory
|
|||||||
$company->markdown_email_enabled = true;
|
$company->markdown_email_enabled = true;
|
||||||
$company->markdown_enabled = false;
|
$company->markdown_enabled = false;
|
||||||
$company->tax_data = new TaxModel();
|
$company->tax_data = new TaxModel();
|
||||||
|
$company->first_month_of_year = 1;
|
||||||
return $company;
|
return $company;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -93,6 +93,7 @@ class DesignFilters extends QueryFilters
|
|||||||
|
|
||||||
return $this->builder->where('is_template', $bool_val);
|
return $this->builder->where('is_template', $bool_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filter the designs by `is_custom` column.
|
* Filter the designs by `is_custom` column.
|
||||||
*
|
*
|
||||||
|
@ -527,7 +527,10 @@ class LoginController extends BaseController
|
|||||||
|
|
||||||
if (request()->has('id_token')) {
|
if (request()->has('id_token')) {
|
||||||
$user = $google->getTokenResponse(request()->input('id_token'));
|
$user = $google->getTokenResponse(request()->input('id_token'));
|
||||||
} else {
|
}elseif(request()->has('access_token')){
|
||||||
|
$user = $google->harvestUser(request()->input('access_token'));
|
||||||
|
}
|
||||||
|
else {
|
||||||
return response()->json(['message' => 'Illegal request'], 403);
|
return response()->json(['message' => 'Illegal request'], 403);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,8 +69,11 @@ class EmailController extends BaseController
|
|||||||
/** @var \App\Models\User $user */
|
/** @var \App\Models\User $user */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
|
|
||||||
if ($request->has('cc_email') && $request->cc_email && (Ninja::isSelfHost() || $user->account->isPaidHostedClient())) {
|
if ($request->has('cc_email') && (Ninja::isSelfHost() || $user->account->isPaidHostedClient())) {
|
||||||
$mo->cc[] = new Address($request->cc_email);
|
|
||||||
|
foreach($request->cc_email as $email)
|
||||||
|
$mo->cc[] = new Address($email);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$entity_obj->invitations->each(function ($invitation) use ($entity_obj, $mo) {
|
$entity_obj->invitations->each(function ($invitation) use ($entity_obj, $mo) {
|
||||||
|
@ -56,11 +56,14 @@ class ExportController extends BaseController
|
|||||||
*/
|
*/
|
||||||
public function index(StoreExportRequest $request)
|
public function index(StoreExportRequest $request)
|
||||||
{
|
{
|
||||||
|
/** @var \App\Models\User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
$hash = Str::uuid();
|
$hash = Str::uuid();
|
||||||
$url = \Illuminate\Support\Facades\URL::temporarySignedRoute('protected_download', now()->addHour(), ['hash' => $hash]);
|
$url = \Illuminate\Support\Facades\URL::temporarySignedRoute('protected_download', now()->addHour(), ['hash' => $hash]);
|
||||||
Cache::put($hash, $url, now()->addHour());
|
Cache::put($hash, $url, now()->addHour());
|
||||||
|
|
||||||
CompanyExport::dispatch(auth()->user()->getCompany(), auth()->user(), $hash);
|
CompanyExport::dispatch($user->getCompany(), $user, $hash);
|
||||||
|
|
||||||
return response()->json(['message' => 'Processing', 'url' => $url], 200);
|
return response()->json(['message' => 'Processing', 'url' => $url], 200);
|
||||||
}
|
}
|
||||||
|
@ -416,7 +416,6 @@ class InvoiceController extends BaseController
|
|||||||
|
|
||||||
$invoice->service()
|
$invoice->service()
|
||||||
->triggeredActions($request)
|
->triggeredActions($request)
|
||||||
// ->deletePdf()
|
|
||||||
->adjustInventory($old_invoice);
|
->adjustInventory($old_invoice);
|
||||||
|
|
||||||
event(new InvoiceWasUpdated($invoice, $invoice->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
event(new InvoiceWasUpdated($invoice, $invoice->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||||
|
@ -137,9 +137,9 @@ class PreviewController extends BaseController
|
|||||||
*/
|
*/
|
||||||
public function show()
|
public function show()
|
||||||
{
|
{
|
||||||
// if(request()->has('template')) {
|
if(request()->has('template')) {
|
||||||
return $this->template();
|
return $this->template();
|
||||||
// }
|
}
|
||||||
|
|
||||||
if (request()->has('entity') &&
|
if (request()->has('entity') &&
|
||||||
request()->has('entity_id') &&
|
request()->has('entity_id') &&
|
||||||
|
@ -19,10 +19,10 @@ use Illuminate\Support\Facades\Storage;
|
|||||||
class ProtectedDownloadController extends BaseController
|
class ProtectedDownloadController extends BaseController
|
||||||
{
|
{
|
||||||
|
|
||||||
public function index(Request $request)
|
public function index(Request $request, string $hash)
|
||||||
{
|
{
|
||||||
/** @var string $hashed_path */
|
/** @var string $hashed_path */
|
||||||
$hashed_path = Cache::pull($request->hash);
|
$hashed_path = Cache::pull($hash);
|
||||||
|
|
||||||
if (!$hashed_path) {
|
if (!$hashed_path) {
|
||||||
throw new SystemError('File no longer available', 404);
|
throw new SystemError('File no longer available', 404);
|
||||||
|
@ -17,6 +17,48 @@ use Illuminate\Support\Facades\App;
|
|||||||
|
|
||||||
class Locale
|
class Locale
|
||||||
{
|
{
|
||||||
|
private array $locales = [
|
||||||
|
'en',
|
||||||
|
'it',
|
||||||
|
'de',
|
||||||
|
'fr',
|
||||||
|
'pt_BR',
|
||||||
|
'nl',
|
||||||
|
'es',
|
||||||
|
'nb_NO',
|
||||||
|
'da',
|
||||||
|
'ja',
|
||||||
|
'sv',
|
||||||
|
'es_ES',
|
||||||
|
'fr_CA',
|
||||||
|
'lt',
|
||||||
|
'pl',
|
||||||
|
'cs',
|
||||||
|
'hr',
|
||||||
|
'sq',
|
||||||
|
'el',
|
||||||
|
'en_GB',
|
||||||
|
'pt_PT',
|
||||||
|
'sl',
|
||||||
|
'fi',
|
||||||
|
'ro',
|
||||||
|
'tr_TR',
|
||||||
|
'th',
|
||||||
|
'mk_MK',
|
||||||
|
'zh_TW',
|
||||||
|
'ru_RU',
|
||||||
|
'ar',
|
||||||
|
'fa',
|
||||||
|
'lv_LV',
|
||||||
|
'sr',
|
||||||
|
'sk',
|
||||||
|
'et',
|
||||||
|
'bg',
|
||||||
|
'he',
|
||||||
|
'km_KH',
|
||||||
|
'hu',
|
||||||
|
'fr_CH',
|
||||||
|
];
|
||||||
/**
|
/**
|
||||||
* Handle an incoming request.
|
* Handle an incoming request.
|
||||||
*
|
*
|
||||||
@ -25,10 +67,10 @@ class Locale
|
|||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function handle($request, Closure $next)
|
public function handle($request, Closure $next)
|
||||||
{
|
{
|
||||||
/*LOCALE SET */
|
/*LOCALE SET */
|
||||||
if ($request->has('lang') && is_string($request->input('lang'))) {
|
if ($request->has('lang') && in_array($request->input('lang','en'), $this->locales) ) {
|
||||||
$locale = $request->string('lang','en');
|
$locale = $request->input('lang');
|
||||||
App::setLocale($locale);
|
App::setLocale($locale);
|
||||||
} elseif (auth()->guard('contact')->user()) {
|
} elseif (auth()->guard('contact')->user()) {
|
||||||
App::setLocale(auth()->guard('contact')->user()->client()->setEagerLoads([])->first()->locale());
|
App::setLocale(auth()->guard('contact')->user()->client()->setEagerLoads([])->first()->locale());
|
||||||
|
@ -17,6 +17,48 @@ use Illuminate\Support\Facades\App;
|
|||||||
|
|
||||||
class VendorLocale
|
class VendorLocale
|
||||||
{
|
{
|
||||||
|
private array $locales = [
|
||||||
|
'en',
|
||||||
|
'it',
|
||||||
|
'de',
|
||||||
|
'fr',
|
||||||
|
'pt_BR',
|
||||||
|
'nl',
|
||||||
|
'es',
|
||||||
|
'nb_NO',
|
||||||
|
'da',
|
||||||
|
'ja',
|
||||||
|
'sv',
|
||||||
|
'es_ES',
|
||||||
|
'fr_CA',
|
||||||
|
'lt',
|
||||||
|
'pl',
|
||||||
|
'cs',
|
||||||
|
'hr',
|
||||||
|
'sq',
|
||||||
|
'el',
|
||||||
|
'en_GB',
|
||||||
|
'pt_PT',
|
||||||
|
'sl',
|
||||||
|
'fi',
|
||||||
|
'ro',
|
||||||
|
'tr_TR',
|
||||||
|
'th',
|
||||||
|
'mk_MK',
|
||||||
|
'zh_TW',
|
||||||
|
'ru_RU',
|
||||||
|
'ar',
|
||||||
|
'fa',
|
||||||
|
'lv_LV',
|
||||||
|
'sr',
|
||||||
|
'sk',
|
||||||
|
'et',
|
||||||
|
'bg',
|
||||||
|
'he',
|
||||||
|
'km_KH',
|
||||||
|
'hu',
|
||||||
|
'fr_CH',
|
||||||
|
];
|
||||||
/**
|
/**
|
||||||
* Handle an incoming request.
|
* Handle an incoming request.
|
||||||
*
|
*
|
||||||
@ -32,7 +74,7 @@ class VendorLocale
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*LOCALE SET */
|
/*LOCALE SET */
|
||||||
if ($request->has('lang') && is_string($request->input('lang'))) {
|
if ($request->has('lang') && in_array($request->input('lang','en'), $this->locales) ) {
|
||||||
$locale = $request->input('lang');
|
$locale = $request->input('lang');
|
||||||
App::setLocale($locale);
|
App::setLocale($locale);
|
||||||
} elseif (auth()->guard('vendor')->user()) {
|
} elseif (auth()->guard('vendor')->user()) {
|
||||||
|
@ -43,8 +43,10 @@ class SendEmailRequest extends Request
|
|||||||
'template' => 'bail|required',
|
'template' => 'bail|required',
|
||||||
'entity' => 'bail|required',
|
'entity' => 'bail|required',
|
||||||
'entity_id' => 'bail|required',
|
'entity_id' => 'bail|required',
|
||||||
'cc_email' => 'bail|sometimes|email|nullable',
|
'cc_email.*' => 'bail|sometimes|email|nullable',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function prepareForValidation()
|
public function prepareForValidation()
|
||||||
@ -72,6 +74,14 @@ class SendEmailRequest extends Request
|
|||||||
$input['entity'] = "App\Models\\".ucfirst(Str::camel($input['entity']));
|
$input['entity'] = "App\Models\\".ucfirst(Str::camel($input['entity']));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(isset($input['cc_email'])){
|
||||||
|
$input['cc_email'] = collect(explode(",", $input['cc_email']))->map(function($email){
|
||||||
|
return trim($email);
|
||||||
|
})->filter(function($email){
|
||||||
|
return filter_var($email, FILTER_VALIDATE_EMAIL);
|
||||||
|
})->slice(0,4)->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
$this->replace($input);
|
$this->replace($input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,7 +22,10 @@ class ImportRequest extends Request
|
|||||||
*/
|
*/
|
||||||
public function authorize() : bool
|
public function authorize() : bool
|
||||||
{
|
{
|
||||||
return auth()->user()->isAdmin();
|
/** @var \App\Models\User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
|
return $user->isAdmin();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function rules()
|
public function rules()
|
||||||
|
@ -24,7 +24,7 @@ class TaskMap
|
|||||||
4 => 'client.name',
|
4 => 'client.name',
|
||||||
5 => 'client.email',
|
5 => 'client.email',
|
||||||
6 => 'task.description',
|
6 => 'task.description',
|
||||||
7 => 'task.is_billable',
|
7 => 'task.billable',
|
||||||
8 => 'task.start_date',
|
8 => 'task.start_date',
|
||||||
9 => 'task.end_date',
|
9 => 'task.end_date',
|
||||||
10 => 'task.start_time',
|
10 => 'task.start_time',
|
||||||
|
@ -162,11 +162,12 @@ class BaseImport
|
|||||||
|
|
||||||
private function groupTasks($csvData, $key)
|
private function groupTasks($csvData, $key)
|
||||||
{
|
{
|
||||||
|
nlog($csvData[0]);
|
||||||
|
|
||||||
if (! $key || count(array_column($csvData, $key)) == 0) {
|
if (! $key || !is_array($csvData) || count($csvData) == 0 || !isset($csvData[0]['task.number']) || empty($csvData[0]['task.number'])) {
|
||||||
return $csvData;
|
return $csvData;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Group by tasks.
|
// Group by tasks.
|
||||||
$grouped = [];
|
$grouped = [];
|
||||||
|
|
||||||
@ -495,7 +496,7 @@ class BaseImport
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nlog($count);
|
|
||||||
return $count;
|
return $count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ class BaseTransformer
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function getString($data, $field)
|
public function getString($data, $field)
|
||||||
{
|
{
|
||||||
return isset($data[$field]) && $data[$field] ? trim($data[$field]) : '';
|
return isset($data[$field]) && $data[$field] ? trim($data[$field]) : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,6 +179,7 @@ class BaseTransformer
|
|||||||
|
|
||||||
public function getClient($client_name, $client_email)
|
public function getClient($client_name, $client_email)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (! empty($client_name)) {
|
if (! empty($client_name)) {
|
||||||
$client_id_search = Client::query()->where('company_id', $this->company->id)
|
$client_id_search = Client::query()->where('company_id', $this->company->id)
|
||||||
->where('is_deleted', false)
|
->where('is_deleted', false)
|
||||||
|
@ -29,8 +29,11 @@ class TaskTransformer extends BaseTransformer
|
|||||||
{
|
{
|
||||||
$this->stubbed_timestamp = time();
|
$this->stubbed_timestamp = time();
|
||||||
|
|
||||||
$task_data = reset($task_items_data);
|
if(count($task_items_data) == count($task_items_data, COUNT_RECURSIVE))
|
||||||
|
$task_data = $task_items_data;
|
||||||
|
else
|
||||||
|
$task_data = reset($task_items_data);
|
||||||
|
|
||||||
$clientId = $this->getClient(
|
$clientId = $this->getClient(
|
||||||
$this->getString($task_data, 'client.name'),
|
$this->getString($task_data, 'client.name'),
|
||||||
$this->getString($task_data, 'client.email')
|
$this->getString($task_data, 'client.email')
|
||||||
|
@ -492,7 +492,7 @@ class CompanyExport implements ShouldQueue
|
|||||||
$nmo->company = $company_reference;
|
$nmo->company = $company_reference;
|
||||||
$nmo->settings = $this->company->settings;
|
$nmo->settings = $this->company->settings;
|
||||||
|
|
||||||
NinjaMailerJob::dispatch($nmo, true);
|
(new NinjaMailerJob($nmo, true))->handle();
|
||||||
|
|
||||||
UnlinkFile::dispatch(config('filesystems.default'), $storage_path)->delay(now()->addHours(1));
|
UnlinkFile::dispatch(config('filesystems.default'), $storage_path)->delay(now()->addHours(1));
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ class CSVIngest implements ShouldQueue
|
|||||||
|
|
||||||
$engine = $this->bootEngine();
|
$engine = $this->bootEngine();
|
||||||
|
|
||||||
foreach (['client', 'product', 'invoice', 'payment', 'vendor', 'expense', 'quote', 'bank_transaction', 'recurring_invoice'] as $entity) {
|
foreach (['client', 'product', 'invoice', 'payment', 'vendor', 'expense', 'quote', 'bank_transaction', 'recurring_invoice', 'task'] as $entity) {
|
||||||
$engine->import($entity);
|
$engine->import($entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,6 +74,7 @@ class EmailPayment implements ShouldQueue
|
|||||||
|
|
||||||
if($this->settings->payment_email_all_contacts && $this->payment->invoices && $this->payment->invoices->count() >= 1) {
|
if($this->settings->payment_email_all_contacts && $this->payment->invoices && $this->payment->invoices->count() >= 1) {
|
||||||
$this->emailAllContacts($email_builder);
|
$this->emailAllContacts($email_builder);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$invitation = null;
|
$invitation = null;
|
||||||
|
@ -96,8 +96,6 @@ class EmailRefundPayment implements ShouldQueue
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$nmo->mailable = new TemplateEmail($email_builder, $this->contact, $invitation);
|
$nmo->mailable = new TemplateEmail($email_builder, $this->contact, $invitation);
|
||||||
$nmo->to_user = $this->contact;
|
$nmo->to_user = $this->contact;
|
||||||
$nmo->settings = $this->settings;
|
$nmo->settings = $this->settings;
|
||||||
|
@ -388,7 +388,7 @@ class ProcessPostmarkWebhook implements ShouldQueue
|
|||||||
'delivery_message' => $event->Details->DeliveryMessage ?? $event->Details->Summary ?? '',
|
'delivery_message' => $event->Details->DeliveryMessage ?? $event->Details->Summary ?? '',
|
||||||
'server' => $event->Details->DestinationServer ?? '',
|
'server' => $event->Details->DestinationServer ?? '',
|
||||||
'server_ip' => $event->Details->DestinationIP ?? '',
|
'server_ip' => $event->Details->DestinationIP ?? '',
|
||||||
'date' => \Carbon\Carbon::parse($event->ReceivedAt)->format('Y-m-d H:m:s') ?? '',
|
'date' => \Carbon\Carbon::parse($event->ReceivedAt)->format('Y-m-d H:i:s') ?? '',
|
||||||
];
|
];
|
||||||
|
|
||||||
})->toArray();
|
})->toArray();
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
namespace App\Libraries\OAuth\Providers;
|
namespace App\Libraries\OAuth\Providers;
|
||||||
|
|
||||||
use Google_Client;
|
use Google_Client;
|
||||||
|
|
||||||
class Google implements ProviderInterface
|
class Google implements ProviderInterface
|
||||||
{
|
{
|
||||||
public function getTokenResponse($token)
|
public function getTokenResponse($token)
|
||||||
@ -27,4 +26,28 @@ class Google implements ProviderInterface
|
|||||||
{
|
{
|
||||||
return $payload['name'];
|
return $payload['name'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function harvestUser($access_token)
|
||||||
|
{
|
||||||
|
$client = new Google_Client();
|
||||||
|
$client->setClientId(config('ninja.auth.google.client_id'));
|
||||||
|
$client->setClientSecret(config('ninja.auth.google.client_secret'));
|
||||||
|
$client->setAccessToken($access_token);
|
||||||
|
|
||||||
|
$oauth2 = new \Google_Service_Oauth2($client);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$userInfo = $oauth2->userinfo->get();
|
||||||
|
}
|
||||||
|
catch (\Exception $e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'email' => $userInfo['email'],
|
||||||
|
'sub' => $userInfo['id'],
|
||||||
|
'name' => $userInfo['name'],
|
||||||
|
];
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -103,7 +103,7 @@ class ClientPresenter extends EntityPresenter
|
|||||||
if ($cityState = $this->getShippingCityState()) {
|
if ($cityState = $this->getShippingCityState()) {
|
||||||
$str .= e($cityState).'<br/>';
|
$str .= e($cityState).'<br/>';
|
||||||
}
|
}
|
||||||
if ($country = $client->shipping_country) {
|
if ($country = $client->shipping_country ?? $client->country) {
|
||||||
$str .= e($country->name).'<br/>';
|
$str .= e($country->name).'<br/>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,10 +261,10 @@ class Task extends BaseModel
|
|||||||
$parent_entity = $this->client ?? $this->company;
|
$parent_entity = $this->client ?? $this->company;
|
||||||
|
|
||||||
if($log[0])
|
if($log[0])
|
||||||
$log[0] = Carbon::createFromTimestamp($log[0])->format($parent_entity->date_format().' H:m:s');
|
$log[0] = Carbon::createFromTimestamp($log[0])->format($parent_entity->date_format().' H:i:s');
|
||||||
|
|
||||||
if($log[1] && $log[1] != 0)
|
if($log[1] && $log[1] != 0)
|
||||||
$log[1] = Carbon::createFromTimestamp($log[1])->format($parent_entity->date_format().' H:m:s');
|
$log[1] = Carbon::createFromTimestamp($log[1])->format($parent_entity->date_format().' H:i:s');
|
||||||
else
|
else
|
||||||
$log[1] = ctrans('texts.running');
|
$log[1] = ctrans('texts.running');
|
||||||
|
|
||||||
@ -291,17 +291,21 @@ class Task extends BaseModel
|
|||||||
|
|
||||||
if($log[0])
|
if($log[0])
|
||||||
$logged['start_date_raw'] = $log[0];
|
$logged['start_date_raw'] = $log[0];
|
||||||
$logged['start_date'] = Carbon::createFromTimestamp($log[0])->format($parent_entity->date_format().' H:m:s');
|
$logged['start_date'] = Carbon::createFromTimestamp($log[0])->setTimeZone($this->company->timezone()->name)->format($parent_entity->date_format().' H:i:s');
|
||||||
|
|
||||||
if($log[1] && $log[1] != 0) {
|
if($log[1] && $log[1] != 0) {
|
||||||
$logged['end_date_raw'] = $log[1];
|
$logged['end_date_raw'] = $log[1];
|
||||||
$logged['end_date'] = Carbon::createFromTimestamp($log[1])->format($parent_entity->date_format().' H:m:s');
|
$logged['end_date'] = Carbon::createFromTimestamp($log[1])->setTimeZone($this->company->timezone()->name)->format($parent_entity->date_format().' H:i:s');
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
$logged['end_date_raw'] = 0;
|
$logged['end_date_raw'] = 0;
|
||||||
$logged['end_date'] = ctrans('texts.running');
|
$logged['end_date'] = ctrans('texts.running');
|
||||||
}
|
}
|
||||||
$logged['duration'] = $duration;
|
|
||||||
|
$logged['description'] = $log[2];
|
||||||
|
$logged['billable'] = $log[3];
|
||||||
|
$logged['duration_raw'] = $duration;
|
||||||
|
$logged['duration'] = gmdate("H:i:s", $duration);
|
||||||
|
|
||||||
return $logged;
|
return $logged;
|
||||||
|
|
||||||
|
@ -743,29 +743,20 @@ class BaseDriver extends AbstractPaymentDriver
|
|||||||
}
|
}
|
||||||
|
|
||||||
$invoices_string = str_replace(["*","<",">","'",'"'], "-", $invoices_string);
|
$invoices_string = str_replace(["*","<",">","'",'"'], "-", $invoices_string);
|
||||||
// $invoices_string = "I-".$invoices_string;
|
|
||||||
// $invoices_string = substr($invoices_string, 0, 22);
|
|
||||||
|
|
||||||
// 2023-11-02 - improve the statement descriptor for string
|
// 2023-11-02 - improve the statement descriptor for string
|
||||||
|
|
||||||
$company_name = $this->client->company->present()->name();
|
$company_name = $this->client->company->present()->name();
|
||||||
|
$company_name = str_replace(["*","<",">","'",'"'], "-", $company_name);
|
||||||
|
|
||||||
if(ctype_digit(substr($company_name, 0, 1)))
|
if(ctype_digit(substr($company_name, 0, 1))) {
|
||||||
$company_name = "X" . $company_name;
|
$company_name = "I" . $company_name;
|
||||||
|
}
|
||||||
$suffix = strlen($invoices_string) + 1;
|
|
||||||
|
|
||||||
$length = 22 - $suffix;
|
|
||||||
|
|
||||||
$company_name = substr($company_name, 0, $length);
|
|
||||||
|
|
||||||
|
$company_name = substr($company_name, 0, 11);
|
||||||
$descriptor = "{$company_name} {$invoices_string}";
|
$descriptor = "{$company_name} {$invoices_string}";
|
||||||
|
$descriptor = substr($descriptor, 0, 22);
|
||||||
$invoices_string = str_pad($descriptor, 5, ctrans('texts.invoice'), STR_PAD_RIGHT);
|
return $descriptor;
|
||||||
$invoices_string = substr($invoices_string, 0, 22);
|
|
||||||
|
|
||||||
// $invoices_string = str_pad($invoices_string, 5, ctrans('texts.invoice'), STR_PAD_LEFT);
|
|
||||||
|
|
||||||
return $invoices_string;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
@ -28,7 +28,7 @@ class ClientContactRepository extends BaseRepository
|
|||||||
|
|
||||||
public function save(array $data, Client $client) : void
|
public function save(array $data, Client $client) : void
|
||||||
{
|
{
|
||||||
//06-09-2022 sometimes users pass a contact object instead of a nested array, this sequence handles this scenario
|
|
||||||
if (isset($data['contacts']) && (count($data['contacts']) !== count($data['contacts'], COUNT_RECURSIVE))) {
|
if (isset($data['contacts']) && (count($data['contacts']) !== count($data['contacts'], COUNT_RECURSIVE))) {
|
||||||
$contacts = collect($data['contacts']);
|
$contacts = collect($data['contacts']);
|
||||||
} elseif (isset($data['contacts'])) {
|
} elseif (isset($data['contacts'])) {
|
||||||
|
@ -25,8 +25,12 @@ class VendorContactRepository extends BaseRepository
|
|||||||
|
|
||||||
public function save(array $data, Vendor $vendor) : void
|
public function save(array $data, Vendor $vendor) : void
|
||||||
{
|
{
|
||||||
if (isset($data['contacts'])) {
|
|
||||||
|
if (isset($data['contacts']) && (count($data['contacts']) !== count($data['contacts'], COUNT_RECURSIVE))) {
|
||||||
$contacts = collect($data['contacts']);
|
$contacts = collect($data['contacts']);
|
||||||
|
} elseif (isset($data['contacts'])) {
|
||||||
|
$temp_array[] = $data['contacts'];
|
||||||
|
$contacts = collect($temp_array);
|
||||||
} else {
|
} else {
|
||||||
$contacts = collect();
|
$contacts = collect();
|
||||||
}
|
}
|
||||||
@ -80,10 +84,10 @@ class VendorContactRepository extends BaseRepository
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$vendor->load('contacts');
|
$vendor->fresh();
|
||||||
|
|
||||||
//always made sure we have one blank contact to maintain state
|
//always made sure we have one blank contact to maintain state
|
||||||
if ($vendor->contacts->count() == 0) {
|
if ($vendor->contacts()->count() == 0) {
|
||||||
$new_contact = new VendorContact;
|
$new_contact = new VendorContact;
|
||||||
$new_contact->vendor_id = $vendor->id;
|
$new_contact->vendor_id = $vendor->id;
|
||||||
$new_contact->company_id = $vendor->company_id;
|
$new_contact->company_id = $vendor->company_id;
|
||||||
|
@ -55,19 +55,15 @@ class VendorRepository extends BaseRepository
|
|||||||
|
|
||||||
if ($vendor->number == '' || ! $vendor->number) {
|
if ($vendor->number == '' || ! $vendor->number) {
|
||||||
$vendor->number = $this->getNextVendorNumber($vendor);
|
$vendor->number = $this->getNextVendorNumber($vendor);
|
||||||
} //todo write tests for this and make sure that custom vendor numbers also works as expected from here
|
}
|
||||||
|
|
||||||
$vendor->saveQuietly();
|
$vendor->saveQuietly();
|
||||||
|
|
||||||
if (isset($data['contacts'])) {
|
if (isset($data['contacts']) || $vendor->contacts()->count() == 0) {
|
||||||
$this->contact_repo->save($data, $vendor);
|
$this->contact_repo->save($data, $vendor);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($data['name'])) {
|
if (array_key_exists('documents', $data) && count($data['documents']) >= 1) {
|
||||||
$data['name'] = $vendor->present()->name();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (array_key_exists('documents', $data)) {
|
|
||||||
$this->saveDocuments($data['documents'], $vendor);
|
$this->saveDocuments($data['documents'], $vendor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,7 +158,12 @@ class Statement
|
|||||||
->where('company_id', $this->client->company_id)
|
->where('company_id', $this->client->company_id)
|
||||||
->first();
|
->first();
|
||||||
|
|
||||||
$ts = $template->service()->build([
|
$ts = $template->service();
|
||||||
|
$ts->addGlobal(['show_credits' => $this->options['show_credits_table']]);
|
||||||
|
$ts->addGlobal(['show_aging' => $this->options['show_aging_table']]);
|
||||||
|
$ts->addGlobal(['show_payments' => $this->options['show_payments_table']]);
|
||||||
|
|
||||||
|
$ts->build([
|
||||||
'variables' => collect([$variables]),
|
'variables' => collect([$variables]),
|
||||||
'invoices' => $this->getInvoices()->get(),
|
'invoices' => $this->getInvoices()->get(),
|
||||||
'payments' => $this->options['show_payments_table'] ? $this->getPayments()->get() : collect([]),
|
'payments' => $this->options['show_payments_table'] ? $this->getPayments()->get() : collect([]),
|
||||||
@ -400,6 +405,7 @@ class Statement
|
|||||||
protected function getAging(): array
|
protected function getAging(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
|
ctrans('texts.current') => $this->getAgingAmount('0'),
|
||||||
'0-30' => $this->getAgingAmount('30'),
|
'0-30' => $this->getAgingAmount('30'),
|
||||||
'30-60' => $this->getAgingAmount('60'),
|
'30-60' => $this->getAgingAmount('60'),
|
||||||
'60-90' => $this->getAgingAmount('90'),
|
'60-90' => $this->getAgingAmount('90'),
|
||||||
@ -421,14 +427,23 @@ class Statement
|
|||||||
$from = $ranges[0];
|
$from = $ranges[0];
|
||||||
$to = $ranges[1];
|
$to = $ranges[1];
|
||||||
|
|
||||||
$amount = Invoice::withTrashed()
|
$query = Invoice::withTrashed()
|
||||||
->where('client_id', $this->client->id)
|
->where('client_id', $this->client->id)
|
||||||
->where('company_id', $this->client->company_id)
|
->where('company_id', $this->client->company_id)
|
||||||
->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL])
|
->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL])
|
||||||
->where('balance', '>', 0)
|
->where('balance', '>', 0)
|
||||||
->where('is_deleted', 0)
|
->where('is_deleted', 0);
|
||||||
->whereBetween('due_date', [$to, $from])
|
|
||||||
->sum('balance');
|
if($range == '0'){
|
||||||
|
$query->where(function ($q) use($to, $from){
|
||||||
|
$q->whereBetween('due_date', [$to, $from])->orWhereNull('due_date');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$query->whereBetween('due_date', [$to, $from]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$amount = $query->sum('balance');
|
||||||
|
|
||||||
return Number::formatMoney($amount, $this->client);
|
return Number::formatMoney($amount, $this->client);
|
||||||
}
|
}
|
||||||
@ -444,6 +459,10 @@ class Statement
|
|||||||
$ranges = [];
|
$ranges = [];
|
||||||
|
|
||||||
switch ($range) {
|
switch ($range) {
|
||||||
|
case '0':
|
||||||
|
$ranges[0] = now()->subYears(50);
|
||||||
|
$ranges[1] = now()->startOfDay()->subMinute();
|
||||||
|
return $ranges;
|
||||||
case '30':
|
case '30':
|
||||||
$ranges[0] = now()->startOfDay();
|
$ranges[0] = now()->startOfDay();
|
||||||
$ranges[1] = now()->startOfDay()->subDays(30);
|
$ranges[1] = now()->startOfDay()->subDays(30);
|
||||||
|
@ -83,6 +83,8 @@ class InstantPayment
|
|||||||
->with(['message' => 'No payable invoices selected.']);
|
->with(['message' => 'No payable invoices selected.']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$invoices = Invoice::query()->whereIn('id', $this->transformKeys($payable_invoices->pluck('invoice_id')->toArray()))->withTrashed()->get();
|
||||||
|
|
||||||
$client = $invoices->first()->client;
|
$client = $invoices->first()->client;
|
||||||
$settings = $client->getMergedSettings();
|
$settings = $client->getMergedSettings();
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ class MarkPaid extends AbstractService
|
|||||||
'amount' => $this->payable_balance,
|
'amount' => $this->payable_balance,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if ($payment->company->getSetting('send_email_on_mark_paid')) {
|
if ($payment->client->getSetting('send_email_on_mark_paid')) {
|
||||||
$payment->service()->sendEmail();
|
$payment->service()->sendEmail();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -483,12 +483,15 @@ class PdfMock
|
|||||||
'_rate3' => '',
|
'_rate3' => '',
|
||||||
'$taxes' => '$40.00',
|
'$taxes' => '$40.00',
|
||||||
'$total' => '$10.00',
|
'$total' => '$10.00',
|
||||||
|
'$refund' => '',
|
||||||
|
'$refunded' => '',
|
||||||
'$phone' => ' ',
|
'$phone' => ' ',
|
||||||
'$terms' => 'Default company invoice terms',
|
'$terms' => 'Default company invoice terms',
|
||||||
'$from' => 'Bob Jones',
|
'$from' => 'Bob Jones',
|
||||||
'$item' => '',
|
'$item' => '',
|
||||||
'$date' => '25/Feb/2023',
|
'$date' => '25/Feb/2023',
|
||||||
'$tax' => '',
|
'$tax' => '',
|
||||||
|
'$net' => 'Net',
|
||||||
'$dir' => 'ltr',
|
'$dir' => 'ltr',
|
||||||
'$to' => 'Jimmy Giggles',
|
'$to' => 'Jimmy Giggles',
|
||||||
'$show_paid_stamp' => $this->settings->show_paid_stamp ? 'flex' : 'none',
|
'$show_paid_stamp' => $this->settings->show_paid_stamp ? 'flex' : 'none',
|
||||||
@ -803,6 +806,8 @@ class PdfMock
|
|||||||
'$tax_rate1_label' => ctrans('texts.tax_rate1'),
|
'$tax_rate1_label' => ctrans('texts.tax_rate1'),
|
||||||
'$tax_rate2_label' => ctrans('texts.tax_rate2'),
|
'$tax_rate2_label' => ctrans('texts.tax_rate2'),
|
||||||
'$tax_rate3_label' => ctrans('texts.tax_rate3'),
|
'$tax_rate3_label' => ctrans('texts.tax_rate3'),
|
||||||
|
'$refund_label' => ctrans('texts.refund'),
|
||||||
|
'$refunded_label' => ctrans('texts.refunded'),
|
||||||
'$phone_label' => ctrans('texts.phone'),
|
'$phone_label' => ctrans('texts.phone'),
|
||||||
'$email_label' => ctrans('texts.email'),
|
'$email_label' => ctrans('texts.email'),
|
||||||
'$taxes_label' => ctrans('texts.taxes'),
|
'$taxes_label' => ctrans('texts.taxes'),
|
||||||
@ -811,6 +816,7 @@ class PdfMock
|
|||||||
'$item_label' => ctrans('texts.item'),
|
'$item_label' => ctrans('texts.item'),
|
||||||
'$date_label' => ctrans('texts.date'),
|
'$date_label' => ctrans('texts.date'),
|
||||||
'$tax_label' => ctrans('texts.tax'),
|
'$tax_label' => ctrans('texts.tax'),
|
||||||
|
'$net_label' => ctrans('texts.net'),
|
||||||
'$dir_label' => '',
|
'$dir_label' => '',
|
||||||
'$to_label' => ctrans('texts.to'),
|
'$to_label' => ctrans('texts.to'),
|
||||||
'$start_date_label' => ctrans('texts.start_date'),
|
'$start_date_label' => ctrans('texts.start_date'),
|
||||||
@ -1115,6 +1121,8 @@ class PdfMock
|
|||||||
'$tax_rate1' => '',
|
'$tax_rate1' => '',
|
||||||
'$tax_rate2' => '',
|
'$tax_rate2' => '',
|
||||||
'$tax_rate3' => '',
|
'$tax_rate3' => '',
|
||||||
|
'$refund' => 'Refund',
|
||||||
|
'$refunded' => 'Refunded',
|
||||||
'$total' => '$10,256.40',
|
'$total' => '$10,256.40',
|
||||||
'$taxes' => '$488.40',
|
'$taxes' => '$488.40',
|
||||||
'$phone' => ' ',
|
'$phone' => ' ',
|
||||||
@ -1123,6 +1131,7 @@ class PdfMock
|
|||||||
'$date' => '14/Mar/2023',
|
'$date' => '14/Mar/2023',
|
||||||
'$tax' => '',
|
'$tax' => '',
|
||||||
'$dir' => 'ltr',
|
'$dir' => 'ltr',
|
||||||
|
'$net' => 'Net',
|
||||||
'$to' => '',
|
'$to' => '',
|
||||||
],
|
],
|
||||||
'labels' => $this->vendorLabels(),
|
'labels' => $this->vendorLabels(),
|
||||||
@ -1334,6 +1343,8 @@ class PdfMock
|
|||||||
'$tax_rate1_label' => ctrans('texts.tax_rate1'),
|
'$tax_rate1_label' => ctrans('texts.tax_rate1'),
|
||||||
'$tax_rate2_label' => ctrans('texts.tax_rate2'),
|
'$tax_rate2_label' => ctrans('texts.tax_rate2'),
|
||||||
'$tax_rate3_label' => ctrans('texts.tax_rate3'),
|
'$tax_rate3_label' => ctrans('texts.tax_rate3'),
|
||||||
|
'$refund_label' => ctrans('texts.refund'),
|
||||||
|
'$refunded_label' => ctrans('texts.refunded'),
|
||||||
'$total_label' => ctrans('texts.total'),
|
'$total_label' => ctrans('texts.total'),
|
||||||
'$taxes_label' => ctrans('texts.taxes'),
|
'$taxes_label' => ctrans('texts.taxes'),
|
||||||
'$phone_label' => ctrans('texts.phone'),
|
'$phone_label' => ctrans('texts.phone'),
|
||||||
@ -1341,6 +1352,7 @@ class PdfMock
|
|||||||
'$item_label' => ctrans('texts.item'),
|
'$item_label' => ctrans('texts.item'),
|
||||||
'$date_label' => ctrans('texts.date'),
|
'$date_label' => ctrans('texts.date'),
|
||||||
'$tax_label' => ctrans('texts.tax'),
|
'$tax_label' => ctrans('texts.tax'),
|
||||||
|
'$net_label' => ctrans('texts.net'),
|
||||||
'$dir_label' => '',
|
'$dir_label' => '',
|
||||||
'$to_label' => ctrans('texts.to'),
|
'$to_label' => ctrans('texts.to'),
|
||||||
];
|
];
|
||||||
|
@ -96,6 +96,7 @@ class TemplateAction implements ShouldQueue
|
|||||||
Project::class => $resource->with('client'),
|
Project::class => $resource->with('client'),
|
||||||
Expense::class => $resource->with('client'),
|
Expense::class => $resource->with('client'),
|
||||||
Payment::class => $resource->with('invoices', 'client'),
|
Payment::class => $resource->with('invoices', 'client'),
|
||||||
|
Client::class => $resource,
|
||||||
};
|
};
|
||||||
|
|
||||||
$result = $resource->withTrashed()
|
$result = $resource->withTrashed()
|
||||||
@ -103,7 +104,7 @@ class TemplateAction implements ShouldQueue
|
|||||||
->where('company_id', $this->company->id)
|
->where('company_id', $this->company->id)
|
||||||
->get();
|
->get();
|
||||||
|
|
||||||
nlog($result->toArray());
|
// nlog($result->toArray());
|
||||||
|
|
||||||
if($result->count() <= 1) {
|
if($result->count() <= 1) {
|
||||||
$data[$key] = collect($result);
|
$data[$key] = collect($result);
|
||||||
@ -111,7 +112,6 @@ class TemplateAction implements ShouldQueue
|
|||||||
$data[$key] = $result;
|
$data[$key] = $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$ts = $template_service
|
$ts = $template_service
|
||||||
->setCompany($this->company)
|
->setCompany($this->company)
|
||||||
->build($data);
|
->build($data);
|
||||||
|
File diff suppressed because one or more lines are too long
@ -11,31 +11,32 @@
|
|||||||
|
|
||||||
namespace App\Services\Template;
|
namespace App\Services\Template;
|
||||||
|
|
||||||
|
use App\Models\User;
|
||||||
|
use App\Models\Quote;
|
||||||
|
use App\Utils\Number;
|
||||||
|
use Twig\Error\Error;
|
||||||
use App\Models\Client;
|
use App\Models\Client;
|
||||||
use App\Models\Company;
|
|
||||||
use App\Models\Credit;
|
use App\Models\Credit;
|
||||||
use App\Models\Design;
|
use App\Models\Design;
|
||||||
|
use App\Models\Vendor;
|
||||||
|
use App\Models\Company;
|
||||||
use App\Models\Invoice;
|
use App\Models\Invoice;
|
||||||
use App\Models\Payment;
|
use App\Models\Payment;
|
||||||
use App\Models\Project;
|
use App\Models\Project;
|
||||||
use App\Models\PurchaseOrder;
|
|
||||||
use App\Models\Quote;
|
|
||||||
use App\Models\RecurringInvoice;
|
|
||||||
use App\Models\Vendor;
|
|
||||||
use App\Utils\HostedPDF\NinjaPdf;
|
|
||||||
use App\Utils\HtmlEngine;
|
use App\Utils\HtmlEngine;
|
||||||
use App\Utils\Number;
|
use Twig\Error\LoaderError;
|
||||||
|
use Twig\Error\SyntaxError;
|
||||||
|
use Twig\Error\RuntimeError;
|
||||||
|
use App\Models\PurchaseOrder;
|
||||||
|
use App\Utils\VendorHtmlEngine;
|
||||||
|
use Twig\Sandbox\SecurityError;
|
||||||
|
use App\Models\RecurringInvoice;
|
||||||
use App\Utils\PaymentHtmlEngine;
|
use App\Utils\PaymentHtmlEngine;
|
||||||
use App\Utils\Traits\MakesDates;
|
use App\Utils\Traits\MakesDates;
|
||||||
|
use App\Utils\HostedPDF\NinjaPdf;
|
||||||
use App\Utils\Traits\Pdf\PdfMaker;
|
use App\Utils\Traits\Pdf\PdfMaker;
|
||||||
use App\Utils\VendorHtmlEngine;
|
|
||||||
use League\CommonMark\CommonMarkConverter;
|
|
||||||
use Twig\Error\Error;
|
|
||||||
use Twig\Error\LoaderError;
|
|
||||||
use Twig\Error\RuntimeError;
|
|
||||||
use Twig\Error\SyntaxError;
|
|
||||||
use Twig\Extra\Intl\IntlExtension;
|
use Twig\Extra\Intl\IntlExtension;
|
||||||
use Twig\Sandbox\SecurityError;
|
use League\CommonMark\CommonMarkConverter;
|
||||||
|
|
||||||
class TemplateService
|
class TemplateService
|
||||||
{
|
{
|
||||||
@ -52,6 +53,8 @@ class TemplateService
|
|||||||
|
|
||||||
private array $variables = [];
|
private array $variables = [];
|
||||||
|
|
||||||
|
private array $global_vars = [];
|
||||||
|
|
||||||
public ?Company $company;
|
public ?Company $company;
|
||||||
|
|
||||||
private ?Client $client;
|
private ?Client $client;
|
||||||
@ -120,9 +123,10 @@ class TemplateService
|
|||||||
* @return self
|
* @return self
|
||||||
*/
|
*/
|
||||||
public function build(array $data): self
|
public function build(array $data): self
|
||||||
{nlog($data);
|
{
|
||||||
$this->compose()
|
$this->compose()
|
||||||
->processData($data)
|
->processData($data)
|
||||||
|
->setGlobals()
|
||||||
->parseNinjaBlocks()
|
->parseNinjaBlocks()
|
||||||
->processVariables($data)
|
->processVariables($data)
|
||||||
->parseGlobalStacks()
|
->parseGlobalStacks()
|
||||||
@ -144,6 +148,25 @@ class TemplateService
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function setGlobals(): self
|
||||||
|
{
|
||||||
|
|
||||||
|
foreach($this->global_vars as $key => $value) {
|
||||||
|
$this->twig->addGlobal($key, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->global_vars = [];
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addGlobal(array $var): self
|
||||||
|
{
|
||||||
|
$this->global_vars = array_merge($this->global_vars, $var);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a Mock Template
|
* Returns a Mock Template
|
||||||
*
|
*
|
||||||
@ -158,6 +181,10 @@ class TemplateService
|
|||||||
|
|
||||||
$this->data = $tm->engines;
|
$this->data = $tm->engines;
|
||||||
$this->variables = $tm->variables[0];
|
$this->variables = $tm->variables[0];
|
||||||
|
$this->twig->addGlobal('currency_code', $this->company->currency()->code);
|
||||||
|
$this->twig->addGlobal('show_credits', true);
|
||||||
|
$this->twig->addGlobal('show_aging', true);
|
||||||
|
$this->twig->addGlobal('show_payments', true);
|
||||||
|
|
||||||
$this->parseNinjaBlocks()
|
$this->parseNinjaBlocks()
|
||||||
->parseGlobalStacks()
|
->parseGlobalStacks()
|
||||||
@ -549,6 +576,8 @@ class TemplateService
|
|||||||
|
|
||||||
$this->payment = $payment;
|
$this->payment = $payment;
|
||||||
|
|
||||||
|
$this->addGlobal(['currency_code' => $payment->currency->code ?? $this->company->currency()->code]);
|
||||||
|
|
||||||
$credits = $payment->credits->map(function ($credit) use ($payment) {
|
$credits = $payment->credits->map(function ($credit) use ($payment) {
|
||||||
return [
|
return [
|
||||||
'credit' => $credit->number,
|
'credit' => $credit->number,
|
||||||
@ -616,7 +645,7 @@ class TemplateService
|
|||||||
'paymentables' => $pivot,
|
'paymentables' => $pivot,
|
||||||
'refund_activity' => $this->getPaymentRefundActivity($payment),
|
'refund_activity' => $this->getPaymentRefundActivity($payment),
|
||||||
];
|
];
|
||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -849,7 +878,7 @@ class TemplateService
|
|||||||
return [
|
return [
|
||||||
'number' => (string) $task->number ?: '',
|
'number' => (string) $task->number ?: '',
|
||||||
'description' => (string) $task->description ?: '',
|
'description' => (string) $task->description ?: '',
|
||||||
'duration' => $task->duration ?: 0,
|
'duration' => $task->calcDuration() ?: 0,
|
||||||
'rate' => Number::formatMoney($task->rate ?? 0, $task->client ?? $task->company),
|
'rate' => Number::formatMoney($task->rate ?? 0, $task->client ?? $task->company),
|
||||||
'rate_raw' => $task->rate ?? 0,
|
'rate_raw' => $task->rate ?? 0,
|
||||||
'created_at' => $this->translateDate($task->created_at, $task->client ? $task->client->date_format() : $task->company->date_format(), $task->client ? $task->client->locale() : $task->company->locale()),
|
'created_at' => $this->translateDate($task->created_at, $task->client ? $task->client->date_format() : $task->company->date_format(), $task->client ? $task->client->locale() : $task->company->locale()),
|
||||||
@ -863,6 +892,7 @@ class TemplateService
|
|||||||
'custom_value3' => $task->custom_value3 ?: '',
|
'custom_value3' => $task->custom_value3 ?: '',
|
||||||
'custom_value4' => $task->custom_value4 ?: '',
|
'custom_value4' => $task->custom_value4 ?: '',
|
||||||
'status' => $task->status ? $task->status->name : '',
|
'status' => $task->status ? $task->status->name : '',
|
||||||
|
'user' => $this->userInfo($task->user),
|
||||||
'client' => $task->client ? [
|
'client' => $task->client ? [
|
||||||
'name' => $task->client->present()->name(),
|
'name' => $task->client->present()->name(),
|
||||||
'balance' => $task->client->balance,
|
'balance' => $task->client->balance,
|
||||||
@ -894,6 +924,14 @@ class TemplateService
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function userInfo(User $user): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'name' => $user->present()->name(),
|
||||||
|
'email' => $user->email,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
private function transformProject(Project $project, bool $nested = false): array
|
private function transformProject(Project $project, bool $nested = false): array
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -921,7 +959,7 @@ class TemplateService
|
|||||||
'payment_balance' => $project->client->payment_balance,
|
'payment_balance' => $project->client->payment_balance,
|
||||||
'credit_balance' => $project->client->credit_balance,
|
'credit_balance' => $project->client->credit_balance,
|
||||||
] : [],
|
] : [],
|
||||||
|
'user' => $this->userInfo($project->user)
|
||||||
];
|
];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -136,7 +136,7 @@ class CompanyTransformer extends EntityTransformer
|
|||||||
'custom_fields' => (object) $company->custom_fields ?? $std,
|
'custom_fields' => (object) $company->custom_fields ?? $std,
|
||||||
'size_id' => (string) $company->size_id ?: '',
|
'size_id' => (string) $company->size_id ?: '',
|
||||||
'industry_id' => (string) $company->industry_id ?: '',
|
'industry_id' => (string) $company->industry_id ?: '',
|
||||||
'first_month_of_year' => (string) $company->first_month_of_year ?: '',
|
'first_month_of_year' => (string) $company->first_month_of_year ?: '1',
|
||||||
'first_day_of_week' => (string) $company->first_day_of_week ?: '',
|
'first_day_of_week' => (string) $company->first_day_of_week ?: '',
|
||||||
'subdomain' => (string) $company->subdomain ?: '',
|
'subdomain' => (string) $company->subdomain ?: '',
|
||||||
'portal_mode' => (string) $company->portal_mode ?: '',
|
'portal_mode' => (string) $company->portal_mode ?: '',
|
||||||
|
@ -166,6 +166,7 @@ class HtmlEngine
|
|||||||
$data['$exchange_rate'] = ['value' => $this->entity->exchange_rate ?: ' ', 'label' => ctrans('texts.exchange_rate')];
|
$data['$exchange_rate'] = ['value' => $this->entity->exchange_rate ?: ' ', 'label' => ctrans('texts.exchange_rate')];
|
||||||
$data['$triangular_tax'] = ['value' => ctrans('texts.triangular_tax'), 'label' => ''];
|
$data['$triangular_tax'] = ['value' => ctrans('texts.triangular_tax'), 'label' => ''];
|
||||||
$data['$tax_info'] = ['value' => $this->taxLabel(), 'label' => ''];
|
$data['$tax_info'] = ['value' => $this->taxLabel(), 'label' => ''];
|
||||||
|
$data['$net'] = ['value' => '', 'label' => ctrans('texts.net')];
|
||||||
|
|
||||||
if ($this->entity_string == 'invoice' || $this->entity_string == 'recurring_invoice') {
|
if ($this->entity_string == 'invoice' || $this->entity_string == 'recurring_invoice') {
|
||||||
$data['$entity'] = ['value' => ctrans('texts.invoice'), 'label' => ctrans('texts.invoice')];
|
$data['$entity'] = ['value' => ctrans('texts.invoice'), 'label' => ctrans('texts.invoice')];
|
||||||
@ -326,7 +327,7 @@ class HtmlEngine
|
|||||||
$data['$amount_raw'] = ['value' => $this->entity->partial, 'label' => ctrans('texts.partial_due')];
|
$data['$amount_raw'] = ['value' => $this->entity->partial, 'label' => ctrans('texts.partial_due')];
|
||||||
$data['$due_date'] = ['value' => $this->translateDate($this->entity->partial_due_date, $this->client->date_format(), $this->client->locale()) ?: ' ', 'label' => ctrans('texts.'.$this->entity_string.'_due_date')];
|
$data['$due_date'] = ['value' => $this->translateDate($this->entity->partial_due_date, $this->client->date_format(), $this->client->locale()) ?: ' ', 'label' => ctrans('texts.'.$this->entity_string.'_due_date')];
|
||||||
} else {
|
} else {
|
||||||
if ($this->entity->status_id == 1) {
|
if ($this->entity->status_id == 1 || $this->entity_string == 'recurring_invoice') {
|
||||||
$data['$balance_due'] = ['value' => Number::formatMoney($this->entity->amount, $this->client) ?: ' ', 'label' => ctrans('texts.balance_due')];
|
$data['$balance_due'] = ['value' => Number::formatMoney($this->entity->amount, $this->client) ?: ' ', 'label' => ctrans('texts.balance_due')];
|
||||||
$data['$balance_due_raw'] = ['value' => $this->entity->amount, 'label' => ctrans('texts.balance_due')];
|
$data['$balance_due_raw'] = ['value' => $this->entity->amount, 'label' => ctrans('texts.balance_due')];
|
||||||
$data['$amount_raw'] = ['value' => $this->entity->amount, 'label' => ctrans('texts.amount')];
|
$data['$amount_raw'] = ['value' => $this->entity->amount, 'label' => ctrans('texts.amount')];
|
||||||
@ -664,6 +665,8 @@ class HtmlEngine
|
|||||||
$data['$payment.custom2'] = ['value' => '', 'label' => ctrans('texts.payment')];
|
$data['$payment.custom2'] = ['value' => '', 'label' => ctrans('texts.payment')];
|
||||||
$data['$payment.custom3'] = ['value' => '', 'label' => ctrans('texts.payment')];
|
$data['$payment.custom3'] = ['value' => '', 'label' => ctrans('texts.payment')];
|
||||||
$data['$payment.custom4'] = ['value' => '', 'label' => ctrans('texts.payment')];
|
$data['$payment.custom4'] = ['value' => '', 'label' => ctrans('texts.payment')];
|
||||||
|
$data['$refund'] = ['value' => '', 'label' => ctrans('texts.refund')];
|
||||||
|
$data['$refunded'] = ['value' => '', 'label' => ctrans('texts.refunded')];
|
||||||
|
|
||||||
$data['$payment.amount'] = ['value' => '', 'label' => ctrans('texts.payment')];
|
$data['$payment.amount'] = ['value' => '', 'label' => ctrans('texts.payment')];
|
||||||
$data['$payment.date'] = ['value' => '', 'label' => ctrans('texts.payment_date')];
|
$data['$payment.date'] = ['value' => '', 'label' => ctrans('texts.payment_date')];
|
||||||
|
@ -5189,6 +5189,30 @@ $LANG = array(
|
|||||||
'payment_receipt' => 'Payment Receipt # :number',
|
'payment_receipt' => 'Payment Receipt # :number',
|
||||||
'load_template_description' => 'The template will be applied to following:',
|
'load_template_description' => 'The template will be applied to following:',
|
||||||
'run_template' => 'Run template',
|
'run_template' => 'Run template',
|
||||||
|
'statement_design' => 'Statement Design',
|
||||||
|
'delivery_note_design' => 'Delivery Note Design',
|
||||||
|
'payment_receipt_design' => 'Payment Receipt Design',
|
||||||
|
'payment_refund_design' => 'Payment Refund Design',
|
||||||
|
'task_extension_banner' => 'Add the Chrome extension to manage your tasks',
|
||||||
|
'watch_video' => 'Watch Video',
|
||||||
|
'view_extension' => 'View Extension',
|
||||||
|
'reactivate_email' => 'Reactivate Email',
|
||||||
|
'email_reactivated' => 'Successfully reactivated email',
|
||||||
|
'template_help' => 'Enable using the design as a template',
|
||||||
|
'quarter' => 'Quarter',
|
||||||
|
'item_description' => 'Item Description',
|
||||||
|
'task_item' => 'Task Item',
|
||||||
|
'record_state' => 'Record State',
|
||||||
|
'save_files_to_this_folder' => 'Save files to this folder',
|
||||||
|
'downloads_folder' => 'Downloads Folder',
|
||||||
|
'total_invoiced_quotes' => 'Invoiced Quotes',
|
||||||
|
'total_invoice_paid_quotes' => 'Invoice Paid Quotes',
|
||||||
|
'downloads_folder_does_not_exist' => 'The downloads folder does not exist :value',
|
||||||
|
'user_logged_in_notification' => 'User Logged in Notification',
|
||||||
|
'user_logged_in_notification_help' => 'Send an email when logging in from a new location',
|
||||||
|
'payment_email_all_contacts' => 'Payment Email To All Contacts',
|
||||||
|
'payment_email_all_contacts_help' => 'Sends the payment email to all contacts when enabled',
|
||||||
|
'add_line' => 'Add Line',
|
||||||
);
|
);
|
||||||
|
|
||||||
return $LANG;
|
return $LANG;
|
||||||
|
@ -17926,18 +17926,22 @@ components:
|
|||||||
description: 'The hashed if of the contact'
|
description: 'The hashed if of the contact'
|
||||||
type: string
|
type: string
|
||||||
example: Opnel5aKBz
|
example: Opnel5aKBz
|
||||||
|
readOnly: true
|
||||||
user_id:
|
user_id:
|
||||||
description: 'The hashed id of the user who created the contact'
|
description: 'The hashed id of the user who created the contact'
|
||||||
type: string
|
type: string
|
||||||
example: Opnel5aKBz
|
example: Opnel5aKBz
|
||||||
|
readOnly: true
|
||||||
company_id:
|
company_id:
|
||||||
description: 'The hashed id of the company'
|
description: 'The hashed id of the company'
|
||||||
type: string
|
type: string
|
||||||
example: Opnel5aKBz
|
example: Opnel5aKBz
|
||||||
|
readOnly: true
|
||||||
client_id:
|
client_id:
|
||||||
description: 'The hashed id of the client'
|
description: 'The hashed id of the client'
|
||||||
type: string
|
type: string
|
||||||
example: Opnel5aKBz
|
example: Opnel5aKBz
|
||||||
|
readOnly: true
|
||||||
first_name:
|
first_name:
|
||||||
description: 'The first name of the contact'
|
description: 'The first name of the contact'
|
||||||
type: string
|
type: string
|
||||||
@ -17974,18 +17978,26 @@ components:
|
|||||||
description: 'The terms of service which the contact has accpeted'
|
description: 'The terms of service which the contact has accpeted'
|
||||||
type: string
|
type: string
|
||||||
example: 'A long set of ToS'
|
example: 'A long set of ToS'
|
||||||
|
readOnly: true
|
||||||
password:
|
password:
|
||||||
description: 'The hashed password of the contact'
|
description: 'The hashed password of the contact'
|
||||||
type: string
|
type: string
|
||||||
example: '*****'
|
example: '*****'
|
||||||
confirmation-code:
|
confirmation_code:
|
||||||
description: 'The confirmation code used to authenticate the contacts email address'
|
description: 'The confirmation code used to authenticate the contacts email address'
|
||||||
type: string
|
type: string
|
||||||
example: 333-sdjkh34gbasd
|
example: 333-sdjkh34gbasd
|
||||||
|
readOnly: true
|
||||||
token:
|
token:
|
||||||
description: 'A uuid based token.'
|
description: 'A uuid based token.'
|
||||||
type: string
|
type: string
|
||||||
example: 333-sdjkh34gbasd
|
example: 333-sdjkh34gbasd
|
||||||
|
readOnly: true
|
||||||
|
contact_key:
|
||||||
|
description: 'A unique identifier for the contact'
|
||||||
|
type: string
|
||||||
|
example: JD0X52bkfZlJRiroCJ0tcSiAjsJTntZ5uqKdiZ0a
|
||||||
|
readOnly: true
|
||||||
is_primary:
|
is_primary:
|
||||||
description: 'Defines is this contact is the primary contact for the client'
|
description: 'Defines is this contact is the primary contact for the client'
|
||||||
type: boolean
|
type: boolean
|
||||||
@ -18007,31 +18019,37 @@ components:
|
|||||||
type: number
|
type: number
|
||||||
format: integer
|
format: integer
|
||||||
example: '3'
|
example: '3'
|
||||||
|
readOnly: true
|
||||||
email_verified_at:
|
email_verified_at:
|
||||||
description: 'The date which the contact confirmed their email'
|
description: 'The date which the contact confirmed their email'
|
||||||
type: number
|
type: number
|
||||||
format: integer
|
format: integer
|
||||||
example: '134341234234'
|
example: '134341234234'
|
||||||
|
readOnly: true
|
||||||
last_login:
|
last_login:
|
||||||
description: Timestamp
|
description: Timestamp
|
||||||
type: number
|
type: number
|
||||||
format: integer
|
format: integer
|
||||||
example: '134341234234'
|
example: '134341234234'
|
||||||
|
readOnly: true
|
||||||
created_at:
|
created_at:
|
||||||
description: Timestamp
|
description: Timestamp
|
||||||
type: number
|
type: number
|
||||||
format: integer
|
format: integer
|
||||||
example: '134341234234'
|
example: '134341234234'
|
||||||
|
readOnly: true
|
||||||
updated_at:
|
updated_at:
|
||||||
description: Timestamp
|
description: Timestamp
|
||||||
type: number
|
type: number
|
||||||
format: integer
|
format: integer
|
||||||
example: '134341234234'
|
example: '134341234234'
|
||||||
|
readOnly: true
|
||||||
deleted_at:
|
deleted_at:
|
||||||
description: Timestamp
|
description: Timestamp
|
||||||
type: number
|
type: number
|
||||||
format: integer
|
format: integer
|
||||||
example: '134341234234'
|
example: '134341234234'
|
||||||
|
readOnly: true
|
||||||
type: object
|
type: object
|
||||||
ClientContactRequest:
|
ClientContactRequest:
|
||||||
properties:
|
properties:
|
||||||
@ -18092,14 +18110,17 @@ components:
|
|||||||
description: 'The hashed id of the user id'
|
description: 'The hashed id of the user id'
|
||||||
type: string
|
type: string
|
||||||
example: Opnel5aKBz
|
example: Opnel5aKBz
|
||||||
|
readOnly: true
|
||||||
company_id:
|
company_id:
|
||||||
description: 'The hashed id of the company'
|
description: 'The hashed id of the company'
|
||||||
type: string
|
type: string
|
||||||
example: Opnel5aKBz
|
example: Opnel5aKBz
|
||||||
|
readOnly: true
|
||||||
vendor_id:
|
vendor_id:
|
||||||
description: 'The hashed id of the vendor'
|
description: 'The hashed id of the vendor'
|
||||||
type: string
|
type: string
|
||||||
example: Opnel5aKBz
|
example: Opnel5aKBz
|
||||||
|
readOnly: true
|
||||||
first_name:
|
first_name:
|
||||||
description: 'The first name of the contact'
|
description: 'The first name of the contact'
|
||||||
type: string
|
type: string
|
||||||
@ -18108,6 +18129,16 @@ components:
|
|||||||
description: 'The last name of the contact'
|
description: 'The last name of the contact'
|
||||||
type: string
|
type: string
|
||||||
example: Windsor
|
example: Windsor
|
||||||
|
contact_key:
|
||||||
|
description: 'A unique identifier for the contact'
|
||||||
|
type: string
|
||||||
|
example: JD0X52bkfZlJRiroCJ0tcSiAjsJTntZ5uqKdiZ0a
|
||||||
|
readOnly: true
|
||||||
|
confirmation_code:
|
||||||
|
description: 'The confirmation code used to authenticate the contacts email address'
|
||||||
|
type: string
|
||||||
|
example: 333-sdjkh34gbasd
|
||||||
|
readOnly: true
|
||||||
phone:
|
phone:
|
||||||
description: 'The contacts phone number'
|
description: 'The contacts phone number'
|
||||||
type: string
|
type: string
|
||||||
@ -18132,6 +18163,16 @@ components:
|
|||||||
description: 'The contact email address'
|
description: 'The contact email address'
|
||||||
type: string
|
type: string
|
||||||
example: harry@windsor.com
|
example: harry@windsor.com
|
||||||
|
email_verified_at:
|
||||||
|
description: 'The date which the contact confirmed their email'
|
||||||
|
type: number
|
||||||
|
format: integer
|
||||||
|
example: '134341234234'
|
||||||
|
readOnly: true
|
||||||
|
password:
|
||||||
|
description: 'The hashed password of the contact'
|
||||||
|
type: string
|
||||||
|
example: '*****'
|
||||||
is_primary:
|
is_primary:
|
||||||
description: 'Boolean flag determining if the contact is the primary contact for the vendor'
|
description: 'Boolean flag determining if the contact is the primary contact for the vendor'
|
||||||
type: boolean
|
type: boolean
|
||||||
@ -19463,10 +19504,6 @@ components:
|
|||||||
description: 'The hashed id of the company. This is a unique identifier for the company.'
|
description: 'The hashed id of the company. This is a unique identifier for the company.'
|
||||||
type: string
|
type: string
|
||||||
example: Opnel5aKBz
|
example: Opnel5aKBz
|
||||||
client_id:
|
|
||||||
description: 'The hashed id of the client. This is a unique identifier for the client.'
|
|
||||||
type: string
|
|
||||||
example: Opnel5aKBz
|
|
||||||
contacts:
|
contacts:
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
@ -19596,8 +19633,6 @@ components:
|
|||||||
type: string
|
type: string
|
||||||
example: 'Bob the vendor'
|
example: 'Bob the vendor'
|
||||||
readOnly: true
|
readOnly: true
|
||||||
settings:
|
|
||||||
$ref: '#/components/schemas/CompanySettings'
|
|
||||||
type: object
|
type: object
|
||||||
ClientSettings:
|
ClientSettings:
|
||||||
required:
|
required:
|
||||||
|
@ -4,18 +4,22 @@
|
|||||||
description: 'The hashed if of the contact'
|
description: 'The hashed if of the contact'
|
||||||
type: string
|
type: string
|
||||||
example: Opnel5aKBz
|
example: Opnel5aKBz
|
||||||
|
readOnly: true
|
||||||
user_id:
|
user_id:
|
||||||
description: 'The hashed id of the user who created the contact'
|
description: 'The hashed id of the user who created the contact'
|
||||||
type: string
|
type: string
|
||||||
example: Opnel5aKBz
|
example: Opnel5aKBz
|
||||||
|
readOnly: true
|
||||||
company_id:
|
company_id:
|
||||||
description: 'The hashed id of the company'
|
description: 'The hashed id of the company'
|
||||||
type: string
|
type: string
|
||||||
example: Opnel5aKBz
|
example: Opnel5aKBz
|
||||||
|
readOnly: true
|
||||||
client_id:
|
client_id:
|
||||||
description: 'The hashed id of the client'
|
description: 'The hashed id of the client'
|
||||||
type: string
|
type: string
|
||||||
example: Opnel5aKBz
|
example: Opnel5aKBz
|
||||||
|
readOnly: true
|
||||||
first_name:
|
first_name:
|
||||||
description: 'The first name of the contact'
|
description: 'The first name of the contact'
|
||||||
type: string
|
type: string
|
||||||
@ -52,18 +56,26 @@
|
|||||||
description: 'The terms of service which the contact has accpeted'
|
description: 'The terms of service which the contact has accpeted'
|
||||||
type: string
|
type: string
|
||||||
example: 'A long set of ToS'
|
example: 'A long set of ToS'
|
||||||
|
readOnly: true
|
||||||
password:
|
password:
|
||||||
description: 'The hashed password of the contact'
|
description: 'The hashed password of the contact'
|
||||||
type: string
|
type: string
|
||||||
example: '*****'
|
example: '*****'
|
||||||
confirmation-code:
|
confirmation_code:
|
||||||
description: 'The confirmation code used to authenticate the contacts email address'
|
description: 'The confirmation code used to authenticate the contacts email address'
|
||||||
type: string
|
type: string
|
||||||
example: 333-sdjkh34gbasd
|
example: 333-sdjkh34gbasd
|
||||||
|
readOnly: true
|
||||||
token:
|
token:
|
||||||
description: 'A uuid based token.'
|
description: 'A uuid based token.'
|
||||||
type: string
|
type: string
|
||||||
example: 333-sdjkh34gbasd
|
example: 333-sdjkh34gbasd
|
||||||
|
readOnly: true
|
||||||
|
contact_key:
|
||||||
|
description: 'A unique identifier for the contact'
|
||||||
|
type: string
|
||||||
|
example: JD0X52bkfZlJRiroCJ0tcSiAjsJTntZ5uqKdiZ0a
|
||||||
|
readOnly: true
|
||||||
is_primary:
|
is_primary:
|
||||||
description: 'Defines is this contact is the primary contact for the client'
|
description: 'Defines is this contact is the primary contact for the client'
|
||||||
type: boolean
|
type: boolean
|
||||||
@ -85,29 +97,35 @@
|
|||||||
type: number
|
type: number
|
||||||
format: integer
|
format: integer
|
||||||
example: '3'
|
example: '3'
|
||||||
|
readOnly: true
|
||||||
email_verified_at:
|
email_verified_at:
|
||||||
description: 'The date which the contact confirmed their email'
|
description: 'The date which the contact confirmed their email'
|
||||||
type: number
|
type: number
|
||||||
format: integer
|
format: integer
|
||||||
example: '134341234234'
|
example: '134341234234'
|
||||||
|
readOnly: true
|
||||||
last_login:
|
last_login:
|
||||||
description: Timestamp
|
description: Timestamp
|
||||||
type: number
|
type: number
|
||||||
format: integer
|
format: integer
|
||||||
example: '134341234234'
|
example: '134341234234'
|
||||||
|
readOnly: true
|
||||||
created_at:
|
created_at:
|
||||||
description: Timestamp
|
description: Timestamp
|
||||||
type: number
|
type: number
|
||||||
format: integer
|
format: integer
|
||||||
example: '134341234234'
|
example: '134341234234'
|
||||||
|
readOnly: true
|
||||||
updated_at:
|
updated_at:
|
||||||
description: Timestamp
|
description: Timestamp
|
||||||
type: number
|
type: number
|
||||||
format: integer
|
format: integer
|
||||||
example: '134341234234'
|
example: '134341234234'
|
||||||
|
readOnly: true
|
||||||
deleted_at:
|
deleted_at:
|
||||||
description: Timestamp
|
description: Timestamp
|
||||||
type: number
|
type: number
|
||||||
format: integer
|
format: integer
|
||||||
example: '134341234234'
|
example: '134341234234'
|
||||||
|
readOnly: true
|
||||||
type: object
|
type: object
|
@ -17,10 +17,6 @@
|
|||||||
description: 'The hashed id of the company. This is a unique identifier for the company.'
|
description: 'The hashed id of the company. This is a unique identifier for the company.'
|
||||||
type: string
|
type: string
|
||||||
example: Opnel5aKBz
|
example: Opnel5aKBz
|
||||||
client_id:
|
|
||||||
description: 'The hashed id of the client. This is a unique identifier for the client.'
|
|
||||||
type: string
|
|
||||||
example: Opnel5aKBz
|
|
||||||
contacts:
|
contacts:
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
@ -150,6 +146,4 @@
|
|||||||
type: string
|
type: string
|
||||||
example: 'Bob the vendor'
|
example: 'Bob the vendor'
|
||||||
readOnly: true
|
readOnly: true
|
||||||
settings:
|
|
||||||
$ref: '#/components/schemas/CompanySettings'
|
|
||||||
type: object
|
type: object
|
@ -9,14 +9,17 @@
|
|||||||
description: 'The hashed id of the user id'
|
description: 'The hashed id of the user id'
|
||||||
type: string
|
type: string
|
||||||
example: Opnel5aKBz
|
example: Opnel5aKBz
|
||||||
|
readOnly: true
|
||||||
company_id:
|
company_id:
|
||||||
description: 'The hashed id of the company'
|
description: 'The hashed id of the company'
|
||||||
type: string
|
type: string
|
||||||
example: Opnel5aKBz
|
example: Opnel5aKBz
|
||||||
|
readOnly: true
|
||||||
vendor_id:
|
vendor_id:
|
||||||
description: 'The hashed id of the vendor'
|
description: 'The hashed id of the vendor'
|
||||||
type: string
|
type: string
|
||||||
example: Opnel5aKBz
|
example: Opnel5aKBz
|
||||||
|
readOnly: true
|
||||||
first_name:
|
first_name:
|
||||||
description: 'The first name of the contact'
|
description: 'The first name of the contact'
|
||||||
type: string
|
type: string
|
||||||
@ -25,6 +28,16 @@
|
|||||||
description: 'The last name of the contact'
|
description: 'The last name of the contact'
|
||||||
type: string
|
type: string
|
||||||
example: Windsor
|
example: Windsor
|
||||||
|
contact_key:
|
||||||
|
description: 'A unique identifier for the contact'
|
||||||
|
type: string
|
||||||
|
example: JD0X52bkfZlJRiroCJ0tcSiAjsJTntZ5uqKdiZ0a
|
||||||
|
readOnly: true
|
||||||
|
confirmation_code:
|
||||||
|
description: 'The confirmation code used to authenticate the contacts email address'
|
||||||
|
type: string
|
||||||
|
example: 333-sdjkh34gbasd
|
||||||
|
readOnly: true
|
||||||
phone:
|
phone:
|
||||||
description: 'The contacts phone number'
|
description: 'The contacts phone number'
|
||||||
type: string
|
type: string
|
||||||
@ -49,6 +62,16 @@
|
|||||||
description: 'The contact email address'
|
description: 'The contact email address'
|
||||||
type: string
|
type: string
|
||||||
example: harry@windsor.com
|
example: harry@windsor.com
|
||||||
|
email_verified_at:
|
||||||
|
description: 'The date which the contact confirmed their email'
|
||||||
|
type: number
|
||||||
|
format: integer
|
||||||
|
example: '134341234234'
|
||||||
|
readOnly: true
|
||||||
|
password:
|
||||||
|
description: 'The hashed password of the contact'
|
||||||
|
type: string
|
||||||
|
example: '*****'
|
||||||
is_primary:
|
is_primary:
|
||||||
description: 'Boolean flag determining if the contact is the primary contact for the vendor'
|
description: 'Boolean flag determining if the contact is the primary contact for the vendor'
|
||||||
type: boolean
|
type: boolean
|
||||||
|
@ -47,6 +47,24 @@ class VendorApiTest extends TestCase
|
|||||||
Model::reguard();
|
Model::reguard();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function testVendorContactCreation()
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'name' => 'hewwo',
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->postJson('/api/v1/vendors', $data);
|
||||||
|
|
||||||
|
$arr = $response->json();
|
||||||
|
|
||||||
|
$this->assertEquals('hewwo', $arr['data']['name']);
|
||||||
|
$this->assertEquals(1, count($arr['data']['contacts']));
|
||||||
|
}
|
||||||
|
|
||||||
public function testVendorLoggedInEvents()
|
public function testVendorLoggedInEvents()
|
||||||
{
|
{
|
||||||
$v = \App\Models\Vendor::factory()->create([
|
$v = \App\Models\Vendor::factory()->create([
|
||||||
@ -69,12 +87,6 @@ class VendorApiTest extends TestCase
|
|||||||
|
|
||||||
Event::assertDispatched(VendorContactLoggedIn::class);
|
Event::assertDispatched(VendorContactLoggedIn::class);
|
||||||
|
|
||||||
// $vc->fresh();
|
|
||||||
// $v->fresh();
|
|
||||||
|
|
||||||
// $this->assertNotNull($vc->fresh()->last_login);
|
|
||||||
// $this->assertNotNull($v->fresh()->last_login);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testVendorLocale()
|
public function testVendorLocale()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user