mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
bug fixes
This commit is contained in:
parent
689d1938e1
commit
0b8ad35d66
@ -59,3 +59,4 @@ Configure config/database.php and then initialize the database
|
|||||||
* [mozilla/pdf.js](https://github.com/mozilla/pdf.js) - PDF Reader in JavaScript
|
* [mozilla/pdf.js](https://github.com/mozilla/pdf.js) - PDF Reader in JavaScript
|
||||||
* [nnnick/Chart.js](https://github.com/nnnick/Chart.js) - Simple HTML5 Charts using the <canvas> tag
|
* [nnnick/Chart.js](https://github.com/nnnick/Chart.js) - Simple HTML5 Charts using the <canvas> tag
|
||||||
* [josscrowcroft/accounting.js](https://github.com/josscrowcroft/accounting.js) - A lightweight JavaScript library for number, money and currency formatting
|
* [josscrowcroft/accounting.js](https://github.com/josscrowcroft/accounting.js) - A lightweight JavaScript library for number, money and currency formatting
|
||||||
|
* [jashkenas/underscore](https://github.com/jashkenas/underscore) - JavaScript's utility _ belt
|
@ -112,8 +112,9 @@ class CreditController extends \BaseController {
|
|||||||
{
|
{
|
||||||
$rules = array(
|
$rules = array(
|
||||||
'client' => 'required',
|
'client' => 'required',
|
||||||
'amount' => 'required'
|
'amount' => 'required',
|
||||||
);
|
);
|
||||||
|
|
||||||
$validator = Validator::make(Input::all(), $rules);
|
$validator = Validator::make(Input::all(), $rules);
|
||||||
|
|
||||||
if ($validator->fails()) {
|
if ($validator->fails()) {
|
||||||
|
@ -216,8 +216,7 @@ class InvoiceController extends \BaseController {
|
|||||||
|
|
||||||
if (!$ref)
|
if (!$ref)
|
||||||
{
|
{
|
||||||
var_dump($response);
|
Utils::fatalError('Sorry, there was an error processing your payment. Please try again later.<p>');
|
||||||
exit('Sorry, there was an error processing your payment. Please try again later.');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$payment = Payment::createNew();
|
$payment = Payment::createNew();
|
||||||
@ -225,7 +224,7 @@ class InvoiceController extends \BaseController {
|
|||||||
$payment->invoice_id = $invoice->id;
|
$payment->invoice_id = $invoice->id;
|
||||||
$payment->amount = $invoice->amount;
|
$payment->amount = $invoice->amount;
|
||||||
$payment->client_id = $invoice->client_id;
|
$payment->client_id = $invoice->client_id;
|
||||||
//$payment->contact_id = 0; // TODO_FIX
|
$payment->contact_id = $invitation->contact_id;
|
||||||
$payment->transaction_reference = $ref;
|
$payment->transaction_reference = $ref;
|
||||||
$payment->save();
|
$payment->save();
|
||||||
|
|
||||||
@ -299,7 +298,7 @@ class InvoiceController extends \BaseController {
|
|||||||
|
|
||||||
public function edit($publicId)
|
public function edit($publicId)
|
||||||
{
|
{
|
||||||
$invoice = Invoice::scope($publicId)->with('account.country', 'client', 'invoice_items')->firstOrFail();
|
$invoice = Invoice::scope($publicId)->with('account.country', 'client.contacts', 'invoice_items')->firstOrFail();
|
||||||
Utils::trackViewed($invoice->invoice_number . ' - ' . $invoice->client->getDisplayName(), ENTITY_INVOICE);
|
Utils::trackViewed($invoice->invoice_number . ' - ' . $invoice->client->getDisplayName(), ENTITY_INVOICE);
|
||||||
|
|
||||||
$invoice->invoice_date = Utils::fromSqlDate($invoice->invoice_date);
|
$invoice->invoice_date = Utils::fromSqlDate($invoice->invoice_date);
|
||||||
@ -420,12 +419,6 @@ class InvoiceController extends \BaseController {
|
|||||||
$account->save();
|
$account->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($action == 'email' && $invoice->invoice_status_id == INVOICE_STATUS_DRAFT)
|
|
||||||
{
|
|
||||||
$client->balance = $client->balance + $invoice->amount;
|
|
||||||
$client->save();
|
|
||||||
}
|
|
||||||
|
|
||||||
$client->load('contacts');
|
$client->load('contacts');
|
||||||
$sendInvoiceIds = [];
|
$sendInvoiceIds = [];
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ class PaymentController extends \BaseController
|
|||||||
$data = array(
|
$data = array(
|
||||||
'clientPublicId' => $clientPublicId,
|
'clientPublicId' => $clientPublicId,
|
||||||
'invoice' => null,
|
'invoice' => null,
|
||||||
'invoices' => Invoice::scope()->with('client')->orderBy('invoice_number')->get(),
|
'invoices' => Invoice::scope()->with('client')->where('balance','>',0)->orderBy('invoice_number')->get(),
|
||||||
'payment' => null,
|
'payment' => null,
|
||||||
'method' => 'POST',
|
'method' => 'POST',
|
||||||
'url' => 'payments',
|
'url' => 'payments',
|
||||||
|
@ -2,9 +2,15 @@
|
|||||||
|
|
||||||
class Utils
|
class Utils
|
||||||
{
|
{
|
||||||
public static function fatalError($error)
|
public static function fatalError($error = false)
|
||||||
{
|
{
|
||||||
|
if (!$error)
|
||||||
|
{
|
||||||
|
$error = "An error occurred, please try again later";
|
||||||
|
}
|
||||||
|
|
||||||
Log::error($error);
|
Log::error($error);
|
||||||
|
|
||||||
return View::make('error')->with('error', $error);
|
return View::make('error')->with('error', $error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ class Activity extends Eloquent
|
|||||||
$activity->user_id = $entity->user_id;
|
$activity->user_id = $entity->user_id;
|
||||||
$activity->account_id = $entity->account_id;
|
$activity->account_id = $entity->account_id;
|
||||||
} else {
|
} else {
|
||||||
exit; // TODO_FIX log error
|
Utils::fatalError();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $activity;
|
return $activity;
|
||||||
@ -104,11 +104,11 @@ class Activity extends Eloquent
|
|||||||
public static function emailInvoice($invitation)
|
public static function emailInvoice($invitation)
|
||||||
{
|
{
|
||||||
$adjustment = 0;
|
$adjustment = 0;
|
||||||
|
$client = $invitation->invoice->client;
|
||||||
|
|
||||||
if (!$invitation->invoice->isSent())
|
if (!$invitation->invoice->isSent())
|
||||||
{
|
{
|
||||||
$adjustment = $invitation->invoice->amount;
|
$adjustment = $invitation->invoice->amount;
|
||||||
$client = $invitation->invoice->client;
|
|
||||||
$client->balance = $client->balance + $adjustment;
|
$client->balance = $client->balance + $adjustment;
|
||||||
$client->save();
|
$client->save();
|
||||||
}
|
}
|
||||||
@ -120,7 +120,7 @@ class Activity extends Eloquent
|
|||||||
$activity->contact_id = $invitation->contact_id;
|
$activity->contact_id = $invitation->contact_id;
|
||||||
$activity->activity_type_id = ACTIVITY_TYPE_EMAIL_INVOICE;
|
$activity->activity_type_id = ACTIVITY_TYPE_EMAIL_INVOICE;
|
||||||
$activity->message = $userName . ' emailed invoice ' . link_to('invoices/'.$invitation->invoice->public_id, $invitation->invoice->invoice_number) . ' to ' . $invitation->contact->getFullName() . ' - ' . $invitation->contact->email;
|
$activity->message = $userName . ' emailed invoice ' . link_to('invoices/'.$invitation->invoice->public_id, $invitation->invoice->invoice_number) . ' to ' . $invitation->contact->getFullName() . ' - ' . $invitation->contact->email;
|
||||||
$activity->balance = $invitation->invoice->client->balance;
|
$activity->balance = $client->balance;
|
||||||
$activity->adjustment = $adjustment;
|
$activity->adjustment = $adjustment;
|
||||||
$activity->save();
|
$activity->save();
|
||||||
}
|
}
|
||||||
@ -176,9 +176,16 @@ class Activity extends Eloquent
|
|||||||
}
|
}
|
||||||
|
|
||||||
$activity->payment_id = $payment->id;
|
$activity->payment_id = $payment->id;
|
||||||
if ($payment->invoice_id) {
|
|
||||||
|
if ($payment->invoice_id)
|
||||||
|
{
|
||||||
$activity->invoice_id = $payment->invoice_id;
|
$activity->invoice_id = $payment->invoice_id;
|
||||||
|
|
||||||
|
$invoice = $payment->invoice;
|
||||||
|
$invoice->balance = $invoice->balance - $payment->amount;
|
||||||
|
$invoice->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
$activity->client_id = $payment->client_id;
|
$activity->client_id = $payment->client_id;
|
||||||
$activity->currency_id = $payment->currency_id;
|
$activity->currency_id = $payment->currency_id;
|
||||||
$activity->activity_type_id = ACTIVITY_TYPE_CREATE_PAYMENT;
|
$activity->activity_type_id = ACTIVITY_TYPE_CREATE_PAYMENT;
|
||||||
@ -197,6 +204,16 @@ class Activity extends Eloquent
|
|||||||
$activity->message = Auth::user()->getFullName() . ' created credit';
|
$activity->message = Auth::user()->getFullName() . ' created credit';
|
||||||
$activity->credit_id = $credit->id;
|
$activity->credit_id = $credit->id;
|
||||||
$activity->client_id = $credit->client_id;
|
$activity->client_id = $credit->client_id;
|
||||||
|
|
||||||
|
if ($credit->invoice_id)
|
||||||
|
{
|
||||||
|
$activity->invoice_id = $payment->invoice_id;
|
||||||
|
|
||||||
|
$invoice = $credit->invoice;
|
||||||
|
$invoice->balance = $invoice->amount - $credit->amount;
|
||||||
|
$invoice->save();
|
||||||
|
}
|
||||||
|
|
||||||
$activity->currency_id = $credit->currency_id;
|
$activity->currency_id = $credit->currency_id;
|
||||||
$activity->activity_type_id = ACTIVITY_TYPE_CREATE_CREDIT;
|
$activity->activity_type_id = ACTIVITY_TYPE_CREATE_CREDIT;
|
||||||
$activity->balance = $client->balance;
|
$activity->balance = $client->balance;
|
||||||
|
@ -15,7 +15,7 @@ class EntityModel extends Eloquent
|
|||||||
$entity->user_id = $parent->user_id;
|
$entity->user_id = $parent->user_id;
|
||||||
$entity->account_id = $parent->account_id;
|
$entity->account_id = $parent->account_id;
|
||||||
} else {
|
} else {
|
||||||
exit; // TODO_FIX
|
Utils::fatalError();
|
||||||
}
|
}
|
||||||
|
|
||||||
$lastEntity = $className::withTrashed()->scope(false, $entity->account_id)->orderBy('public_id', 'DESC')->first();
|
$lastEntity = $className::withTrashed()->scope(false, $entity->account_id)->orderBy('public_id', 'DESC')->first();
|
||||||
|
@ -106,7 +106,7 @@ class Invoice extends EntityModel
|
|||||||
case FREQUENCY_ANNUALLY:
|
case FREQUENCY_ANNUALLY:
|
||||||
return ($dayOfMonthStart == $dayOfMonthToday && (!$daysSinceLastSent || $monthsSinceLastSent == 12)) || $daysSinceLastSent > (12 *31);
|
return ($dayOfMonthStart == $dayOfMonthToday && (!$daysSinceLastSent || $monthsSinceLastSent == 12)) || $daysSinceLastSent > (12 *31);
|
||||||
default:
|
default:
|
||||||
echo "Error: invalid frequency_id - ".$this->frequency_id; exit; //TODO_FIX
|
Utils::fatalError("Invalid frequency supplied: " . $this->frequency_id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,6 +71,8 @@ class ClientRepository
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$client->save();
|
||||||
|
|
||||||
return $client;
|
return $client;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -22,6 +22,7 @@
|
|||||||
<script type="text/javascript" src="{{ asset('js/knockout.mapping-latest.js') }}"></script>
|
<script type="text/javascript" src="{{ asset('js/knockout.mapping-latest.js') }}"></script>
|
||||||
<script src="{{ asset('js/knockout-sortable.js') }}" type="text/javascript"></script>
|
<script src="{{ asset('js/knockout-sortable.js') }}" type="text/javascript"></script>
|
||||||
<link rel="stylesheet" type="text/css" href="{{ asset('css/font-awesome.css') }}"/>
|
<link rel="stylesheet" type="text/css" href="{{ asset('css/font-awesome.css') }}"/>
|
||||||
|
<script src="{{ asset('js/underscore-min.js') }}" type="text/javascript"></script>
|
||||||
|
|
||||||
<script src="{{ asset('js/jspdf.source.js') }}" type="text/javascript"></script>
|
<script src="{{ asset('js/jspdf.source.js') }}" type="text/javascript"></script>
|
||||||
<script src="{{ asset('js/jspdf.plugin.split_text_to_size.js') }}" type="text/javascript"></script>
|
<script src="{{ asset('js/jspdf.plugin.split_text_to_size.js') }}" type="text/javascript"></script>
|
||||||
@ -91,15 +92,18 @@
|
|||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<div class="navbar-form navbar-right">
|
<div class="navbar-form navbar-right">
|
||||||
@if (Auth::check() && Auth::user()->registered)
|
@if (!Auth::check() || !Auth::user()->registered)
|
||||||
{{ Auth::user()->email }}
|
|
||||||
@else
|
|
||||||
{{ Button::sm_primary('Sign up', array('data-toggle'=>'modal', 'data-target'=>'#signUpModal')) }}
|
{{ Button::sm_primary('Sign up', array('data-toggle'=>'modal', 'data-target'=>'#signUpModal')) }}
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
<button type="button" class="btn btn-default btn-sm dropdown-toggle" data-toggle="dropdown">
|
<button type="button" class="btn btn-default btn-sm dropdown-toggle" data-toggle="dropdown">
|
||||||
My Account <span class="caret"></span>
|
@if (Auth::check() && Auth::user()->registered)
|
||||||
|
{{ Auth::user()->getFullName() }}
|
||||||
|
@else
|
||||||
|
My Account
|
||||||
|
@endif
|
||||||
|
<span class="caret"></span>
|
||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu" role="menu">
|
<ul class="dropdown-menu" role="menu">
|
||||||
<li>{{ link_to('account/details', 'Details') }}</li>
|
<li>{{ link_to('account/details', 'Details') }}</li>
|
||||||
@ -359,7 +363,7 @@
|
|||||||
|
|
||||||
$('#signUpModal').on('shown.bs.modal', function () {
|
$('#signUpModal').on('shown.bs.modal', function () {
|
||||||
$(['first_name','last_name','email','password']).each(function(i, field) {
|
$(['first_name','last_name','email','password']).each(function(i, field) {
|
||||||
var $input = $('form.signUpForm #'+field);
|
var $input = $('form.signUpForm #new_'+field);
|
||||||
if (!$input.val()) {
|
if (!$input.val()) {
|
||||||
$input.focus();
|
$input.focus();
|
||||||
return false;
|
return false;
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
|
|
||||||
<div class="form-group" style="margin-bottom: 8px">
|
<div class="form-group" style="margin-bottom: 8px">
|
||||||
<div class="col-lg-8 col-sm-8 col-lg-offset-4 col-sm-offset-4">
|
<div class="col-lg-8 col-sm-8 col-lg-offset-4 col-sm-offset-4">
|
||||||
<a href="#" data-bind="click: $root.showClientForm, text: client.linkText"></a>
|
<a href="#" data-bind="click: $root.showClientForm, text: $root.clientLinkText"></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -204,12 +204,12 @@
|
|||||||
array('Delete Invoice', "javascript:onDeleteClick()"),
|
array('Delete Invoice', "javascript:onDeleteClick()"),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
, array('id'=>'actionDropDown', 'style'=>'text-align:left', 'data-bind'=>'css: enable.save'))->split(); }}
|
, array('id'=>'actionDropDown', 'style'=>'text-align:left', 'data-bind'=>'css: $root.enable.save'))->split(); }}
|
||||||
@else
|
@else
|
||||||
{{ Button::primary_submit('Save Invoice', array('data-bind'=>'css: enable.save')) }}
|
{{ Button::primary_submit('Save Invoice', array('data-bind'=>'css: $root.enable.save')) }}
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
{{ Button::primary('Send Email', array('id' => 'email_button', 'onclick' => 'onEmailClick()', 'data-bind' => 'css: enable.email')) }}
|
{{ Button::primary('Send Email', array('id' => 'email_button', 'onclick' => 'onEmailClick()', 'data-bind' => 'css: $root.enable.email')) }}
|
||||||
</div>
|
</div>
|
||||||
<p> </p>
|
<p> </p>
|
||||||
|
|
||||||
@ -326,7 +326,7 @@
|
|||||||
<input onkeyup="onTaxRateChange()" data-bind="value: prettyRate, valueUpdate: 'afterkeydown'" style="text-align: right" class="form-control" onchange="refreshPDF()"//>
|
<input onkeyup="onTaxRateChange()" data-bind="value: prettyRate, valueUpdate: 'afterkeydown'" style="text-align: right" class="form-control" onchange="refreshPDF()"//>
|
||||||
</td>
|
</td>
|
||||||
<td style="width:10px; cursor:pointer" class="hide-border td-icon">
|
<td style="width:10px; cursor:pointer" class="hide-border td-icon">
|
||||||
<i data-bind="click: $root.removeTaxRate, visible: actionsVisible() && $root.tax_rates().length > 1" class="fa fa-minus-circle" title="Remove item"/>
|
<i data-bind="click: $root.removeTaxRate, visible: actionsVisible() && !isEmpty()" class="fa fa-minus-circle" title="Remove item"/>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
@ -380,7 +380,7 @@
|
|||||||
model.loadClient($.parseJSON(ko.toJSON(new ClientModel())));
|
model.loadClient($.parseJSON(ko.toJSON(new ClientModel())));
|
||||||
}
|
}
|
||||||
refreshPDF();
|
refreshPDF();
|
||||||
}).trigger('change');
|
}); //.trigger('change');
|
||||||
|
|
||||||
$('#terms, #public_notes, #invoice_number, #invoice_date, #due_date, #po_number, #discout, #currency_id').change(function() {
|
$('#terms, #public_notes, #invoice_number, #invoice_date, #due_date, #po_number, #discout, #currency_id').change(function() {
|
||||||
refreshPDF();
|
refreshPDF();
|
||||||
@ -410,7 +410,9 @@
|
|||||||
$('#taxModal').on('shown.bs.modal', function () {
|
$('#taxModal').on('shown.bs.modal', function () {
|
||||||
$('#taxModal input:first').focus();
|
$('#taxModal input:first').focus();
|
||||||
}).on('hidden.bs.modal', function () {
|
}).on('hidden.bs.modal', function () {
|
||||||
|
// if the user changed the tax rates we need to trigger the
|
||||||
|
// change event on the selects for the model to get updated
|
||||||
|
$('table.invoice-table select').trigger('change');
|
||||||
})
|
})
|
||||||
|
|
||||||
$('#actionDropDown > button:first').click(function() {
|
$('#actionDropDown > button:first').click(function() {
|
||||||
@ -419,7 +421,13 @@
|
|||||||
|
|
||||||
$('label.radio').addClass('radio-inline');
|
$('label.radio').addClass('radio-inline');
|
||||||
|
|
||||||
|
var client = model.invoice().client();
|
||||||
|
setComboboxValue($('.client_select'),
|
||||||
|
client.public_id(),
|
||||||
|
client.name.display());
|
||||||
|
|
||||||
applyComboboxListeners();
|
applyComboboxListeners();
|
||||||
|
refreshPDF();
|
||||||
});
|
});
|
||||||
|
|
||||||
function applyComboboxListeners() {
|
function applyComboboxListeners() {
|
||||||
@ -534,6 +542,11 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
|
if (model.enable.save() != 'enabled') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$('.main_form').submit();
|
$('.main_form').submit();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -609,7 +622,18 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
self.tax_rates.filtered = ko.computed(function() {
|
self.tax_rates.filtered = ko.computed(function() {
|
||||||
return self.tax_rates().slice(1, self.tax_rates().length);
|
var i = 0;
|
||||||
|
for (i; i<self.tax_rates().length; i++) {
|
||||||
|
var taxRate = self.tax_rates()[i];
|
||||||
|
if (taxRate.isEmpty()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//console.log('i is %s', i);
|
||||||
|
var rates = self.tax_rates().concat();
|
||||||
|
rates.splice(i, 1);
|
||||||
|
return rates;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@ -624,6 +648,7 @@
|
|||||||
applyComboboxListeners();
|
applyComboboxListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
self.getBlankTaxRate = function() {
|
self.getBlankTaxRate = function() {
|
||||||
for (var i=0; i<self.tax_rates().length; i++) {
|
for (var i=0; i<self.tax_rates().length; i++) {
|
||||||
var taxRate = self.tax_rates()[i];
|
var taxRate = self.tax_rates()[i];
|
||||||
@ -632,6 +657,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
self.getTaxRate = function(name, rate) {
|
self.getTaxRate = function(name, rate) {
|
||||||
for (var i=0; i<self.tax_rates().length; i++) {
|
for (var i=0; i<self.tax_rates().length; i++) {
|
||||||
@ -640,10 +666,11 @@
|
|||||||
return taxRate;
|
return taxRate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var taxRate = new TaxRateModel();
|
var taxRate = new TaxRateModel();
|
||||||
taxRate.name(name);
|
taxRate.name(name);
|
||||||
taxRate.rate(parseFloat(rate));
|
taxRate.rate(parseFloat(rate));
|
||||||
taxRate.is_deleted(true);
|
if (parseFloat(rate) > 0) taxRate.is_deleted(true);
|
||||||
self.tax_rates.push(taxRate);
|
self.tax_rates.push(taxRate);
|
||||||
return taxRate;
|
return taxRate;
|
||||||
}
|
}
|
||||||
@ -688,9 +715,11 @@
|
|||||||
name = email;
|
name = email;
|
||||||
}
|
}
|
||||||
|
|
||||||
$('.client_select select').combobox('setSelected');
|
setComboboxValue($('.client_select'), -1, name);
|
||||||
$('.client_select input.form-control').val(name);
|
|
||||||
$('.client_select .combobox-container').addClass('combobox-selected');
|
//$('.client_select select').combobox('setSelected');
|
||||||
|
//$('.client_select input.form-control').val(name);
|
||||||
|
//$('.client_select .combobox-container').addClass('combobox-selected');
|
||||||
|
|
||||||
$('#emailError').css( "display", "none" );
|
$('#emailError').css( "display", "none" );
|
||||||
//$('.client_select input.form-control').focus();
|
//$('.client_select input.form-control').focus();
|
||||||
@ -700,6 +729,44 @@
|
|||||||
model.clientBackup = false;
|
model.clientBackup = false;
|
||||||
$('#clientModal').modal('hide');
|
$('#clientModal').modal('hide');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.enable = {};
|
||||||
|
self.enable.save = ko.computed(function() {
|
||||||
|
var isValid = false;
|
||||||
|
|
||||||
|
for (var i=0; i<self.invoice().client().contacts().length; i++) {
|
||||||
|
var contact = self.invoice().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.invoice().client().contacts().length; i++) {
|
||||||
|
var contact = self.invoice().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.clientLinkText = ko.computed(function() {
|
||||||
|
return self.invoice().client().public_id() ? 'Edit client details' : 'Create new client';
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function InvoiceModel(data) {
|
function InvoiceModel(data) {
|
||||||
@ -708,7 +775,7 @@
|
|||||||
this.id = ko.observable('');
|
this.id = ko.observable('');
|
||||||
self.discount = ko.observable('');
|
self.discount = ko.observable('');
|
||||||
self.frequency_id = ko.observable('');
|
self.frequency_id = ko.observable('');
|
||||||
self.currency_id = ko.observable({{ Session::get(SESSION_CURRENCY, DEFAULT_CURRENCY) }});
|
self.currency_id = ko.observable({{ Session::get(SESSION_CURRENCY) }});
|
||||||
self.terms = ko.observable(wordWrapText('{{ $account->invoice_terms }}', 340));
|
self.terms = ko.observable(wordWrapText('{{ $account->invoice_terms }}', 340));
|
||||||
self.public_notes = ko.observable('');
|
self.public_notes = ko.observable('');
|
||||||
self.po_number = ko.observable('');
|
self.po_number = ko.observable('');
|
||||||
@ -799,43 +866,6 @@
|
|||||||
owner: this
|
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.removeItem = function(item) {
|
||||||
self.invoice_items.remove(item);
|
self.invoice_items.remove(item);
|
||||||
@ -933,6 +963,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
self.showContact = function(elem) { if (elem.nodeType === 1) $(elem).hide().slideDown() }
|
self.showContact = function(elem) { if (elem.nodeType === 1) $(elem).hide().slideDown() }
|
||||||
self.hideContact = function(elem) { if (elem.nodeType === 1) $(elem).slideUp(function() { $(elem).remove(); }) }
|
self.hideContact = function(elem) { if (elem.nodeType === 1) $(elem).slideUp(function() { $(elem).remove(); }) }
|
||||||
|
|
||||||
@ -949,17 +980,19 @@
|
|||||||
self.contacts.remove(this);
|
self.contacts.remove(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
self.name.display = ko.computed(function() {
|
||||||
self.placeholderName = ko.computed(function() {
|
if (self.name()) {
|
||||||
|
return self.name();
|
||||||
|
}
|
||||||
if (self.contacts().length == 0) return;
|
if (self.contacts().length == 0) return;
|
||||||
var contact = self.contacts()[0];
|
var contact = self.contacts()[0];
|
||||||
if (contact.first_name() || contact.last_name()) {
|
if (contact.first_name() || contact.last_name()) {
|
||||||
return contact.first_name() + ' ' + contact.last_name();
|
return contact.first_name() + ' ' + contact.last_name();
|
||||||
} else {
|
} else {
|
||||||
return '';
|
return contact.email();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
*/
|
|
||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
ko.mapping.fromJS(data, {}, this);
|
ko.mapping.fromJS(data, {}, this);
|
||||||
@ -992,6 +1025,7 @@
|
|||||||
self.rate = ko.observable(0);
|
self.rate = ko.observable(0);
|
||||||
self.name = ko.observable('');
|
self.name = ko.observable('');
|
||||||
self.is_deleted = ko.observable(false);
|
self.is_deleted = ko.observable(false);
|
||||||
|
self.is_blank = ko.observable(false);
|
||||||
self.actionsVisible = ko.observable(false);
|
self.actionsVisible = ko.observable(false);
|
||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
@ -1012,7 +1046,7 @@
|
|||||||
self.displayName = ko.computed({
|
self.displayName = ko.computed({
|
||||||
read: function () {
|
read: function () {
|
||||||
var name = self.name() ? self.name() : '';
|
var name = self.name() ? self.name() : '';
|
||||||
var rate = self.rate() ? parseFloat(self.rate()) + '% -' : '';
|
var rate = self.rate() ? parseFloat(self.rate()) + '% ' : '';
|
||||||
return rate + name;
|
return rate + name;
|
||||||
},
|
},
|
||||||
write: function (value) {
|
write: function (value) {
|
||||||
@ -1086,8 +1120,7 @@
|
|||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
ko.mapping.fromJS(data, self.mapping, this);
|
ko.mapping.fromJS(data, self.mapping, this);
|
||||||
//if (this.cost()) this.cost(formatMoney(this.cost(), parent.invoice.currency_id(), true)); // TODO_FIX
|
//if (this.cost()) this.cost(formatMoney(this.cost(), model ? model.invoice().currency_id() : 1, true));
|
||||||
if (this.cost()) this.cost(formatMoney(this.cost(), 1, true));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.wrapped_notes = ko.computed({
|
self.wrapped_notes = ko.computed({
|
||||||
@ -1159,6 +1192,7 @@
|
|||||||
function onTaxRateChange()
|
function onTaxRateChange()
|
||||||
{
|
{
|
||||||
var emptyCount = 0;
|
var emptyCount = 0;
|
||||||
|
|
||||||
for(var i=0; i<model.tax_rates().length; i++) {
|
for(var i=0; i<model.tax_rates().length; i++) {
|
||||||
var taxRate = model.tax_rates()[i];
|
var taxRate = model.tax_rates()[i];
|
||||||
if (taxRate.isEmpty()) {
|
if (taxRate.isEmpty()) {
|
||||||
@ -1166,7 +1200,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (emptyCount < 2) {
|
for(var i=0; i<2-emptyCount; i++) {
|
||||||
model.addTaxRate();
|
model.addTaxRate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1203,16 +1237,18 @@
|
|||||||
var contact = client.contacts[i];
|
var contact = client.contacts[i];
|
||||||
contact.send_invoice = invitationContactIds.indexOf(contact.public_id) >= 0;
|
contact.send_invoice = invitationContactIds.indexOf(contact.public_id) >= 0;
|
||||||
}
|
}
|
||||||
@endif
|
|
||||||
model.invoice().addItem();
|
model.invoice().addItem();
|
||||||
model.addTaxRate();
|
//model.addTaxRate();
|
||||||
|
@endif
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
model.invoice().tax(model.getTaxRate(model.invoice().tax_name(), model.invoice().tax_rate()));
|
model.invoice().tax(model.getTaxRate(model.invoice().tax_name(), model.invoice().tax_rate()));
|
||||||
for (var i=0; i<model.invoice().invoice_items().length; i++) {
|
for (var i=0; i<model.invoice().invoice_items().length; i++) {
|
||||||
var item = model.invoice().invoice_items()[i];
|
var item = model.invoice().invoice_items()[i];
|
||||||
item.tax(model.getTaxRate(item.tax_name(), item.tax_rate()));
|
item.tax(model.getTaxRate(item.tax_name(), item.tax_rate()));
|
||||||
|
item.cost(parseFloat(item.cost()) > 0 ? formatMoney(item.cost(), model.invoice().currency_id(), true) : '');
|
||||||
}
|
}
|
||||||
|
onTaxRateChange();
|
||||||
|
|
||||||
if (!model.invoice().discount()) model.invoice().discount('');
|
if (!model.invoice().discount()) model.invoice().discount('');
|
||||||
|
|
||||||
|
@ -120,7 +120,7 @@
|
|||||||
for (var i=0; i<list.length; i++) {
|
for (var i=0; i<list.length; i++) {
|
||||||
var invoice = list[i];
|
var invoice = list[i];
|
||||||
var client = clientMap[invoice.client.public_id];
|
var client = clientMap[invoice.client.public_id];
|
||||||
$invoiceCombobox.append(new Option(invoice.invoice_number + ' - ' + getClientDisplayName(client), invoice.public_id));
|
$invoiceCombobox.append(new Option(invoice.invoice_number + ' - ' + getClientDisplayName(client) + ' - ' + formatMoney(invoice.balance, invoice.currency_id), invoice.public_id));
|
||||||
}
|
}
|
||||||
$('select#invoice').combobox('refresh');
|
$('select#invoice').combobox('refresh');
|
||||||
}).trigger('change');
|
}).trigger('change');
|
||||||
|
2
public/js/bootstrap-combobox.js
vendored
2
public/js/bootstrap-combobox.js
vendored
@ -326,6 +326,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
, keyup: function (e) {
|
, keyup: function (e) {
|
||||||
|
console.log('keyCode: %s', e.keyCode);
|
||||||
switch(e.keyCode) {
|
switch(e.keyCode) {
|
||||||
case 40: // down arrow
|
case 40: // down arrow
|
||||||
case 39: // right arrow
|
case 39: // right arrow
|
||||||
@ -353,7 +354,6 @@
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
console.log('keyCode: %s', e.keyCode);
|
|
||||||
this.clearTarget();
|
this.clearTarget();
|
||||||
this.lookup();
|
this.lookup();
|
||||||
}
|
}
|
||||||
|
@ -237,7 +237,7 @@ function generatePDF(invoice) {
|
|||||||
|
|
||||||
x += 16;
|
x += 16;
|
||||||
doc.text(footerLeft, x, 'Paid to Date');
|
doc.text(footerLeft, x, 'Paid to Date');
|
||||||
var paid = formatMoney(0, currencyId, true);
|
var paid = formatMoney(invoice.amount - invoice.balance, currencyId, true);
|
||||||
var paidX = headerRight - (doc.getStringUnitWidth(paid) * doc.internal.getFontSize());
|
var paidX = headerRight - (doc.getStringUnitWidth(paid) * doc.internal.getFontSize());
|
||||||
doc.text(paidX, x, paid);
|
doc.text(paidX, x, paid);
|
||||||
|
|
||||||
@ -246,7 +246,7 @@ function generatePDF(invoice) {
|
|||||||
doc.setFontType("bold");
|
doc.setFontType("bold");
|
||||||
doc.text(footerLeft, x, 'Balance Due');
|
doc.text(footerLeft, x, 'Balance Due');
|
||||||
|
|
||||||
var total = formatMoney(total, currencyId);
|
var total = formatMoney(invoice.balance, currencyId);
|
||||||
var totalX = headerRight - (doc.getStringUnitWidth(total) * doc.internal.getFontSize());
|
var totalX = headerRight - (doc.getStringUnitWidth(total) * doc.internal.getFontSize());
|
||||||
doc.text(totalX, x, total);
|
doc.text(totalX, x, total);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user