Merge pull request #9558 from dshoreman/ds/preview-entity-numbers

"Real" entity numbers in Invoice Designer/Settings previews
This commit is contained in:
David Bomba 2024-05-31 21:25:28 +10:00 committed by GitHub
commit aa340d070c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 58 additions and 14 deletions

View File

@ -29,6 +29,7 @@ use App\Utils\HostedPDF\NinjaPdf;
use App\Utils\HtmlEngine; use App\Utils\HtmlEngine;
use App\Utils\Ninja; use App\Utils\Ninja;
use App\Utils\PhantomJS\Phantom; use App\Utils\PhantomJS\Phantom;
use App\Utils\Traits\GeneratesCounter;
use App\Utils\Traits\MakesHash; use App\Utils\Traits\MakesHash;
use App\Utils\Traits\MakesInvoiceHtml; use App\Utils\Traits\MakesInvoiceHtml;
use App\Utils\Traits\Pdf\PageNumbering; use App\Utils\Traits\Pdf\PageNumbering;
@ -40,6 +41,7 @@ use Twig\Error\SyntaxError;
class PreviewController extends BaseController class PreviewController extends BaseController
{ {
use GeneratesCounter;
use MakesHash; use MakesHash;
use MakesInvoiceHtml; use MakesInvoiceHtml;
use PageNumbering; use PageNumbering;
@ -404,23 +406,24 @@ class PreviewController extends BaseController
/** @var \App\Models\Client $client */ /** @var \App\Models\Client $client */
$client = Client::factory()->create([ $client = Client::factory()->create([
'user_id' => auth()->user()->id, 'user_id' => $user->id,
'company_id' => $company->id, 'company_id' => $company->id,
]); ]);
/** @var \App\Models\ClientContact $contact */ /** @var \App\Models\ClientContact $contact */
$contact = ClientContact::factory()->create([ $contact = ClientContact::factory()->create([
'user_id' => auth()->user()->id, 'user_id' => $user->id,
'company_id' => $company->id, 'company_id' => $company->id,
'client_id' => $client->id, 'client_id' => $client->id,
'is_primary' => 1, 'is_primary' => 1,
'send_email' => true, 'send_email' => true,
]); ]);
/** @var \App\Models\Invoice $invoice */ $settings = $company->settings;
/** @var \App\Models\Invoice $invoice */
$invoice = Invoice::factory()->create([ $invoice = Invoice::factory()->create([
'user_id' => auth()->user()->id, 'user_id' => $user->id,
'company_id' => $company->id, 'company_id' => $company->id,
'client_id' => $client->id, 'client_id' => $client->id,
'terms' => $company->settings->invoice_terms, 'terms' => $company->settings->invoice_terms,
@ -428,8 +431,18 @@ class PreviewController extends BaseController
'public_notes' => 'Sample Public Notes', 'public_notes' => 'Sample Public Notes',
]); ]);
if ($settings->invoice_number_pattern) {
$invoice->number = $this->getFormattedEntityNumber(
$invoice,
rand(1, 9999),
$settings->counter_padding ?: 4,
$settings->invoice_number_pattern,
);
$invoice->save();
}
$invitation = InvoiceInvitation::factory()->create([ $invitation = InvoiceInvitation::factory()->create([
'user_id' => auth()->user()->id, 'user_id' => $user->id,
'company_id' => $company->id, 'company_id' => $company->id,
'invoice_id' => $invoice->id, 'invoice_id' => $invoice->id,
'client_contact_id' => $contact->id, 'client_contact_id' => $contact->id,
@ -454,7 +467,7 @@ class PreviewController extends BaseController
'template' => $design->elements([ 'template' => $design->elements([
'client' => $invoice->client, 'client' => $invoice->client,
'entity' => $invoice, 'entity' => $invoice,
'pdf_variables' => (array) $invoice->company->settings->pdf_variables, 'pdf_variables' => (array) $settings->pdf_variables,
'products' => request()->design['design']['product'], 'products' => request()->design['design']['product'],
]), ]),
'variables' => $html->generateLabelsAndValues(), 'variables' => $html->generateLabelsAndValues(),

View File

@ -27,11 +27,13 @@ use App\Models\PurchaseOrderInvitation;
use App\Models\Quote; use App\Models\Quote;
use App\Models\QuoteInvitation; use App\Models\QuoteInvitation;
use App\Models\Vendor; use App\Models\Vendor;
use App\Utils\Traits\GeneratesCounter;
use App\Utils\Traits\MakesHash; use App\Utils\Traits\MakesHash;
class PdfMock class PdfMock
{ {
use MakesHash; use MakesHash;
use GeneratesCounter;
private mixed $mock; private mixed $mock;
@ -206,6 +208,20 @@ class PdfMock
*/ */
public function getStubVariables(): array public function getStubVariables(): array
{ {
$entity_pattern = $this->entity_string.'_number_pattern';
$entity_number = '0029';
if (!empty($this->settings->{$entity_pattern})) {
// Although $this->mock is the Invoice/etc entity,
// we need the invitation to get company details.
$entity_number = $this->getFormattedEntityNumber(
$this->mock->invitation,
(int) $entity_number,
$this->settings->counter_padding,
$this->settings->{$entity_pattern},
);
}
return ['values' => return ['values' =>
[ [
'$client.shipping_postal_code' => '46420', '$client.shipping_postal_code' => '46420',
@ -370,7 +386,7 @@ class PdfMock
'$company.phone' => $this->settings->phone, '$company.phone' => $this->settings->phone,
'$company.state' => $this->settings->state, '$company.state' => $this->settings->state,
'$credit.number' => '0029', '$credit.number' => '0029',
'$entity_number' => '0029', '$entity_number' => $entity_number,
'$credit_number' => '0029', '$credit_number' => '0029',
'$global_margin' => '6.35mm', '$global_margin' => '6.35mm',
'$contact.phone' => '681-480-9828', '$contact.phone' => '681-480-9828',

View File

@ -288,7 +288,6 @@ trait GeneratesCounter
*/ */
public function getNextProjectNumber(Project $project): string public function getNextProjectNumber(Project $project): string
{ {
$entity_number = $this->getNextEntityNumber(Project::class, $project->client, false); $entity_number = $this->getNextEntityNumber(Project::class, $project->client, false);
return $this->replaceUserVars($project, $entity_number); return $this->replaceUserVars($project, $entity_number);
@ -412,7 +411,7 @@ trait GeneratesCounter
* *
* @param string $pattern * @param string $pattern
* @param string $prefix * @param string $prefix
* @return string The padded and prefixed entity number * @return string The padded, prefixed and unique entity number
*/ */
private function checkEntityNumber($class, $entity, $counter, $padding, $pattern, $prefix = ''): string private function checkEntityNumber($class, $entity, $counter, $padding, $pattern, $prefix = ''): string
{ {
@ -420,11 +419,7 @@ trait GeneratesCounter
$check_counter = 1; $check_counter = 1;
do { do {
$number = $this->padCounter($counter, $padding); $number = $this->getFormattedEntityNumber($entity, $counter, $padding, $pattern);
$number = $this->applyNumberPattern($entity, $number, $pattern);
$number = $this->prefixCounter($number, $prefix);
$check = $class::where('company_id', $entity->company_id)->where('number', $number)->withTrashed()->exists(); $check = $class::where('company_id', $entity->company_id)->where('number', $number)->withTrashed()->exists();
@ -443,6 +438,26 @@ trait GeneratesCounter
return $number; return $number;
} }
/**
* Formats the entity number according to pattern, prefix and padding.
*
* @param Collection $entity The entity ie App\Models\Client, Invoice, Quote etc
* @param int $counter The counter
* @param int $padding The padding
* @param string $pattern
* @param string $prefix
*
* @return string The padded and prefixed entity number
*/
public function getFormattedEntityNumber($entity, $counter, $padding, $pattern, $prefix = ''): string
{
$number = $this->padCounter($counter, $padding);
$number = $this->applyNumberPattern($entity, $number, $pattern);
return $this->prefixCounter($number, $prefix);
}
/*Check if a number is available for use. */ /*Check if a number is available for use. */
public function checkNumberAvailable($class, $entity, $number): bool public function checkNumberAvailable($class, $entity, $number): bool
{ {