mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-10 05:02:36 +01: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(
|
||||
$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
|
||||
);
|
||||
|
||||
|
@ -26,13 +26,20 @@ class BulkCompanyGatewayRequest extends Request
|
||||
*/
|
||||
public function authorize() : bool
|
||||
{
|
||||
return auth()->user()->isAdmin();
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
return $user->isAdmin();
|
||||
}
|
||||
|
||||
public function rules()
|
||||
{
|
||||
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
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'
|
||||
];
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ class StoreDesignRequest extends Request
|
||||
'design.footer' => 'required|min:1',
|
||||
'design.includes' => 'required|min:1',
|
||||
'is_template' => 'sometimes|boolean',
|
||||
'entities' => 'sometimes|string'
|
||||
'entities' => 'sometimes|string|nullable'
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@ class UpdateDesignRequest extends Request
|
||||
{
|
||||
return [
|
||||
'is_template' => 'sometimes|boolean',
|
||||
'entities' => 'sometimes|string'
|
||||
'entities' => 'sometimes|string|nullable'
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -65,8 +65,6 @@ class UpdateInvoiceRequest extends Request
|
||||
|
||||
$rules['is_amount_discount'] = ['boolean'];
|
||||
|
||||
nlog($this->partial);
|
||||
|
||||
$rules['line_items'] = 'array';
|
||||
$rules['discount'] = 'sometimes|numeric';
|
||||
$rules['project_id'] = ['bail', 'sometimes', new ValidProjectForClient($this->all())];
|
||||
|
@ -17,9 +17,10 @@ class CreateStatementRequest extends Request
|
||||
*/
|
||||
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()
|
||||
{
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
return [
|
||||
'start_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_aging_table' => 'boolean',
|
||||
'show_credits_table' => 'boolean',
|
||||
'status' => 'string',
|
||||
'template' => 'sometimes|string|nullable',
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,7 @@ class PayFastPaymentDriver extends BaseDriver
|
||||
if ($this->client->currency()->code == 'ZAR') {
|
||||
$types[] = GatewayType::CREDIT_CARD;
|
||||
}
|
||||
|
||||
|
||||
return $types;
|
||||
}
|
||||
|
||||
|
@ -78,6 +78,19 @@ class PaymentMethod
|
||||
->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
|
||||
});
|
||||
|
||||
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 {
|
||||
$this->gateways = CompanyGateway::query()
|
||||
->with('gateway')
|
||||
|
@ -29,11 +29,12 @@ use App\Utils\Traits\Pdf\PdfMaker as PdfMakerTrait;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use App\Models\Credit;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
|
||||
class Statement
|
||||
{
|
||||
use PdfMakerTrait;
|
||||
|
||||
use MakesHash;
|
||||
/**
|
||||
* @var Invoice|Payment|null
|
||||
*/
|
||||
@ -88,21 +89,44 @@ class Statement
|
||||
'process_markdown' => $this->entity->client->company->markdown_enabled,
|
||||
];
|
||||
|
||||
$maker = new PdfMaker($state);
|
||||
if($this->options['template'] ?? false){
|
||||
|
||||
$maker
|
||||
->design($template)
|
||||
->build();
|
||||
$template = Design::where('id', $this->decodePrimaryKey($this->options['template']))
|
||||
->where('company_id', $this->client->company_id)
|
||||
->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 {
|
||||
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') {
|
||||
$pdf = (new NinjaPdf())->build($maker->getCompiledHTML(true));
|
||||
$pdf = (new NinjaPdf())->build($html);
|
||||
} else {
|
||||
$pdf = $this->makePdf(null, null, $maker->getCompiledHTML(true));
|
||||
$pdf = $this->makePdf(null, null, $html);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
nlog(print_r($e->getMessage(), 1));
|
||||
|
@ -20,10 +20,12 @@ use App\Models\Payment;
|
||||
use App\Models\Project;
|
||||
use App\Utils\HtmlEngine;
|
||||
use League\Fractal\Manager;
|
||||
use App\Models\ClientContact;
|
||||
use App\Models\PurchaseOrder;
|
||||
use App\Utils\VendorHtmlEngine;
|
||||
use App\Utils\PaymentHtmlEngine;
|
||||
use Illuminate\Support\Collection;
|
||||
use Twig\Extra\Intl\IntlExtension;
|
||||
use App\Transformers\TaskTransformer;
|
||||
use App\Transformers\QuoteTransformer;
|
||||
use App\Transformers\CreditTransformer;
|
||||
@ -91,7 +93,7 @@ class TemplateService
|
||||
{
|
||||
$data = $this->preProcessDataBlocks($data);
|
||||
$replacements = [];
|
||||
|
||||
nlog($data);
|
||||
$contents = $this->document->getElementsByTagName('ninja');
|
||||
|
||||
foreach ($contents as $content) {
|
||||
@ -103,10 +105,13 @@ class TemplateService
|
||||
|
||||
$string_extension = new \Twig\Extension\StringLoaderExtension();
|
||||
$twig->addExtension($string_extension);
|
||||
|
||||
$twig->addExtension(new IntlExtension());
|
||||
|
||||
$template = $twig->createTemplate(html_entity_decode($template));
|
||||
$template = $template->render($data);
|
||||
|
||||
nlog($template);
|
||||
|
||||
$f = $this->document->createDocumentFragment();
|
||||
$f->appendXML($template);
|
||||
$replacements[] = $f;
|
||||
@ -228,67 +233,92 @@ class TemplateService
|
||||
private function processInvoices($invoices): array
|
||||
{
|
||||
$it = new InvoiceTransformer();
|
||||
$it->setDefaultIncludes(['client']);
|
||||
$it->setDefaultIncludes(['client','payments']);
|
||||
$manager = new Manager();
|
||||
// $manager->setSerializer(new JsonApiSerializer());
|
||||
$resource = new \League\Fractal\Resource\Collection($invoices, $it, Invoice::class);
|
||||
$i = $manager->createData($resource)->toArray();
|
||||
return $i['data'];
|
||||
$manager->parseIncludes(['client','payments','payments.type']);
|
||||
$resource = new \League\Fractal\Resource\Collection($invoices, $it, null);
|
||||
$invoices = $manager->createData($resource)->toArray();
|
||||
|
||||
// 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->setDefaultIncludes(['client']);
|
||||
$manager = new Manager();
|
||||
$manager->setSerializer(new ArraySerializer());
|
||||
$resource = new \League\Fractal\Resource\Collection($quotes, $it, Quote::class);
|
||||
$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->setDefaultIncludes(['client']);
|
||||
$manager = new Manager();
|
||||
$manager->setSerializer(new ArraySerializer());
|
||||
$resource = new \League\Fractal\Resource\Collection($credits, $it, Credit::class);
|
||||
$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->setDefaultIncludes(['client','invoices','paymentables']);
|
||||
$manager = new Manager();
|
||||
$manager->setSerializer(new ArraySerializer());
|
||||
$resource = new \League\Fractal\Resource\Collection($payments, $it, Payment::class);
|
||||
$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->setDefaultIncludes(['client','tasks','project','invoice']);
|
||||
$manager = new Manager();
|
||||
$manager->setSerializer(new ArraySerializer());
|
||||
$resource = new \League\Fractal\Resource\Collection($tasks, $it, Task::class);
|
||||
$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->setDefaultIncludes(['client','tasks']);
|
||||
$manager = new Manager();
|
||||
$manager->setSerializer(new ArraySerializer());
|
||||
$resource = new \League\Fractal\Resource\Collection($projects, $it, Project::class);
|
||||
$i = $manager->createData($resource)->toArray();
|
||||
return $i['data'];
|
||||
return $i[Project::class];
|
||||
|
||||
}
|
||||
|
||||
@ -298,9 +328,10 @@ class TemplateService
|
||||
$it = new PurchaseOrderTransformer();
|
||||
$it->setDefaultIncludes(['vendor','expense']);
|
||||
$manager = new Manager();
|
||||
$manager->setSerializer(new ArraySerializer());
|
||||
$resource = new \League\Fractal\Resource\Collection($purchase_orders, $it, PurchaseOrder::class);
|
||||
$i = $manager->createData($resource)->toArray();
|
||||
return $i['data'];
|
||||
return $i[PurchaseOrder::class];
|
||||
|
||||
}
|
||||
}
|
@ -32,6 +32,7 @@ class PaymentTransformer extends EntityTransformer
|
||||
protected array $availableIncludes = [
|
||||
'client',
|
||||
'invoices',
|
||||
'type',
|
||||
];
|
||||
|
||||
public function __construct($serializer = null)
|
||||
@ -69,6 +70,13 @@ class PaymentTransformer extends EntityTransformer
|
||||
return $this->includeCollection($payment->documents, $transformer, Document::class);
|
||||
}
|
||||
|
||||
public function includeType(Payment $payment)
|
||||
{
|
||||
return [
|
||||
'type' => $payment->type->translatedType() ?? '',
|
||||
];
|
||||
}
|
||||
|
||||
public function transform(Payment $payment)
|
||||
{
|
||||
return [
|
||||
|
@ -94,6 +94,7 @@
|
||||
"symfony/mailgun-mailer": "^6.1",
|
||||
"symfony/postmark-mailer": "^6.1",
|
||||
"turbo124/beacon": "^1.5",
|
||||
"twig/intl-extra": "^3.7",
|
||||
"twig/twig": "^3",
|
||||
"twilio/sdk": "^6.40",
|
||||
"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",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "08bc4729962b495b68162a069269f74f",
|
||||
"content-hash": "0e0f7606a875b132577ee735309b1247",
|
||||
"packages": [
|
||||
{
|
||||
"name": "afosto/yaac",
|
||||
@ -13864,6 +13864,70 @@
|
||||
},
|
||||
"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",
|
||||
"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
|
||||
{
|
||||
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()
|
||||
{
|
||||
$design_model = Design::find(2);
|
||||
|
Loading…
Reference in New Issue
Block a user