Fixes for is_quote

This commit is contained in:
Hillel Coren 2016-05-29 15:34:44 +03:00
parent 59d0a1cb80
commit a9302d4d01
3 changed files with 63 additions and 59 deletions

View File

@ -29,9 +29,9 @@ class Invoice extends EntityModel implements BalanceAffecting
'tax_name1', 'tax_name1',
'tax_rate1', 'tax_rate1',
'tax_name2', 'tax_name2',
'tax_rate2', 'tax_rate2',
]; ];
protected $casts = [ protected $casts = [
'is_recurring' => 'boolean', 'is_recurring' => 'boolean',
'has_tasks' => 'boolean', 'has_tasks' => 'boolean',
@ -243,6 +243,10 @@ class Invoice extends EntityModel implements BalanceAffecting
return $this->invoice_type_id == $typeId; return $this->invoice_type_id == $typeId;
} }
public function isQuote() {
return $this->isType(INVOICE_TYPE_QUOTE);
}
public function markInvitationsSent($notify = false) public function markInvitationsSent($notify = false)
{ {
foreach ($this->invitations as $invitation) { foreach ($this->invitations as $invitation) {
@ -524,12 +528,12 @@ class Invoice extends EntityModel implements BalanceAffecting
'name', 'name',
]); ]);
} }
foreach ($this->expenses as $expense) { foreach ($this->expenses as $expense) {
$expense->setVisible([ $expense->setVisible([
'documents', 'documents',
]); ]);
foreach ($expense->documents as $document) { foreach ($expense->documents as $document) {
$document->setVisible([ $document->setVisible([
'public_id', 'public_id',
@ -588,12 +592,12 @@ class Invoice extends EntityModel implements BalanceAffecting
return $schedule[1]->getStart(); return $schedule[1]->getStart();
} }
public function getDueDate($invoice_date = null){ public function getDueDate($invoice_date = null){
if(!$this->is_recurring) { if(!$this->is_recurring) {
return $this->due_date ? $this->due_date : null; return $this->due_date ? $this->due_date : null;
} }
else{ else{
$now = time(); $now = time();
if($invoice_date) { if($invoice_date) {
// If $invoice_date is specified, all calculations are based on that 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(); $now = $invoice_date->getTimestamp();
} }
} }
if($this->due_date && $this->due_date != '0000-00-00'){ if($this->due_date && $this->due_date != '0000-00-00'){
// This is a recurring invoice; we're using a custom format here. // 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. // 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); $monthVal = (int)date('n', $dueDateVal);
$dayVal = (int)date('j', $dueDateVal); $dayVal = (int)date('j', $dueDateVal);
$dueDate = false; $dueDate = false;
if($monthVal == 1) {// January; day of month if($monthVal == 1) {// January; day of month
$currentDay = (int)date('j', $now); $currentDay = (int)date('j', $now);
$lastDayOfMonth = (int)date('t', $now); $lastDayOfMonth = (int)date('t', $now);
@ -643,7 +647,7 @@ class Invoice extends EntityModel implements BalanceAffecting
if($dueDay > $lastDayOfMonth){ if($dueDay > $lastDayOfMonth){
// No later than the end of the month // No later than the end of the month
$dueDay = $lastDayOfMonth; $dueDay = $lastDayOfMonth;
} }
} }
$dueDate = mktime(0, 0, 0, $dueMonth, $dueDay, $dueYear); $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)); return date('Y-m-d', strtotime('+'.$days.' day', $now));
} }
} }
// Couldn't calculate one // Couldn't calculate one
return null; return null;
} }
@ -690,11 +694,11 @@ class Invoice extends EntityModel implements BalanceAffecting
$dateStart = $date->getStart(); $dateStart = $date->getStart();
$date = $this->account->formatDate($dateStart); $date = $this->account->formatDate($dateStart);
$dueDate = $this->getDueDate($dateStart); $dueDate = $this->getDueDate($dateStart);
if($dueDate) { if($dueDate) {
$date .= ' <small>(' . trans('texts.due') . ' ' . $this->account->formatDate($dueDate) . ')</small>'; $date .= ' <small>(' . trans('texts.due') . ' ' . $this->account->formatDate($dueDate) . ')</small>';
} }
$dates[] = $date; $dates[] = $date;
} }
@ -808,16 +812,16 @@ class Invoice extends EntityModel implements BalanceAffecting
$invitation = $this->invitations[0]; $invitation = $this->invitations[0];
$link = $invitation->getLink('view', true); $link = $invitation->getLink('view', true);
$key = env('PHANTOMJS_CLOUD_KEY'); $key = env('PHANTOMJS_CLOUD_KEY');
if (Utils::isNinjaDev()) { if (Utils::isNinjaDev()) {
$link = env('TEST_LINK'); $link = env('TEST_LINK');
} }
$url = "http://api.phantomjscloud.com/api/browser/v2/{$key}/?request=%7Burl:%22{$link}?phantomjs=true%22,renderType:%22html%22%7D"; $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 = file_get_contents($url);
$pdfString = strip_tags($pdfString); $pdfString = strip_tags($pdfString);
if ( ! $pdfString || strlen($pdfString) < 200) { if ( ! $pdfString || strlen($pdfString) < 200) {
Utils::logError("PhantomJSCloud - failed to create pdf: {$pdfString}"); Utils::logError("PhantomJSCloud - failed to create pdf: {$pdfString}");
return false; return false;
@ -870,14 +874,14 @@ class Invoice extends EntityModel implements BalanceAffecting
return $total; 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 // determine the sum, otherwise we'll use the cached paid_to_date amount
public function getTaxes($calculatePaid = false) public function getTaxes($calculatePaid = false)
{ {
$taxes = []; $taxes = [];
$taxable = $this->getTaxable(); $taxable = $this->getTaxable();
$paidAmount = $this->getAmountPaid($calculatePaid); $paidAmount = $this->getAmountPaid($calculatePaid);
if ($this->tax_name1) { if ($this->tax_name1) {
$invoiceTaxAmount = round($taxable * ($this->tax_rate1 / 100), 2); $invoiceTaxAmount = round($taxable * ($this->tax_rate1 / 100), 2);
$invoicePaidAmount = $this->amount && $invoiceTaxAmount ? ($paidAmount / $this->amount * $invoiceTaxAmount) : 0; $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) { foreach ($this->invoice_items as $invoiceItem) {
$itemTaxAmount = $this->getItemTaxable($invoiceItem, $taxable); $itemTaxAmount = $this->getItemTaxable($invoiceItem, $taxable);
if ($invoiceItem->tax_name1) { if ($invoiceItem->tax_name1) {
$itemTaxAmount = round($taxable * ($invoiceItem->tax_rate1 / 100), 2); $itemTaxAmount = round($taxable * ($invoiceItem->tax_rate1 / 100), 2);
$itemPaidAmount = $this->amount && $itemTaxAmount ? ($paidAmount / $this->amount * $itemTaxAmount) : 0; $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); $this->calculateTax($taxes, $invoiceItem->tax_name2, $invoiceItem->tax_rate2, $itemTaxAmount, $itemPaidAmount);
} }
} }
return $taxes; return $taxes;
} }
private function calculateTax(&$taxes, $name, $rate, $amount, $paid) private function calculateTax(&$taxes, $name, $rate, $amount, $paid)
{ {
if ( ! $amount) { if ( ! $amount) {
return; return;
} }
$amount = round($amount, 2); $amount = round($amount, 2);
$paid = round($paid, 2); $paid = round($paid, 2);
$key = $rate . ' ' . $name; $key = $rate . ' ' . $name;
if ( ! isset($taxes[$key])) { if ( ! isset($taxes[$key])) {
$taxes[$key] = [ $taxes[$key] = [
'name' => $name, 'name' => $name,
@ -929,14 +933,14 @@ class Invoice extends EntityModel implements BalanceAffecting
} }
$taxes[$key]['amount'] += $amount; $taxes[$key]['amount'] += $amount;
$taxes[$key]['paid'] += $paid; $taxes[$key]['paid'] += $paid;
} }
public function hasDocuments(){ public function hasDocuments(){
if(count($this->documents))return true; if(count($this->documents))return true;
return $this->hasExpenseDocuments(); return $this->hasExpenseDocuments();
} }
public function hasExpenseDocuments(){ public function hasExpenseDocuments(){
foreach($this->expenses as $expense){ foreach($this->expenses as $expense){
if(count($expense->documents))return true; if(count($expense->documents))return true;

View File

@ -210,7 +210,7 @@ class InvoiceRepository extends BaseRepository
->where('contacts.is_primary', '=', true) ->where('contacts.is_primary', '=', true)
->where('invoices.is_recurring', '=', false) ->where('invoices.is_recurring', '=', false)
// This needs to be a setting to also hide the activity on the dashboard page // 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( ->select(
DB::raw('COALESCE(clients.currency_id, accounts.currency_id) currency_id'), DB::raw('COALESCE(clients.currency_id, accounts.currency_id) currency_id'),
DB::raw('COALESCE(clients.country_id, accounts.country_id) country_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->invoice_footer = trim($data['invoice_footer']);
} }
$account->save(); $account->save();
} }
if (isset($data['invoice_number']) && !$invoice->is_recurring) { if (isset($data['invoice_number']) && !$invoice->is_recurring) {
$invoice->invoice_number = trim($data['invoice_number']); $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 ) { if ($invoice->auto_bill < AUTO_BILL_OFF || $invoice->auto_bill > AUTO_BILL_ALWAYS ) {
$invoice->auto_bill = AUTO_BILL_OFF; $invoice->auto_bill = AUTO_BILL_OFF;
} }
if (isset($data['recurring_due_date'])) { if (isset($data['recurring_due_date'])) {
$invoice->due_date = $data['recurring_due_date']; $invoice->due_date = $data['recurring_due_date'];
} elseif (isset($data['due_date'])) { } elseif (isset($data['due_date'])) {
@ -351,7 +351,7 @@ class InvoiceRepository extends BaseRepository
} else { } else {
$invoice->terms = ''; $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->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; $invoice->public_notes = isset($data['public_notes']) ? trim($data['public_notes']) : null;
@ -370,8 +370,8 @@ class InvoiceRepository extends BaseRepository
// provide backwards compatability // provide backwards compatability
if (isset($data['tax_name']) && isset($data['tax_rate'])) { if (isset($data['tax_name']) && isset($data['tax_rate'])) {
$data['tax_name1'] = $data['tax_name']; $data['tax_name1'] = $data['tax_name'];
$data['tax_rate1'] = $data['tax_rate']; $data['tax_rate1'] = $data['tax_rate'];
} }
$total = 0; $total = 0;
@ -405,11 +405,11 @@ class InvoiceRepository extends BaseRepository
} }
if (isset($item['tax_rate1']) && Utils::parseFloat($item['tax_rate1']) > 0) { 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); $itemTax += round($lineTotal * $invoiceItemTaxRate / 100, 2);
} }
if (isset($item['tax_rate2']) && Utils::parseFloat($item['tax_rate2']) > 0) { 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); $itemTax += round($lineTotal * $invoiceItemTaxRate / 100, 2);
} }
} }
@ -453,7 +453,7 @@ class InvoiceRepository extends BaseRepository
$taxAmount1 = round($total * $invoice->tax_rate1 / 100, 2); $taxAmount1 = round($total * $invoice->tax_rate1 / 100, 2);
$taxAmount2 = round($total * $invoice->tax_rate2 / 100, 2); $taxAmount2 = round($total * $invoice->tax_rate2 / 100, 2);
$total = round($total + $taxAmount1 + $taxAmount2, 2); $total = round($total + $taxAmount1 + $taxAmount2, 2);
$total += $itemTax; $total += $itemTax;
// custom fields not charged taxes // custom fields not charged taxes
@ -476,24 +476,24 @@ class InvoiceRepository extends BaseRepository
if ($publicId) { if ($publicId) {
$invoice->invoice_items()->forceDelete(); $invoice->invoice_items()->forceDelete();
} }
$document_ids = !empty($data['document_ids'])?array_map('intval', $data['document_ids']):array();; $document_ids = !empty($data['document_ids'])?array_map('intval', $data['document_ids']):array();;
foreach ($document_ids as $document_id){ foreach ($document_ids as $document_id){
$document = Document::scope($document_id)->first(); $document = Document::scope($document_id)->first();
if($document && Auth::user()->can('edit', $document)){ if($document && Auth::user()->can('edit', $document)){
if($document->invoice_id && $document->invoice_id != $invoice->id){ if($document->invoice_id && $document->invoice_id != $invoice->id){
// From a clone // From a clone
$document = $document->cloneDocument(); $document = $document->cloneDocument();
$document_ids[] = $document->public_id;// Don't remove this document $document_ids[] = $document->public_id;// Don't remove this document
} }
$document->invoice_id = $invoice->id; $document->invoice_id = $invoice->id;
$document->expense_id = null; $document->expense_id = null;
$document->save(); $document->save();
} }
} }
if(!empty($data['documents']) && Auth::user()->can('create', ENTITY_DOCUMENT)){ if(!empty($data['documents']) && Auth::user()->can('create', ENTITY_DOCUMENT)){
// Fallback upload // Fallback upload
$doc_errors = array(); $doc_errors = array();
@ -512,7 +512,7 @@ class InvoiceRepository extends BaseRepository
Session::flash('error', implode('<br>',array_map('htmlentities',$doc_errors))); Session::flash('error', implode('<br>',array_map('htmlentities',$doc_errors)));
} }
} }
foreach ($invoice->documents as $document){ foreach ($invoice->documents as $document){
if(!in_array($document->public_id, $document_ids)){ if(!in_array($document->public_id, $document_ids)){
// Removed // Removed
@ -586,12 +586,12 @@ class InvoiceRepository extends BaseRepository
// provide backwards compatability // provide backwards compatability
if (isset($item['tax_name']) && isset($item['tax_rate'])) { if (isset($item['tax_name']) && isset($item['tax_rate'])) {
$item['tax_name1'] = $item['tax_name']; $item['tax_name1'] = $item['tax_name'];
$item['tax_rate1'] = $item['tax_rate']; $item['tax_rate1'] = $item['tax_rate'];
} }
$invoiceItem->fill($item); $invoiceItem->fill($item);
$invoice->invoice_items()->save($invoiceItem); $invoice->invoice_items()->save($invoiceItem);
} }
@ -675,9 +675,9 @@ class InvoiceRepository extends BaseRepository
'cost', 'cost',
'qty', 'qty',
'tax_name1', 'tax_name1',
'tax_rate1', 'tax_rate1',
'tax_name2', 'tax_name2',
'tax_rate2', 'tax_rate2',
] as $field) { ] as $field) {
$cloneItem->$field = $item->$field; $cloneItem->$field = $item->$field;
} }
@ -686,7 +686,7 @@ class InvoiceRepository extends BaseRepository
} }
foreach ($invoice->documents as $document) { foreach ($invoice->documents as $document) {
$cloneDocument = $document->cloneDocument(); $cloneDocument = $document->cloneDocument();
$invoice->documents()->save($cloneDocument); $invoice->documents()->save($cloneDocument);
} }
@ -731,8 +731,8 @@ class InvoiceRepository extends BaseRepository
public function findOpenInvoices($clientId) public function findOpenInvoices($clientId)
{ {
return Invoice::scope() return Invoice::scope()
->invoiceType(INVOICE_TYPE_STANDARD)
->whereClientId($clientId) ->whereClientId($clientId)
->whereIsQuote(false)
->whereIsRecurring(false) ->whereIsRecurring(false)
->whereDeletedAt(null) ->whereDeletedAt(null)
->whereHasTasks(true) ->whereHasTasks(true)

View File

@ -4,15 +4,15 @@
@parent @parent
@include('money_script') @include('money_script')
@foreach ($invoice->client->account->getFontFolders() as $font) @foreach ($invoice->client->account->getFontFolders() as $font)
<script src="{{ asset('js/vfs_fonts/'.$font.'.js') }}" type="text/javascript"></script> <script src="{{ asset('js/vfs_fonts/'.$font.'.js') }}" type="text/javascript"></script>
@endforeach @endforeach
<script src="{{ asset('pdf.built.js') }}" type="text/javascript"></script> <script src="{{ asset('pdf.built.js') }}" type="text/javascript"></script>
<style type="text/css"> <style type="text/css">
body { body {
background-color: #f8f8f8; background-color: #f8f8f8;
} }
.dropdown-menu li a{ .dropdown-menu li a{
@ -70,7 +70,7 @@
@include('partials.checkout_com_payment') @include('partials.checkout_com_payment')
@else @else
<div class="pull-right" style="text-align:right"> <div class="pull-right" style="text-align:right">
@if ($invoice->is_quote) @if ($invoice->isQuote())
{!! Button::normal(trans('texts.download_pdf'))->withAttributes(['onclick' => 'onDownloadClick()'])->large() !!}&nbsp;&nbsp; {!! Button::normal(trans('texts.download_pdf'))->withAttributes(['onclick' => 'onDownloadClick()'])->large() !!}&nbsp;&nbsp;
@if ($showApprove) @if ($showApprove)
{!! Button::success(trans('texts.approve'))->asLinkTo(URL::to('/approve/' . $invitation->invitation_key))->large() !!} {!! Button::success(trans('texts.approve'))->asLinkTo(URL::to('/approve/' . $invitation->invitation_key))->large() !!}
@ -81,7 +81,7 @@
{!! DropdownButton::success(trans('texts.pay_now'))->withContents($paymentTypes)->large() !!} {!! DropdownButton::success(trans('texts.pay_now'))->withContents($paymentTypes)->large() !!}
@else @else
<a href='{!! $paymentURL !!}' class="btn btn-success btn-lg">{{ trans('texts.pay_now') }}</a> <a href='{!! $paymentURL !!}' class="btn btn-success btn-lg">{{ trans('texts.pay_now') }}</a>
@endif @endif
@else @else
{!! Button::normal(trans('texts.download_pdf'))->withAttributes(['onclick' => 'onDownloadClick()'])->large() !!} {!! Button::normal(trans('texts.download_pdf'))->withAttributes(['onclick' => 'onDownloadClick()'])->large() !!}
@if ($account->isNinjaAccount()) @if ($account->isNinjaAccount())
@ -112,7 +112,7 @@
</ul> </ul>
</div> </div>
@endif @endif
@if ($account->hasFeature(FEATURE_DOCUMENTS) && $account->invoice_embed_documents) @if ($account->hasFeature(FEATURE_DOCUMENTS) && $account->invoice_embed_documents)
@foreach ($invoice->documents as $document) @foreach ($invoice->documents as $document)
@if($document->isPDFEmbeddable()) @if($document->isPDFEmbeddable())
@ -135,7 +135,7 @@
remove_created_by:{{ $invoice->client->account->hasFeature(FEATURE_REMOVE_CREATED_BY) ? 'true' : 'false' }}, remove_created_by:{{ $invoice->client->account->hasFeature(FEATURE_REMOVE_CREATED_BY) ? 'true' : 'false' }},
invoice_settings:{{ $invoice->client->account->hasFeature(FEATURE_INVOICE_SETTINGS) ? 'true' : 'false' }} invoice_settings:{{ $invoice->client->account->hasFeature(FEATURE_INVOICE_SETTINGS) ? 'true' : 'false' }}
}; };
invoice.is_quote = {{ $invoice->is_quote ? 'true' : 'false' }}; invoice.is_quote = {{ $invoice->isQuote() ? 'true' : 'false' }};
invoice.contact = {!! $contact->toJson() !!}; invoice.contact = {!! $contact->toJson() !!};
function getPDFString(cb) { function getPDFString(cb) {
@ -152,16 +152,16 @@
doc.getDataUrl(function(pdfString) { doc.getDataUrl(function(pdfString) {
document.write(pdfString); document.write(pdfString);
document.close(); document.close();
if (window.hasOwnProperty('pjsc_meta')) { if (window.hasOwnProperty('pjsc_meta')) {
window['pjsc_meta'].remainingTasks--; window['pjsc_meta'].remainingTasks--;
} }
}); });
@else @else
refreshPDF(); refreshPDF();
@endif @endif
}); });
function onDownloadClick() { function onDownloadClick() {
var doc = generatePDF(invoice, invoice.invoice_design.javascript, true); var doc = generatePDF(invoice, invoice.invoice_design.javascript, true);
var fileName = invoice.is_quote ? invoiceLabels.quote : invoiceLabels.invoice; var fileName = invoice.is_quote ? invoiceLabels.quote : invoiceLabels.invoice;