mirror of
				https://github.com/invoiceninja/invoiceninja.git
				synced 2025-11-04 01:17:30 -05:00 
			
		
		
		
	Merge pull request #8885 from turbo124/v5-develop
Fixes for Swiss QR Codes
This commit is contained in:
		
						commit
						45d5838aa8
					
				@ -1 +1 @@
 | 
				
			|||||||
5.7.30
 | 
					5.7.31
 | 
				
			||||||
@ -168,6 +168,7 @@ class BaseExport
 | 
				
			|||||||
        'tax_rate1' => 'invoice.tax_rate1',
 | 
					        'tax_rate1' => 'invoice.tax_rate1',
 | 
				
			||||||
        'tax_rate2' => 'invoice.tax_rate2',
 | 
					        'tax_rate2' => 'invoice.tax_rate2',
 | 
				
			||||||
        'tax_rate3' => 'invoice.tax_rate3',
 | 
					        'tax_rate3' => 'invoice.tax_rate3',
 | 
				
			||||||
 | 
					        'recurring_invoice' => 'invoice.recurring_id',
 | 
				
			||||||
    ];
 | 
					    ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected array $recurring_invoice_report_keys = [    
 | 
					    protected array $recurring_invoice_report_keys = [    
 | 
				
			||||||
@ -230,7 +231,7 @@ class BaseExport
 | 
				
			|||||||
        'po_number' => 'purchase_order.po_number',
 | 
					        'po_number' => 'purchase_order.po_number',
 | 
				
			||||||
        'private_notes' => 'purchase_order.private_notes',
 | 
					        'private_notes' => 'purchase_order.private_notes',
 | 
				
			||||||
        'public_notes' => 'purchase_order.public_notes',
 | 
					        'public_notes' => 'purchase_order.public_notes',
 | 
				
			||||||
        'status' => 'purchase_order.status_id',
 | 
					        'status' => 'purchase_order.status',
 | 
				
			||||||
        'tax_name1' => 'purchase_order.tax_name1',
 | 
					        'tax_name1' => 'purchase_order.tax_name1',
 | 
				
			||||||
        'tax_name2' => 'purchase_order.tax_name2',
 | 
					        'tax_name2' => 'purchase_order.tax_name2',
 | 
				
			||||||
        'tax_name3' => 'purchase_order.tax_name3',
 | 
					        'tax_name3' => 'purchase_order.tax_name3',
 | 
				
			||||||
@ -377,6 +378,7 @@ class BaseExport
 | 
				
			|||||||
        "custom_value4" => "payment.custom_value4",
 | 
					        "custom_value4" => "payment.custom_value4",
 | 
				
			||||||
        "user" => "payment.user_id",
 | 
					        "user" => "payment.user_id",
 | 
				
			||||||
        "assigned_user" => "payment.assigned_user_id",
 | 
					        "assigned_user" => "payment.assigned_user_id",
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
  ];
 | 
					  ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected array $expense_report_keys = [
 | 
					    protected array $expense_report_keys = [
 | 
				
			||||||
@ -429,6 +431,14 @@ class BaseExport
 | 
				
			|||||||
        'project' => 'task.project_id',
 | 
					        'project' => 'task.project_id',
 | 
				
			||||||
    ];
 | 
					    ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected array $forced_client_fields = [
 | 
				
			||||||
 | 
					        "client.name",
 | 
				
			||||||
 | 
					    ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected array $forced_vendor_fields = [
 | 
				
			||||||
 | 
					        "vendor.name",
 | 
				
			||||||
 | 
					    ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected function filterByClients($query)
 | 
					    protected function filterByClients($query)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (isset($this->input['client_id']) && $this->input['client_id'] != 'all') {
 | 
					        if (isset($this->input['client_id']) && $this->input['client_id'] != 'all') {
 | 
				
			||||||
 | 
				
			|||||||
@ -93,6 +93,8 @@ class CreditExport extends BaseExport
 | 
				
			|||||||
            $this->input['report_keys'] = array_values($this->credit_report_keys);
 | 
					            $this->input['report_keys'] = array_values($this->credit_report_keys);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->input['report_keys'] = array_merge($this->input['report_keys'], array_diff($this->forced_client_fields, $this->input['report_keys']));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $query = Credit::query()
 | 
					        $query = Credit::query()
 | 
				
			||||||
                        ->withTrashed()
 | 
					                        ->withTrashed()
 | 
				
			||||||
                        ->with('client')
 | 
					                        ->with('client')
 | 
				
			||||||
 | 
				
			|||||||
@ -50,6 +50,8 @@ class InvoiceExport extends BaseExport
 | 
				
			|||||||
            $this->input['report_keys'] = array_values($this->invoice_report_keys);
 | 
					            $this->input['report_keys'] = array_values($this->invoice_report_keys);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->input['report_keys'] = array_merge($this->input['report_keys'], array_diff($this->forced_client_fields, $this->input['report_keys']));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $query = Invoice::query()
 | 
					        $query = Invoice::query()
 | 
				
			||||||
                        ->withTrashed()
 | 
					                        ->withTrashed()
 | 
				
			||||||
                        ->with('client')
 | 
					                        ->with('client')
 | 
				
			||||||
@ -142,6 +144,11 @@ class InvoiceExport extends BaseExport
 | 
				
			|||||||
        if (in_array('invoice.status', $this->input['report_keys'])) {
 | 
					        if (in_array('invoice.status', $this->input['report_keys'])) {
 | 
				
			||||||
            $entity['invoice.status'] = $invoice->stringStatus($invoice->status_id);
 | 
					            $entity['invoice.status'] = $invoice->stringStatus($invoice->status_id);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (in_array('invoice.recurring_id', $this->input['report_keys'])) {
 | 
				
			||||||
 | 
					            $entity['invoice.recurring_id'] = $invoice->recurring_invoice->number ?? '';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        return $entity;
 | 
					        return $entity;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -62,6 +62,8 @@ class InvoiceItemExport extends BaseExport
 | 
				
			|||||||
            $this->input['report_keys'] = array_values($this->mergeItemsKeys('invoice_report_keys'));
 | 
					            $this->input['report_keys'] = array_values($this->mergeItemsKeys('invoice_report_keys'));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->input['report_keys'] = array_merge($this->input['report_keys'], array_diff($this->forced_client_fields, $this->input['report_keys']));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $query = Invoice::query()
 | 
					        $query = Invoice::query()
 | 
				
			||||||
                        ->withTrashed()
 | 
					                        ->withTrashed()
 | 
				
			||||||
                        ->with('client')
 | 
					                        ->with('client')
 | 
				
			||||||
@ -200,6 +202,27 @@ class InvoiceItemExport extends BaseExport
 | 
				
			|||||||
            $entity['tax_category'] = $invoice->taxTypeString($entity['tax_category']);
 | 
					            $entity['tax_category'] = $invoice->taxTypeString($entity['tax_category']);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (in_array('invoice.country_id', $this->input['report_keys'])) {
 | 
				
			||||||
 | 
					            $entity['invoice.country_id'] = $invoice->client->country ? ctrans("texts.country_{$invoice->client->country->name}") : '';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (in_array('invoice.currency_id', $this->input['report_keys'])) {
 | 
				
			||||||
 | 
					            $entity['invoice.currency_id'] = $invoice->client->currency() ? $invoice->client->currency()->code : $invoice->company->currency()->code;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (in_array('invoice.client_id', $this->input['report_keys'])) {
 | 
				
			||||||
 | 
					            $entity['invoice.client_id'] = $invoice->client->present()->name();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (in_array('invoice.status', $this->input['report_keys'])) {
 | 
				
			||||||
 | 
					            $entity['invoice.status'] = $invoice->stringStatus($invoice->status_id);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (in_array('invoice.recurring_id', $this->input['report_keys'])) {
 | 
				
			||||||
 | 
					            $entity['invoice.recurring_id'] = $invoice->recurring_invoice->number ?? '';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $entity;
 | 
					        return $entity;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -48,6 +48,8 @@ class PaymentExport extends BaseExport
 | 
				
			|||||||
            $this->input['report_keys'] = array_values($this->payment_report_keys);
 | 
					            $this->input['report_keys'] = array_values($this->payment_report_keys);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->input['report_keys'] = array_merge($this->input['report_keys'], array_diff($this->forced_client_fields, $this->input['report_keys']));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $query = Payment::query()
 | 
					        $query = Payment::query()
 | 
				
			||||||
                            ->withTrashed()
 | 
					                            ->withTrashed()
 | 
				
			||||||
                            ->where('company_id', $this->company->id)
 | 
					                            ->where('company_id', $this->company->id)
 | 
				
			||||||
@ -69,6 +71,8 @@ class PaymentExport extends BaseExport
 | 
				
			|||||||
            return ['identifier' => $key, 'display_value' => $headerdisplay[$value]];
 | 
					            return ['identifier' => $key, 'display_value' => $headerdisplay[$value]];
 | 
				
			||||||
        })->toArray();
 | 
					        })->toArray();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        nlog($header);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $report = $query->cursor()
 | 
					        $report = $query->cursor()
 | 
				
			||||||
                ->map(function ($resource) {
 | 
					                ->map(function ($resource) {
 | 
				
			||||||
                    $row = $this->buildRow($resource);
 | 
					                    $row = $this->buildRow($resource);
 | 
				
			||||||
 | 
				
			|||||||
@ -54,7 +54,7 @@ class PurchaseOrderExport extends BaseExport
 | 
				
			|||||||
        'po_number' => 'purchase_order.po_number',
 | 
					        'po_number' => 'purchase_order.po_number',
 | 
				
			||||||
        'private_notes' => 'purchase_order.private_notes',
 | 
					        'private_notes' => 'purchase_order.private_notes',
 | 
				
			||||||
        'public_notes' => 'purchase_order.public_notes',
 | 
					        'public_notes' => 'purchase_order.public_notes',
 | 
				
			||||||
        'status' => 'purchase_order.status_id',
 | 
					        'status' => 'purchase_order.status',
 | 
				
			||||||
        'tax_name1' => 'purchase_order.tax_name1',
 | 
					        'tax_name1' => 'purchase_order.tax_name1',
 | 
				
			||||||
        'tax_name2' => 'purchase_order.tax_name2',
 | 
					        'tax_name2' => 'purchase_order.tax_name2',
 | 
				
			||||||
        'tax_name3' => 'purchase_order.tax_name3',
 | 
					        'tax_name3' => 'purchase_order.tax_name3',
 | 
				
			||||||
@ -95,6 +95,9 @@ class PurchaseOrderExport extends BaseExport
 | 
				
			|||||||
        if (count($this->input['report_keys']) == 0) {
 | 
					        if (count($this->input['report_keys']) == 0) {
 | 
				
			||||||
            $this->input['report_keys'] = array_values($this->purchase_order_report_keys);
 | 
					            $this->input['report_keys'] = array_values($this->purchase_order_report_keys);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->input['report_keys'] = array_merge($this->input['report_keys'], array_diff($this->forced_vendor_fields, $this->input['report_keys']));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $query = PurchaseOrder::query()
 | 
					        $query = PurchaseOrder::query()
 | 
				
			||||||
                        ->withTrashed()
 | 
					                        ->withTrashed()
 | 
				
			||||||
                        ->with('vendor')
 | 
					                        ->with('vendor')
 | 
				
			||||||
@ -181,8 +184,8 @@ class PurchaseOrderExport extends BaseExport
 | 
				
			|||||||
            $entity['vendor'] = $purchase_order->vendor->present()->name();
 | 
					            $entity['vendor'] = $purchase_order->vendor->present()->name();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (in_array('status_id', $this->input['report_keys'])) {
 | 
					        if (in_array('purchase_order.status', $this->input['report_keys'])) {
 | 
				
			||||||
            $entity['status'] = $purchase_order->stringStatus($purchase_order->status_id);
 | 
					            $entity['purchase_order.status'] = $purchase_order->stringStatus($purchase_order->status_id);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $entity;
 | 
					        return $entity;
 | 
				
			||||||
 | 
				
			|||||||
@ -55,6 +55,8 @@ class PurchaseOrderItemExport extends BaseExport
 | 
				
			|||||||
            $this->input['report_keys'] = array_values($this->mergeItemsKeys('purchase_order_report_keys'));
 | 
					            $this->input['report_keys'] = array_values($this->mergeItemsKeys('purchase_order_report_keys'));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->input['report_keys'] = array_merge($this->input['report_keys'], array_diff($this->forced_vendor_fields, $this->input['report_keys']));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $query = PurchaseOrder::query()
 | 
					        $query = PurchaseOrder::query()
 | 
				
			||||||
                        ->withTrashed()
 | 
					                        ->withTrashed()
 | 
				
			||||||
                        ->with('vendor')->where('company_id', $this->company->id)
 | 
					                        ->with('vendor')->where('company_id', $this->company->id)
 | 
				
			||||||
 | 
				
			|||||||
@ -56,6 +56,8 @@ class QuoteExport extends BaseExport
 | 
				
			|||||||
            $this->input['report_keys'] = array_values($this->quote_report_keys);
 | 
					            $this->input['report_keys'] = array_values($this->quote_report_keys);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->input['report_keys'] = array_merge($this->input['report_keys'], array_diff($this->forced_client_fields, $this->input['report_keys']));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $query = Quote::query()
 | 
					        $query = Quote::query()
 | 
				
			||||||
                        ->withTrashed()
 | 
					                        ->withTrashed()
 | 
				
			||||||
                        ->with('client')
 | 
					                        ->with('client')
 | 
				
			||||||
 | 
				
			|||||||
@ -57,6 +57,8 @@ class QuoteItemExport extends BaseExport
 | 
				
			|||||||
            $this->input['report_keys'] = array_values($this->mergeItemsKeys('quote_report_keys'));
 | 
					            $this->input['report_keys'] = array_values($this->mergeItemsKeys('quote_report_keys'));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->input['report_keys'] = array_merge($this->input['report_keys'], array_diff($this->forced_client_fields, $this->input['report_keys']));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $query = Quote::query()
 | 
					        $query = Quote::query()
 | 
				
			||||||
                            ->withTrashed()
 | 
					                            ->withTrashed()
 | 
				
			||||||
                            ->with('client')->where('company_id', $this->company->id)
 | 
					                            ->with('client')->where('company_id', $this->company->id)
 | 
				
			||||||
 | 
				
			|||||||
@ -48,6 +48,8 @@ class RecurringInvoiceExport extends BaseExport
 | 
				
			|||||||
            $this->input['report_keys'] = array_values($this->recurring_invoice_report_keys);
 | 
					            $this->input['report_keys'] = array_values($this->recurring_invoice_report_keys);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->input['report_keys'] = array_merge($this->input['report_keys'], array_diff($this->forced_client_fields, $this->input['report_keys']));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $query = RecurringInvoice::query()
 | 
					        $query = RecurringInvoice::query()
 | 
				
			||||||
                        ->withTrashed()
 | 
					                        ->withTrashed()
 | 
				
			||||||
                        ->with('client')
 | 
					                        ->with('client')
 | 
				
			||||||
@ -135,8 +137,8 @@ class RecurringInvoiceExport extends BaseExport
 | 
				
			|||||||
            $entity['client'] = $invoice->client->present()->name();
 | 
					            $entity['client'] = $invoice->client->present()->name();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (in_array('status_id', $this->input['report_keys'])) {
 | 
					        if (in_array('recurring_invoice.status', $this->input['report_keys'])) {
 | 
				
			||||||
            $entity['status'] = $invoice->stringStatus($invoice->status_id);
 | 
					            $entity['recurring_invoice.status'] = $invoice->stringStatus($invoice->status_id);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (in_array('project_id', $this->input['report_keys'])) {
 | 
					        if (in_array('project_id', $this->input['report_keys'])) {
 | 
				
			||||||
 | 
				
			|||||||
@ -60,6 +60,8 @@ class TaskExport extends BaseExport
 | 
				
			|||||||
            $this->input['report_keys'] = array_values($this->task_report_keys);
 | 
					            $this->input['report_keys'] = array_values($this->task_report_keys);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->input['report_keys'] = array_merge($this->input['report_keys'], array_diff($this->forced_client_fields, $this->input['report_keys']));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $query = Task::query()
 | 
					        $query = Task::query()
 | 
				
			||||||
                        ->withTrashed()
 | 
					                        ->withTrashed()
 | 
				
			||||||
                        ->where('company_id', $this->company->id)
 | 
					                        ->where('company_id', $this->company->id)
 | 
				
			||||||
 | 
				
			|||||||
@ -27,7 +27,8 @@ class UserFactory
 | 
				
			|||||||
        $user->last_login = now();
 | 
					        $user->last_login = now();
 | 
				
			||||||
        $user->failed_logins = 0;
 | 
					        $user->failed_logins = 0;
 | 
				
			||||||
        $user->signature = '';
 | 
					        $user->signature = '';
 | 
				
			||||||
        $user->theme_id = 0;
 | 
					        $user->theme_id = 0;   
 | 
				
			||||||
 | 
					        $user->user_logged_in_notification = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $user;
 | 
					        return $user;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -50,7 +50,8 @@ class EpcQrGenerator
 | 
				
			|||||||
            );
 | 
					            );
 | 
				
			||||||
            $writer = new Writer($renderer);
 | 
					            $writer = new Writer($renderer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $this->validateFields();
 | 
					            if($this->validateFields())
 | 
				
			||||||
 | 
					                return '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $qr = $writer->writeString($this->encodeMessage(), 'utf-8');
 | 
					            $qr = $writer->writeString($this->encodeMessage(), 'utf-8');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -87,12 +88,16 @@ class EpcQrGenerator
 | 
				
			|||||||
    private function validateFields()
 | 
					    private function validateFields()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (Ninja::isSelfHost() && isset($this->company?->custom_fields?->company2)) {
 | 
					        if (Ninja::isSelfHost() && isset($this->company?->custom_fields?->company2)) {
 | 
				
			||||||
 | 
					            return true;
 | 
				
			||||||
            nlog('The BIC field is not present and _may_ be a required fields for EPC QR codes');
 | 
					            nlog('The BIC field is not present and _may_ be a required fields for EPC QR codes');
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (Ninja::isSelfHost() && isset($this->company?->custom_fields?->company1)) {
 | 
					        if (Ninja::isSelfHost() && isset($this->company?->custom_fields?->company1)) {
 | 
				
			||||||
 | 
					            return true;
 | 
				
			||||||
            nlog('The IBAN field is required');
 | 
					            nlog('The IBAN field is required');
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private function formatMoney($value)
 | 
					    private function formatMoney($value)
 | 
				
			||||||
 | 
				
			|||||||
@ -174,9 +174,14 @@ class SwissQrGenerator
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            return $html;
 | 
					            return $html;
 | 
				
			||||||
        } catch (\Exception $e) {
 | 
					        } catch (\Exception $e) {
 | 
				
			||||||
            foreach ($qrBill->getViolations() as $key => $violation) {
 | 
					
 | 
				
			||||||
                nlog("qr");
 | 
					            if(is_iterable($qrBill->getViolations())) {
 | 
				
			||||||
                nlog($violation);
 | 
					           
 | 
				
			||||||
 | 
					                foreach ($qrBill->getViolations() as $key => $violation) {
 | 
				
			||||||
 | 
					                    nlog("qr");
 | 
				
			||||||
 | 
					                    nlog($violation);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            nlog($e->getMessage());
 | 
					            nlog($e->getMessage());
 | 
				
			||||||
 | 
				
			|||||||
@ -31,11 +31,11 @@ class EmailHistoryController extends BaseController
 | 
				
			|||||||
                 ->where('category_id', SystemLog::CATEGORY_MAIL)
 | 
					                 ->where('category_id', SystemLog::CATEGORY_MAIL)
 | 
				
			||||||
                 ->orderBy('id', 'DESC')
 | 
					                 ->orderBy('id', 'DESC')
 | 
				
			||||||
                 ->cursor()
 | 
					                 ->cursor()
 | 
				
			||||||
                 ->map(function ($system_log) {
 | 
					                ->filter(function ($system_log) {
 | 
				
			||||||
                     if(($system_log->log['history'] && $system_log->log['history']['events'] && count($system_log->log['history']['events']) >=1) ?? false) {
 | 
					                    return ($system_log->log['history'] && isset($system_log->log['history']['events']) && count($system_log->log['history']['events']) >=1) !== false;
 | 
				
			||||||
                        return $system_log->log['history'];
 | 
					                })->map(function  ($system_log) {
 | 
				
			||||||
                     }
 | 
					                    return $system_log->log['history'];
 | 
				
			||||||
                 });
 | 
					                })->values()->all();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return response()->json($data, 200);
 | 
					        return response()->json($data, 200);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -51,16 +51,17 @@ class EmailHistoryController extends BaseController
 | 
				
			|||||||
        /** @var \App\Models\User $user */
 | 
					        /** @var \App\Models\User $user */
 | 
				
			||||||
        $user = auth()->user();
 | 
					        $user = auth()->user();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $data = SystemLog::where('company_id', $user->company()->id)
 | 
					        $data = SystemLog::where('company_id', $user->company()->id)
 | 
				
			||||||
                ->where('category_id', SystemLog::CATEGORY_MAIL)
 | 
					        ->where('category_id', SystemLog::CATEGORY_MAIL)
 | 
				
			||||||
                ->whereJsonContains('log->history->entity_id', $this->encodePrimaryKey($request->entity_id))
 | 
					        ->whereJsonContains('log->history->entity_id', $this->encodePrimaryKey($request->entity_id))
 | 
				
			||||||
                ->orderBy('id', 'DESC')
 | 
					        ->orderBy('id', 'DESC')
 | 
				
			||||||
                ->cursor()
 | 
					        ->cursor()
 | 
				
			||||||
                ->map(function ($system_log) {
 | 
					        ->filter(function ($system_log) {
 | 
				
			||||||
                    if(($system_log->log['history'] && $system_log->log['history']['events'] && count($system_log->log['history']['events']) >=1) ?? false) {
 | 
					            return ($system_log->log['history'] && isset($system_log->log['history']['events']) && count($system_log->log['history']['events']) >=1) !== false;
 | 
				
			||||||
                        return $system_log->log['history'];
 | 
					        })->map(function  ($system_log) {
 | 
				
			||||||
                    }
 | 
					            return $system_log->log['history'];
 | 
				
			||||||
                });
 | 
					        })->values()->all();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return response()->json($data, 200);
 | 
					        return response()->json($data, 200);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -157,6 +157,7 @@ class RecurringInvoiceController extends BaseController
 | 
				
			|||||||
        $user = auth()->user();
 | 
					        $user = auth()->user();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $recurring_invoice = RecurringInvoiceFactory::create($user->company()->id, $user->id);
 | 
					        $recurring_invoice = RecurringInvoiceFactory::create($user->company()->id, $user->id);
 | 
				
			||||||
 | 
					        $recurring_invoice->auto_bill = $user->company()->settings->auto_bill;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $this->itemResponse($recurring_invoice);
 | 
					        return $this->itemResponse($recurring_invoice);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -39,11 +39,11 @@ class TasksTable extends Component
 | 
				
			|||||||
            ->where('is_deleted', false)
 | 
					            ->where('is_deleted', false)
 | 
				
			||||||
            ->where('client_id', auth()->guard('contact')->user()->client_id);
 | 
					            ->where('client_id', auth()->guard('contact')->user()->client_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if ($this->company->getSetting('show_all_tasks_client_portal') === 'invoiced') {
 | 
					        if ( auth()->guard('contact')->user()->client->getSetting('show_all_tasks_client_portal') === 'invoiced') {
 | 
				
			||||||
            $query = $query->whereNotNull('invoice_id');
 | 
					            $query = $query->whereNotNull('invoice_id');
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if ($this->company->getSetting('show_all_tasks_client_portal') === 'uninvoiced') {
 | 
					        if ( auth()->guard('contact')->user()->client->getSetting('show_all_tasks_client_portal') === 'uninvoiced') {
 | 
				
			||||||
            $query = $query->whereNull('invoice_id');
 | 
					            $query = $query->whereNull('invoice_id');
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -180,7 +180,7 @@ class Request extends FormRequest
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                //Filter the client contact password - if it is sent with ***** we should ignore it!
 | 
					                //Filter the client contact password - if it is sent with ***** we should ignore it!
 | 
				
			||||||
                if (isset($contact['password'])) {
 | 
					                if (isset($contact['password']) && is_string($contact['password'])) {
 | 
				
			||||||
                    if (strlen($contact['password']) == 0) {
 | 
					                    if (strlen($contact['password']) == 0) {
 | 
				
			||||||
                        $input['contacts'][$key]['password'] = '';
 | 
					                        $input['contacts'][$key]['password'] = '';
 | 
				
			||||||
                    } else {
 | 
					                    } else {
 | 
				
			||||||
 | 
				
			|||||||
@ -32,12 +32,12 @@ class NinjaMailerObject
 | 
				
			|||||||
    /* Variable for cascading notifications */
 | 
					    /* Variable for cascading notifications */
 | 
				
			||||||
    public $entity_string = false;
 | 
					    public $entity_string = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* @var bool | App\Models\InvoiceInvitation | app\Models\QuoteInvitation | app\Models\CreditInvitation | app\Models\RecurringInvoiceInvitation | app\Models\PurchaseOrderInvitation $invitation*/
 | 
					    /* @var bool | App\Models\InvoiceInvitation | App\Models\QuoteInvitation | App\Models\CreditInvitation | App\Models\RecurringInvoiceInvitation | App\Models\PurchaseOrderInvitation $invitation*/
 | 
				
			||||||
    public $invitation = false;
 | 
					    public $invitation = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public $template = false;
 | 
					    public $template = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* @var bool | App\Models\Invoice | app\Models\Quote | app\Models\Credit | app\Models\RecurringInvoice | app\Models\PurchaseOrder $invitation*/
 | 
					    /* @var bool | App\Models\Invoice | App\Models\Quote | App\Models\Credit | App\Models\RecurringInvoice | App\Models\PurchaseOrder  | App\Models\Payment $entity */
 | 
				
			||||||
    public $entity = false;
 | 
					    public $entity = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public $reminder_template = '';
 | 
					    public $reminder_template = '';
 | 
				
			||||||
 | 
				
			|||||||
@ -55,7 +55,7 @@ class UpdateUserLastLogin implements ShouldQueue
 | 
				
			|||||||
        $key = "user_logged_in_{$user->id}{$event->company->db}";
 | 
					        $key = "user_logged_in_{$user->id}{$event->company->db}";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        if ($user->ip != $ip && is_null(Cache::get($key))) {
 | 
					        if ($user->ip != $ip && is_null(Cache::get($key)) && $user->user_logged_in_notification) {
 | 
				
			||||||
            $nmo = new NinjaMailerObject;
 | 
					            $nmo = new NinjaMailerObject;
 | 
				
			||||||
            $nmo->mailable = new UserLoggedIn($user, $user->account->companies->first(), $ip);
 | 
					            $nmo->mailable = new UserLoggedIn($user, $user->account->companies->first(), $ip);
 | 
				
			||||||
            $nmo->company = $user->account->companies->first();
 | 
					            $nmo->company = $user->account->companies->first();
 | 
				
			||||||
@ -69,6 +69,7 @@ class UpdateUserLastLogin implements ShouldQueue
 | 
				
			|||||||
        
 | 
					        
 | 
				
			||||||
        Cache::put($key, true, 60 * 24);
 | 
					        Cache::put($key, true, 60 * 24);
 | 
				
			||||||
        $arr = json_encode(['ip' => $ip]);
 | 
					        $arr = json_encode(['ip' => $ip]);
 | 
				
			||||||
 | 
					        $arr = ctrans('texts.new_login_detected'). " {$ip}";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        SystemLogger::dispatch(
 | 
					        SystemLogger::dispatch(
 | 
				
			||||||
            $arr,
 | 
					            $arr,
 | 
				
			||||||
 | 
				
			|||||||
@ -108,12 +108,15 @@ class TemplateEmail extends Mailable
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if (strlen($settings->bcc_email) > 1) {
 | 
					        if (strlen($settings->bcc_email) > 1) {
 | 
				
			||||||
            if (Ninja::isHosted()) {
 | 
					            if (Ninja::isHosted()) {
 | 
				
			||||||
                $bccs = explode(',', str_replace(' ', '', $settings->bcc_email));
 | 
					
 | 
				
			||||||
                $this->bcc(array_slice($bccs, 0, 2));
 | 
					                if($company->account->isPaid()) {
 | 
				
			||||||
                //$this->bcc(reset($bccs)); //remove whitespace if any has been inserted.
 | 
					                    $bccs = explode(',', str_replace(' ', '', $settings->bcc_email));
 | 
				
			||||||
 | 
					                    $this->bcc(array_slice($bccs, 0, 5));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                $this->bcc(explode(',', str_replace(' ', '', $settings->bcc_email)));
 | 
					                $this->bcc(explode(',', str_replace(' ', '', $settings->bcc_email)));
 | 
				
			||||||
            }//remove whitespace if any has been inserted.
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->subject(str_replace("<br>", "", $this->build_email->getSubject()))
 | 
					        $this->subject(str_replace("<br>", "", $this->build_email->getSubject()))
 | 
				
			||||||
 | 
				
			|||||||
@ -11,10 +11,11 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\Mail;
 | 
					namespace App\Mail;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Utils\Ninja;
 | 
				
			||||||
use App\Models\VendorContact;
 | 
					use App\Models\VendorContact;
 | 
				
			||||||
use App\Services\PdfMaker\Designs\Utilities\DesignHelpers;
 | 
					 | 
				
			||||||
use App\Utils\VendorHtmlEngine;
 | 
					 | 
				
			||||||
use Illuminate\Mail\Mailable;
 | 
					use Illuminate\Mail\Mailable;
 | 
				
			||||||
 | 
					use App\Utils\VendorHtmlEngine;
 | 
				
			||||||
 | 
					use App\Services\PdfMaker\Designs\Utilities\DesignHelpers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class VendorTemplateEmail extends Mailable
 | 
					class VendorTemplateEmail extends Mailable
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -102,8 +103,19 @@ class VendorTemplateEmail extends Mailable
 | 
				
			|||||||
        $this->from(config('mail.from.address'), $email_from_name);
 | 
					        $this->from(config('mail.from.address'), $email_from_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (strlen($settings->bcc_email) > 1) {
 | 
					        if (strlen($settings->bcc_email) > 1) {
 | 
				
			||||||
            $this->bcc(explode(',', str_replace(' ', '', $settings->bcc_email)));
 | 
					        
 | 
				
			||||||
        }//remove whitespace if any has been inserted.
 | 
					            if (Ninja::isHosted()) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if($this->company->account->isPaid()) {
 | 
				
			||||||
 | 
					                    $bccs = explode(',', str_replace(' ', '', $settings->bcc_email));
 | 
				
			||||||
 | 
					                    $this->bcc(array_slice($bccs, 0, 5));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                $this->bcc(explode(',', str_replace(' ', '', $settings->bcc_email)));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->subject($this->build_email->getSubject())
 | 
					        $this->subject($this->build_email->getSubject())
 | 
				
			||||||
            ->text('email.template.text', [
 | 
					            ->text('email.template.text', [
 | 
				
			||||||
 | 
				
			|||||||
@ -23,7 +23,7 @@ class ClientPresenter extends EntityPresenter
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    public function name()
 | 
					    public function name()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if ($this->entity->name) {
 | 
					        if (strlen($this->entity->name) > 1) {
 | 
				
			||||||
            return $this->entity->name;
 | 
					            return $this->entity->name;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -73,7 +73,8 @@ use Illuminate\Foundation\Auth\User as Authenticatable;
 | 
				
			|||||||
 * @property int|null $deleted_at
 | 
					 * @property int|null $deleted_at
 | 
				
			||||||
 * @property string|null $oauth_user_refresh_token
 | 
					 * @property string|null $oauth_user_refresh_token
 | 
				
			||||||
 * @property string|null $last_confirmed_email_address
 | 
					 * @property string|null $last_confirmed_email_address
 | 
				
			||||||
 * @property int $has_password
 | 
					 * @property bool $has_password
 | 
				
			||||||
 | 
					 * @property bool $user_logged_in_notification
 | 
				
			||||||
 * @property Carbon|null $oauth_user_token_expiry
 | 
					 * @property Carbon|null $oauth_user_token_expiry
 | 
				
			||||||
 * @property string|null $sms_verification_code
 | 
					 * @property string|null $sms_verification_code
 | 
				
			||||||
 * @property bool $verified_phone_number
 | 
					 * @property bool $verified_phone_number
 | 
				
			||||||
@ -140,6 +141,7 @@ class User extends Authenticatable implements MustVerifyEmail
 | 
				
			|||||||
     *
 | 
					     *
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    protected $fillable = [
 | 
					    protected $fillable = [
 | 
				
			||||||
 | 
					        'user_logged_in_notification',
 | 
				
			||||||
        'first_name',
 | 
					        'first_name',
 | 
				
			||||||
        'last_name',
 | 
					        'last_name',
 | 
				
			||||||
        'email',
 | 
					        'email',
 | 
				
			||||||
 | 
				
			|||||||
@ -251,7 +251,7 @@ class CreditCard
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $response = $this->eway_driver->init()->eway->createTransaction(\Eway\Rapid\Enum\ApiMethod::DIRECT, $transaction);
 | 
					        $response = $this->eway_driver->init()->eway->createTransaction(\Eway\Rapid\Enum\ApiMethod::DIRECT, $transaction);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if ($response->TransactionStatus) {
 | 
					        if ($response->TransactionStatus ?? false) {
 | 
				
			||||||
            $this->logResponse($response, true);
 | 
					            $this->logResponse($response, true);
 | 
				
			||||||
            $payment = $this->storePayment($response);
 | 
					            $payment = $this->storePayment($response);
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
 | 
				
			|||||||
@ -134,8 +134,8 @@ class SquareWebhook implements ShouldQueue
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            nlog("Searching by payment hash");
 | 
					            nlog("Searching by payment hash");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $payment_hash_id = $apiResponse->getPayment()->getReferenceId() ?? false;
 | 
					            $payment_hash_id = $apiResponse->getResult()->getPayment()->getReferenceId() ?? false;
 | 
				
			||||||
            $square_payment = $apiResponse->getPayment()->jsonSerialize();
 | 
					            $square_payment = $apiResponse->getResult()->getPayment()->jsonSerialize();
 | 
				
			||||||
            $payment_hash = PaymentHash::query()->where('hash', $payment_hash_id)->firstOrFail();
 | 
					            $payment_hash = PaymentHash::query()->where('hash', $payment_hash_id)->firstOrFail();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $payment_hash->data = array_merge((array) $payment_hash->data, (array)$square_payment);
 | 
					            $payment_hash->data = array_merge((array) $payment_hash->data, (array)$square_payment);
 | 
				
			||||||
 | 
				
			|||||||
@ -140,7 +140,7 @@ class Email implements ShouldQueue
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $this->email_object->client_id ? $this->email_object->settings = $this->email_object->client->getMergedSettings() : $this->email_object->settings = $this->company->settings;
 | 
					        $this->email_object->client_id ? $this->email_object->settings = $this->email_object->client->getMergedSettings() : $this->email_object->settings = $this->company->settings;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->email_object->client_id ? nlog("client settings") : nlog("company settings ");
 | 
					        // $this->email_object->client_id ? nlog("client settings") : nlog("company settings ");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->email_object->whitelabel = $this->company->account->isPaid() ? true : false;
 | 
					        $this->email_object->whitelabel = $this->company->account->isPaid() ? true : false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -413,6 +413,14 @@ class Email implements ShouldQueue
 | 
				
			|||||||
            if ($address_object->address == " ") {
 | 
					            if ($address_object->address == " ") {
 | 
				
			||||||
                return true;
 | 
					                return true;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($address_object->address == "") {
 | 
				
			||||||
 | 
					                return true;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if($address_object->name == " " || $address_object->name == "") {
 | 
				
			||||||
 | 
					                return true;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -255,8 +255,8 @@ class EmailDefaults
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if (strlen($this->email->email_object->settings->bcc_email) > 1) {
 | 
					        if (strlen($this->email->email_object->settings->bcc_email) > 1) {
 | 
				
			||||||
            if (Ninja::isHosted() && $this->email->company->account->isPaid()) {
 | 
					            if (Ninja::isHosted() && $this->email->company->account->isPaid()) {
 | 
				
			||||||
                $bccs = array_slice(explode(',', str_replace(' ', '', $this->email->email_object->settings->bcc_email)), 0, 2);
 | 
					                $bccs = array_slice(explode(',', str_replace(' ', '', $this->email->email_object->settings->bcc_email)), 0, 5);
 | 
				
			||||||
            } elseif (Ninja::isSelfHost()) {
 | 
					            } else  {
 | 
				
			||||||
                $bccs = (explode(',', str_replace(' ', '', $this->email->email_object->settings->bcc_email)));
 | 
					                $bccs = (explode(',', str_replace(' ', '', $this->email->email_object->settings->bcc_email)));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -120,7 +120,7 @@ class AutoBillInvoice extends AbstractService
 | 
				
			|||||||
        /* Build payment hash */
 | 
					        /* Build payment hash */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $payment_hash = PaymentHash::create([
 | 
					        $payment_hash = PaymentHash::create([
 | 
				
			||||||
            'hash' => Str::random(64),
 | 
					            'hash' => Str::random(32),
 | 
				
			||||||
            'data' => [
 | 
					            'data' => [
 | 
				
			||||||
                'amount_with_fee' => $amount + $fee,
 | 
					                'amount_with_fee' => $amount + $fee,
 | 
				
			||||||
                'invoices' => [
 | 
					                'invoices' => [
 | 
				
			||||||
 | 
				
			|||||||
@ -75,7 +75,7 @@ class ZugferdEInvoice extends AbstractService
 | 
				
			|||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            $this->xrechnung->setDocumentBuyerReference($client->routing_id);
 | 
					            $this->xrechnung->setDocumentBuyerReference($client->routing_id);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (!empty($client->shipping_address1)){
 | 
					        if (!empty($client->shipping_address1) && $client->shipping_country->exists()){
 | 
				
			||||||
            $this->xrechnung->setDocumentShipToAddress($client->shipping_address1, $client->shipping_address2, "", $client->shipping_postal_code, $client->shipping_city, $client->shipping_country->iso_3166_2, $client->shipping_state);
 | 
					            $this->xrechnung->setDocumentShipToAddress($client->shipping_address1, $client->shipping_address2, "", $client->shipping_postal_code, $client->shipping_city, $client->shipping_country->iso_3166_2, $client->shipping_state);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -17,6 +17,7 @@ use App\Models\ClientContact;
 | 
				
			|||||||
use App\Models\ClientGatewayToken;
 | 
					use App\Models\ClientGatewayToken;
 | 
				
			||||||
use App\Models\CompanyLedger;
 | 
					use App\Models\CompanyLedger;
 | 
				
			||||||
use App\Models\Document;
 | 
					use App\Models\Document;
 | 
				
			||||||
 | 
					use App\Models\GroupSetting;
 | 
				
			||||||
use App\Models\SystemLog;
 | 
					use App\Models\SystemLog;
 | 
				
			||||||
use App\Utils\Traits\MakesHash;
 | 
					use App\Utils\Traits\MakesHash;
 | 
				
			||||||
use League\Fractal\Resource\Collection;
 | 
					use League\Fractal\Resource\Collection;
 | 
				
			||||||
@ -42,6 +43,7 @@ class ClientTransformer extends EntityTransformer
 | 
				
			|||||||
        'activities',
 | 
					        'activities',
 | 
				
			||||||
        'ledger',
 | 
					        'ledger',
 | 
				
			||||||
        'system_logs',
 | 
					        'system_logs',
 | 
				
			||||||
 | 
					        'group_settings',
 | 
				
			||||||
    ];
 | 
					    ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
@ -96,6 +98,16 @@ class ClientTransformer extends EntityTransformer
 | 
				
			|||||||
        return $this->includeCollection($client->system_logs, $transformer, SystemLog::class);
 | 
					        return $this->includeCollection($client->system_logs, $transformer, SystemLog::class);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function includeGroupSettings(Client $client)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (!$client->group_settings)
 | 
				
			||||||
 | 
					            return null;
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        $transformer = new GroupSettingTransformer($this->serializer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->includeItem($client->group_settings, $transformer, GroupSetting::class);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * @param Client $client
 | 
					     * @param Client $client
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
 | 
				
			|||||||
@ -64,6 +64,7 @@ class UserTransformer extends EntityTransformer
 | 
				
			|||||||
            'oauth_user_token' => empty($user->oauth_user_token) ? '' : '***',
 | 
					            'oauth_user_token' => empty($user->oauth_user_token) ? '' : '***',
 | 
				
			||||||
            'verified_phone_number' => (bool) $user->verified_phone_number,
 | 
					            'verified_phone_number' => (bool) $user->verified_phone_number,
 | 
				
			||||||
            'language_id' => (string) $user->language_id ?? '',
 | 
					            'language_id' => (string) $user->language_id ?? '',
 | 
				
			||||||
 | 
					            'user_logged_in_notification' => (bool) $user->user_logged_in_notification,
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -15,8 +15,8 @@ return [
 | 
				
			|||||||
    'require_https' => env('REQUIRE_HTTPS', true),
 | 
					    'require_https' => env('REQUIRE_HTTPS', true),
 | 
				
			||||||
    'app_url' => rtrim(env('APP_URL', ''), '/'),
 | 
					    'app_url' => rtrim(env('APP_URL', ''), '/'),
 | 
				
			||||||
    'app_domain' => env('APP_DOMAIN', 'invoicing.co'),
 | 
					    'app_domain' => env('APP_DOMAIN', 'invoicing.co'),
 | 
				
			||||||
    'app_version' => env('APP_VERSION','5.7.30'),
 | 
					    'app_version' => env('APP_VERSION','5.7.31'),
 | 
				
			||||||
    'app_tag' => env('APP_TAG','5.7.30'),
 | 
					    'app_tag' => env('APP_TAG','5.7.31'),
 | 
				
			||||||
    'minimum_client_version' => '5.0.16',
 | 
					    'minimum_client_version' => '5.0.16',
 | 
				
			||||||
    'terms_version' => '1.0.1',
 | 
					    'terms_version' => '1.0.1',
 | 
				
			||||||
    'api_secret' => env('API_SECRET', ''),
 | 
					    'api_secret' => env('API_SECRET', ''),
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,43 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Models\Currency;
 | 
				
			||||||
 | 
					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
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Schema::table('users', function (Blueprint $table) {
 | 
				
			||||||
 | 
					            $table->boolean('user_logged_in_notification')->default(true);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $cur = Currency::find(120);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(!$cur) {
 | 
				
			||||||
 | 
					            $cur = new \App\Models\Currency();
 | 
				
			||||||
 | 
					            $cur->id = 120;
 | 
				
			||||||
 | 
					            $cur->code = 'TOP';
 | 
				
			||||||
 | 
					            $cur->name = "Tongan Pa'anga";
 | 
				
			||||||
 | 
					            $cur->symbol = 'T$';
 | 
				
			||||||
 | 
					            $cur->thousand_separator = ',';
 | 
				
			||||||
 | 
					            $cur->decimal_separator = '.';
 | 
				
			||||||
 | 
					            $cur->precision = 2;
 | 
				
			||||||
 | 
					            $cur->save();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Reverse the migrations.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function down(): void
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        //
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
@ -142,6 +142,7 @@ class CurrenciesSeeder extends Seeder
 | 
				
			|||||||
            ['id' => 117, 'name' => 'Gold Troy Ounce', 'code' => 'XAU', 'symbol' => 'XAU', 'precision' => '3', 'thousand_separator' => ',', 'decimal_separator' => '.'],
 | 
					            ['id' => 117, 'name' => 'Gold Troy Ounce', 'code' => 'XAU', 'symbol' => 'XAU', 'precision' => '3', 'thousand_separator' => ',', 'decimal_separator' => '.'],
 | 
				
			||||||
            ['id' => 118, 'name' => 'Nicaraguan Córdoba', 'code' => 'NIO', 'symbol' => 'C$', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'],
 | 
					            ['id' => 118, 'name' => 'Nicaraguan Córdoba', 'code' => 'NIO', 'symbol' => 'C$', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'],
 | 
				
			||||||
            ['id' => 119, 'name' => 'Malagasy ariary', 'code' => 'MGA', 'symbol' => 'Ar', 'precision' => '0', 'thousand_separator' => ',', 'decimal_separator' => '.'],
 | 
					            ['id' => 119, 'name' => 'Malagasy ariary', 'code' => 'MGA', 'symbol' => 'Ar', 'precision' => '0', 'thousand_separator' => ',', 'decimal_separator' => '.'],
 | 
				
			||||||
 | 
					            ['id' => 120, 'name' => "Tongan Pa anga", 'code' => 'TOP', 'symbol' => 'T$', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'],
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        foreach ($currencies as $currency) {
 | 
					        foreach ($currencies as $currency) {
 | 
				
			||||||
 | 
				
			|||||||
@ -2402,6 +2402,9 @@ $LANG = array(
 | 
				
			|||||||
    'currency_libyan_dinar' => 'Libyan Dinar',
 | 
					    'currency_libyan_dinar' => 'Libyan Dinar',
 | 
				
			||||||
    'currency_silver_troy_ounce' => 'Silver Troy Ounce',
 | 
					    'currency_silver_troy_ounce' => 'Silver Troy Ounce',
 | 
				
			||||||
    'currency_gold_troy_ounce' => 'Gold Troy Ounce',
 | 
					    'currency_gold_troy_ounce' => 'Gold Troy Ounce',
 | 
				
			||||||
 | 
					    'currency_nicaraguan_córdoba' => 'Nicaraguan Córdoba',
 | 
				
			||||||
 | 
					    'currency_malagasy_ariary' => 'Malagasy ariary',
 | 
				
			||||||
 | 
					    "currency_tongan_pa_anga" => "Tongan Pa'anga",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    'review_app_help' => 'We hope you\'re enjoying using the app.<br/>If you\'d consider :link we\'d greatly appreciate it!',
 | 
					    'review_app_help' => 'We hope you\'re enjoying using the app.<br/>If you\'d consider :link we\'d greatly appreciate it!',
 | 
				
			||||||
    'writing_a_review' => 'writing a review',
 | 
					    'writing_a_review' => 'writing a review',
 | 
				
			||||||
@ -5180,6 +5183,8 @@ $LANG = array(
 | 
				
			|||||||
    'upcoming' => 'Upcoming',
 | 
					    'upcoming' => 'Upcoming',
 | 
				
			||||||
    'client_contact' => 'Client Contact',
 | 
					    'client_contact' => 'Client Contact',
 | 
				
			||||||
    'uncategorized' => 'Uncategorized',
 | 
					    'uncategorized' => 'Uncategorized',
 | 
				
			||||||
 | 
					    'login_notification' => 'Login Notification',
 | 
				
			||||||
 | 
					    'login_notification_help' => 'Sends an email notifying that a login has taken place.'
 | 
				
			||||||
); 
 | 
					); 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
return $LANG;
 | 
					return $LANG;
 | 
				
			||||||
 | 
				
			|||||||
@ -64,7 +64,7 @@
 | 
				
			|||||||
                                    {{ ctrans('texts.public_notes') }}
 | 
					                                    {{ ctrans('texts.public_notes') }}
 | 
				
			||||||
                                </dt>
 | 
					                                </dt>
 | 
				
			||||||
                                <dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
 | 
					                                <dd class="mt-1 text-sm leading-5 text-gray-900 sm:mt-0 sm:col-span-2">
 | 
				
			||||||
                                    {{ $invoice->public_notes }}
 | 
					                                    {!! html_entity_decode($invoice->public_notes) !!}
 | 
				
			||||||
                                </dd>
 | 
					                                </dd>
 | 
				
			||||||
                                @else
 | 
					                                @else
 | 
				
			||||||
                                <dt class="text-sm font-medium leading-5 text-gray-500">
 | 
					                                <dt class="text-sm font-medium leading-5 text-gray-500">
 | 
				
			||||||
 | 
				
			|||||||
@ -65,6 +65,34 @@ class ClientTest extends TestCase
 | 
				
			|||||||
        $this->makeTestData();
 | 
					        $this->makeTestData();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function testStoreClientFixes()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $data = [
 | 
				
			||||||
 | 
					            "contacts" => [
 | 
				
			||||||
 | 
					            [
 | 
				
			||||||
 | 
					            "email" => "tenda@gmail.com", 
 | 
				
			||||||
 | 
					            "first_name" => "Tenda", 
 | 
				
			||||||
 | 
					            "is_primary" => True, 
 | 
				
			||||||
 | 
					            "last_name" => "Bavuma", 
 | 
				
			||||||
 | 
					            "password" => null, 
 | 
				
			||||||
 | 
					            "send_email" => True
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					        ],  
 | 
				
			||||||
 | 
					            "country_id" => "356", 
 | 
				
			||||||
 | 
					            "display_name" => "Tenda Bavuma", 
 | 
				
			||||||
 | 
					            "name" => "Tenda Bavuma", 
 | 
				
			||||||
 | 
					            "shipping_country_id" => "356", 
 | 
				
			||||||
 | 
					            ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $response = $this->withHeaders([
 | 
				
			||||||
 | 
					                'X-API-SECRET' => config('ninja.api_secret'),
 | 
				
			||||||
 | 
					                'X-API-TOKEN' => $this->token,
 | 
				
			||||||
 | 
					            ])->postJson('/api/v1/clients', $data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $response->assertStatus(200);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function testClientMergeContactDrop()
 | 
					    public function testClientMergeContactDrop()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -20,7 +20,6 @@ use App\Models\Account;
 | 
				
			|||||||
use App\Models\Company;
 | 
					use App\Models\Company;
 | 
				
			||||||
use App\Models\Expense;
 | 
					use App\Models\Expense;
 | 
				
			||||||
use App\Models\Invoice;
 | 
					use App\Models\Invoice;
 | 
				
			||||||
use Tests\MockAccountData;
 | 
					 | 
				
			||||||
use App\Models\CompanyToken;
 | 
					use App\Models\CompanyToken;
 | 
				
			||||||
use App\Models\ClientContact;
 | 
					use App\Models\ClientContact;
 | 
				
			||||||
use App\Export\CSV\TaskExport;
 | 
					use App\Export\CSV\TaskExport;
 | 
				
			||||||
@ -30,8 +29,6 @@ use App\Export\CSV\ProductExport;
 | 
				
			|||||||
use App\DataMapper\CompanySettings;
 | 
					use App\DataMapper\CompanySettings;
 | 
				
			||||||
use App\Export\CSV\PaymentExport;
 | 
					use App\Export\CSV\PaymentExport;
 | 
				
			||||||
use App\Factory\CompanyUserFactory;
 | 
					use App\Factory\CompanyUserFactory;
 | 
				
			||||||
use App\Factory\InvoiceItemFactory;
 | 
					 | 
				
			||||||
use App\Services\Report\ARDetailReport;
 | 
					 | 
				
			||||||
use Illuminate\Routing\Middleware\ThrottleRequests;
 | 
					use Illuminate\Routing\Middleware\ThrottleRequests;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@ -262,6 +259,21 @@ class ReportCsvGenerationTest extends TestCase
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function testForcedInsertionOfMandatoryColumns()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $forced = ['client.name'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $report_keys = ['invoice.number','client.name', 'invoice.amount'];
 | 
				
			||||||
 | 
					        $array = array_merge($report_keys, array_diff($forced, $report_keys));
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        $this->assertEquals('client.name', $array[1]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $report_keys = ['invoice.number','invoice.amount'];
 | 
				
			||||||
 | 
					        $array = array_merge($report_keys, array_diff($forced, $report_keys));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->assertEquals('client.name', $array[2]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function testVendorCsvGeneration()
 | 
					    public function testVendorCsvGeneration()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -322,7 +334,7 @@ class ReportCsvGenerationTest extends TestCase
 | 
				
			|||||||
        $data = $export->returnJson();
 | 
					        $data = $export->returnJson();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->assertNotNull($data);
 | 
					        $this->assertNotNull($data);
 | 
				
			||||||
// nlog($data);
 | 
					        // nlog($data);
 | 
				
			||||||
        // $this->assertEquals(0, $this->traverseJson($data, 'columns.0.identifier'));
 | 
					        // $this->assertEquals(0, $this->traverseJson($data, 'columns.0.identifier'));
 | 
				
			||||||
        $this->assertEquals('Vendor Name', $this->traverseJson($data, 'columns.9.display_value'));
 | 
					        $this->assertEquals('Vendor Name', $this->traverseJson($data, 'columns.9.display_value'));
 | 
				
			||||||
        $this->assertEquals('vendor', $this->traverseJson($data, '0.0.entity'));
 | 
					        $this->assertEquals('vendor', $this->traverseJson($data, '0.0.entity'));
 | 
				
			||||||
@ -1021,6 +1033,44 @@ class ReportCsvGenerationTest extends TestCase
 | 
				
			|||||||
            'X-API-TOKEN' => $this->token,
 | 
					            'X-API-TOKEN' => $this->token,
 | 
				
			||||||
        ])->post('/api/v1/reports/recurring_invoices', $data)->assertStatus(200);
 | 
					        ])->post('/api/v1/reports/recurring_invoices', $data)->assertStatus(200);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function testRecurringInvoiceColumnsCsvGeneration()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        \App\Models\RecurringInvoice::factory()->create([
 | 
				
			||||||
 | 
					           'user_id' => $this->user->id,
 | 
				
			||||||
 | 
					           'company_id' => $this->company->id,
 | 
				
			||||||
 | 
					           'client_id' => $this->client->id,
 | 
				
			||||||
 | 
					           'amount' => 100,
 | 
				
			||||||
 | 
					           'balance' => 50,
 | 
				
			||||||
 | 
					           'number' => '1234',
 | 
				
			||||||
 | 
					           'status_id' => 2,
 | 
				
			||||||
 | 
					           'discount' => 10,
 | 
				
			||||||
 | 
					           'po_number' => '1234',
 | 
				
			||||||
 | 
					           'public_notes' => 'Public',
 | 
				
			||||||
 | 
					           'private_notes' => 'Private',
 | 
				
			||||||
 | 
					           'terms' => 'Terms',
 | 
				
			||||||
 | 
					           'frequency_id' => 1,
 | 
				
			||||||
 | 
					       ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $data = [
 | 
				
			||||||
 | 
					            'date_range' => 'all',
 | 
				
			||||||
 | 
					            'report_keys' => [],
 | 
				
			||||||
 | 
					            'send_email' => false,
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $response = $this->withHeaders([
 | 
				
			||||||
 | 
					            'X-API-SECRET' => config('ninja.api_secret'),
 | 
				
			||||||
 | 
					            'X-API-TOKEN' => $this->token,
 | 
				
			||||||
 | 
					        ])->post('/api/v1/reports/recurring_invoices', $data);
 | 
				
			||||||
 | 
					       
 | 
				
			||||||
 | 
					        $csv = $response->streamedContent();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->assertEquals('1234', $this->getFirstValueByColumn($csv, 'Recurring Invoice Invoice Number'));
 | 
				
			||||||
 | 
					        $this->assertEquals('Daily', $this->getFirstValueByColumn($csv, 'Recurring Invoice How Often'));
 | 
				
			||||||
 | 
					        $this->assertEquals('Active', $this->getFirstValueByColumn($csv, 'Recurring Invoice Status'));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -32,6 +32,8 @@ class InvoiceEmailTest extends TestCase
 | 
				
			|||||||
    use DatabaseTransactions;
 | 
					    use DatabaseTransactions;
 | 
				
			||||||
    use GeneratesCounter;
 | 
					    use GeneratesCounter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public $faker;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected function setUp() :void
 | 
					    protected function setUp() :void
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        parent::setUp();
 | 
					        parent::setUp();
 | 
				
			||||||
@ -48,6 +50,14 @@ class InvoiceEmailTest extends TestCase
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function testInvalidEmailParsing()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $email = 'illegal@example.com';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->assertTrue(strpos($email, '@example.com') !== false);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function testClientEmailHistory()
 | 
					    public function testClientEmailHistory()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $system_log = new SystemLog();
 | 
					        $system_log = new SystemLog();
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user