mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-07 17:34:29 -04:00
bug fixes
This commit is contained in:
parent
fff1aa69d3
commit
f0bf0a52ec
@ -317,6 +317,7 @@ class InvoiceController extends \BaseController {
|
||||
$data = array(
|
||||
'account' => $invoice->account,
|
||||
'invoice' => $invoice,
|
||||
'data' => false,
|
||||
'method' => 'PUT',
|
||||
'invitationContactIds' => $contactIds,
|
||||
'url' => 'invoices/' . $publicId,
|
||||
@ -338,13 +339,13 @@ class InvoiceController extends \BaseController {
|
||||
|
||||
$data = array(
|
||||
'account' => $account,
|
||||
'invoice' => null,
|
||||
'invoice' => null,
|
||||
'data' => Input::old('data'),
|
||||
'invoiceNumber' => $invoiceNumber,
|
||||
'method' => 'POST',
|
||||
'url' => 'invoices',
|
||||
'title' => '- New Invoice',
|
||||
'client' => $client,
|
||||
'items' => json_decode(Input::old('items')));
|
||||
'client' => $client);
|
||||
$data = array_merge($data, InvoiceController::getViewModel());
|
||||
return View::make('invoices.edit', $data);
|
||||
}
|
||||
@ -393,20 +394,21 @@ class InvoiceController extends \BaseController {
|
||||
}
|
||||
|
||||
$input = json_decode(Input::get('data'));
|
||||
|
||||
if (!$input->client->contacts[0]->email)
|
||||
$invoice = $input->invoice;
|
||||
|
||||
if ($errors = $this->invoiceRepo->getErrors($invoice))
|
||||
{
|
||||
return Redirect::to('invoices/create')
|
||||
->withInput();
|
||||
->withInput()->withErrors($errors);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->taxRateRepo->save($input->tax_rates);
|
||||
|
||||
$clientData = (array) $input->client;
|
||||
$client = $this->clientRepo->save($input->client->public_id, $clientData);
|
||||
|
||||
$invoiceData = (array) $input;
|
||||
$clientData = (array) $invoice->client;
|
||||
$client = $this->clientRepo->save($invoice->client->public_id, $clientData);
|
||||
|
||||
$invoiceData = (array) $invoice;
|
||||
$invoiceData['client_id'] = $client->id;
|
||||
$invoice = $this->invoiceRepo->save($publicId, $invoiceData);
|
||||
|
||||
@ -454,7 +456,7 @@ class InvoiceController extends \BaseController {
|
||||
}
|
||||
|
||||
$message = '';
|
||||
if ($input->client->public_id == '-1')
|
||||
if ($input->invoice->client->public_id == '-1')
|
||||
{
|
||||
$message = ' and created client';
|
||||
$url = URL::to('clients/' . $client->public_id);
|
||||
|
@ -321,6 +321,7 @@ class ConfideSetupUsersTable extends Migration {
|
||||
|
||||
$t->unsignedInteger('public_id')->index();
|
||||
$t->unique( array('account_id','public_id') );
|
||||
$t->unique( array('account_id','invoice_number') );
|
||||
});
|
||||
|
||||
|
||||
|
@ -68,6 +68,29 @@ class InvoiceRepository
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function getErrors($input)
|
||||
{
|
||||
$contact = (array) $input->client->contacts[0];
|
||||
$rules = ['email' => 'required|email'];
|
||||
$validator = \Validator::make($contact, $rules);
|
||||
|
||||
if ($validator->fails())
|
||||
{
|
||||
return $validator;
|
||||
}
|
||||
|
||||
$invoice = (array) $input;
|
||||
$rules = ['invoice_number' => 'unique:invoices,invoice_number,' . $input->id];
|
||||
$validator = \Validator::make($invoice, $rules);
|
||||
|
||||
if ($validator->fails())
|
||||
{
|
||||
return $validator;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function save($publicId, $data)
|
||||
{
|
||||
if ($publicId)
|
||||
@ -94,10 +117,10 @@ class InvoiceRepository
|
||||
$invoice->po_number = trim($data['po_number']);
|
||||
$invoice->currency_id = $data['currency_id'];
|
||||
|
||||
if (isset($data['tax']) && isset($data['tax']->rate) && floatval($data['tax']->rate) > 0)
|
||||
if (isset($data['tax_rate']) && floatval($data['tax_rate']) > 0)
|
||||
{
|
||||
$invoice->tax_rate = floatval($data['tax']->rate);
|
||||
$invoice->tax_name = trim($data['tax']->name);
|
||||
$invoice->tax_rate = floatval($data['tax_rate']);
|
||||
$invoice->tax_name = trim($data['tax_name']);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -144,10 +167,10 @@ class InvoiceRepository
|
||||
$invoiceItem->qty = floatval($item->qty);
|
||||
$invoiceItem->tax_rate = 0;
|
||||
|
||||
if ($item->tax && isset($item->tax->rate) && floatval($item->tax->rate) > 0)
|
||||
if (isset($item->tax_rate) && floatval($item->tax_rate) > 0)
|
||||
{
|
||||
$invoiceItem->tax_rate = floatval($item->tax->rate);
|
||||
$invoiceItem->tax_name = trim($item->tax->name);
|
||||
$invoiceItem->tax_rate = floatval($item->tax_rate);
|
||||
$invoiceItem->tax_name = trim($item->tax_name);
|
||||
}
|
||||
|
||||
$invoice->invoice_items()->save($invoiceItem);
|
||||
|
@ -10,7 +10,7 @@ class TaxRateRepository
|
||||
|
||||
foreach ($taxRates as $record)
|
||||
{
|
||||
if (!isset($record->rate) || $record->is_deleted)
|
||||
if (!isset($record->rate) || (isset($record->is_deleted) && $record->is_deleted))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
include_once(app_path().'/libraries/utils.php'); // TODO_FIX
|
||||
include_once(app_path().'/handlers/UserEventHandler.php'); // TODO_FIX
|
||||
|
||||
|
||||
Route::get('/send_emails', function() {
|
||||
Artisan::call('ninja:send-invoices');
|
||||
});
|
||||
@ -172,4 +173,9 @@ define('DEFAULT_CURRENCY', 1); // US Dollar
|
||||
define('DEFAULT_DATE_FORMAT', 'M j, Y');
|
||||
define('DEFAULT_DATE_PICKER_FORMAT', 'M d, yyyy');
|
||||
define('DEFAULT_DATETIME_FORMAT', 'F j, Y, g:i a');
|
||||
define('DEFAULT_QUERY_CACHE', 120);
|
||||
define('DEFAULT_QUERY_CACHE', 120);
|
||||
|
||||
|
||||
if (Auth::check() && !Session::has(SESSION_TIMEZONE)) {
|
||||
Event::fire('user.refresh');
|
||||
}
|
@ -9,14 +9,16 @@
|
||||
|
||||
@section('content')
|
||||
|
||||
|
||||
<p> </p>
|
||||
|
||||
{{ Former::open($url)->method($method)->addClass('main_form')->rules(array(
|
||||
'client' => 'required',
|
||||
'email' => 'required',
|
||||
'product_key' => 'max:14',
|
||||
)); }}
|
||||
)); }}
|
||||
|
||||
<div data-bind="with: invoice">
|
||||
<div class="row" style="min-height:195px" onkeypress="formEnterClick(event)">
|
||||
<div class="col-md-5" id="col_1">
|
||||
|
||||
@ -24,7 +26,7 @@
|
||||
<div class="form-group">
|
||||
<label for="client" class="control-label col-lg-4 col-sm-4">Client</label>
|
||||
<div class="col-lg-8 col-sm-8" style="padding-top: 7px">
|
||||
<a href="#" data-bind="click: showClientForm">{{ $client->getDisplayName() }}</a>
|
||||
<a href="#" data-bind="click: $root.showClientForm">{{ $client->getDisplayName() }}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display:none">
|
||||
@ -35,7 +37,7 @@
|
||||
|
||||
<div class="form-group" style="margin-bottom: 8px">
|
||||
<div class="col-lg-8 col-sm-8 col-lg-offset-4 col-sm-offset-4">
|
||||
<a href="#" data-bind="click: showClientForm, text: showClientText"></a>
|
||||
<a href="#" data-bind="click: $root.showClientForm, text: client.linkText"></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -48,7 +50,7 @@
|
||||
<div class="col-lg-8 col-lg-offset-4">
|
||||
<label for="test" class="checkbox" data-bind="attr: {for: $index() + '_check'}">
|
||||
<input type="checkbox" value="1" data-bind="checked: send_invoice, attr: {id: $index() + '_check'}">
|
||||
<span data-bind="text: displayName"/>
|
||||
<span data-bind="text: email.display"/>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
@ -89,7 +91,7 @@
|
||||
<div class="form-group" style="margin-bottom: 8px">
|
||||
<label for="recurring" class="control-label col-lg-4 col-sm-4">Taxes</label>
|
||||
<div class="col-lg-8 col-sm-8" style="padding-top: 7px">
|
||||
<a href="#" data-bind="click: showTaxesForm">Manage taxe rates</a>
|
||||
<a href="#" data-bind="click: $root.showTaxesForm">Manage taxe rates</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -98,7 +100,7 @@
|
||||
|
||||
<p> </p>
|
||||
|
||||
{{ Former::hidden('data')->data_bind("value: ko.toJSON(model)") }}
|
||||
{{ Former::hidden('data')->data_bind("value: ko.mapping.toJSON(model)") }}
|
||||
|
||||
<table class="table invoice-table" style="margin-bottom: 0px !important">
|
||||
<thead>
|
||||
@ -108,7 +110,7 @@
|
||||
<th>Description</th>
|
||||
<th>Unit Cost</th>
|
||||
<th>Quantity</th>
|
||||
<th data-bind="visible: showInvoiceItemTaxes">Tax</th>
|
||||
<th data-bind="visible: $root.invoice_item_taxes.show">Tax</th>
|
||||
<th>Line Total</th>
|
||||
<th class="hide-border"></th>
|
||||
</tr>
|
||||
@ -131,11 +133,11 @@
|
||||
<td style="min-width:120px">
|
||||
<input onkeyup="onItemChange()" data-bind="value: prettyQty, valueUpdate: 'afterkeydown'" style="text-align: right" class="form-control"//>
|
||||
</td>
|
||||
<td style="min-width:120px; vertical-align:middle" data-bind="visible: $parent.showInvoiceItemTaxes">
|
||||
<select class="form-control" style="width:100%" data-bind="value: tax, options: $parent.tax_rates, optionsText: 'displayName'"></select>
|
||||
<td style="min-width:120px; vertical-align:middle" data-bind="visible: $root.invoice_item_taxes.show">
|
||||
<select class="form-control" style="width:100%" data-bind="value: tax, options: $root.tax_rates, optionsText: 'displayName'"></select>
|
||||
</td>
|
||||
<td style="min-width:120px;text-align: right;padding-top:9px !important">
|
||||
<span data-bind="text: total"></span>
|
||||
<span data-bind="text: totals.total"></span>
|
||||
</td>
|
||||
<td style="min-width:20px; cursor:pointer" class="hide-border td-icon">
|
||||
<i data-bind="click: $parent.removeItem, visible: actionsVisible() && $parent.invoice_items().length > 1" class="fa fa-minus-circle" title="Remove item"/>
|
||||
@ -146,34 +148,34 @@
|
||||
<tr>
|
||||
<td class="hide-border"/>
|
||||
<td colspan="2"/>
|
||||
<td data-bind="visible: showInvoiceItemTaxes"/>
|
||||
<td data-bind="visible: $root.invoice_item_taxes.show"/>
|
||||
<td colspan="2">Subtotal</td>
|
||||
<td style="text-align: right"><span data-bind="text: subtotal"/></td>
|
||||
<td style="text-align: right"><span data-bind="text: totals.subtotal"/></td>
|
||||
</tr>
|
||||
<tr data-bind="visible: discount() > 0">
|
||||
<td class="hide-border" colspan="3"/>
|
||||
<td class="hide-border" data-bind="visible: showInvoiceItemTaxes"/>
|
||||
<td class="hide-border" data-bind="visible: $root.invoice_item_taxes.show"/>
|
||||
<td colspan="2">Discount</td>
|
||||
<td style="text-align: right"><span data-bind="text: discounted"/></td>
|
||||
<td style="text-align: right"><span data-bind="text: totals.discounted"/></td>
|
||||
</tr>
|
||||
<tr data-bind="visible: showInvoiceTaxes">
|
||||
<tr data-bind="visible: $root.invoice_taxes.show">
|
||||
<td class="hide-border" colspan="3"/>
|
||||
<td class="hide-border" data-bind="visible: showInvoiceItemTaxes"/>
|
||||
<td class="hide-border" data-bind="visible: $root.invoice_item_taxes.show"/>
|
||||
<td style="vertical-align: middle">Tax</td>
|
||||
<td><select class="form-control" style="width:100%" data-bind="value: tax, options: tax_rates, optionsText: 'displayName'"></select></td>
|
||||
<td style="vertical-align: middle; text-align: right"><span data-bind="text: taxAmount"/></td>
|
||||
<td><select class="form-control" style="width:100%" data-bind="value: tax, options: $root.tax_rates, optionsText: 'displayName'"></select></td>
|
||||
<td style="vertical-align: middle; text-align: right"><span data-bind="text: totals.taxAmount"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="hide-border" colspan="3"/>
|
||||
<td class="hide-border" data-bind="visible: showInvoiceItemTaxes"/>
|
||||
<td class="hide-border" data-bind="visible: $root.invoice_item_taxes.show"/>
|
||||
<td colspan="2">Paid to Date</td>
|
||||
<td style="text-align: right"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="hide-border" colspan="3"/>
|
||||
<td class="hide-border" data-bind="visible: showInvoiceItemTaxes"/>
|
||||
<td class="hide-border" data-bind="visible: $root.invoice_item_taxes.show"/>
|
||||
<td colspan="2"><b>Balance Due</b></td>
|
||||
<td style="text-align: right"><span data-bind="text: total"/></td>
|
||||
<td style="text-align: right"><span data-bind="text: totals.total"/></td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
@ -183,8 +185,9 @@
|
||||
|
||||
<div style="display:none">
|
||||
{{ Former::text('action') }}
|
||||
@if ($invoice)
|
||||
@if ($invoice)
|
||||
{{ Former::text('id') }}
|
||||
{{ Former::populateField('id', $invoice->id) }}
|
||||
@endif
|
||||
</div>
|
||||
|
||||
@ -202,12 +205,12 @@
|
||||
array('Delete Invoice', "javascript:onDeleteClick()"),
|
||||
)
|
||||
)
|
||||
, array('id'=>'actionDropDown', 'style'=>'text-align:left', 'data-bind'=>'css: saveButtonEnabled'))->split(); }}
|
||||
, array('id'=>'actionDropDown', 'style'=>'text-align:left', 'data-bind'=>'css: enable.save'))->split(); }}
|
||||
@else
|
||||
{{ Button::primary_submit('Save Invoice', array('data-bind'=>'css: saveButtonEnabled')) }}
|
||||
{{ Button::primary_submit('Save Invoice', array('data-bind'=>'css: enable.save')) }}
|
||||
@endif
|
||||
|
||||
{{ Button::primary('Send Email', array('id' => 'email_button', 'onclick' => 'onEmailClick()', 'data-bind' => 'css: emailButtonEnabled')) }}
|
||||
{{ Button::primary('Send Email', array('id' => 'email_button', 'onclick' => 'onEmailClick()', 'data-bind' => 'css: enable.email')) }}
|
||||
</div>
|
||||
<p> </p>
|
||||
|
||||
@ -253,7 +256,7 @@
|
||||
</div>
|
||||
|
||||
{{ Former::legend('Additional Info') }}
|
||||
{{ Former::select('payment_terms')->addOption('','')->data_bind('value: payment_terms')
|
||||
{{ Former::select('payment_terms')->addOption('','0')->data_bind('value: payment_terms')
|
||||
->fromQuery($paymentTerms, 'name', 'num_days') }}
|
||||
{{ Former::select('currency_id')->addOption('','')->label('Currency')->data_bind('value: currency_id')
|
||||
->fromQuery($currencies, 'name', 'id') }}
|
||||
@ -289,7 +292,7 @@
|
||||
<div class="modal-footer" style="margin-top: 0px">
|
||||
<span class="error-block" id="emailError" style="display:none;float:left;font-weight:bold">Please provide a valid email address.</span><span> </span>
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
|
||||
<button type="button" class="btn btn-primary" data-bind="click: clientFormComplete">Done</button>
|
||||
<button type="button" class="btn btn-primary" data-bind="click: $root.clientFormComplete">Done</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@ -314,7 +317,7 @@
|
||||
<th class="hide-border"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody data-bind="foreach: tax_rates">
|
||||
<tbody data-bind="foreach: $root.tax_rates.filtered">
|
||||
<tr data-bind="event: { mouseover: showActions, mouseout: hideActions }">
|
||||
<td style="width:10px" class="hide-border"></td>
|
||||
<td style="width:60px">
|
||||
@ -324,7 +327,7 @@
|
||||
<input onkeyup="onTaxRateChange()" data-bind="value: prettyRate, valueUpdate: 'afterkeydown'" style="text-align: right" class="form-control" onchange="refreshPDF()"//>
|
||||
</td>
|
||||
<td style="width:10px; cursor:pointer" class="hide-border td-icon">
|
||||
<i data-bind="click: $parent.removeTaxRate, visible: actionsVisible() && $parent.tax_rates().length > 1" class="fa fa-minus-circle" title="Remove item"/>
|
||||
<i data-bind="click: $root.removeTaxRate, visible: actionsVisible() && $root.tax_rates().length > 1" class="fa fa-minus-circle" title="Remove item"/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@ -332,15 +335,15 @@
|
||||
|
||||
|
||||
{{ Former::checkbox('invoice_taxes')->text('Enable specifying an <b>invoice tax</b>')
|
||||
->label('Settings')->data_bind('checked: invoice_taxes, enable: tax_rates().length > 1') }}
|
||||
->label('Settings')->data_bind('checked: $root.invoice_taxes, enable: $root.tax_rates().length > 1') }}
|
||||
{{ Former::checkbox('invoice_item_taxes')->text('Enable specifying <b>line item taxes</b>')
|
||||
->label(' ')->data_bind('checked: invoice_item_taxes, enable: tax_rates().length > 1') }}
|
||||
->label(' ')->data_bind('checked: $root.invoice_item_taxes, enable: $root.tax_rates().length > 1') }}
|
||||
|
||||
</div>
|
||||
|
||||
<div class="modal-footer" style="margin-top: 0px">
|
||||
<!-- <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button> -->
|
||||
<button type="button" class="btn btn-primary" data-bind="click: taxFormComplete">Done</button>
|
||||
<button type="button" class="btn btn-primary" data-bind="click: $root.taxFormComplete">Done</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@ -349,6 +352,7 @@
|
||||
|
||||
|
||||
{{ Former::close() }}
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
@ -463,7 +467,7 @@
|
||||
}
|
||||
|
||||
function createInvoiceModel() {
|
||||
var invoice = ko.toJS(model);
|
||||
var invoice = ko.toJS(model).invoice;
|
||||
@if (file_exists($account->getLogoPath()))
|
||||
invoice.image = "{{ HTML::image_data($account->getLogoPath()) }}";
|
||||
invoice.imageWidth = {{ $account->getLogoWidth() }};
|
||||
@ -573,192 +577,61 @@
|
||||
}
|
||||
}
|
||||
|
||||
function InvoiceModel(data) {
|
||||
var self = this;
|
||||
this.client = new ClientModel();
|
||||
self.discount = ko.observable('');
|
||||
self.frequency_id = ko.observable('');
|
||||
self.currency_id = ko.observable({{ Session::get(SESSION_CURRENCY, DEFAULT_CURRENCY) }});
|
||||
self.terms = ko.observable('');
|
||||
self.public_notes = ko.observable('');
|
||||
self.po_number = ko.observable('');
|
||||
self.invoice_date = ko.observable('');
|
||||
self.invoice_number = ko.observable('');
|
||||
self.due_date = ko.observable('');
|
||||
self.start_date = ko.observable('');
|
||||
self.end_date = ko.observable('');
|
||||
self.tax = ko.observable();
|
||||
self.is_recurring = ko.observable(false);
|
||||
self.invoice_status_id = ko.observable(0);
|
||||
|
||||
self.invoice_items = ko.observableArray();
|
||||
function ViewModel() {
|
||||
var self = this;
|
||||
self.invoice = new InvoiceModel();
|
||||
self.tax_rates = ko.observableArray();
|
||||
|
||||
self.loadClient = function(client) {
|
||||
//console.log(client);
|
||||
ko.mapping.fromJS(client, model.invoice.client.mapping, model.invoice.client);
|
||||
}
|
||||
|
||||
self.invoice_taxes = ko.observable({{ Auth::user()->account->invoice_taxes ? 'true' : 'false' }});
|
||||
self.invoice_item_taxes = ko.observable({{ Auth::user()->account->invoice_item_taxes ? 'true' : 'false' }});
|
||||
|
||||
/*
|
||||
self.mapping = {
|
||||
'invoice_items': {
|
||||
'invoice': {
|
||||
create: function(options) {
|
||||
return new ItemModel(options.data);
|
||||
return new InvoiceModel(options.data);
|
||||
}
|
||||
}
|
||||
}
|
||||
self.loadClient = function(client) {
|
||||
//console.log(client);
|
||||
ko.mapping.fromJS(client, model.client.mapping, model.client);
|
||||
},
|
||||
'tax_rates': {
|
||||
create: function(options) {
|
||||
return new TaxRateModel(options.data);
|
||||
}
|
||||
},
|
||||
}
|
||||
*/
|
||||
|
||||
self.wrapped_terms = ko.computed({
|
||||
read: function() {
|
||||
$('#terms').height(this.terms().split('\n').length * 36);
|
||||
return this.terms();
|
||||
},
|
||||
write: function(value) {
|
||||
value = wordWrapText(value, 340);
|
||||
self.terms(value);
|
||||
$('#terms').height(value.split('\n').length * 36);
|
||||
},
|
||||
owner: this
|
||||
});
|
||||
|
||||
self.showInvoiceTaxes = ko.computed(function() {
|
||||
if (self.tax_rates().length > 1 && self.invoice_taxes()) {
|
||||
self.invoice_taxes.show = ko.computed(function() {
|
||||
if (self.tax_rates().length > 2 && self.invoice_taxes()) {
|
||||
return true;
|
||||
}
|
||||
if (self.tax() && self.tax().rate() > 0) {
|
||||
if (self.invoice.tax_rate() > 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
self.showInvoiceItemTaxes = ko.computed(function() {
|
||||
if (self.tax_rates().length > 1 && self.invoice_item_taxes()) {
|
||||
self.invoice_item_taxes.show = ko.computed(function() {
|
||||
if (self.tax_rates().length > 2 && self.invoice_item_taxes()) {
|
||||
return true;
|
||||
}
|
||||
for (var i=0; i<self.invoice_items().length; i++) {
|
||||
var item = self.invoice_items()[i];
|
||||
if (item.tax() && item.tax().rate() > 0) {
|
||||
for (var i=0; i<self.invoice.invoice_items().length; i++) {
|
||||
var item = self.invoice.invoice_items()[i];
|
||||
if (item.tax_rate() > 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
|
||||
self.wrapped_notes = ko.computed({
|
||||
read: function() {
|
||||
$('#public_notes').height(this.public_notes().split('\n').length * 36);
|
||||
return this.public_notes();
|
||||
},
|
||||
write: function(value) {
|
||||
value = wordWrapText(value, 340);
|
||||
self.public_notes(value);
|
||||
$('#public_notes').height(value.split('\n').length * 36);
|
||||
},
|
||||
owner: this
|
||||
self.tax_rates.filtered = ko.computed(function() {
|
||||
return self.tax_rates().slice(1, self.tax_rates().length);
|
||||
});
|
||||
|
||||
self.showClientText = ko.computed(function() {
|
||||
return self.client.public_id() ? 'Edit client details' : 'Create new client';
|
||||
});
|
||||
|
||||
self.saveButtonEnabled = ko.computed(function() {
|
||||
var isValid = false;
|
||||
|
||||
for (var i=0; i<self.client.contacts().length; i++) {
|
||||
var contact = self.client.contacts()[i];
|
||||
if (isValidEmailAddress(contact.email())) {
|
||||
isValid = true;
|
||||
} else {
|
||||
isValid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return isValid ? "enabled" : "disabled";
|
||||
});
|
||||
|
||||
self.emailButtonEnabled = ko.computed(function() {
|
||||
var isValid = false;
|
||||
var sendTo = false;
|
||||
for (var i=0; i<self.client.contacts().length; i++) {
|
||||
var contact = self.client.contacts()[i];
|
||||
if (isValidEmailAddress(contact.email())) {
|
||||
isValid = true;
|
||||
if (contact.send_invoice()) {
|
||||
sendTo = true;
|
||||
}
|
||||
} else {
|
||||
isValid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return isValid && sendTo ? "enabled" : "disabled";
|
||||
});
|
||||
|
||||
self.showTaxesForm = function() {
|
||||
self.taxBackup = ko.mapping.toJS(self.tax_rates);
|
||||
|
||||
$('#taxModal').modal('show');
|
||||
}
|
||||
|
||||
self.taxFormComplete = function() {
|
||||
model.taxBackup = false;
|
||||
$('#taxModal').modal('hide');
|
||||
}
|
||||
|
||||
self.showClientForm = function() {
|
||||
self.clientBackup = ko.mapping.toJS(self.client);
|
||||
|
||||
$('#emailError').css( "display", "none" );
|
||||
$('#clientModal').modal('show');
|
||||
}
|
||||
|
||||
self.clientFormComplete = function() {
|
||||
var email = $('#email').val();
|
||||
var firstName = $('#first_name').val();
|
||||
var lastName = $('#last_name').val();
|
||||
var name = $('#name').val();
|
||||
if (!email || !isValidEmailAddress(email)) {
|
||||
$('#emailError').css( "display", "inline" );
|
||||
return;
|
||||
}
|
||||
|
||||
if (self.client.public_id() == 0) {
|
||||
self.client.public_id(-1);
|
||||
}
|
||||
|
||||
if (name) {
|
||||
//
|
||||
} else if (firstName || lastName) {
|
||||
name = firstName + ' ' + lastName;
|
||||
} else {
|
||||
name = email;
|
||||
}
|
||||
|
||||
$('.client_select select').combobox('setSelected');
|
||||
$('.client_select input.form-control').val(name);
|
||||
$('.client_select .combobox-container').addClass('combobox-selected');
|
||||
|
||||
$('#emailError').css( "display", "none" );
|
||||
//$('.client_select input.form-control').focus();
|
||||
$('#invoice_number').focus();
|
||||
|
||||
refreshPDF();
|
||||
model.clientBackup = false;
|
||||
$('#clientModal').modal('hide');
|
||||
}
|
||||
|
||||
self.removeItem = function(item) {
|
||||
self.invoice_items.remove(item);
|
||||
refreshPDF();
|
||||
}
|
||||
|
||||
self.addItem = function() {
|
||||
var itemModel = new ItemModel();
|
||||
self.invoice_items.push(itemModel);
|
||||
applyComboboxListeners();
|
||||
}
|
||||
|
||||
self.removeTaxRate = function(taxRate) {
|
||||
self.tax_rates.remove(taxRate);
|
||||
@ -780,37 +653,239 @@
|
||||
}
|
||||
}
|
||||
|
||||
this.rawSubtotal = ko.computed(function() {
|
||||
self.getTaxRate = function(name, rate) {
|
||||
for (var i=0; i<self.tax_rates().length; i++) {
|
||||
var taxRate = self.tax_rates()[i];
|
||||
if (taxRate.name() == name && taxRate.rate() == parseFloat(rate)) {
|
||||
return taxRate;
|
||||
}
|
||||
}
|
||||
var taxRate = new TaxRateModel();
|
||||
taxRate.name(name);
|
||||
taxRate.rate(parseFloat(rate));
|
||||
taxRate.is_deleted(true);
|
||||
model.tax_rates.push(taxRate);
|
||||
return taxRate;
|
||||
}
|
||||
|
||||
self.showTaxesForm = function() {
|
||||
self.taxBackup = ko.mapping.toJS(self.tax_rates);
|
||||
|
||||
$('#taxModal').modal('show');
|
||||
}
|
||||
|
||||
self.taxFormComplete = function() {
|
||||
model.taxBackup = false;
|
||||
$('#taxModal').modal('hide');
|
||||
}
|
||||
|
||||
self.showClientForm = function() {
|
||||
self.clientBackup = ko.mapping.toJS(self.invoice.client);
|
||||
|
||||
$('#emailError').css( "display", "none" );
|
||||
$('#clientModal').modal('show');
|
||||
}
|
||||
|
||||
self.clientFormComplete = function() {
|
||||
var email = $('#email').val();
|
||||
var firstName = $('#first_name').val();
|
||||
var lastName = $('#last_name').val();
|
||||
var name = $('#name').val();
|
||||
if (!email || !isValidEmailAddress(email)) {
|
||||
$('#emailError').css( "display", "inline" );
|
||||
return;
|
||||
}
|
||||
|
||||
if (self.invoice.client.public_id() == 0) {
|
||||
self.invoice.client.public_id(-1);
|
||||
}
|
||||
|
||||
if (name) {
|
||||
//
|
||||
} else if (firstName || lastName) {
|
||||
name = firstName + ' ' + lastName;
|
||||
} else {
|
||||
name = email;
|
||||
}
|
||||
|
||||
$('.client_select select').combobox('setSelected');
|
||||
$('.client_select input.form-control').val(name);
|
||||
$('.client_select .combobox-container').addClass('combobox-selected');
|
||||
|
||||
$('#emailError').css( "display", "none" );
|
||||
//$('.client_select input.form-control').focus();
|
||||
$('#invoice_number').focus();
|
||||
|
||||
refreshPDF();
|
||||
model.clientBackup = false;
|
||||
$('#clientModal').modal('hide');
|
||||
}
|
||||
}
|
||||
|
||||
function InvoiceModel(data) {
|
||||
var self = this;
|
||||
this.client = new ClientModel();
|
||||
this.id = ko.observable('');
|
||||
self.discount = ko.observable('');
|
||||
self.frequency_id = ko.observable('');
|
||||
self.currency_id = ko.observable({{ Session::get(SESSION_CURRENCY, DEFAULT_CURRENCY) }});
|
||||
self.terms = ko.observable(wordWrapText('{{ $account->invoice_terms }}', 340));
|
||||
self.public_notes = ko.observable('');
|
||||
self.po_number = ko.observable('');
|
||||
self.invoice_date = ko.observable('{{ Utils::today() }}');
|
||||
self.invoice_number = ko.observable('{{ isset($invoiceNumber) ? $invoiceNumber : '' }}');
|
||||
self.due_date = ko.observable('');
|
||||
self.start_date = ko.observable('{{ Utils::today() }}');
|
||||
self.end_date = ko.observable('');
|
||||
self.tax_name = ko.observable();
|
||||
self.tax_rate = ko.observable();
|
||||
self.is_recurring = ko.observable(false);
|
||||
self.invoice_status_id = ko.observable(0);
|
||||
self.invoice_items = ko.observableArray();
|
||||
|
||||
|
||||
self.mapping = {
|
||||
'invoice_items': {
|
||||
create: function(options) {
|
||||
return new ItemModel(options.data);
|
||||
}
|
||||
},
|
||||
'tax': {
|
||||
create: function(options) {
|
||||
return new TaxRateModel(options.data);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
self._tax = ko.observable();
|
||||
this.tax = ko.computed({
|
||||
read: function () {
|
||||
return self._tax();
|
||||
},
|
||||
write: function(value) {
|
||||
if (value) {
|
||||
console.log("WRITE INVOICE TAX");
|
||||
console.log(value.name());
|
||||
self._tax(value);
|
||||
self.tax_name(value.name());
|
||||
self.tax_rate(value.rate());
|
||||
} else {
|
||||
self._tax(false);
|
||||
self.tax_name('');
|
||||
self.tax_rate(0);
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
self.wrapped_terms = ko.computed({
|
||||
read: function() {
|
||||
$('#terms').height(this.terms().split('\n').length * 36);
|
||||
return this.terms();
|
||||
},
|
||||
write: function(value) {
|
||||
value = wordWrapText(value, 340);
|
||||
self.terms(value);
|
||||
$('#terms').height(value.split('\n').length * 36);
|
||||
},
|
||||
owner: this
|
||||
});
|
||||
|
||||
|
||||
self.wrapped_notes = ko.computed({
|
||||
read: function() {
|
||||
$('#public_notes').height(this.public_notes().split('\n').length * 36);
|
||||
return this.public_notes();
|
||||
},
|
||||
write: function(value) {
|
||||
value = wordWrapText(value, 340);
|
||||
self.public_notes(value);
|
||||
$('#public_notes').height(value.split('\n').length * 36);
|
||||
},
|
||||
owner: this
|
||||
});
|
||||
|
||||
self.client.linkText = ko.computed(function() {
|
||||
return self.client.public_id() ? 'Edit client details' : 'Create new client';
|
||||
});
|
||||
|
||||
self.enable = {};
|
||||
self.enable.save = ko.computed(function() {
|
||||
var isValid = false;
|
||||
|
||||
for (var i=0; i<self.client.contacts().length; i++) {
|
||||
var contact = self.client.contacts()[i];
|
||||
if (isValidEmailAddress(contact.email())) {
|
||||
isValid = true;
|
||||
} else {
|
||||
isValid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return isValid ? "enabled" : "disabled";
|
||||
});
|
||||
|
||||
self.enable.email = ko.computed(function() {
|
||||
var isValid = false;
|
||||
var sendTo = false;
|
||||
for (var i=0; i<self.client.contacts().length; i++) {
|
||||
var contact = self.client.contacts()[i];
|
||||
if (isValidEmailAddress(contact.email())) {
|
||||
isValid = true;
|
||||
if (contact.send_invoice()) {
|
||||
sendTo = true;
|
||||
}
|
||||
} else {
|
||||
isValid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return isValid && sendTo ? "enabled" : "disabled";
|
||||
});
|
||||
|
||||
self.removeItem = function(item) {
|
||||
self.invoice_items.remove(item);
|
||||
refreshPDF();
|
||||
}
|
||||
|
||||
self.addItem = function() {
|
||||
var itemModel = new ItemModel();
|
||||
self.invoice_items.push(itemModel);
|
||||
applyComboboxListeners();
|
||||
}
|
||||
|
||||
this.totals = ko.observable();
|
||||
|
||||
this.totals.rawSubtotal = ko.computed(function() {
|
||||
var total = 0;
|
||||
for(var p = 0; p < self.invoice_items().length; ++p)
|
||||
{
|
||||
total += self.invoice_items()[p].rawTotal();
|
||||
total += self.invoice_items()[p].totals.rawTotal();
|
||||
}
|
||||
return total;
|
||||
});
|
||||
|
||||
this.subtotal = ko.computed(function() {
|
||||
var total = self.rawSubtotal();
|
||||
this.totals.subtotal = ko.computed(function() {
|
||||
var total = self.totals.rawSubtotal();
|
||||
return total > 0 ? formatMoney(total, self.currency_id()) : '';
|
||||
});
|
||||
|
||||
this.rawDiscounted = ko.computed(function() {
|
||||
return self.rawSubtotal() * (self.discount()/100);
|
||||
this.totals.rawDiscounted = ko.computed(function() {
|
||||
return self.totals.rawSubtotal() * (self.discount()/100);
|
||||
});
|
||||
|
||||
this.discounted = ko.computed(function() {
|
||||
return formatMoney(self.rawDiscounted(), self.currency_id());
|
||||
this.totals.discounted = ko.computed(function() {
|
||||
return formatMoney(self.totals.rawDiscounted(), self.currency_id());
|
||||
});
|
||||
|
||||
self.taxAmount = ko.computed(function() {
|
||||
var total = self.rawSubtotal();
|
||||
self.totals.taxAmount = ko.computed(function() {
|
||||
var total = self.totals.rawSubtotal();
|
||||
|
||||
var discount = parseFloat(self.discount());
|
||||
if (discount > 0) {
|
||||
total = total * ((100 - discount)/100);
|
||||
}
|
||||
|
||||
var taxRate = self.tax() ? parseFloat(self.tax().rate()) : 0;
|
||||
var taxRate = parseFloat(self.tax_rate());
|
||||
if (taxRate > 0) {
|
||||
var tax = total * (taxRate/100);
|
||||
return formatMoney(tax, self.currency_id());
|
||||
@ -820,15 +895,15 @@
|
||||
});
|
||||
|
||||
|
||||
this.total = ko.computed(function() {
|
||||
var total = self.rawSubtotal();
|
||||
this.totals.total = ko.computed(function() {
|
||||
var total = self.totals.rawSubtotal();
|
||||
|
||||
var discount = parseFloat(self.discount());
|
||||
if (discount > 0) {
|
||||
total = total * ((100 - discount)/100);
|
||||
}
|
||||
|
||||
var taxRate = self.tax() ? parseFloat(self.tax().rate()) : 0;
|
||||
var taxRate = parseFloat(self.tax_rate());
|
||||
if (taxRate > 0) {
|
||||
total = parseFloat(total) + (total * (taxRate/100));
|
||||
}
|
||||
@ -857,7 +932,7 @@
|
||||
self.client_industry_id = ko.observable('');
|
||||
self.currency_id = ko.observable('');
|
||||
self.website = ko.observable('');
|
||||
self.payment_terms = ko.observable();
|
||||
self.payment_terms = ko.observable(0);
|
||||
self.contacts = ko.observableArray();
|
||||
|
||||
self.mapping = {
|
||||
@ -885,6 +960,7 @@
|
||||
self.contacts.remove(this);
|
||||
}
|
||||
|
||||
/*
|
||||
self.placeholderName = ko.computed(function() {
|
||||
if (self.contacts().length == 0) return;
|
||||
var contact = self.contacts()[0];
|
||||
@ -894,6 +970,7 @@
|
||||
return '';
|
||||
}
|
||||
});
|
||||
*/
|
||||
|
||||
if (data) {
|
||||
ko.mapping.fromJS(data, {}, this);
|
||||
@ -915,7 +992,7 @@
|
||||
ko.mapping.fromJS(data, {}, this);
|
||||
}
|
||||
|
||||
self.displayName = ko.computed(function() {
|
||||
self.email.display = ko.computed(function() {
|
||||
return self.first_name() + ' ' + self.last_name() + ' - ' + self.email();
|
||||
});
|
||||
}
|
||||
@ -923,12 +1000,14 @@
|
||||
function TaxRateModel(data) {
|
||||
var self = this;
|
||||
self.public_id = ko.observable('');
|
||||
self.rate = ko.observable();
|
||||
self.rate = ko.observable(0);
|
||||
self.name = ko.observable('');
|
||||
self.is_deleted = ko.observable(false);
|
||||
self.actionsVisible = ko.observable(false);
|
||||
|
||||
if (data) {
|
||||
console.log("NEW TAX MODEL");
|
||||
console.log(data);
|
||||
ko.mapping.fromJS(data, {}, this);
|
||||
}
|
||||
|
||||
@ -943,10 +1022,16 @@
|
||||
});
|
||||
|
||||
|
||||
self.displayName = ko.computed(function() {
|
||||
var name = self.name() ? self.name() : '';
|
||||
var rate = self.rate() ? parseFloat(self.rate()) + '% -' : '';
|
||||
return rate + name;
|
||||
self.displayName = ko.computed({
|
||||
read: function () {
|
||||
var name = self.name() ? self.name() : '';
|
||||
var rate = self.rate() ? parseFloat(self.rate()) + '% -' : '';
|
||||
return rate + name;
|
||||
},
|
||||
write: function (value) {
|
||||
// do nothing
|
||||
},
|
||||
owner: this
|
||||
});
|
||||
|
||||
self.hideActions = function() {
|
||||
@ -968,9 +1053,25 @@
|
||||
this.notes = ko.observable('');
|
||||
this.cost = ko.observable(0);
|
||||
this.qty = ko.observable(0);
|
||||
this.tax = ko.observable();
|
||||
self.tax_name = ko.observable('');
|
||||
self.tax_rate = ko.observable(0);
|
||||
this.actionsVisible = ko.observable(false);
|
||||
|
||||
|
||||
self._tax = ko.observable();
|
||||
this.tax = ko.computed({
|
||||
read: function () {
|
||||
return self._tax();
|
||||
},
|
||||
write: function(value) {
|
||||
console.log("TAX-WRITE");
|
||||
console.log(value);
|
||||
self._tax(value);
|
||||
self.tax_name(value.name());
|
||||
self.tax_rate(value.rate());
|
||||
}
|
||||
})
|
||||
|
||||
this.prettyQty = ko.computed({
|
||||
read: function () {
|
||||
return this.qty() ? parseFloat(this.qty()) : '';
|
||||
@ -991,31 +1092,44 @@
|
||||
owner: this
|
||||
});
|
||||
|
||||
if (data) {
|
||||
ko.mapping.fromJS(data, {}, this);
|
||||
if (this.cost()) this.cost(formatMoney(this.cost(), model.currency_id(), true));
|
||||
self.mapping = {
|
||||
'tax': {
|
||||
create: function(options) {
|
||||
console.log('CALLED');
|
||||
return new TaxRateModel(options.data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (data) {
|
||||
ko.mapping.fromJS(data, self.mapping, this);
|
||||
if (this.cost()) this.cost(formatMoney(this.cost(), model.invoice.currency_id(), true));
|
||||
if (self.tax_rate()) {
|
||||
self.tax(model.getTaxRate(self.tax_name(), self.tax_rate()));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
for (var i=0; i<model.tax_rates().length; i++) {
|
||||
var taxRate = model.tax_rates()[i];
|
||||
if (data && (data.tax_name == taxRate.name() && data.tax_rate == taxRate.rate())) {
|
||||
console.log("SETTING TAX: " + data.tax_name);
|
||||
self.tax(taxRate);
|
||||
break;
|
||||
} else if ((!data || !data.tax_name) && !taxRate.name()) {
|
||||
self.tax(taxRate);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if the tax was deleted but exists for the line item
|
||||
if (data && data.tax_name && (parseFloat(data.tax_rate)) && !self.tax()) {
|
||||
if (data && data.tax_name && (parseFloat(data.tax_rate)) && !self.tax_rate()) {
|
||||
var taxRate = new TaxRateModel();
|
||||
taxRate.rate(parseFloat(data.tax_rate));
|
||||
taxRate.name(data.tax_name);
|
||||
taxRate.is_deleted(true);
|
||||
model.tax_rates.push(taxRate);
|
||||
console.log("SETTING TAX: " + taxRate.name());
|
||||
self.tax(taxRate);
|
||||
}
|
||||
*/
|
||||
|
||||
self.wrapped_notes = ko.computed({
|
||||
read: function() {
|
||||
@ -1029,10 +1143,12 @@
|
||||
owner: this
|
||||
});
|
||||
|
||||
this.rawTotal = ko.computed(function() {
|
||||
this.totals = ko.observable();
|
||||
|
||||
this.totals.rawTotal = ko.computed(function() {
|
||||
var cost = parseFloat(self.cost());
|
||||
var qty = parseFloat(self.qty());
|
||||
var taxRate = self.tax() ? parseFloat(self.tax().rate()) : 0;
|
||||
var taxRate = parseFloat(self.tax_rate());
|
||||
var value = cost * qty;
|
||||
if (taxRate > 0) {
|
||||
value += value * (taxRate/100);
|
||||
@ -1040,9 +1156,9 @@
|
||||
return value ? value : '';
|
||||
});
|
||||
|
||||
this.total = ko.computed(function() {
|
||||
var total = self.rawTotal();
|
||||
return total ? formatMoney(total, model.currency_id()) : '';
|
||||
this.totals.total = ko.computed(function() {
|
||||
var total = self.totals.rawTotal();
|
||||
return total ? formatMoney(total, model.invoice.currency_id()) : '';
|
||||
});
|
||||
|
||||
this.hideActions = function() {
|
||||
@ -1065,15 +1181,15 @@
|
||||
function onItemChange()
|
||||
{
|
||||
var hasEmpty = false;
|
||||
for(var i=0; i<model.invoice_items().length; i++) {
|
||||
var item = model.invoice_items()[i];
|
||||
for(var i=0; i<model.invoice.invoice_items().length; i++) {
|
||||
var item = model.invoice.invoice_items()[i];
|
||||
if (item.isEmpty()) {
|
||||
hasEmpty = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasEmpty) {
|
||||
model.addItem();
|
||||
model.invoice.addItem();
|
||||
}
|
||||
|
||||
$('.word-wrap').each(function(index, input) {
|
||||
@ -1083,15 +1199,15 @@
|
||||
|
||||
function onTaxRateChange()
|
||||
{
|
||||
var hasEmpty = false;
|
||||
var emptyCount = 0;
|
||||
for(var i=0; i<model.tax_rates().length; i++) {
|
||||
var taxRate = model.tax_rates()[i];
|
||||
if (taxRate.isEmpty()) {
|
||||
hasEmpty = true;
|
||||
emptyCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasEmpty) {
|
||||
if (emptyCount < 2) {
|
||||
model.addTaxRate();
|
||||
}
|
||||
}
|
||||
@ -1111,36 +1227,52 @@
|
||||
$clientSelect.append(new Option(getClientDisplayName(client), client.public_id));
|
||||
}
|
||||
|
||||
window.model = new InvoiceModel();
|
||||
@foreach ($taxRates as $taxRate)
|
||||
model.addTaxRate({{ $taxRate }});
|
||||
@endforeach
|
||||
model.addTaxRate();
|
||||
model.tax(model.getBlankTaxRate());
|
||||
@if ($invoice)
|
||||
var invoice = {{ $invoice }};
|
||||
ko.mapping.fromJS(invoice, model.mapping, model);
|
||||
window.model = new ViewModel();
|
||||
@if (!$data)
|
||||
model.addTaxRate();
|
||||
@foreach ($taxRates as $taxRate)
|
||||
model.addTaxRate({{ $taxRate }});
|
||||
@endforeach
|
||||
@endif
|
||||
//model.tax(model.getBlankTaxRate());
|
||||
@if ($invoice || $data)
|
||||
var invoice = {{ $invoice ? $invoice : $data }};
|
||||
ko.mapping.fromJS(invoice, model.invoice.mapping, model.invoice);
|
||||
var taxRate = model.getTaxRate(invoice.tax_name, invoice.tax_rate);
|
||||
model.invoice.tax(taxRate);
|
||||
/*
|
||||
for (var i=0; i<model.tax_rates().length; i++) {
|
||||
var taxRate = model.tax_rates()[i];
|
||||
if (model.tax_name() == taxRate.name() && model.tax_rate() == taxRate.rate()) {
|
||||
model.tax(taxRate);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// if the tax was deleted but exists for the line item
|
||||
if (parseFloat(invoice.tax_rate) && !model.tax_rate()) {
|
||||
var taxRate = new TaxRateModel();
|
||||
taxRate.rate(parseFloat(invoice.tax_rate));
|
||||
taxRate.name(invoice.tax_name);
|
||||
taxRate.is_deleted(true);
|
||||
model.tax_rates.push(taxRate);
|
||||
model.tax(taxRate);
|
||||
}
|
||||
if (!model.discount()) model.discount('');
|
||||
var invitationContactIds = {{ json_encode($invitationContactIds) }};
|
||||
var client = clientMap[invoice.client.public_id];
|
||||
for (var i=0; i<client.contacts.length; i++) {
|
||||
var contact = client.contacts[i];
|
||||
contact.send_invoice = invitationContactIds.indexOf(contact.public_id) >= 0;
|
||||
}
|
||||
@else
|
||||
model.invoice_date('{{ Utils::today() }}');
|
||||
model.start_date('{{ Utils::today() }}');
|
||||
model.invoice_number('{{ $invoiceNumber }}');
|
||||
model.terms(wordWrapText('{{ $account->invoice_terms }}', 340));
|
||||
@if ($invoice)
|
||||
var invitationContactIds = {{ json_encode($invitationContactIds) }};
|
||||
var client = clientMap[invoice.client.public_id];
|
||||
for (var i=0; i<client.contacts.length; i++) {
|
||||
var contact = client.contacts[i];
|
||||
contact.send_invoice = invitationContactIds.indexOf(contact.public_id) >= 0;
|
||||
}
|
||||
@endif
|
||||
*/
|
||||
if (!model.invoice.discount()) model.invoice.discount('');
|
||||
|
||||
@endif
|
||||
@if (!$data)
|
||||
model.addTaxRate();
|
||||
model.invoice.addItem();
|
||||
@endif
|
||||
model.addItem();
|
||||
ko.applyBindings(model);
|
||||
|
||||
</script>
|
||||
|
Loading…
x
Reference in New Issue
Block a user