From 17f853f907ae88a93ed778031d05d90ca37c3d73 Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Fri, 23 Oct 2015 14:55:18 +0300 Subject: [PATCH] Working on custom invoice numbers --- app/Console/Commands/CreateRandomData.php | 2 +- app/Http/Controllers/AccountController.php | 2 +- app/Http/Controllers/InvoiceApiController.php | 2 +- app/Http/Controllers/InvoiceController.php | 31 +++++----- app/Http/Controllers/QuoteController.php | 27 +++++---- app/Models/Account.php | 44 +++++++------- app/Models/Invoice.php | 38 +++++++++++- app/Ninja/Repositories/AccountRepository.php | 2 +- app/Ninja/Repositories/InvoiceRepository.php | 13 ++-- resources/views/invoices/edit.blade.php | 60 +++++++++---------- resources/views/invoices/knockout.blade.php | 18 +++--- tests/acceptance/InvoiceCest.php | 4 +- 12 files changed, 136 insertions(+), 107 deletions(-) diff --git a/app/Console/Commands/CreateRandomData.php b/app/Console/Commands/CreateRandomData.php index 9fe826cc9b5b..de4da39cbe71 100644 --- a/app/Console/Commands/CreateRandomData.php +++ b/app/Console/Commands/CreateRandomData.php @@ -59,7 +59,7 @@ class CreateRandomData extends Command { } $invoice = Invoice::createNew($user); - $invoice->invoice_number = $user->account->getNextInvoiceNumber(); + $invoice->invoice_number = $user->account->getNextInvoiceNumber($invoice); $invoice->amount = $invoice->balance = $price; $invoice->created_at = date('Y-m-d', strtotime(date("Y-m-d") . ' - ' . rand(1, 100) . ' days')); $client->invoices()->save($invoice); diff --git a/app/Http/Controllers/AccountController.php b/app/Http/Controllers/AccountController.php index 4922c68163ec..a2785e1e0930 100644 --- a/app/Http/Controllers/AccountController.php +++ b/app/Http/Controllers/AccountController.php @@ -308,7 +308,7 @@ class AccountController extends BaseController $client->work_phone = ''; $client->work_email = ''; - $invoice->invoice_number = $account->getNextInvoiceNumber(); + $invoice->invoice_number = '0000'; $invoice->invoice_date = Utils::fromSqlDate(date('Y-m-d')); $invoice->account = json_decode($account->toJson()); $invoice->amount = $invoice->balance = 100; diff --git a/app/Http/Controllers/InvoiceApiController.php b/app/Http/Controllers/InvoiceApiController.php index 3a70c51883ba..d3bb9b44bfec 100644 --- a/app/Http/Controllers/InvoiceApiController.php +++ b/app/Http/Controllers/InvoiceApiController.php @@ -87,7 +87,7 @@ class InvoiceApiController extends Controller // check if the invoice number is set and unique if (!isset($data['invoice_number']) && !isset($data['id'])) { - $data['invoice_number'] = Auth::user()->account->getNextInvoiceNumber(false, '', $client, Auth::user()); + // do nothing... invoice number will be set automatically } else if (isset($data['invoice_number'])) { $invoice = Invoice::scope()->where('invoice_number', '=', $data['invoice_number'])->first(); if ($invoice) { diff --git a/app/Http/Controllers/InvoiceController.php b/app/Http/Controllers/InvoiceController.php index e31341eb2747..89ef59bd9189 100644 --- a/app/Http/Controllers/InvoiceController.php +++ b/app/Http/Controllers/InvoiceController.php @@ -248,7 +248,7 @@ class InvoiceController extends BaseController if ($clone) { $invoice->id = null; - $invoice->invoice_number = $account->getNextInvoiceNumber($invoice->is_quote, '', $invoice->client, Auth::user()); + $invoice->invoice_number = $account->getNextInvoiceNumber($invoice); $invoice->balance = $invoice->amount; $invoice->invoice_status_id = 0; $invoice->invoice_date = date_create()->format('Y-m-d'); @@ -350,26 +350,23 @@ class InvoiceController extends BaseController public function create($clientPublicId = 0, $isRecurring = false) { $client = null; - if ($isRecurring) { - $invoiceNumber = microtime(true); - } else { - $invoiceNumber = Auth::user()->account->getDefaultInvoiceNumber(false, false, false, Auth::user()); - } - if ($clientPublicId) { $client = Client::scope($clientPublicId)->firstOrFail(); } - $data = array( - 'entityType' => ENTITY_INVOICE, - 'invoice' => null, - 'data' => Input::old('data'), - 'invoiceNumber' => $invoiceNumber, - 'method' => 'POST', - 'url' => 'invoices', - 'title' => trans('texts.new_invoice'), - 'isRecurring' => $isRecurring, - 'client' => $client); + $invoice = Invoice::createNew(); + $invoice->client = $client; + $invoice->is_recurring = $isRecurring; + $invoice->initialize(); + + $data = [ + 'entityType' => $invoice->getEntityType(), + 'invoice' => $invoice, + 'data' => Input::old('data'), + 'method' => 'POST', + 'url' => 'invoices', + 'title' => trans('texts.new_invoice'), + ]; $data = array_merge($data, self::getViewModel()); return View::make('invoices.edit', $data); diff --git a/app/Http/Controllers/QuoteController.php b/app/Http/Controllers/QuoteController.php index 46d885e51ace..e987fc458e2c 100644 --- a/app/Http/Controllers/QuoteController.php +++ b/app/Http/Controllers/QuoteController.php @@ -82,24 +82,25 @@ class QuoteController extends BaseController } $client = null; - $invoiceNumber = Auth::user()->account->getDefaultInvoiceNumber(true); - $account = Account::with('country')->findOrFail(Auth::user()->account_id); - if ($clientPublicId) { $client = Client::scope($clientPublicId)->firstOrFail(); } - $data = array( - 'account' => $account, - 'invoice' => null, - 'data' => Input::old('data'), - 'invoiceNumber' => $invoiceNumber, - 'method' => 'POST', - 'url' => 'invoices', - 'title' => trans('texts.new_quote'), - 'client' => $client, ); + $invoice = Invoice::createNew(); + $invoice->client = $client; + $invoice->is_quote = true; + $invoice->initialize(); + + $data = [ + 'entityType' => $invoice->getEntityType(), + 'invoice' => $invoice, + 'data' => Input::old('data'), + 'method' => 'POST', + 'url' => 'invoices', + 'title' => trans('texts.new_quote'), + ]; $data = array_merge($data, self::getViewModel()); - + return View::make('invoices.edit', $data); } diff --git a/app/Models/Account.php b/app/Models/Account.php index ac0bee0bee35..90bfff497d0c 100644 --- a/app/Models/Account.php +++ b/app/Models/Account.php @@ -248,16 +248,16 @@ class Account extends Eloquent return $isQuote ? ($this->quote_number_pattern ? true : false) : ($this->invoice_number_pattern ? true : false); } - public function hasClientNumberPattern($isQuote) + public function hasClientNumberPattern($invoice) { - $pattern = $this->getNumberPattern($isQuote); + $pattern = $invoice->is_quote ? $this->quote_number_pattern : $this->invoice_number_pattern; return strstr($pattern, '$custom'); } - public function getNumberPattern($isQuote, $client = null, $user = null) + public function getNumberPattern($invoice) { - $pattern = $isQuote ? $this->quote_number_pattern : $this->invoice_number_pattern; + $pattern = $invoice->is_quote ? $this->quote_number_pattern : $this->invoice_number_pattern; if (!$pattern) { return false; @@ -267,11 +267,11 @@ class Account extends Eloquent $replace = [date('Y')]; $search[] = '{$counter}'; - $replace[] = str_pad($this->getCounter($isQuote), 4, '0', STR_PAD_LEFT); + $replace[] = str_pad($this->getCounter($invoice->is_quote), 4, '0', STR_PAD_LEFT); - if ($user) { + if (strstr($pattern, '{$userId}')) { $search[] = '{$userId}'; - $replace[] = str_pad($user->public_id, 2, '0', STR_PAD_LEFT); + $replace[] = str_pad($invoice->user->public_id, 2, '0', STR_PAD_LEFT); } $matches = false; @@ -284,16 +284,16 @@ class Account extends Eloquent $pattern = str_replace($search, $replace, $pattern); - if ($client) { - $pattern = $this->getClientInvoiceNumber($pattern, $isQuote, $client); + if ($invoice->client->id) { + $pattern = $this->getClientInvoiceNumber($pattern, $invoice); } return $pattern; } - private function getClientInvoiceNumber($pattern, $isQuote, $client) + private function getClientInvoiceNumber($pattern, $invoice) { - if (!$client) { + if (!$invoice->client) { return $pattern; } @@ -305,8 +305,8 @@ class Account extends Eloquent $replace = [ //str_pad($client->public_id, 3, '0', STR_PAD_LEFT), - $client->custom_value1, - $client->custom_value2, + $invoice->client->custom_value1, + $invoice->client->custom_value2, ]; return str_replace($search, $replace, $pattern); @@ -314,13 +314,13 @@ class Account extends Eloquent // if we're using a pattern we don't know the next number until a client // is selected, to support this the default value is blank - public function getDefaultInvoiceNumber($isQuote = false, $prefix = '', $client = null, $user = null) + public function getDefaultInvoiceNumber($invoice = false, $prefix = '') { - if ($this->hasClientNumberPattern($isQuote)) { + if ($this->hasClientNumberPattern($invoice)) { return false; } - return $this->getNextInvoiceNumber($isQuote = false, $prefix = '', $client, $user); + return $this->getNextInvoiceNumber($invoice, $prefix = ''); } public function getCounter($isQuote) @@ -328,14 +328,14 @@ class Account extends Eloquent return $isQuote && !$this->share_counter ? $this->quote_number_counter : $this->invoice_number_counter; } - public function getNextInvoiceNumber($isQuote = false, $prefix = '', $client = null, $user = null) + public function getNextInvoiceNumber($invoice, $prefix = '') { - if ($this->hasNumberPattern($isQuote)) { - return $this->getNumberPattern($isQuote, $client, $user); + if ($this->hasNumberPattern($invoice->is_quote)) { + return $this->getNumberPattern($invoice); } - $counter = $this->getCounter($isQuote); - $prefix .= $isQuote ? $this->quote_number_prefix : $this->invoice_number_prefix; + $counter = $this->getCounter($invoice->is_quote); + $prefix .= $invoice->is_quote ? $this->quote_number_prefix : $this->invoice_number_prefix; $counterOffset = 0; // confirm the invoice number isn't already taken @@ -348,7 +348,7 @@ class Account extends Eloquent // update the invoice counter to be caught up if ($counterOffset > 1) { - if ($isQuote && !$this->share_counter) { + if ($invoice->is_quote && !$this->share_counter) { $this->quote_number_counter += $counterOffset - 1; } else { $this->invoice_number_counter += $counterOffset - 1; diff --git a/app/Models/Invoice.php b/app/Models/Invoice.php index 38a5c0c48fde..bfad62ebb8c8 100644 --- a/app/Models/Invoice.php +++ b/app/Models/Invoice.php @@ -20,11 +20,47 @@ class Invoice extends EntityModel 'custom1', 'custom2', 'userId', - //'clientId', // need to update after saving 'year', 'date:', ]; + public function initialize() + { + $account = $this->account; + + $this->invoice_date = Utils::today(); + $this->start_date = Utils::today(); + $this->invoice_design_id = $account->invoice_design_id; + $this->terms = $account->invoice_terms; + $this->invoice_footer = $account->invoice_footer; + + if (!$this->invoice_number) { + if ($this->is_recurring) { + $this->invoice_number = microtime(true); + } else { + if ($account->hasClientNumberPattern($this) && !$this->client) { + // do nothing, we don't yet know the value + } else { + $this->invoice_number = $account->getNextInvoiceNumber($this); + } + } + } + + if (!$this->client) { + $this->client = Client::createNew($this); + $this->client->public_id = 0; + } + } + + public function isTrashed() + { + if ($this->client && $this->client->isTrashed()) { + return true; + } + + return parent::isTrashed(); + } + public function account() { return $this->belongsTo('App\Models\Account'); diff --git a/app/Ninja/Repositories/AccountRepository.php b/app/Ninja/Repositories/AccountRepository.php index d1bf2cadbced..0cc11aa6c016 100644 --- a/app/Ninja/Repositories/AccountRepository.php +++ b/app/Ninja/Repositories/AccountRepository.php @@ -139,7 +139,7 @@ class AccountRepository $invoice->user_id = $account->users()->first()->id; $invoice->public_id = $publicId; $invoice->client_id = $client->id; - $invoice->invoice_number = $account->getNextInvoiceNumber(); + $invoice->invoice_number = $account->getNextInvoiceNumber($invoice); $invoice->invoice_date = date_create()->format('Y-m-d'); $invoice->amount = PRO_PLAN_PRICE; $invoice->balance = PRO_PLAN_PRICE; diff --git a/app/Ninja/Repositories/InvoiceRepository.php b/app/Ninja/Repositories/InvoiceRepository.php index 25536647a4ef..92564cb13206 100644 --- a/app/Ninja/Repositories/InvoiceRepository.php +++ b/app/Ninja/Repositories/InvoiceRepository.php @@ -254,10 +254,12 @@ class InvoiceRepository $invoice = Invoice::scope($publicId)->firstOrFail(); } else { $invoice = Invoice::createNew(); - + $invoice->client_id = $data['client_id']; + $invoice->is_recurring = $data['is_recurring'] ? true : false; if ($entityType == ENTITY_QUOTE) { $invoice->is_quote = true; } + $invoice->initialize(); } $account = \Auth::user()->account; @@ -283,11 +285,6 @@ class InvoiceRepository $invoice->invoice_date = isset($data['invoice_date_sql']) ? $data['invoice_date_sql'] : Utils::toSqlDate($data['invoice_date']); $invoice->has_tasks = isset($data['has_tasks']) ? $data['has_tasks'] : false; - if (!$publicId) { - $invoice->client_id = $data['client_id']; - $invoice->is_recurring = $data['is_recurring'] ? true : false; - } - if ($invoice->is_recurring) { if ($invoice->start_date && $invoice->start_date != Utils::toSqlDate($data['start_date'])) { $invoice->last_sent_date = null; @@ -478,7 +475,7 @@ class InvoiceRepository } $clone->invoice_number = $account->invoice_number_prefix.$invoiceNumber; } else { - $clone->invoice_number = $account->getNextInvoiceNumber($invoice->is_quote, '', $invoice->client, Auth::user()); + $clone->invoice_number = $account->getNextInvoiceNumber($invoice); } foreach ([ @@ -631,7 +628,7 @@ class InvoiceRepository $invoice = Invoice::createNew($recurInvoice); $invoice->client_id = $recurInvoice->client_id; $invoice->recurring_invoice_id = $recurInvoice->id; - $invoice->invoice_number = $recurInvoice->account->getNextInvoiceNumber(false, 'R', $recurInvoice->client, $recurInvoice->user); + $invoice->invoice_number = $recurInvoice->account->getNextInvoiceNumber($recurInvoice, 'R'); $invoice->amount = $recurInvoice->amount; $invoice->balance = $recurInvoice->amount; $invoice->invoice_date = date_create()->format('Y-m-d'); diff --git a/resources/views/invoices/edit.blade.php b/resources/views/invoices/edit.blade.php index 48e9748e518e..0e22f32453cb 100644 --- a/resources/views/invoices/edit.blade.php +++ b/resources/views/invoices/edit.blade.php @@ -8,9 +8,9 @@ @section('content') - @if ($invoice && $invoice->id) + @if ($invoice->id)