mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
Additional Templates
This commit is contained in:
parent
7a8fb8f486
commit
2957227422
@ -64,7 +64,9 @@ class Statement
|
||||
$variables = [];
|
||||
$variables = $html->generateLabelsAndValues();
|
||||
|
||||
if($this->client->getSetting('statement_design_id') != '') {
|
||||
$option_template = &$this->options['template'];
|
||||
|
||||
if($this->client->getSetting('statement_design_id') != '' || $option_template && $option_template != '') {
|
||||
|
||||
$variables['values']['$start_date'] = $this->translateDate($this->options['start_date'], $this->client->date_format(), $this->client->locale());
|
||||
$variables['values']['$end_date'] = $this->translateDate($this->options['end_date'], $this->client->date_format(), $this->client->locale());
|
||||
|
@ -11,33 +11,34 @@
|
||||
|
||||
namespace App\Services\Template;
|
||||
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\Task;
|
||||
use App\Models\User;
|
||||
use App\Models\Quote;
|
||||
use App\Models\Client;
|
||||
use App\Models\Company;
|
||||
use App\Models\Credit;
|
||||
use App\Models\Design;
|
||||
use App\Models\Vendor;
|
||||
use App\Models\Company;
|
||||
use App\Models\Expense;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\Payment;
|
||||
use App\Models\Product;
|
||||
use App\Models\Project;
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\PurchaseOrder;
|
||||
use App\Models\Quote;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use App\Models\RecurringInvoice;
|
||||
use App\Models\Task;
|
||||
use App\Models\User;
|
||||
use App\Models\Vendor;
|
||||
use App\Services\Email\AdminEmail;
|
||||
use App\Services\Email\EmailObject;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use App\Services\PdfMaker\PdfMerge;
|
||||
use Illuminate\Mail\Mailables\Address;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\Middleware\WithoutOverlapping;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\Middleware\WithoutOverlapping;
|
||||
|
||||
class TemplateAction implements ShouldQueue
|
||||
{
|
||||
@ -111,6 +112,39 @@ class TemplateAction implements ShouldQueue
|
||||
/** Set a global currency_code */
|
||||
$first_entity = $result->first();
|
||||
|
||||
/** Lets be clever and sniff out Statements */
|
||||
if($first_entity instanceof Client && stripos(json_encode($template->design), '##statement##') !== false) {
|
||||
|
||||
$options = [
|
||||
'show_payments_table' => true,
|
||||
'show_aging_table' => true,
|
||||
'status' => 'all',
|
||||
'show_credits_table' => false,
|
||||
'template' => $this->template,
|
||||
];
|
||||
|
||||
$pdfs = [];
|
||||
|
||||
foreach($result as $client) {
|
||||
$pdfs[] = $client->service()->statement($options);
|
||||
}
|
||||
|
||||
if(count($pdfs) == 1) {
|
||||
$pdf = $pdfs[0];
|
||||
} else {
|
||||
$pdf = (new PdfMerge($pdfs))->run();
|
||||
}
|
||||
|
||||
if($this->send_email) {
|
||||
$this->sendEmail($pdf, $template);
|
||||
} else {
|
||||
$filename = "templates/{$this->hash}.pdf";
|
||||
Storage::disk(config('filesystems.default'))->put($filename, $pdf);
|
||||
return $pdf;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if($first_entity instanceof Client)
|
||||
$currency_code = $first_entity->currency()->code;
|
||||
elseif($first_entity->client)
|
||||
|
205
resources/views/templates/delivery_notes/td13.html
Normal file
205
resources/views/templates/delivery_notes/td13.html
Normal file
@ -0,0 +1,205 @@
|
||||
<!doctype html>
|
||||
<!-- Delivery Note Design 4 - MONO - TemplateID #TD13 -->
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<style>
|
||||
html {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Ubuntu, sans-serif;
|
||||
}
|
||||
|
||||
table {
|
||||
margin-top: 2rem;
|
||||
min-width: 100%;
|
||||
table-layout: fixed;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
.table-header>tr>th {
|
||||
border-bottom: solid 1px #efefef;
|
||||
}
|
||||
|
||||
.table-body>tr>td {
|
||||
border-bottom: solid 1px #efefef;
|
||||
}
|
||||
|
||||
th {
|
||||
text-align: left;
|
||||
padding-left: 6px;
|
||||
padding-right: 6px;
|
||||
padding-top: 6px;
|
||||
padding-bottom: 6px;
|
||||
}
|
||||
|
||||
td {
|
||||
padding-left: 6px;
|
||||
padding-right: 6px;
|
||||
padding-top: 1rem;
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
|
||||
.item-row {
|
||||
border-bottom: 1px #000 dotted;
|
||||
}
|
||||
|
||||
.totals-row-label {
|
||||
text-align: right;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.totals-row-value {
|
||||
text-align: right;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.table-totals {
|
||||
display: grid;
|
||||
grid-template-columns: 2fr 1fr;
|
||||
}
|
||||
|
||||
.centered {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.doc-title {
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
span {
|
||||
padding-right: 5px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
div .label {
|
||||
text-align: right;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
div .value {
|
||||
text-align: left;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.two-col-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
}
|
||||
|
||||
.client-details {
|
||||
padding-top: 0.2rem;
|
||||
padding-bottom: 0.1rem;
|
||||
}
|
||||
|
||||
.container {
|
||||
padding-top: 2rem;
|
||||
}
|
||||
|
||||
.bottom-margin {
|
||||
padding-bottom: 2rem;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-style: italic;
|
||||
color: #454545
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<ninja>
|
||||
<table width="100%" cellspacing="0" cellpadding="0" class="" border="0">
|
||||
<tr>
|
||||
<td align="left" class="doc-title">Delivery Note</td>
|
||||
<td align="right">{{ img('$company.logo') }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</ninja>
|
||||
|
||||
<table width="100%" cellspacing="0" cellpadding="0" class="" border="0">
|
||||
<tr>
|
||||
<td align="left" class="">
|
||||
<div class="">
|
||||
<div class="client-details">
|
||||
<p class="section-title">Bill To:</p>
|
||||
</div>
|
||||
<div class="client-details">
|
||||
<p>$client.name</p>
|
||||
</div>
|
||||
<div class="client-details">
|
||||
<p>$client.shipping_address</p>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td align="left">
|
||||
<div class="">
|
||||
<div class="client-details">
|
||||
<p class="section-title">Ship To:</p>
|
||||
</div>
|
||||
<div class="client-details">
|
||||
<p>$client.name</p>
|
||||
</div>
|
||||
<div class="client-details">
|
||||
<p>$client.shipping_address</p>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table width="100%" cellspacing="0" cellpadding="0" class="">
|
||||
<tr>
|
||||
<td align="left" class="">
|
||||
<div class="">
|
||||
<p>Order # $invoice.po_number</p>
|
||||
</div>
|
||||
</td>
|
||||
<td align="left">
|
||||
<div class="">
|
||||
<p>Order Date: $invoice.date</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<ninja>
|
||||
{% set invoice = invoices|first %}
|
||||
<table width="100%" cellspacing="0" cellpadding="0" class="">
|
||||
<thead class="table-header">
|
||||
<tr class="table-header">
|
||||
<th class="">Item #</th>
|
||||
<th class="" width="50%">Description</th>
|
||||
<th class="totals-row-label centered">Delivered</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="table-body">
|
||||
{% for item in invoice.line_items|filter(item => item.type_id == 1) %}
|
||||
<tr class="item-row">
|
||||
<td class="">{{ item.product_key }}</td>
|
||||
<td class="">{{ item.notes }}</td>
|
||||
<td class="centered">{{ item.quantity }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</ninja>
|
||||
|
||||
<table width="100%" cellspacing="0" cellpadding="0" class="">
|
||||
<div class="container">
|
||||
<p class="bottom-margin">Notes:</p>
|
||||
|
||||
$invoice.public_notes
|
||||
</div>
|
||||
</table>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
@ -1,5 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<!-- Plain Statement - TemplateID #TS1 -->
|
||||
<!-- Plain Statement - TemplateID #TS1 ##statement##-->
|
||||
<html>
|
||||
|
||||
<head>
|
||||
@ -13,7 +13,7 @@
|
||||
}
|
||||
|
||||
@page {
|
||||
margin: 0 !important; //removes top and bottom default headers
|
||||
margin: 0 !important;
|
||||
size: $page_size $page_layout;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<!-- Color Statement - TemplateID #TS2 -->
|
||||
<!-- Color Statement - TemplateID #TS2 ##statement##-->
|
||||
<html>
|
||||
|
||||
<head>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<!-- Vertial Statement - TemplateID #TS3 -->
|
||||
<!-- Vertial Statement - TemplateID #TS3 ##statement##-->
|
||||
<html>
|
||||
|
||||
<head>
|
||||
|
216
resources/views/templates/statements/ts4.html
Normal file
216
resources/views/templates/statements/ts4.html
Normal file
@ -0,0 +1,216 @@
|
||||
<!doctype html>
|
||||
<!-- Statement - TemplateID #TS4 ##statement##-->
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<style>
|
||||
@import url($font_url);
|
||||
|
||||
@page {
|
||||
margin: 50 0 50 0 !important;
|
||||
}
|
||||
|
||||
body {
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
font-family: $font_name, Helvetica, sans-serif;
|
||||
font-size: $font_size !important;
|
||||
zoom: 80%;
|
||||
}
|
||||
|
||||
#logo-container {
|
||||
width: 100%;
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
img {
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.two-col-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
border: 0px solid #000;
|
||||
}
|
||||
|
||||
.body-margin {
|
||||
margin-left: 2rem;
|
||||
margin-right: 2rem;
|
||||
}
|
||||
|
||||
.aging-table {
|
||||
border: 0px dashed $primary_color;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#client-wrapper {
|
||||
width: 100%;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
border: 0px solid #000;
|
||||
}
|
||||
|
||||
#client-details {}
|
||||
|
||||
#company-details {}
|
||||
|
||||
#company-address {}
|
||||
|
||||
#company-wrapper {
|
||||
margin-left: auto;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
#statement-details {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
#statement-details>h2 {
|
||||
font-style: italic;
|
||||
font-size: 1.3rem;
|
||||
}
|
||||
|
||||
#date-range {
|
||||
font-size: 1rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="repeating-header" id="header"></div>
|
||||
<table style="min-width: 100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<td>
|
||||
<!-- repeating header -->
|
||||
</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<!-- body -->
|
||||
<div id="logo-container">
|
||||
<img src="$company.logo">
|
||||
</div>
|
||||
|
||||
<div class="two-col-grid body-margin">
|
||||
<div id="client-details"></div>
|
||||
<div id="company-wrapper">
|
||||
<div id="company-details"></div>
|
||||
<div id="company-address"></div>
|
||||
|
||||
<div id="statement-details">
|
||||
<h2>$statement_label</h2>
|
||||
<p id="date-range">$start_date - $end_date</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ninja>
|
||||
<table class="min-w-full text-left text-sm font-light">
|
||||
<thead class="border-b font-medium dark:border-neutral-500">
|
||||
<tr class="text-sm leading-normal">
|
||||
<th scope="col" class="px-6 py-4">Doc #</th>
|
||||
<th scope="col" class="px-6 py-4">Date</th>
|
||||
<th scope="col" class="px-6 py-4">Due Date</th>
|
||||
<th scope="col" class="px-6 py-4">Total</th>
|
||||
<th scope="col" class="px-6 py-4">Transaction</th>
|
||||
<th scope="col" class="px-6 py-4">Outstanding</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{% for invoice in invoices %}
|
||||
<tr class="border-b dark:border-neutral-500">
|
||||
<td class="whitespace-nowrap px-6 py-4 font-medium">Invoice - {{ invoice.number }}
|
||||
</td>
|
||||
<td class="whitespace-nowrap px-6 py-4 font-medium">{{ invoice.date }}</td>
|
||||
<td class="whitespace-nowrap px-6 py-4 font-medium">{{ invoice.due_date }}</td>
|
||||
<td class="whitespace-nowrap px-6 py-4 font-medium">{{
|
||||
invoice.amount_raw|format_currency(invoice.client.currency) }}</td>
|
||||
<td class="whitespace-nowrap px-6 py-4 font-medium"></td>
|
||||
<td class="whitespace-nowrap px-6 py-4 font-medium">{{
|
||||
invoice.balance_raw|format_currency(invoice.client.currency) }}</td>
|
||||
</tr>
|
||||
|
||||
{% for payment in invoice.payments|filter(payment => payment.is_deleted == false) %}
|
||||
|
||||
{% for pivot in payment.paymentables %}
|
||||
|
||||
<tr class="border-b dark:border-neutral-500">
|
||||
<td class="whitespace-nowrap px-6 py-4 font-medium">Payment - {{ payment.number }}
|
||||
</td>
|
||||
<td class="whitespace-nowrap px-6 py-4 font-medium">{{ payment.date }}</td>
|
||||
<td class="whitespace-nowrap px-6 py-4 font-medium"></td>
|
||||
<td class="whitespace-nowrap px-6 py-4 font-medium">
|
||||
{% if pivot.amount > 0 %}
|
||||
{{ pivot.amount_raw|format_currency(payment.currency) }} - {{ payment.type.name
|
||||
}}
|
||||
{% else %}
|
||||
({{ pivot.refunded_raw|format_currency(payment.currency) }})
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="whitespace-nowrap px-6 py-4 font-medium">{{ payment.transaction_reference
|
||||
}}</td>
|
||||
<td class="whitespace-nowrap px-6 py-4 font-medium"></td>
|
||||
</tr>
|
||||
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% endfor%}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</ninja>
|
||||
|
||||
<ninja>
|
||||
{% if aging and show_aging %}
|
||||
<div id="entity-container" style="break-inside: avoid;">
|
||||
<table width="100%" cellspacing="0" cellpadding="0" class="">
|
||||
<thead class="">
|
||||
<tr class="item-row border-bottom">
|
||||
{% for key, age in aging %}
|
||||
<th class="">{{ key }}</th>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="item-row">
|
||||
{% for key, age in aging %}
|
||||
<td class="aging-table">{{ age }}</td>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% endif %}
|
||||
</ninja>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td>
|
||||
<!-- repeating header -->
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
<div id="footer">
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
Loading…
x
Reference in New Issue
Block a user