mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-06-03 06:44:37 -04:00
Updates for twig templates
This commit is contained in:
parent
2a40658222
commit
487ca15749
@ -43,7 +43,7 @@ class ClientStatementController extends BaseController
|
|||||||
}
|
}
|
||||||
|
|
||||||
$pdf = $request->client()->service()->statement(
|
$pdf = $request->client()->service()->statement(
|
||||||
$request->only(['start_date', 'end_date', 'show_payments_table', 'show_aging_table', 'status', 'show_credits_table']),
|
$request->only(['start_date', 'end_date', 'show_payments_table', 'show_aging_table', 'status', 'show_credits_table', 'template']),
|
||||||
$send_email
|
$send_email
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -26,13 +26,20 @@ class BulkCompanyGatewayRequest extends Request
|
|||||||
*/
|
*/
|
||||||
public function authorize() : bool
|
public function authorize() : bool
|
||||||
{
|
{
|
||||||
return auth()->user()->isAdmin();
|
/** @var \App\Models\User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
|
return $user->isAdmin();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function rules()
|
public function rules()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/** @var \App\Models\User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'ids' => ['required','bail','array',Rule::exists('company_gateways', 'id')->where('company_id', auth()->user()->company()->id)],
|
'ids' => ['required','bail','array',Rule::exists('company_gateways', 'id')->where('company_id', $user->company()->id)],
|
||||||
'action' => 'required|bail|in:archive,restore,delete'
|
'action' => 'required|bail|in:archive,restore,delete'
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ class StoreDesignRequest extends Request
|
|||||||
'design.footer' => 'required|min:1',
|
'design.footer' => 'required|min:1',
|
||||||
'design.includes' => 'required|min:1',
|
'design.includes' => 'required|min:1',
|
||||||
'is_template' => 'sometimes|boolean',
|
'is_template' => 'sometimes|boolean',
|
||||||
'entities' => 'sometimes|string'
|
'entities' => 'sometimes|string|nullable'
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ class UpdateDesignRequest extends Request
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'is_template' => 'sometimes|boolean',
|
'is_template' => 'sometimes|boolean',
|
||||||
'entities' => 'sometimes|string'
|
'entities' => 'sometimes|string|nullable'
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,8 +65,6 @@ class UpdateInvoiceRequest extends Request
|
|||||||
|
|
||||||
$rules['is_amount_discount'] = ['boolean'];
|
$rules['is_amount_discount'] = ['boolean'];
|
||||||
|
|
||||||
nlog($this->partial);
|
|
||||||
|
|
||||||
$rules['line_items'] = 'array';
|
$rules['line_items'] = 'array';
|
||||||
$rules['discount'] = 'sometimes|numeric';
|
$rules['discount'] = 'sometimes|numeric';
|
||||||
$rules['project_id'] = ['bail', 'sometimes', new ValidProjectForClient($this->all())];
|
$rules['project_id'] = ['bail', 'sometimes', new ValidProjectForClient($this->all())];
|
||||||
|
@ -17,9 +17,10 @@ class CreateStatementRequest extends Request
|
|||||||
*/
|
*/
|
||||||
public function authorize(): bool
|
public function authorize(): bool
|
||||||
{
|
{
|
||||||
// return auth()->user()->isAdmin();
|
/** @var \App\Models\User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
return auth()->user()->can('view', $this->client());
|
return $user->can('view', $this->client());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -29,14 +30,18 @@ class CreateStatementRequest extends Request
|
|||||||
*/
|
*/
|
||||||
public function rules()
|
public function rules()
|
||||||
{
|
{
|
||||||
|
/** @var \App\Models\User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'start_date' => 'required|date_format:Y-m-d',
|
'start_date' => 'required|date_format:Y-m-d',
|
||||||
'end_date' => 'required|date_format:Y-m-d',
|
'end_date' => 'required|date_format:Y-m-d',
|
||||||
'client_id' => 'bail|required|exists:clients,id,company_id,'.auth()->user()->company()->id,
|
'client_id' => 'bail|required|exists:clients,id,company_id,'.$user->company()->id,
|
||||||
'show_payments_table' => 'boolean',
|
'show_payments_table' => 'boolean',
|
||||||
'show_aging_table' => 'boolean',
|
'show_aging_table' => 'boolean',
|
||||||
'show_credits_table' => 'boolean',
|
'show_credits_table' => 'boolean',
|
||||||
'status' => 'string',
|
'status' => 'string',
|
||||||
|
'template' => 'sometimes|string|nullable',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ class PayFastPaymentDriver extends BaseDriver
|
|||||||
if ($this->client->currency()->code == 'ZAR') {
|
if ($this->client->currency()->code == 'ZAR') {
|
||||||
$types[] = GatewayType::CREDIT_CARD;
|
$types[] = GatewayType::CREDIT_CARD;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $types;
|
return $types;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,6 +78,19 @@ class PaymentMethod
|
|||||||
->sortby(function ($model) use ($transformed_ids) { //company gateways are sorted in order of priority
|
->sortby(function ($model) use ($transformed_ids) { //company gateways are sorted in order of priority
|
||||||
return array_search($model->id, $transformed_ids); // this closure sorts for us
|
return array_search($model->id, $transformed_ids); // this closure sorts for us
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if($this->gateways->count() == 0 && count($transformed_ids) >=1) {
|
||||||
|
|
||||||
|
/** This is a fallback in case a user archives some gateways that have been ordered preferentially. */
|
||||||
|
$this->gateways = CompanyGateway::query()
|
||||||
|
->with('gateway')
|
||||||
|
->where('company_id', $this->client->company_id)
|
||||||
|
->where('gateway_key', '!=', '54faab2ab6e3223dbe848b1686490baa')
|
||||||
|
->whereNull('deleted_at')
|
||||||
|
->where('is_deleted', false)->get();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
$this->gateways = CompanyGateway::query()
|
$this->gateways = CompanyGateway::query()
|
||||||
->with('gateway')
|
->with('gateway')
|
||||||
|
@ -29,11 +29,12 @@ use App\Utils\Traits\Pdf\PdfMaker as PdfMakerTrait;
|
|||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use App\Models\Credit;
|
use App\Models\Credit;
|
||||||
|
use App\Utils\Traits\MakesHash;
|
||||||
|
|
||||||
class Statement
|
class Statement
|
||||||
{
|
{
|
||||||
use PdfMakerTrait;
|
use PdfMakerTrait;
|
||||||
|
use MakesHash;
|
||||||
/**
|
/**
|
||||||
* @var Invoice|Payment|null
|
* @var Invoice|Payment|null
|
||||||
*/
|
*/
|
||||||
@ -88,21 +89,44 @@ class Statement
|
|||||||
'process_markdown' => $this->entity->client->company->markdown_enabled,
|
'process_markdown' => $this->entity->client->company->markdown_enabled,
|
||||||
];
|
];
|
||||||
|
|
||||||
$maker = new PdfMaker($state);
|
if($this->options['template'] ?? false){
|
||||||
|
|
||||||
$maker
|
$template = Design::where('id', $this->decodePrimaryKey($this->options['template']))
|
||||||
->design($template)
|
->where('company_id', $this->client->company_id)
|
||||||
->build();
|
->first();
|
||||||
|
|
||||||
$pdf = null;
|
$ts = $template->service()->build([
|
||||||
|
'client' => $this->client,
|
||||||
|
'entity' => $this->entity,
|
||||||
|
'variables' => $variables,
|
||||||
|
'invoices' => $this->getInvoices(),
|
||||||
|
'payments' => $this->getPayments(),
|
||||||
|
'credits' => $this->getCredits(),
|
||||||
|
'aging' => $this->getAging(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$html = $ts->getHtml();
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
$maker = new PdfMaker($state);
|
||||||
|
|
||||||
|
$maker
|
||||||
|
->design($template)
|
||||||
|
->build();
|
||||||
|
|
||||||
|
$pdf = null;
|
||||||
|
$html = $maker->getCompiledHTML(true);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (config('ninja.phantomjs_pdf_generation') || config('ninja.pdf_generator') == 'phantom') {
|
if (config('ninja.phantomjs_pdf_generation') || config('ninja.pdf_generator') == 'phantom') {
|
||||||
$pdf = (new Phantom)->convertHtmlToPdf($maker->getCompiledHTML(true));
|
$pdf = (new Phantom)->convertHtmlToPdf($html);
|
||||||
} elseif (config('ninja.invoiceninja_hosted_pdf_generation') || config('ninja.pdf_generator') == 'hosted_ninja') {
|
} elseif (config('ninja.invoiceninja_hosted_pdf_generation') || config('ninja.pdf_generator') == 'hosted_ninja') {
|
||||||
$pdf = (new NinjaPdf())->build($maker->getCompiledHTML(true));
|
$pdf = (new NinjaPdf())->build($html);
|
||||||
} else {
|
} else {
|
||||||
$pdf = $this->makePdf(null, null, $maker->getCompiledHTML(true));
|
$pdf = $this->makePdf(null, null, $html);
|
||||||
}
|
}
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
nlog(print_r($e->getMessage(), 1));
|
nlog(print_r($e->getMessage(), 1));
|
||||||
|
@ -20,10 +20,12 @@ use App\Models\Payment;
|
|||||||
use App\Models\Project;
|
use App\Models\Project;
|
||||||
use App\Utils\HtmlEngine;
|
use App\Utils\HtmlEngine;
|
||||||
use League\Fractal\Manager;
|
use League\Fractal\Manager;
|
||||||
|
use App\Models\ClientContact;
|
||||||
use App\Models\PurchaseOrder;
|
use App\Models\PurchaseOrder;
|
||||||
use App\Utils\VendorHtmlEngine;
|
use App\Utils\VendorHtmlEngine;
|
||||||
use App\Utils\PaymentHtmlEngine;
|
use App\Utils\PaymentHtmlEngine;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
|
use Twig\Extra\Intl\IntlExtension;
|
||||||
use App\Transformers\TaskTransformer;
|
use App\Transformers\TaskTransformer;
|
||||||
use App\Transformers\QuoteTransformer;
|
use App\Transformers\QuoteTransformer;
|
||||||
use App\Transformers\CreditTransformer;
|
use App\Transformers\CreditTransformer;
|
||||||
@ -91,7 +93,7 @@ class TemplateService
|
|||||||
{
|
{
|
||||||
$data = $this->preProcessDataBlocks($data);
|
$data = $this->preProcessDataBlocks($data);
|
||||||
$replacements = [];
|
$replacements = [];
|
||||||
|
nlog($data);
|
||||||
$contents = $this->document->getElementsByTagName('ninja');
|
$contents = $this->document->getElementsByTagName('ninja');
|
||||||
|
|
||||||
foreach ($contents as $content) {
|
foreach ($contents as $content) {
|
||||||
@ -103,10 +105,13 @@ class TemplateService
|
|||||||
|
|
||||||
$string_extension = new \Twig\Extension\StringLoaderExtension();
|
$string_extension = new \Twig\Extension\StringLoaderExtension();
|
||||||
$twig->addExtension($string_extension);
|
$twig->addExtension($string_extension);
|
||||||
|
$twig->addExtension(new IntlExtension());
|
||||||
|
|
||||||
$template = $twig->createTemplate(html_entity_decode($template));
|
$template = $twig->createTemplate(html_entity_decode($template));
|
||||||
$template = $template->render($data);
|
$template = $template->render($data);
|
||||||
|
|
||||||
|
nlog($template);
|
||||||
|
|
||||||
$f = $this->document->createDocumentFragment();
|
$f = $this->document->createDocumentFragment();
|
||||||
$f->appendXML($template);
|
$f->appendXML($template);
|
||||||
$replacements[] = $f;
|
$replacements[] = $f;
|
||||||
@ -228,67 +233,92 @@ class TemplateService
|
|||||||
private function processInvoices($invoices): array
|
private function processInvoices($invoices): array
|
||||||
{
|
{
|
||||||
$it = new InvoiceTransformer();
|
$it = new InvoiceTransformer();
|
||||||
$it->setDefaultIncludes(['client']);
|
$it->setDefaultIncludes(['client','payments']);
|
||||||
$manager = new Manager();
|
$manager = new Manager();
|
||||||
// $manager->setSerializer(new JsonApiSerializer());
|
$manager->parseIncludes(['client','payments','payments.type']);
|
||||||
$resource = new \League\Fractal\Resource\Collection($invoices, $it, Invoice::class);
|
$resource = new \League\Fractal\Resource\Collection($invoices, $it, null);
|
||||||
$i = $manager->createData($resource)->toArray();
|
$invoices = $manager->createData($resource)->toArray();
|
||||||
return $i['data'];
|
|
||||||
|
// nlog($invoices);
|
||||||
|
|
||||||
|
foreach($invoices['data'] as $key => $invoice)
|
||||||
|
{
|
||||||
|
|
||||||
|
$invoices['data'][$key]['client'] = $invoice['client']['data'] ?? [];
|
||||||
|
$invoices['data'][$key]['client']['contacts'] = $invoice['client']['data']['contacts']['data'] ?? [];
|
||||||
|
$invoices['data'][$key]['payments'] = $invoice['payments']['data'] ?? [];
|
||||||
|
|
||||||
|
if($invoice['payments']['data'] ?? false) {
|
||||||
|
foreach($invoice['payments']['data'] as $keyx => $payment) {
|
||||||
|
$invoices['data'][$key]['payments'][$keyx]['paymentables']= $payment['paymentables']['data'] ?? [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return $invoices['data'];
|
||||||
}
|
}
|
||||||
|
|
||||||
private function processQuotes($quotes): Collection
|
private function processQuotes($quotes): array
|
||||||
{
|
{
|
||||||
$it = new QuoteTransformer();
|
$it = new QuoteTransformer();
|
||||||
$it->setDefaultIncludes(['client']);
|
$it->setDefaultIncludes(['client']);
|
||||||
$manager = new Manager();
|
$manager = new Manager();
|
||||||
|
$manager->setSerializer(new ArraySerializer());
|
||||||
$resource = new \League\Fractal\Resource\Collection($quotes, $it, Quote::class);
|
$resource = new \League\Fractal\Resource\Collection($quotes, $it, Quote::class);
|
||||||
$i = $manager->createData($resource)->toArray();
|
$i = $manager->createData($resource)->toArray();
|
||||||
return $i['data'];
|
|
||||||
|
$i['client']['contacts'] = $i['client']['contacts'][ClientContact::class];
|
||||||
|
return $i[Quote::class];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function processCredits($credits): Collection
|
private function processCredits($credits): array
|
||||||
{
|
{
|
||||||
$it = new CreditTransformer();
|
$it = new CreditTransformer();
|
||||||
$it->setDefaultIncludes(['client']);
|
$it->setDefaultIncludes(['client']);
|
||||||
$manager = new Manager();
|
$manager = new Manager();
|
||||||
|
$manager->setSerializer(new ArraySerializer());
|
||||||
$resource = new \League\Fractal\Resource\Collection($credits, $it, Credit::class);
|
$resource = new \League\Fractal\Resource\Collection($credits, $it, Credit::class);
|
||||||
$i = $manager->createData($resource)->toArray();
|
$i = $manager->createData($resource)->toArray();
|
||||||
return $i['data'];
|
return $i[Credit::class];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function processPayments($payments): Collection
|
private function processPayments($payments): array
|
||||||
{
|
{
|
||||||
$it = new PaymentTransformer();
|
$it = new PaymentTransformer();
|
||||||
$it->setDefaultIncludes(['client','invoices','paymentables']);
|
$it->setDefaultIncludes(['client','invoices','paymentables']);
|
||||||
$manager = new Manager();
|
$manager = new Manager();
|
||||||
|
$manager->setSerializer(new ArraySerializer());
|
||||||
$resource = new \League\Fractal\Resource\Collection($payments, $it, Payment::class);
|
$resource = new \League\Fractal\Resource\Collection($payments, $it, Payment::class);
|
||||||
$i = $manager->createData($resource)->toArray();
|
$i = $manager->createData($resource)->toArray();
|
||||||
return $i['data'];
|
return $i[Payment::class];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function processTasks($tasks): Collection
|
private function processTasks($tasks): array
|
||||||
{
|
{
|
||||||
$it = new TaskTransformer();
|
$it = new TaskTransformer();
|
||||||
$it->setDefaultIncludes(['client','tasks','project','invoice']);
|
$it->setDefaultIncludes(['client','tasks','project','invoice']);
|
||||||
$manager = new Manager();
|
$manager = new Manager();
|
||||||
|
$manager->setSerializer(new ArraySerializer());
|
||||||
$resource = new \League\Fractal\Resource\Collection($tasks, $it, Task::class);
|
$resource = new \League\Fractal\Resource\Collection($tasks, $it, Task::class);
|
||||||
$i = $manager->createData($resource)->toArray();
|
$i = $manager->createData($resource)->toArray();
|
||||||
return $i['data'];
|
return $i[Task::class];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function processProjects($projects): Collection
|
private function processProjects($projects): array
|
||||||
{
|
{
|
||||||
|
|
||||||
$it = new ProjectTransformer();
|
$it = new ProjectTransformer();
|
||||||
$it->setDefaultIncludes(['client','tasks']);
|
$it->setDefaultIncludes(['client','tasks']);
|
||||||
$manager = new Manager();
|
$manager = new Manager();
|
||||||
|
$manager->setSerializer(new ArraySerializer());
|
||||||
$resource = new \League\Fractal\Resource\Collection($projects, $it, Project::class);
|
$resource = new \League\Fractal\Resource\Collection($projects, $it, Project::class);
|
||||||
$i = $manager->createData($resource)->toArray();
|
$i = $manager->createData($resource)->toArray();
|
||||||
return $i['data'];
|
return $i[Project::class];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -298,9 +328,10 @@ class TemplateService
|
|||||||
$it = new PurchaseOrderTransformer();
|
$it = new PurchaseOrderTransformer();
|
||||||
$it->setDefaultIncludes(['vendor','expense']);
|
$it->setDefaultIncludes(['vendor','expense']);
|
||||||
$manager = new Manager();
|
$manager = new Manager();
|
||||||
|
$manager->setSerializer(new ArraySerializer());
|
||||||
$resource = new \League\Fractal\Resource\Collection($purchase_orders, $it, PurchaseOrder::class);
|
$resource = new \League\Fractal\Resource\Collection($purchase_orders, $it, PurchaseOrder::class);
|
||||||
$i = $manager->createData($resource)->toArray();
|
$i = $manager->createData($resource)->toArray();
|
||||||
return $i['data'];
|
return $i[PurchaseOrder::class];
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -32,6 +32,7 @@ class PaymentTransformer extends EntityTransformer
|
|||||||
protected array $availableIncludes = [
|
protected array $availableIncludes = [
|
||||||
'client',
|
'client',
|
||||||
'invoices',
|
'invoices',
|
||||||
|
'type',
|
||||||
];
|
];
|
||||||
|
|
||||||
public function __construct($serializer = null)
|
public function __construct($serializer = null)
|
||||||
@ -69,6 +70,13 @@ class PaymentTransformer extends EntityTransformer
|
|||||||
return $this->includeCollection($payment->documents, $transformer, Document::class);
|
return $this->includeCollection($payment->documents, $transformer, Document::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function includeType(Payment $payment)
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'type' => $payment->type->translatedType() ?? '',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
public function transform(Payment $payment)
|
public function transform(Payment $payment)
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
|
@ -94,6 +94,7 @@
|
|||||||
"symfony/mailgun-mailer": "^6.1",
|
"symfony/mailgun-mailer": "^6.1",
|
||||||
"symfony/postmark-mailer": "^6.1",
|
"symfony/postmark-mailer": "^6.1",
|
||||||
"turbo124/beacon": "^1.5",
|
"turbo124/beacon": "^1.5",
|
||||||
|
"twig/intl-extra": "^3.7",
|
||||||
"twig/twig": "^3",
|
"twig/twig": "^3",
|
||||||
"twilio/sdk": "^6.40",
|
"twilio/sdk": "^6.40",
|
||||||
"webpatser/laravel-countries": "dev-master#75992ad",
|
"webpatser/laravel-countries": "dev-master#75992ad",
|
||||||
|
66
composer.lock
generated
66
composer.lock
generated
@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "08bc4729962b495b68162a069269f74f",
|
"content-hash": "0e0f7606a875b132577ee735309b1247",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "afosto/yaac",
|
"name": "afosto/yaac",
|
||||||
@ -13864,6 +13864,70 @@
|
|||||||
},
|
},
|
||||||
"time": "2023-09-24T07:20:04+00:00"
|
"time": "2023-09-24T07:20:04+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "twig/intl-extra",
|
||||||
|
"version": "v3.7.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/twigphp/intl-extra.git",
|
||||||
|
"reference": "4f4fe572f635534649cc069e1dafe4a8ad63774d"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/twigphp/intl-extra/zipball/4f4fe572f635534649cc069e1dafe4a8ad63774d",
|
||||||
|
"reference": "4f4fe572f635534649cc069e1dafe4a8ad63774d",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=7.1.3",
|
||||||
|
"symfony/intl": "^5.4|^6.0",
|
||||||
|
"twig/twig": "^2.7|^3.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"symfony/phpunit-bridge": "^5.4|^6.3"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Twig\\Extra\\Intl\\": ""
|
||||||
|
},
|
||||||
|
"exclude-from-classmap": [
|
||||||
|
"/Tests/"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Fabien Potencier",
|
||||||
|
"email": "fabien@symfony.com",
|
||||||
|
"homepage": "http://fabien.potencier.org",
|
||||||
|
"role": "Lead Developer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "A Twig extension for Intl",
|
||||||
|
"homepage": "https://twig.symfony.com",
|
||||||
|
"keywords": [
|
||||||
|
"intl",
|
||||||
|
"twig"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/twigphp/intl-extra/tree/v3.7.1"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://github.com/fabpot",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://tidelift.com/funding/github/packagist/twig/twig",
|
||||||
|
"type": "tidelift"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2023-07-29T15:34:56+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "twig/twig",
|
"name": "twig/twig",
|
||||||
"version": "v3.7.1",
|
"version": "v3.7.1",
|
||||||
|
@ -101,6 +101,59 @@ class TemplateTest extends TestCase
|
|||||||
|
|
||||||
';
|
';
|
||||||
|
|
||||||
|
private string $payments_body = '
|
||||||
|
<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">Invoice #</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.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|format_currency("EUR") }}</td>
|
||||||
|
<td class="whitespace-nowrap px-6 py-4 font-medium"></td>
|
||||||
|
<td class="whitespace-nowrap px-6 py-4 font-medium">{{ invoice.balance|format_currency("EUR") }}</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.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|format_currency("EUR") }} - {{ payment.type.name }}
|
||||||
|
{% else %}
|
||||||
|
({{ pivot.refunded|format_currency("EUR") }})
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td class="whitespace-nowrap px-6 py-4 font-medium"></td>
|
||||||
|
<td class="whitespace-nowrap px-6 py-4 font-medium"></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor%}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</ninja>
|
||||||
|
';
|
||||||
|
|
||||||
protected function setUp() :void
|
protected function setUp() :void
|
||||||
{
|
{
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
@ -113,6 +166,67 @@ class TemplateTest extends TestCase
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testVariableResolutionViaTransformersForPaymentsInStatements()
|
||||||
|
{
|
||||||
|
Invoice::factory()->count(20)->create([
|
||||||
|
'company_id' => $this->company->id,
|
||||||
|
'user_id' => $this->user->id,
|
||||||
|
'client_id' => $this->client->id,
|
||||||
|
'status_id' => Invoice::STATUS_SENT,
|
||||||
|
'amount' => 100,
|
||||||
|
'balance' => 100,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$i = Invoice::orderBy('id','desc')
|
||||||
|
->where('client_id', $this->client->id)
|
||||||
|
->where('status_id', 2)
|
||||||
|
->cursor()
|
||||||
|
->each(function ($i){
|
||||||
|
$i->service()->applyPaymentAmount(random_int(1,100));
|
||||||
|
});
|
||||||
|
|
||||||
|
$invoices = Invoice::withTrashed()
|
||||||
|
->with('payments.type')
|
||||||
|
->where('is_deleted', false)
|
||||||
|
->where('company_id', $this->client->company_id)
|
||||||
|
->where('client_id', $this->client->id)
|
||||||
|
->whereIn('status_id', [2,3,4])
|
||||||
|
->orderBy('due_date', 'ASC')
|
||||||
|
->orderBy('date', 'ASC')
|
||||||
|
->cursor();
|
||||||
|
|
||||||
|
$invoices->each(function ($i){
|
||||||
|
|
||||||
|
$rand = [1,2,4,5,6,7,8,9,10,11,12,13,14,15,16,17,24,25,32,49,50];
|
||||||
|
|
||||||
|
$i->payments()->each(function ($p) use ($rand){
|
||||||
|
shuffle($rand);
|
||||||
|
$p->type_id = $rand[0];
|
||||||
|
$p->save();
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$design_model = Design::find(2);
|
||||||
|
|
||||||
|
$replicated_design = $design_model->replicate();
|
||||||
|
$design = $replicated_design->design;
|
||||||
|
$design->body .= $this->payments_body;
|
||||||
|
$replicated_design->design = $design;
|
||||||
|
$replicated_design->is_custom = true;
|
||||||
|
$replicated_design->is_template =true;
|
||||||
|
$replicated_design->entities = 'client';
|
||||||
|
$replicated_design->save();
|
||||||
|
|
||||||
|
$data['invoices'] = $invoices;
|
||||||
|
$ts = $replicated_design->service()->build($data);
|
||||||
|
|
||||||
|
nlog("results = ");
|
||||||
|
nlog($ts->getHtml());
|
||||||
|
$this->assertNotNull($ts->getHtml());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public function testDoubleEntityNestedDataTemplateServiceBuild()
|
public function testDoubleEntityNestedDataTemplateServiceBuild()
|
||||||
{
|
{
|
||||||
$design_model = Design::find(2);
|
$design_model = Design::find(2);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user