diff --git a/VERSION.txt b/VERSION.txt index 3c665e5ccf..97eeb36657 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -5.7.54 \ No newline at end of file +5.7.55 \ No newline at end of file diff --git a/app/Http/Controllers/PreviewController.php b/app/Http/Controllers/PreviewController.php index e98f65c1f9..7829b1945d 100644 --- a/app/Http/Controllers/PreviewController.php +++ b/app/Http/Controllers/PreviewController.php @@ -95,7 +95,6 @@ class PreviewController extends BaseController } - /** * Returns the mocked PDF for the invoice design preview. * @@ -108,6 +107,10 @@ class PreviewController extends BaseController { $start = microtime(true); + if($request->has('entity_type') && in_array($request->entity_type, ['payment_receipt', 'payment_refund', 'statement', 'delivery_note'])) { + return $this->liveTemplate($request->all()); + } + /** @var \App\Models\User $user */ $user = auth()->user(); @@ -234,6 +237,44 @@ class PreviewController extends BaseController return $this->blankEntity(); } + private function liveTemplate(array $request_data) + { + nlog($request_data['entity_type']); + + /** @var \App\Models\User $user */ + $user = auth()->user(); + + /** @var \App\Models\Company $company */ + $company = $user->company(); + $design = \App\Models\Design::query() + ->where('id', $request_data['design_id']) + ->where(function ($q) use ($user){ + $q->whereNull('company_id')->orWhere('company_id', $user->companyId()); + }) + ->first(); + + $ts = (new TemplateService($design)); + + try { + + if(isset($request_data['settings']) && is_array($request_data['settings'])) { + $ts->setSettings(json_decode(json_encode($request_data['settings']))); + } + + $ts->setCompany($company) + ->compose() + ->mock(); + } catch(SyntaxError $e) { + // return response()->json(['message' => 'Twig syntax is invalid.', 'errors' => new \stdClass], 422); + } + + $response = Response::make($ts->getPdf(), 200); + $response->header('Content-Type', 'application/pdf'); + + return $response; + + } + private function template() { @@ -256,31 +297,11 @@ class PreviewController extends BaseController // return response()->json(['message' => 'Twig syntax is invalid.', 'errors' => new \stdClass], 422); } - $html = $ts->getHtml(); - if (request()->query('html') == 'true') { - return $html; + return $ts->getHtml(); } - if (config('ninja.phantomjs_pdf_generation') || config('ninja.pdf_generator') == 'phantom') { - return (new Phantom)->convertHtmlToPdf($html); - } - - if (config('ninja.invoiceninja_hosted_pdf_generation') || config('ninja.pdf_generator') == 'hosted_ninja') { - $pdf = (new NinjaPdf())->build($html); - - $numbered_pdf = $this->pageNumbering($pdf, $company); - - if ($numbered_pdf) { - $pdf = $numbered_pdf; - } - - return $pdf; - } - - $file_path = (new PreviewPdf($html, $company))->handle(); - - $response = Response::make($file_path, 200); + $response = Response::make($ts->getPdf(), 200); $response->header('Content-Type', 'application/pdf'); return $response; diff --git a/app/Http/Requests/Preview/DesignPreviewRequest.php b/app/Http/Requests/Preview/DesignPreviewRequest.php index ac2b72fb1a..a3d3409a8f 100644 --- a/app/Http/Requests/Preview/DesignPreviewRequest.php +++ b/app/Http/Requests/Preview/DesignPreviewRequest.php @@ -45,12 +45,12 @@ class DesignPreviewRequest extends Request public function rules() { $rules = [ - 'entity_type' => 'bail|required|in:invoice,quote,credit,purchase_order', + 'entity_type' => 'bail|required|in:invoice,quote,credit,purchase_order,statement,payment_receipt,payment_refund,delivery_note', 'settings_type' => 'bail|required|in:company,group,client', 'settings' => 'sometimes', 'group_id' => 'sometimes', 'client_id' => 'sometimes', - 'design' => 'bail|sometimes|array' + 'design' => 'bail|sometimes|array', ]; return $rules; diff --git a/app/Services/Pdf/PdfBuilder.php b/app/Services/Pdf/PdfBuilder.php index cb269d85b5..789a34ec97 100644 --- a/app/Services/Pdf/PdfBuilder.php +++ b/app/Services/Pdf/PdfBuilder.php @@ -113,6 +113,7 @@ class PdfBuilder $contents = $this->document->getElementsByTagName('ninja'); $template_service = new TemplateService(); + $template_service->setCompany($this->service->company); $data = $template_service->processData($this->service->options)->getData(); $twig = $template_service->twig; diff --git a/app/Services/Pdf/PdfMock.php b/app/Services/Pdf/PdfMock.php index cebf46dc27..50203d0000 100644 --- a/app/Services/Pdf/PdfMock.php +++ b/app/Services/Pdf/PdfMock.php @@ -64,8 +64,14 @@ class PdfMock $pdf_config->setPdfVariables(); $pdf_config->setCurrency(Currency::find($this->settings->currency_id)); $pdf_config->setCountry(Country::find($this->settings->country_id ?: 840)); - $pdf_config->design = Design::withTrashed()->find($this->decodePrimaryKey($pdf_config->entity_design_id)); $pdf_config->currency_entity = $this->mock->client; + + if(isset($this->request['design_id']) && $design = Design::withTrashed()->find($this->request['design_id'])) { + $pdf_config->design = $design; + $pdf_config->entity_design_id = $design->hashed_id; + } + else + $pdf_config->design = Design::withTrashed()->find($this->decodePrimaryKey($pdf_config->entity_design_id)); $pdf_service->config = $pdf_config; @@ -1389,6 +1395,7 @@ class PdfMock '$delivery_note_label' => ctrans('texts.delivery_note'), '$quantity_label' => ctrans('texts.quantity'), '$order_number_label' => ctrans('texts.order_number'), + '$shipping_label' => ctrans('texts.shipping_address'), ]; } } diff --git a/app/Services/PdfMaker/PdfMaker.php b/app/Services/PdfMaker/PdfMaker.php index 680bf7ef81..c13f1a974d 100644 --- a/app/Services/PdfMaker/PdfMaker.php +++ b/app/Services/PdfMaker/PdfMaker.php @@ -81,6 +81,17 @@ class PdfMaker $contents = $this->document->getElementsByTagName('ninja'); $ts = new TemplateService(); + + if(isset($this->data['template']['entity'])){ + try{ + $entity = $this->data['template']['entity']; + $ts->setCompany($entity->company); + } + catch(\Exception $e){ + + } + } + $data = $ts->processData($this->options)->getData(); $twig = $ts->twig; diff --git a/app/Services/Template/TemplateMock.php b/app/Services/Template/TemplateMock.php index e8c3907cfa..1fd183eabb 100644 --- a/app/Services/Template/TemplateMock.php +++ b/app/Services/Template/TemplateMock.php @@ -17,6 +17,8 @@ use App\Services\Pdf\PdfMock; class TemplateMock { + protected ?object $settings; + public array $engines = []; public array $variables = []; @@ -74,15 +76,21 @@ class TemplateMock 'entity_type' => rtrim($type, "s"), 'design' => '', 'settings_type' => 'company', - 'settings' => $this->company->settings, + 'settings' => $this->settings ?? $this->company->settings, ]; $mock = (new PdfMock($data, $this->company)); - $mock->settings = $this->company->settings; + $mock->settings = $this->settings ?? $this->company->settings; $mock->build(); return [$type => $mock->getStubVariables()]; } + public function setSettings($settings): self + { + $this->settings = $settings; + + return $this; + } } diff --git a/app/Services/Template/TemplateService.php b/app/Services/Template/TemplateService.php index 4ff42546c5..81c613724b 100644 --- a/app/Services/Template/TemplateService.php +++ b/app/Services/Template/TemplateService.php @@ -55,11 +55,11 @@ class TemplateService private array $global_vars = []; - public ?Company $company; + public ?Company $company = null; - private ?Client $client; + private ?Client $client = null; - private ?Vendor $vendor; + private ?Vendor $vendor = null; private Invoice | Quote | Credit | PurchaseOrder | RecurringInvoice $entity; @@ -67,6 +67,8 @@ class TemplateService private CommonMarkConverter $commonmark; + private ?object $settings = null; + public function __construct(public ?Design $template = null) { $this->template = $template; @@ -167,6 +169,25 @@ class TemplateService return $this; } + public function setSettings($settings): self + { + $this->settings = $settings; + + return $this; + + } + + private function getSettings(): object + { + if($this->settings) + return $this->settings; + + if($this->client) + return $this->client->getMergedSettings(); + + return $this->company->settings; + } + public function addGlobal(array $var): self { $this->global_vars = array_merge($this->global_vars, $var); @@ -182,7 +203,7 @@ class TemplateService public function mock(): self { $tm = new TemplateMock($this->company); - $tm->init(); + $tm->setSettings($this->getSettings())->init(); $this->entity = $this->company->invoices()->first(); @@ -218,6 +239,8 @@ class TemplateService public function getPdf(): string { + // nlog($this->getHtml()); + if (config('ninja.invoiceninja_hosted_pdf_generation') || config('ninja.pdf_generator') == 'hosted_ninja') { $pdf = (new NinjaPdf())->build($this->compiled_html); } else { @@ -345,7 +368,7 @@ class TemplateService * * @return self */ - private function compose(): self + public function compose(): self { if(!$this->template) { return $this; @@ -403,19 +426,19 @@ class TemplateService match ($key) { 'variables' => $processed = $value->first() ?? [], - 'invoices' => $processed = (new HtmlEngine($value->first()->invitations()->first()))->generateLabelsAndValues() ?? [], - 'quotes' => $processed = (new HtmlEngine($value->first()->invitations()->first()))->generateLabelsAndValues() ?? [], - 'credits' => $processed = (new HtmlEngine($value->first()->invitations()->first()))->generateLabelsAndValues() ?? [], - 'payments' => $processed = (new PaymentHtmlEngine($value->first(), $value->first()->client->contacts()->first()))->generateLabelsAndValues() ?? [], + 'invoices' => $processed = (new HtmlEngine($value->first()->invitations()->first()))->setSettings($this->getSettings())->generateLabelsAndValues() ?? [], + 'quotes' => $processed = (new HtmlEngine($value->first()->invitations()->first()))->setSettings($this->getSettings())->generateLabelsAndValues() ?? [], + 'credits' => $processed = (new HtmlEngine($value->first()->invitations()->first()))->setSettings($this->getSettings())->generateLabelsAndValues() ?? [], + 'payments' => $processed = (new PaymentHtmlEngine($value->first(), $value->first()->client->contacts()->first()))->setSettings($this->getSettings())->generateLabelsAndValues() ?? [], 'tasks' => $processed = [], 'projects' => $processed = [], - 'purchase_orders' => (new VendorHtmlEngine($value->first()->invitations()->first()))->generateLabelsAndValues() ?? [], + 'purchase_orders' => (new VendorHtmlEngine($value->first()->invitations()->first()))->setSettings($this->getSettings())->generateLabelsAndValues() ?? [], 'aging' => $processed = [], default => $processed = [], }; - nlog($key); - nlog($processed); + // nlog($key); + // nlog($processed); return $processed; @@ -1159,7 +1182,7 @@ class TemplateService $var_set = $this->getVarSet(); $company_details = - collect($this->company->settings->pdf_variables->company_details) + collect($this->getSettings()->pdf_variables->company_details) ->filter(function ($variable) use ($var_set) { return isset($var_set['values'][$variable]) && !empty($var_set['values'][$variable]); }) @@ -1186,7 +1209,7 @@ class TemplateService $var_set = $this->getVarSet(); $company_address = - collect($this->company->settings->pdf_variables->company_address) + collect($this->getSettings()->pdf_variables->company_address) ->filter(function ($variable) use ($var_set) { return isset($var_set['values'][$variable]) && !empty($var_set['values'][$variable]); }) @@ -1251,7 +1274,7 @@ class TemplateService $var_set = $this->getVarSet(); $client_details = - collect($this->company->settings->pdf_variables->client_details) + collect($this->getSettings()->pdf_variables->client_details) ->filter(function ($variable) use ($var_set) { return isset($var_set['values'][$variable]) && !empty($var_set['values'][$variable]); }) @@ -1314,7 +1337,7 @@ class TemplateService $var_set = $this->getVarSet(); $entity_details = - collect($this->company->settings->pdf_variables->{$entity_string_prop}) + collect($this->getSettings()->pdf_variables->{$entity_string_prop}) ->filter(function ($variable) use ($var_set) { return isset($var_set['values'][$variable]) && !empty($var_set['values'][$variable]); })->toArray(); @@ -1372,7 +1395,7 @@ class TemplateService $var_set = $this->getVarSet(); $vendor_details = - collect($this->company->settings->pdf_variables->vendor_details) + collect($this->getSettings()->pdf_variables->vendor_details) ->filter(function ($variable) use ($var_set) { return isset($var_set['values'][$variable]) && !empty($var_set['values'][$variable]); })->when(!$include_labels, function ($collection) { diff --git a/app/Utils/HtmlEngine.php b/app/Utils/HtmlEngine.php index e21fee5644..9775a4ad40 100644 --- a/app/Utils/HtmlEngine.php +++ b/app/Utils/HtmlEngine.php @@ -90,6 +90,12 @@ class HtmlEngine $this->helpers = new Helpers(); } + public function setSettings($settings): self + { + $this->settings = $settings; + + return $this; + } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -138,7 +144,8 @@ class HtmlEngine $data['$app_url'] = ['value' => $this->generateAppUrl(), 'label' => '']; $data['$from'] = ['value' => '', 'label' => ctrans('texts.from')]; $data['$to'] = ['value' => '', 'label' => ctrans('texts.to')]; - $data['$ship_to'] = ['value' => '', 'label' => ctrans('texts.ship_to')]; + $data['$shipping'] = ['value' => '', 'label' => ctrans('texts.ship_to')]; + $data['$total_tax_labels'] = ['value' => $this->totalTaxLabels(), 'label' => ctrans('texts.taxes')]; $data['$total_tax_values'] = ['value' => $this->totalTaxValues(), 'label' => ctrans('texts.taxes')]; $data['$line_tax_labels'] = ['value' => $this->lineTaxLabels(), 'label' => ctrans('texts.taxes')]; @@ -147,6 +154,7 @@ class HtmlEngine $data['$status_logo'] = ['value' => ' ', 'label' => ' ']; $data['$delivery_note'] = ['value' => ' ', 'label' => ctrans('texts.delivery_note')]; $data['$receipt'] = ['value' => ' ', 'label' => ctrans('texts.receipt')]; + $data['$shipping'] = ['value' => ' ', 'label' => ctrans('texts.ship_to')]; $data['$invoice.date'] = &$data['$date']; $data['$invoiceDate'] = &$data['$date']; diff --git a/app/Utils/PaymentHtmlEngine.php b/app/Utils/PaymentHtmlEngine.php index b8cf29e405..7c376d20cd 100644 --- a/app/Utils/PaymentHtmlEngine.php +++ b/app/Utils/PaymentHtmlEngine.php @@ -45,6 +45,13 @@ class PaymentHtmlEngine $this->helpers = new Helpers(); } + public function setSettings($settings):self + { + $this->settings = $settings; + + return $this; + } + public function makePaymentVariables() { App::forgetInstance('translator'); diff --git a/app/Utils/VendorHtmlEngine.php b/app/Utils/VendorHtmlEngine.php index 8a7fddfbbe..2e0765c84d 100644 --- a/app/Utils/VendorHtmlEngine.php +++ b/app/Utils/VendorHtmlEngine.php @@ -83,6 +83,13 @@ class VendorHtmlEngine $this->helpers = new Helpers(); } + public function setSettings($settings):self + { + $this->settings = $settings; + + return $this; + } + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/config/ninja.php b/config/ninja.php index 1b74cfb250..da32551240 100644 --- a/config/ninja.php +++ b/config/ninja.php @@ -17,8 +17,8 @@ return [ 'require_https' => env('REQUIRE_HTTPS', true), 'app_url' => rtrim(env('APP_URL', ''), '/'), 'app_domain' => env('APP_DOMAIN', 'invoicing.co'), - 'app_version' => env('APP_VERSION', '5.7.54'), - 'app_tag' => env('APP_TAG', '5.7.54'), + 'app_version' => env('APP_VERSION', '5.7.55'), + 'app_tag' => env('APP_TAG', '5.7.55'), 'minimum_client_version' => '5.0.16', 'terms_version' => '1.0.1', 'api_secret' => env('API_SECRET', false), diff --git a/resources/views/pdf-designs/basic_statement.html b/resources/views/pdf-designs/basic_statement.html new file mode 100644 index 0000000000..b82183de61 --- /dev/null +++ b/resources/views/pdf-designs/basic_statement.html @@ -0,0 +1,254 @@ + + + + + + + + + + +
+
+
+
+ + +
+
+
+ +
+ +

{{ t('statement') }}

+

$start_date - $end_date

+
+
+ +
+ + {% if invoices|e %} +
+

{{ t('invoices') }}

+ + + + + + + + + + + + {% for invoice in invoices %} + + + + + + + + {% endfor %} + +
{{ t('invoice')}} #{{ t('invoice_date') }}{{ t('invoice_due_date') }}{{ t('total') }}{{ t('balance') }}
{{ invoice.number }}{{ invoice.date }}{{ invoice.due_date }}{{ invoice.amount }}{{ invoice.balance }}
+

+ {% endif %} +
+ + + {% if payments|e %} +
+

{{ t('payments') }}

+ + + + + + + + + + + {% for payment in payments %} + + + + {%if payment.is_credit %} + + {%else%} + + {%endif%} + + + {% endfor %} + +
{{ t('invoice') }} #{{ t('payment_date') }}{{ t('method') }}{{ t('amount') }}
{{ payment.number }}{{ payment.date }}Credit {{ payment.number }}{{ payment.method }}{{ payment.amount }}
+

+ {% endif %} +
+ + + {% if credits|e %} +
+

Credits

+ + + + + + + + + + + {% for credit in credits %} + + + + + + + {% endfor %} + +
{{ t('credit') }} #{{ t('credit_date') }}{{ t('total') }}{{ t('balance') }}
{{ credit.number }}{{ credit.date }}{{ credit.amount }}{{ credit.balance }}
+

+ {% endif %} +
+ + + {% if aging %} +
+

{{ t('aging') }}

+ + + + {% for key, age in aging %} + + {% endfor %} + + + + + {% for key, age in aging %} + + {% endfor %} + + +
{{ key }}
{{ age }}
+

+ {% endif %} +
+ + + + \ No newline at end of file diff --git a/resources/views/pdf-designs/crisp_refund.html b/resources/views/pdf-designs/crisp_refund.html new file mode 100644 index 0000000000..d6c38e6caf --- /dev/null +++ b/resources/views/pdf-designs/crisp_refund.html @@ -0,0 +1,550 @@ + + + + Refund #$number + + + + + + {%set payment = payments|first %} + {%set pivot = payment.paymentables|filter(pivot => pivot.refunded_raw > 0)|first %} + + + + + + +
+ + + + + + +
+ $refund_label{{ pivot.refunded + }} + $date_label {{ pivot.updated_at }} +
+
+ + + + + + +
+ {{ img('$company.logo','max-width: $company_logo_size; max-height: 100px; + vertical-align: middle;') }} +
+
+ + + + +
+ + + + + + + + + +
+ $refund_label #$number +
+
 
+
+ + + {%set payment = payments|first %} + {%if payment.transaction_reference %} + + + + + + + + +
+   + $reference_label: {{ payment.transaction_reference + }} + +  
+ {% endif %} +
+ + + + + + + + + + +
+ +
+
 
+
+ + + + + + +
+
 
+
+ + + + + + + + + + + + + +
+ +   + + + + + + + + + +
+ $refunded_label +
+ {{ payment.refunded }} +
+
+   + + + + + + + + + +
+ $refund_label $date_label +
+ {{ payment.updated_at}} +
+
+   + + + + + + + + + +
+ $method_label +
+ {% if payment.method %} + + {{ payment.method }} + + {% else %} + + - + + {% endif %} +
+
+  
+ + + + + + + + + + + + + + +
+
 
+
+
 
+
+
 
+
+
 
+
+
 
+
+ + + + + + + + + + + + + + +
+
 
+
+
 
+
+ + + + + + +
+ + + + + + + + + + + + + + +
+
 
+
+
 
+
+ + + + + + {% set totalInvoices = 0 %} + {% set totalRefunds = 0 %} + {% for pivot in + payment.paymentables|filter((pivot) => + (pivot.is_credit == '0' + and pivot.refunded_raw > 0)) %} + + + + + + {% set totalInvoices = totalInvoices + + pivot.amount_raw %} + {% set totalRefunds = totalRefunds + + pivot.refunded_raw %} + {% endfor %} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Invoice: #{{ pivot.invoice }} + ({{ pivot.amount }}) + +   + $refunded_label {{ + pivot.refunded }} +
+  
+  
+  
+  
+ $total_label $invoices_label + +   + {{ + totalInvoices|format_currency(currency_code) + }} +
+  
+ $total_label $refunded_label + +   + {{ payment.refunded }} +
+  
+  
+
+
 
+
+
 
+
+
+
+
 
+
+
 
+
+ + {% if payment.refund_activity %} + + + + + + + + + + + + + + +
+
 
+
+
 
+
+ + History + + +
 
+
+
 
+
+ + + + + + + + + + + + + + +
+
 
+
+
 
+
+ + + + + + +
+ + + + + + + + + + + + + + +
+
 
+
+
 
+
+ + + + + + {% for activity in + payment.refund_activity %} + + + + + + {% endfor %} + + +
+ {{ activity }} + +   + +
+
+
 
+
+
 
+
+
+
+
 
+
+
 
+
+ {% endif %} + + +
+
+ + + \ No newline at end of file diff --git a/resources/views/pdf-designs/exact_refund.html b/resources/views/pdf-designs/exact_refund.html new file mode 100644 index 0000000000..cc07992948 --- /dev/null +++ b/resources/views/pdf-designs/exact_refund.html @@ -0,0 +1,186 @@ + + + + + + + + + + + + +
+
+

$refund_label {% if + payments|length == 1%}#$number {% endif %}

+
+
{{ img('$company.logo','max-width: $company_logo_size; max-height: 100px; + vertical-align: middle;') }}
+
+
+
+
+

$to_label

+

$client.name

+ + {% set payment = payments|first %} + {% if payment.client.vat_number %} +

$vat_number_label: $vat_number

+ {% endif %} +
+
+
+ +
+
+ +
+ + + {% if payments|e %} + {% set totalInvoices = 0 %} + {% set totalRefunds = 0 %} + {% for payment in payments %} + {% for pivot in payment.paymentables|filter((pivot) => (pivot.is_credit == '0' and pivot.refunded_raw > 0)) + %} + +
+
+

$invoice_label #{{ pivot.invoice }}

+

({{ pivot.amount }})

+
+
+

{{ pivot.refunded }}

+

($refund_label)

+
+
+
+
+
+
+ + {% set totalInvoices = totalInvoices + pivot.amount_raw %} + {% set totalRefunds = totalRefunds + pivot.refunded_raw %} + {% endfor %} + {% endfor %} + +
+
+

$invoices_label:

+
+
+

{{ totalInvoices|format_currency(currency_code) }}

+
+
+

$refund_label:

+
+
+

{{ totalRefunds|format_currency(currency_code) }}

+
+
+ + {% endif %} +
+ +
+ +
+
+ +
+
+

$public_notes

+
+
+ + + + \ No newline at end of file diff --git a/resources/views/pdf-designs/fluid_delivery_note.html b/resources/views/pdf-designs/fluid_delivery_note.html new file mode 100644 index 0000000000..0d52f57f46 --- /dev/null +++ b/resources/views/pdf-designs/fluid_delivery_note.html @@ -0,0 +1,273 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + +
$delivery_note_label
+ + + + + + + +
+
+
+

$to_label:

+
+
+
+
+
+
+

$ship_to_label:

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

$order_number_label # $invoice.po_number

+
+
+
+

$date_label: $invoice.date

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

$notes_label:

+ $invoice.public_notes +
+
+ +
+
+ +
+
+ + + + + + \ No newline at end of file diff --git a/resources/views/pdf-designs/harmony_delivery_note.html b/resources/views/pdf-designs/harmony_delivery_note.html new file mode 100644 index 0000000000..07d21c5802 --- /dev/null +++ b/resources/views/pdf-designs/harmony_delivery_note.html @@ -0,0 +1,246 @@ + + + + + + + + + + + + + + + + +
$delivery_note_label
+ + + + + +
+
+ +
+
+

$to_label:

+
+
+
+ +
+
+

$ship_to_label:

+
+
+
+ + +
+
+

$details_label:

+
+
+
$order_number_label #
+ + {%set invoice = invoices|first|e %} +
{% if invoice.po_number %} {{ + invoice.po_number }} {% else %} {{ invoice.number}} {% endif %}
+
+
$date_label
+
$invoice.date
+
$client_label #
+
$client.number
+ +
+
+ +
+ + + {% set invoice = invoices|first %} + + + + + + + + + + + {% for item in invoice.line_items|filter(item => item.type_id == 1) %} + + + + + + + {% endfor %} + +
$item_label #$description_label$quantity_label
{{ item.product_key }}{{ item.notes }}{{ item.quantity }}
+
+ + +
+

$notes_label:

+ + $invoice.public_notes +
+
+ + + + \ No newline at end of file diff --git a/resources/views/pdf-designs/prime_statement.html b/resources/views/pdf-designs/prime_statement.html new file mode 100644 index 0000000000..be53a34df7 --- /dev/null +++ b/resources/views/pdf-designs/prime_statement.html @@ -0,0 +1,320 @@ + + + + + + + +
+ +
+ +
+
+
+
+
+
+
+ +
+
+
+

$statement_label

+

$start_date - $end_date

+
+
+ + + {% if invoices|e %} +
+

{{ t('invoices') }}

+ + + + + + + + + + + + {% for invoice in invoices %} + + + + + + + + {% endfor %} + + {% set sum_balance = invoices|sum('balance_raw') %} + {% if sum_balance > 0 %} + + + + + + + + {% endif %} + +
{{ t('invoice') }} #{{ t('invoice_date') }}{{ t('invoice_due_date') }}{{ t('total') }}{{ t('balance') }}
{{ invoice.number }}{{ invoice.date }}{{ invoice.due_date }}{{ invoice.amount }}{{ invoice.balance }}
$balance_label{{ sum_balance|format_currency(currency_code) }}
+

+ {% endif %} +
+ + + {% if invoices|e and show_payments %} +
+

{{ t('payments') }}

+ + + + + + + + + + + + {% set net_refunds = 0 %} + {% set total_payments = 0%} + {% for invoice in invoices %} + {% if invoice.payments|e %} + {% set parent_payment = invoice.payments|first %} + + {% for payment in invoice.payments %} + {% set currency_code = payment.currency %} + + {% for pivot in payment.paymentables %} + + + + + {%if pivot.is_credit %} + + {%else%} + + {%endif%} + + + {% if pivot.refunded_raw > 0 %} + + + + + + + + {% set net_refunds = net_refunds + pivot.refunded_raw %} + {% endif %} + {% set total_payments = total_payments + pivot.amount_raw %} + {% endfor %} + {% endfor %} + {% endif %} + {% endfor %} + + + + + + + + + {% if net_refunds > 0 %} + + + + + + + + + + + + + + + {% endif %} + +
{{ t('invoice') }} #{{ t('payment_date') }}{{ t('method') }}{{ t('amount') }}
{{ pivot.invoice }}{{ pivot.created_at }}$credit_label {{ pivot.number }}{{ payment.method }}{{ pivot.amount }}
{{ pivot.invoice }}{{ pivot.updated_at }}$refund_label({{ pivot.refunded }})
{{ currency_code }}$payments_label{{ total_payments|format_currency(currency_code) }}
$refunded_label({{ net_refunds|format_currency(currency_code) }})
$net_label{{ (total_payments-net_refunds)|format_currency(currency_code) }}
+

+ {% endif %} +
+ + + {% if credits|e and show_credits %} +
+

{{ t('credits') }}

+ + + + + + + + + + + {% for credit in credits %} + + + + + + + {% endfor %} + +
{{ t('credit') }} #{{ t('credit_date') }}{{ t('total') }}{{ t('balance') }}
{{ credit.number }}{{ credit.date }}{{ credit.amount }}{{ credit.balance }}
+

+ {% endif %} +
+ + + {% if aging and show_aging %} +
+

{{ t('aging') }}

+ + + + {% for key, age in aging %} + + {% endfor %} + + + + + {% for key, age in aging %} + + {% endfor %} + + +
{{ key }}
{{ age }}
+

+ {% endif %} +
+ + + \ No newline at end of file diff --git a/resources/views/pdf-designs/swift_receipt.html b/resources/views/pdf-designs/swift_receipt.html new file mode 100644 index 0000000000..7061510d5e --- /dev/null +++ b/resources/views/pdf-designs/swift_receipt.html @@ -0,0 +1,451 @@ + + + + + + + + + + + + + + + + +
+ + + + + + +
+  
+
+ + + + + + +
+ +
+ + + + + + + + + +
+   + $receipt_label $from_label $company.name + +  
+ + + + + + + +
+  
+ + + + + + + +
+  
+ + + + + + + + + + + {%set payment = payments|first %} + {%if payment.transaction_reference %} + + + + + + {% endif %} + + + +
+   + $receipt_label #$number + +  
+   + Reference: {{ payment.transaction_reference }} + +  
+ + + + + + + +
+  
+ + + + + + + + + +
+   + + + + + + + + + + + +
+ + + + + + + + + +
+ $amount_paid_label +
+ $amount +
+
+   + + + + + + + + + +
+ $date_label +
+ $payment.date +
+
+   + + + + + + + + + +
+ $method_label +
+ + + {% set payment = payments|first %} + {% if payment %} + {{ payment.method }} + {% endif %} + + + +
+
+
+  
+ + + + + + + +
+  
+ + + + + + + + + + + + +
+   + Summary + +  
+  
+ + + + + + + + + +
+   + + + + + + + + + + + + + + +
+  
+   + + + + + + + + + + {% set totalPrice = 0 %} + {% for payment in payments %} + {% for pivot in payment.paymentables|filter(pivot => + pivot.is_credit == '0') %} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {% set totalPrice = totalPrice + pivot.amount_raw %} + + {% endfor %} + {% endfor %} + + + + + + + + + + + + + +
+  
+  
+ {{ pivot.date }} + +   +  
+  
+  
+
+ $invoice_label #{{ pivot.invoice }} + + + +
+
+   + {{ pivot.amount }} +
+  
+  
+  
+  
+  
+ $amount_paid_label + +   + ${{ totalPrice|number_format(2, '.', ',') }} + + +
+  
+
+  
+  
+
+  
+ + + + + + + +
+  
+
+
+ + + \ No newline at end of file diff --git a/resources/views/pdf-designs/tidy_receipt.html b/resources/views/pdf-designs/tidy_receipt.html new file mode 100644 index 0000000000..f54ea77d34 --- /dev/null +++ b/resources/views/pdf-designs/tidy_receipt.html @@ -0,0 +1,166 @@ + + + + + + + + + + +
+ +
+

$receipt_label {%if payments|length == 1%}#$number{% endif %}

+
+
+
+
+ +
+
+

$to_label

+

$client.name

+ + {% set payment = payments|first %} + {% if payment.client.vat_number %} +

$vat_number_label: $vat_number

+ {% endif %} +
+
+
+ +
+
+ +
+
+
$number_label
+
$date_label
+
$method_label
+
$amount_label
+
+ + + {% if payments|e %} + {% for payment in payments %} +
+
+

#{{ payment.number }}

+
+
+

{{ payment.date }}

+
+
+

{{ payment.method }}

+
+
+

{{ payment.amount }}

+
+
+ {% endfor %} + {% endif %} +
+ +
+ +
+
+ +
+
+

$public_notes

+
+
+ + + + \ No newline at end of file diff --git a/resources/views/pdf-designs/vertical_statement.html b/resources/views/pdf-designs/vertical_statement.html new file mode 100644 index 0000000000..44a82eaf0b --- /dev/null +++ b/resources/views/pdf-designs/vertical_statement.html @@ -0,0 +1,281 @@ + + + + + + + + +
+
+

$statement_label

+
+
+
+
+

$company.name

+
+
+ +
+
+
+
+
+
+
+

$start_date - $end_date

+
+
+ +
+ + {% if invoices|e %} + + + + + + + + + + + + {% set running_total = 0%} + {% for invoice in invoices %} + + + + + + + + {% for payment in invoice.payments %} + {% for pivot in payment.paymentables %} + + + + + + + + {% if pivot.refunded_raw > 0%} + + + + + + + + {% endif %} + {% endfor %} + {% endfor %} + {% endfor %} + + +
$date_label$invoice_label #{{ t('charges') }}{{ t('credits') }}{{ t('line_total') }}
{{ invoice.date }}{{ invoice.number }}{{ invoice.amount }}{%set running_total = running_total + invoice.amount_raw %}{{ running_total|format_currency(currency_code) }}
{{ invoice.date }}{{ invoice.number }}{%set running_total = running_total - pivot.amount_raw %}{{ pivot.amount }}{{ running_total|format_currency(currency_code) }}
{{ invoice.date }}{{ invoice.number }} $refund_label{%set running_total = running_total + pivot.refunded_raw %}({{ pivot.refunded }}){{ running_total|format_currency(currency_code) }}
+ {% endif %} +
+ + + {% if aging and show_aging %} +
+ + + + {% for key, age in aging %} + + {% endfor %} + + + + + {% for key, age in aging %} + + {% endfor %} + + +
{{ key }}
{{ age }}
+
+ {% endif %} +
+ +
+
+
+ + + \ No newline at end of file