diff --git a/app/Models/Invoice.php b/app/Models/Invoice.php index f3717e9afa65..17b6292739c1 100644 --- a/app/Models/Invoice.php +++ b/app/Models/Invoice.php @@ -29,9 +29,9 @@ class Invoice extends EntityModel implements BalanceAffecting 'tax_name1', 'tax_rate1', 'tax_name2', - 'tax_rate2', + 'tax_rate2', ]; - + protected $casts = [ 'is_recurring' => 'boolean', 'has_tasks' => 'boolean', @@ -243,6 +243,10 @@ class Invoice extends EntityModel implements BalanceAffecting return $this->invoice_type_id == $typeId; } + public function isQuote() { + return $this->isType(INVOICE_TYPE_QUOTE); + } + public function markInvitationsSent($notify = false) { foreach ($this->invitations as $invitation) { @@ -524,12 +528,12 @@ class Invoice extends EntityModel implements BalanceAffecting 'name', ]); } - + foreach ($this->expenses as $expense) { $expense->setVisible([ 'documents', ]); - + foreach ($expense->documents as $document) { $document->setVisible([ 'public_id', @@ -588,12 +592,12 @@ class Invoice extends EntityModel implements BalanceAffecting return $schedule[1]->getStart(); } - + public function getDueDate($invoice_date = null){ if(!$this->is_recurring) { return $this->due_date ? $this->due_date : null; } - else{ + else{ $now = time(); if($invoice_date) { // If $invoice_date is specified, all calculations are based on that date @@ -607,7 +611,7 @@ class Invoice extends EntityModel implements BalanceAffecting $now = $invoice_date->getTimestamp(); } } - + if($this->due_date && $this->due_date != '0000-00-00'){ // This is a recurring invoice; we're using a custom format here. // The year is always 1998; January is 1st, 2nd, last day of the month. @@ -616,7 +620,7 @@ class Invoice extends EntityModel implements BalanceAffecting $monthVal = (int)date('n', $dueDateVal); $dayVal = (int)date('j', $dueDateVal); $dueDate = false; - + if($monthVal == 1) {// January; day of month $currentDay = (int)date('j', $now); $lastDayOfMonth = (int)date('t', $now); @@ -643,7 +647,7 @@ class Invoice extends EntityModel implements BalanceAffecting if($dueDay > $lastDayOfMonth){ // No later than the end of the month $dueDay = $lastDayOfMonth; - } + } } $dueDate = mktime(0, 0, 0, $dueMonth, $dueDay, $dueYear); @@ -672,7 +676,7 @@ class Invoice extends EntityModel implements BalanceAffecting return date('Y-m-d', strtotime('+'.$days.' day', $now)); } } - + // Couldn't calculate one return null; } @@ -690,11 +694,11 @@ class Invoice extends EntityModel implements BalanceAffecting $dateStart = $date->getStart(); $date = $this->account->formatDate($dateStart); $dueDate = $this->getDueDate($dateStart); - + if($dueDate) { $date .= ' (' . trans('texts.due') . ' ' . $this->account->formatDate($dueDate) . ')'; } - + $dates[] = $date; } @@ -808,16 +812,16 @@ class Invoice extends EntityModel implements BalanceAffecting $invitation = $this->invitations[0]; $link = $invitation->getLink('view', true); $key = env('PHANTOMJS_CLOUD_KEY'); - + if (Utils::isNinjaDev()) { $link = env('TEST_LINK'); } $url = "http://api.phantomjscloud.com/api/browser/v2/{$key}/?request=%7Burl:%22{$link}?phantomjs=true%22,renderType:%22html%22%7D"; - + $pdfString = file_get_contents($url); $pdfString = strip_tags($pdfString); - + if ( ! $pdfString || strlen($pdfString) < 200) { Utils::logError("PhantomJSCloud - failed to create pdf: {$pdfString}"); return false; @@ -870,14 +874,14 @@ class Invoice extends EntityModel implements BalanceAffecting return $total; } - // if $calculatePaid is true we'll loop through each payment to + // if $calculatePaid is true we'll loop through each payment to // determine the sum, otherwise we'll use the cached paid_to_date amount public function getTaxes($calculatePaid = false) { $taxes = []; $taxable = $this->getTaxable(); $paidAmount = $this->getAmountPaid($calculatePaid); - + if ($this->tax_name1) { $invoiceTaxAmount = round($taxable * ($this->tax_rate1 / 100), 2); $invoicePaidAmount = $this->amount && $invoiceTaxAmount ? ($paidAmount / $this->amount * $invoiceTaxAmount) : 0; @@ -892,7 +896,7 @@ class Invoice extends EntityModel implements BalanceAffecting foreach ($this->invoice_items as $invoiceItem) { $itemTaxAmount = $this->getItemTaxable($invoiceItem, $taxable); - + if ($invoiceItem->tax_name1) { $itemTaxAmount = round($taxable * ($invoiceItem->tax_rate1 / 100), 2); $itemPaidAmount = $this->amount && $itemTaxAmount ? ($paidAmount / $this->amount * $itemTaxAmount) : 0; @@ -905,20 +909,20 @@ class Invoice extends EntityModel implements BalanceAffecting $this->calculateTax($taxes, $invoiceItem->tax_name2, $invoiceItem->tax_rate2, $itemTaxAmount, $itemPaidAmount); } } - + return $taxes; } - - private function calculateTax(&$taxes, $name, $rate, $amount, $paid) - { + + private function calculateTax(&$taxes, $name, $rate, $amount, $paid) + { if ( ! $amount) { return; - } - + } + $amount = round($amount, 2); $paid = round($paid, 2); $key = $rate . ' ' . $name; - + if ( ! isset($taxes[$key])) { $taxes[$key] = [ 'name' => $name, @@ -929,14 +933,14 @@ class Invoice extends EntityModel implements BalanceAffecting } $taxes[$key]['amount'] += $amount; - $taxes[$key]['paid'] += $paid; + $taxes[$key]['paid'] += $paid; } - + public function hasDocuments(){ if(count($this->documents))return true; return $this->hasExpenseDocuments(); } - + public function hasExpenseDocuments(){ foreach($this->expenses as $expense){ if(count($expense->documents))return true; diff --git a/app/Ninja/Repositories/InvoiceRepository.php b/app/Ninja/Repositories/InvoiceRepository.php index 6a48c9a74921..290e22ed296c 100644 --- a/app/Ninja/Repositories/InvoiceRepository.php +++ b/app/Ninja/Repositories/InvoiceRepository.php @@ -210,7 +210,7 @@ class InvoiceRepository extends BaseRepository ->where('contacts.is_primary', '=', true) ->where('invoices.is_recurring', '=', false) // This needs to be a setting to also hide the activity on the dashboard page - //->where('invoices.invoice_status_id', '>=', INVOICE_STATUS_SENT) + //->where('invoices.invoice_status_id', '>=', INVOICE_STATUS_SENT) ->select( DB::raw('COALESCE(clients.currency_id, accounts.currency_id) currency_id'), DB::raw('COALESCE(clients.country_id, accounts.country_id) country_id'), @@ -287,7 +287,7 @@ class InvoiceRepository extends BaseRepository $account->invoice_footer = trim($data['invoice_footer']); } $account->save(); - } + } if (isset($data['invoice_number']) && !$invoice->is_recurring) { $invoice->invoice_number = trim($data['invoice_number']); @@ -329,7 +329,7 @@ class InvoiceRepository extends BaseRepository if ($invoice->auto_bill < AUTO_BILL_OFF || $invoice->auto_bill > AUTO_BILL_ALWAYS ) { $invoice->auto_bill = AUTO_BILL_OFF; } - + if (isset($data['recurring_due_date'])) { $invoice->due_date = $data['recurring_due_date']; } elseif (isset($data['due_date'])) { @@ -351,7 +351,7 @@ class InvoiceRepository extends BaseRepository } else { $invoice->terms = ''; } - + $invoice->invoice_footer = (isset($data['invoice_footer']) && trim($data['invoice_footer'])) ? trim($data['invoice_footer']) : (!$publicId && $account->invoice_footer ? $account->invoice_footer : ''); $invoice->public_notes = isset($data['public_notes']) ? trim($data['public_notes']) : null; @@ -370,8 +370,8 @@ class InvoiceRepository extends BaseRepository // provide backwards compatability if (isset($data['tax_name']) && isset($data['tax_rate'])) { - $data['tax_name1'] = $data['tax_name']; - $data['tax_rate1'] = $data['tax_rate']; + $data['tax_name1'] = $data['tax_name']; + $data['tax_rate1'] = $data['tax_rate']; } $total = 0; @@ -405,11 +405,11 @@ class InvoiceRepository extends BaseRepository } if (isset($item['tax_rate1']) && Utils::parseFloat($item['tax_rate1']) > 0) { - $invoiceItemTaxRate = Utils::parseFloat($item['tax_rate1']); + $invoiceItemTaxRate = Utils::parseFloat($item['tax_rate1']); $itemTax += round($lineTotal * $invoiceItemTaxRate / 100, 2); } if (isset($item['tax_rate2']) && Utils::parseFloat($item['tax_rate2']) > 0) { - $invoiceItemTaxRate = Utils::parseFloat($item['tax_rate2']); + $invoiceItemTaxRate = Utils::parseFloat($item['tax_rate2']); $itemTax += round($lineTotal * $invoiceItemTaxRate / 100, 2); } } @@ -453,7 +453,7 @@ class InvoiceRepository extends BaseRepository $taxAmount1 = round($total * $invoice->tax_rate1 / 100, 2); $taxAmount2 = round($total * $invoice->tax_rate2 / 100, 2); - $total = round($total + $taxAmount1 + $taxAmount2, 2); + $total = round($total + $taxAmount1 + $taxAmount2, 2); $total += $itemTax; // custom fields not charged taxes @@ -476,24 +476,24 @@ class InvoiceRepository extends BaseRepository if ($publicId) { $invoice->invoice_items()->forceDelete(); } - + $document_ids = !empty($data['document_ids'])?array_map('intval', $data['document_ids']):array();; foreach ($document_ids as $document_id){ $document = Document::scope($document_id)->first(); if($document && Auth::user()->can('edit', $document)){ - + if($document->invoice_id && $document->invoice_id != $invoice->id){ // From a clone $document = $document->cloneDocument(); $document_ids[] = $document->public_id;// Don't remove this document } - + $document->invoice_id = $invoice->id; $document->expense_id = null; $document->save(); } } - + if(!empty($data['documents']) && Auth::user()->can('create', ENTITY_DOCUMENT)){ // Fallback upload $doc_errors = array(); @@ -512,7 +512,7 @@ class InvoiceRepository extends BaseRepository Session::flash('error', implode('
',array_map('htmlentities',$doc_errors))); } } - + foreach ($invoice->documents as $document){ if(!in_array($document->public_id, $document_ids)){ // Removed @@ -586,12 +586,12 @@ class InvoiceRepository extends BaseRepository // provide backwards compatability if (isset($item['tax_name']) && isset($item['tax_rate'])) { - $item['tax_name1'] = $item['tax_name']; - $item['tax_rate1'] = $item['tax_rate']; + $item['tax_name1'] = $item['tax_name']; + $item['tax_rate1'] = $item['tax_rate']; } $invoiceItem->fill($item); - + $invoice->invoice_items()->save($invoiceItem); } @@ -675,9 +675,9 @@ class InvoiceRepository extends BaseRepository 'cost', 'qty', 'tax_name1', - 'tax_rate1', + 'tax_rate1', 'tax_name2', - 'tax_rate2', + 'tax_rate2', ] as $field) { $cloneItem->$field = $item->$field; } @@ -686,7 +686,7 @@ class InvoiceRepository extends BaseRepository } foreach ($invoice->documents as $document) { - $cloneDocument = $document->cloneDocument(); + $cloneDocument = $document->cloneDocument(); $invoice->documents()->save($cloneDocument); } @@ -731,8 +731,8 @@ class InvoiceRepository extends BaseRepository public function findOpenInvoices($clientId) { return Invoice::scope() + ->invoiceType(INVOICE_TYPE_STANDARD) ->whereClientId($clientId) - ->whereIsQuote(false) ->whereIsRecurring(false) ->whereDeletedAt(null) ->whereHasTasks(true) diff --git a/resources/views/invoices/view.blade.php b/resources/views/invoices/view.blade.php index 5c32210f0c80..096b7b74f765 100644 --- a/resources/views/invoices/view.blade.php +++ b/resources/views/invoices/view.blade.php @@ -4,15 +4,15 @@ @parent @include('money_script') - + @foreach ($invoice->client->account->getFontFolders() as $font) @endforeach - +