Enabled fixed amount discounts

This commit is contained in:
Hillel Coren 2014-12-04 00:05:38 +02:00
parent 6b519f6833
commit dcc852eafa
27 changed files with 171 additions and 41 deletions

View File

@ -41,7 +41,7 @@ class DashboardController extends \BaseController {
->orderBy('due_date', 'asc')->take(6)->get(); ->orderBy('due_date', 'asc')->take(6)->get();
$upcoming = Invoice::scope() $upcoming = Invoice::scope()
->where('due_date', '>', date('Y-m-d')) ->where('due_date', '>=', date('Y-m-d'))
->where('balance', '>', 0) ->where('balance', '>', 0)
->where('is_recurring', '=', false) ->where('is_recurring', '=', false)
->where('is_quote', '=', false) ->where('is_quote', '=', false)

View File

@ -186,8 +186,15 @@ class InvoiceController extends \BaseController {
$invoice->invoice_date = Utils::fromSqlDate($invoice->invoice_date); $invoice->invoice_date = Utils::fromSqlDate($invoice->invoice_date);
$invoice->due_date = Utils::fromSqlDate($invoice->due_date); $invoice->due_date = Utils::fromSqlDate($invoice->due_date);
$invoice->is_pro = $client->account->isPro(); $invoice->is_pro = $client->account->isPro();
$contact = $invitation->contact;
$contact->setVisible([
'first_name',
'last_name',
'email',
'phone']);
$data = array( $data = array(
'showClientHeader' => true, 'showClientHeader' => true,
'showBreadcrumbs' => false, 'showBreadcrumbs' => false,
@ -195,6 +202,7 @@ class InvoiceController extends \BaseController {
'invoice' => $invoice->hidePrivateFields(), 'invoice' => $invoice->hidePrivateFields(),
'invitation' => $invitation, 'invitation' => $invitation,
'invoiceLabels' => $client->account->getInvoiceLabels(), 'invoiceLabels' => $client->account->getInvoiceLabels(),
'contact' => $contact
); );
return View::make('invoices.view', $data); return View::make('invoices.view', $data);
@ -347,7 +355,6 @@ class InvoiceController extends \BaseController {
} }
$input = json_decode(Input::get('data')); $input = json_decode(Input::get('data'));
$invoice = $input->invoice; $invoice = $input->invoice;
if ($errors = $this->invoiceRepo->getErrors($invoice)) if ($errors = $this->invoiceRepo->getErrors($invoice))

View File

@ -498,7 +498,7 @@ class PaymentController extends \BaseController
{ {
$errorMessage = trans('texts.payment_error'); $errorMessage = trans('texts.payment_error');
Session::flash('error', $errorMessage); Session::flash('error', $errorMessage);
Utils::logError($e->getMessage()); Utils::logError(Utils::getErrorString($e));
return Redirect::to('license')->withInput(); return Redirect::to('license')->withInput();
} }
} }
@ -653,7 +653,7 @@ class PaymentController extends \BaseController
{ {
$errorMessage = trans('texts.payment_error'); $errorMessage = trans('texts.payment_error');
Session::flash('error', $errorMessage); Session::flash('error', $errorMessage);
Utils::logError($e->getMessage()); Utils::logError(Utils::getErrorString($e));
return Redirect::to('payment/' . $invitationKey) return Redirect::to('payment/' . $invitationKey)
->withInput(); ->withInput();
} }

View File

@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddDiscountType extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('invoices', function($table)
{
$table->boolean('is_amount_discount')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('invoices', function($table)
{
$table->dropColumn('is_amount_discount');
});
}
}

View File

@ -490,6 +490,8 @@ return array(
'restored_credit' => 'Successfully restored credit', 'restored_credit' => 'Successfully restored credit',
'reason_for_canceling' => 'Help us improve our site by telling us why you\'re leaving.', 'reason_for_canceling' => 'Help us improve our site by telling us why you\'re leaving.',
'discount_percent' => 'Percent',
'discount_amount' => 'Amount',
); );

View File

@ -479,6 +479,9 @@ return array(
'restored_payment' => 'Successfully restored payment', 'restored_payment' => 'Successfully restored payment',
'restored_credit' => 'Successfully restored credit', 'restored_credit' => 'Successfully restored credit',
'reason_for_canceling' => 'Help us improve our site by telling us why you\'re leaving.',
'discount_percent' => 'Percent',
'discount_amount' => 'Amount',

View File

@ -488,6 +488,7 @@ return array(
'restored_credit' => 'Successfully restored credit', 'restored_credit' => 'Successfully restored credit',
'reason_for_canceling' => 'Help us improve our site by telling us why you\'re leaving.', 'reason_for_canceling' => 'Help us improve our site by telling us why you\'re leaving.',
'discount_percent' => 'Percent',
'discount_amount' => 'Amount',
); );

View File

@ -460,6 +460,8 @@ return array(
'restored_credit' => 'Successfully restored credit', 'restored_credit' => 'Successfully restored credit',
'reason_for_canceling' => 'Help us improve our site by telling us why you\'re leaving.', 'reason_for_canceling' => 'Help us improve our site by telling us why you\'re leaving.',
'discount_percent' => 'Percent',
'discount_amount' => 'Amount',
); );

View File

@ -481,6 +481,8 @@ return array(
'restored_credit' => 'Successfully restored credit', 'restored_credit' => 'Successfully restored credit',
'reason_for_canceling' => 'Help us improve our site by telling us why you\'re leaving.', 'reason_for_canceling' => 'Help us improve our site by telling us why you\'re leaving.',
'discount_percent' => 'Percent',
'discount_amount' => 'Amount',
); );

View File

@ -483,6 +483,8 @@ return array(
'restored_credit' => 'Successfully restored credit', 'restored_credit' => 'Successfully restored credit',
'reason_for_canceling' => 'Help us improve our site by telling us why you\'re leaving.', 'reason_for_canceling' => 'Help us improve our site by telling us why you\'re leaving.',
'discount_percent' => 'Percent',
'discount_amount' => 'Amount',

View File

@ -491,6 +491,8 @@ return array(
'restored_credit' => 'Successfully restored credit', 'restored_credit' => 'Successfully restored credit',
'reason_for_canceling' => 'Help us improve our site by telling us why you\'re leaving.', 'reason_for_canceling' => 'Help us improve our site by telling us why you\'re leaving.',
'discount_percent' => 'Percent',
'discount_amount' => 'Amount',
); );

View File

@ -489,6 +489,8 @@ return array(
'restored_credit' => 'Successfully restored credit', 'restored_credit' => 'Successfully restored credit',
'reason_for_canceling' => 'Help us improve our site by telling us why you\'re leaving.', 'reason_for_canceling' => 'Help us improve our site by telling us why you\'re leaving.',
'discount_percent' => 'Percent',
'discount_amount' => 'Amount',

View File

@ -484,7 +484,9 @@ return array(
'restored_credit' => 'Successfully restored credit', 'restored_credit' => 'Successfully restored credit',
'reason_for_canceling' => 'Help us improve our site by telling us why you\'re leaving.', 'reason_for_canceling' => 'Help us improve our site by telling us why you\'re leaving.',
'discount_percent' => 'Percent',
'discount_amount' => 'Amount',
); );

View File

@ -471,6 +471,8 @@ return array(
'restored_credit' => 'Successfully restored credit', 'restored_credit' => 'Successfully restored credit',
'reason_for_canceling' => 'Help us improve our site by telling us why you\'re leaving.', 'reason_for_canceling' => 'Help us improve our site by telling us why you\'re leaving.',
'discount_percent' => 'Percent',
'discount_amount' => 'Amount',

View File

@ -140,6 +140,11 @@ class Utils
return View::make('error', $data)->with('error', $message); return View::make('error', $data)->with('error', $message);
} }
public static function getErrorString($exception)
{
return "{$exception->getFile()} [Line {$exception->getLine()}] => {$exception->getMessage()}";
}
public static function logError($error, $context = 'PHP') public static function logError($error, $context = 'PHP')
{ {
$count = Session::get('error_count', 0); $count = Session::get('error_count', 0);

View File

@ -34,7 +34,7 @@ class Invoice extends EntityModel
public function invitations() public function invitations()
{ {
return $this->hasMany('Invitation'); return $this->hasMany('Invitation')->orderBy('invitations.contact_id');
} }
public function getName() public function getName()
@ -72,6 +72,7 @@ class Invoice extends EntityModel
$this->setVisible([ $this->setVisible([
'invoice_number', 'invoice_number',
'discount', 'discount',
'is_amount_discount',
'po_number', 'po_number',
'invoice_date', 'invoice_date',
'due_date', 'due_date',
@ -95,8 +96,8 @@ class Invoice extends EntityModel
$this->client->setVisible([ $this->client->setVisible([
'name', 'name',
'id_number', 'id_number',
'vat_number', 'vat_number',
'address1', 'address1',
'address2', 'address2',
'city', 'city',
@ -112,8 +113,8 @@ class Invoice extends EntityModel
$this->account->setVisible([ $this->account->setVisible([
'name', 'name',
'id_number', 'id_number',
'vat_number', 'vat_number',
'address1', 'address1',
'address2', 'address2',
'city', 'city',

View File

@ -214,7 +214,10 @@ class InvoiceRepository
$invoice = (array) $input; $invoice = (array) $input;
$invoiceId = isset($invoice['public_id']) && $invoice['public_id'] ? Invoice::getPrivateId($invoice['public_id']) : null; $invoiceId = isset($invoice['public_id']) && $invoice['public_id'] ? Invoice::getPrivateId($invoice['public_id']) : null;
$rules = ['invoice_number' => 'required|unique:invoices,invoice_number,' . $invoiceId . ',id,account_id,' . \Auth::user()->account_id]; $rules = [
'invoice_number' => 'required|unique:invoices,invoice_number,' . $invoiceId . ',id,account_id,' . \Auth::user()->account_id,
'discount' => 'positive'
];
if ($invoice['is_recurring'] && $invoice['start_date'] && $invoice['end_date']) if ($invoice['is_recurring'] && $invoice['start_date'] && $invoice['end_date'])
{ {
@ -248,7 +251,8 @@ class InvoiceRepository
} }
$invoice->client_id = $data['client_id']; $invoice->client_id = $data['client_id'];
$invoice->discount = Utils::parseFloat($data['discount']); $invoice->discount = round(Utils::parseFloat($data['discount']), 2);
$invoice->is_amount_discount = $data['is_amount_discount'] ? true : false;
$invoice->invoice_number = trim($data['invoice_number']); $invoice->invoice_number = trim($data['invoice_number']);
$invoice->is_recurring = $data['is_recurring'] && !Utils::isDemo() ? true : false; $invoice->is_recurring = $data['is_recurring'] && !Utils::isDemo() ? true : false;
$invoice->invoice_date = Utils::toSqlDate($data['invoice_date']); $invoice->invoice_date = Utils::toSqlDate($data['invoice_date']);
@ -309,7 +313,14 @@ class InvoiceRepository
if ($invoice->discount > 0) if ($invoice->discount > 0)
{ {
$total *= (100 - $invoice->discount) / 100; if ($invoice->is_amount_discount)
{
$total -= $invoice->discount;
}
else
{
$total *= (100 - $invoice->discount) / 100;
}
} }
$invoice->custom_value1 = round($data['custom_value1'], 2); $invoice->custom_value1 = round($data['custom_value1'], 2);
@ -430,6 +441,7 @@ class InvoiceRepository
foreach ([ foreach ([
'client_id', 'client_id',
'discount', 'discount',
'is_amount_discount',
'invoice_date', 'invoice_date',
'po_number', 'po_number',
'due_date', 'due_date',

View File

@ -56,7 +56,7 @@ class PaymentRepository
->where('clients.is_deleted', '=', false) ->where('clients.is_deleted', '=', false)
->where('payments.is_deleted', '=', false) ->where('payments.is_deleted', '=', false)
->where('invitations.deleted_at', '=', null) ->where('invitations.deleted_at', '=', null)
->where('contacts.id', '=', $contactId) ->where('invitations.contact_id', '=', $contactId)
->select('invitations.invitation_key', 'payments.public_id', 'payments.transaction_reference', 'clients.name as client_name', 'clients.public_id as client_public_id', 'payments.amount', 'payments.payment_date', 'invoices.public_id as invoice_public_id', 'invoices.invoice_number', 'clients.currency_id', 'contacts.first_name', 'contacts.last_name', 'contacts.email', 'payment_types.name as payment_type', 'payments.account_gateway_id'); ->select('invitations.invitation_key', 'payments.public_id', 'payments.transaction_reference', 'clients.name as client_name', 'clients.public_id as client_public_id', 'payments.amount', 'payments.payment_date', 'invoices.public_id as invoice_public_id', 'invoices.invoice_number', 'clients.currency_id', 'contacts.first_name', 'contacts.last_name', 'contacts.email', 'payment_types.name as payment_type', 'payments.account_gateway_id');
if ($filter) if ($filter)

View File

@ -395,7 +395,7 @@ function otrans($text)
Validator::extend('positive', function($attribute, $value, $parameters) Validator::extend('positive', function($attribute, $value, $parameters)
{ {
return Utils::parseFloat($value) > 0; return Utils::parseFloat($value) >= 0;
}); });
Validator::extend('has_credit', function($attribute, $value, $parameters) Validator::extend('has_credit', function($attribute, $value, $parameters)

View File

@ -60,7 +60,7 @@ App::error(function(Exception $exception, $code)
{ {
if (Utils::isNinjaProd()) if (Utils::isNinjaProd())
{ {
Utils::logError("{$code} {$exception->getFile()} [Line {$exception->getLine()}] => {$exception->getMessage()}"); Utils::logError($code . ' ' . Utils::getErrorString($exception));
return Response::view('error', ['hideHeader' => true, 'error' => "A {$code} error occurred."], $code); return Response::view('error', ['hideHeader' => true, 'error' => "A {$code} error occurred."], $code);
} }
else else

View File

@ -361,7 +361,7 @@ Want something changed? We're {{ link_to('https://github.com/hillelcoren/invoice
</div> </div>
<div style="background-color: #fff; padding:20px"> <div style="background-color: #fff; padding:20px">
<h4>{{ trans('texts.white_label_text')}}</h4> <p>{{ trans('texts.white_label_text')}}</p>
</div> </div>
<div class="modal-footer" id="signUpFooter" style="margin-top: 0px"> <div class="modal-footer" id="signUpFooter" style="margin-top: 0px">

View File

@ -19,7 +19,7 @@
{{ Former::open($url)->method($method)->addClass('warn-on-exit')->rules(array( {{ Former::open($url)->method($method)->addClass('warn-on-exit')->rules(array(
'client' => 'required', 'client' => 'required',
'email' => 'required', 'email' => 'required',
'product_key' => 'max:20', 'product_key' => 'max:20'
)) }} )) }}
<input type="submit" style="display:none" name="submitButton" id="submitButton"> <input type="submit" style="display:none" name="submitButton" id="submitButton">
@ -53,7 +53,7 @@
<div data-bind="with: client"> <div data-bind="with: client">
<div style="display:none" class="form-group" data-bind="visible: contacts().length > 0 &amp;&amp; contacts()[0].email(), foreach: contacts"> <div style="display:none" class="form-group" data-bind="visible: contacts().length > 0 &amp;&amp; contacts()[0].email(), foreach: contacts">
<div class="col-lg-8 col-lg-offset-4"> <div class="col-lg-8 col-lg-offset-4">
<label for="test" class="checkbox" data-bind="attr: {for: $index() + '_check'}"> <label class="checkbox" data-bind="attr: {for: $index() + '_check'}" onclick="refreshPDF()">
<input type="checkbox" value="1" data-bind="checked: send_invoice, attr: {id: $index() + '_check'}"> <input type="checkbox" value="1" data-bind="checked: send_invoice, attr: {id: $index() + '_check'}">
<span data-bind="html: email.display"/> <span data-bind="html: email.display"/>
</label> </label>
@ -94,7 +94,11 @@
<div class="col-md-4" id="col_2"> <div class="col-md-4" id="col_2">
{{ Former::text('invoice_number')->label(trans("texts.{$entityType}_number_short"))->data_bind("value: invoice_number, valueUpdate: 'afterkeydown'") }} {{ Former::text('invoice_number')->label(trans("texts.{$entityType}_number_short"))->data_bind("value: invoice_number, valueUpdate: 'afterkeydown'") }}
{{ Former::text('po_number')->label(trans('texts.po_number_short'))->data_bind("value: po_number, valueUpdate: 'afterkeydown'") }} {{ Former::text('po_number')->label(trans('texts.po_number_short'))->data_bind("value: po_number, valueUpdate: 'afterkeydown'") }}
{{ Former::text('discount')->data_bind("value: discount, valueUpdate: 'afterkeydown'")->append('%') }} {{ Former::text('discount')->data_bind("value: discount, valueUpdate: 'afterkeydown'")
->addGroupClass('discount-group')->type('number')->min('0')->step('any')->append(
Former::select('is_amount_discount')->addOption(trans('texts.discount_percent'), '0')
->addOption(trans('texts.discount_amount'), '1')->data_bind("value: is_amount_discount")->raw()
) }}
{{-- Former::select('currency_id')->addOption('', '')->fromQuery($currencies, 'name', 'id')->data_bind("value: currency_id") --}} {{-- Former::select('currency_id')->addOption('', '')->fromQuery($currencies, 'name', 'id')->data_bind("value: currency_id") --}}
<div class="form-group" style="margin-bottom: 8px"> <div class="form-group" style="margin-bottom: 8px">
@ -175,7 +179,7 @@
<td style="text-align: right"><span data-bind="text: totals.subtotal"/></td> <td style="text-align: right"><span data-bind="text: totals.subtotal"/></td>
</tr> </tr>
<tr style="display:none" data-bind="visible: discount() > 0"> <tr style="display:none" data-bind="visible: discount() != 0">
<td class="hide-border" colspan="3"/> <td class="hide-border" colspan="3"/>
<td style="display:none" class="hide-border" data-bind="visible: $root.invoice_item_taxes.show"/> <td style="display:none" class="hide-border" data-bind="visible: $root.invoice_item_taxes.show"/>
<td colspan="{{ $account->hide_quantity ? 1 : 2 }}">{{ trans('texts.discount') }}</td> <td colspan="{{ $account->hide_quantity ? 1 : 2 }}">{{ trans('texts.discount') }}</td>
@ -558,7 +562,7 @@
}); });
} }
$('#terms, #public_notes, #invoice_number, #invoice_date, #due_date, #po_number, #discount, #currency_id, #invoice_design_id, #recurring').change(function() { $('#terms, #public_notes, #invoice_number, #invoice_date, #due_date, #po_number, #discount, #currency_id, #invoice_design_id, #recurring, #is_amount_discount').change(function() {
setTimeout(function() { setTimeout(function() {
refreshPDF(); refreshPDF();
}, 1); }, 1);
@ -639,6 +643,7 @@
var invoice = ko.toJS(model).invoice; var invoice = ko.toJS(model).invoice;
invoice.is_pro = {{ Auth::user()->isPro() ? 'true' : 'false' }}; invoice.is_pro = {{ Auth::user()->isPro() ? 'true' : 'false' }};
invoice.is_quote = {{ $entityType == ENTITY_QUOTE ? 'true' : 'false' }}; invoice.is_quote = {{ $entityType == ENTITY_QUOTE ? 'true' : 'false' }};
invoice.contact = _.findWhere(invoice.client.contacts, {send_invoice: true});
@if (file_exists($account->getLogoPath())) @if (file_exists($account->getLogoPath()))
invoice.image = "{{ HTML::image_data($account->getLogoPath()) }}"; invoice.image = "{{ HTML::image_data($account->getLogoPath()) }}";
@ -1003,6 +1008,7 @@
self.account = {{ $account }}; self.account = {{ $account }};
this.id = ko.observable(''); this.id = ko.observable('');
self.discount = ko.observable(''); self.discount = ko.observable('');
self.is_amount_discount = ko.observable(0);
self.frequency_id = ko.observable(''); self.frequency_id = ko.observable('');
//self.currency_id = ko.observable({{ $client && $client->currency_id ? $client->currency_id : Session::get(SESSION_CURRENCY) }}); //self.currency_id = ko.observable({{ $client && $client->currency_id ? $client->currency_id : Session::get(SESSION_CURRENCY) }});
self.terms = ko.observable(wordWrapText('{{ str_replace(["\r\n","\r","\n"], '\n', addslashes($account->invoice_terms)) }}', 300)); self.terms = ko.observable(wordWrapText('{{ str_replace(["\r\n","\r","\n"], '\n', addslashes($account->invoice_terms)) }}', 300));
@ -1114,9 +1120,9 @@
} }
this.totals = ko.observable(); self.totals = ko.observable();
this.totals.rawSubtotal = ko.computed(function() { self.totals.rawSubtotal = ko.computed(function() {
var total = 0; var total = 0;
for(var p=0; p < self.invoice_items().length; ++p) { for(var p=0; p < self.invoice_items().length; ++p) {
var item = self.invoice_items()[p]; var item = self.invoice_items()[p];
@ -1125,26 +1131,34 @@
return total; return total;
}); });
this.totals.subtotal = ko.computed(function() { self.totals.subtotal = ko.computed(function() {
var total = self.totals.rawSubtotal(); var total = self.totals.rawSubtotal();
return total > 0 ? formatMoney(total, self.client().currency_id()) : ''; return total > 0 ? formatMoney(total, self.client().currency_id()) : '';
}); });
this.totals.rawDiscounted = ko.computed(function() { self.totals.rawDiscounted = ko.computed(function() {
return roundToTwo(self.totals.rawSubtotal() * (self.discount()/100)); if (parseInt(self.is_amount_discount())) {
return roundToTwo(self.discount());
} else {
return roundToTwo(self.totals.rawSubtotal() * (self.discount()/100));
}
}); });
this.totals.discounted = ko.computed(function() { self.totals.discounted = ko.computed(function() {
return formatMoney(self.totals.rawDiscounted(), self.client().currency_id()); return formatMoney(self.totals.rawDiscounted(), self.client().currency_id());
}); });
self.totals.taxAmount = ko.computed(function() { self.totals.taxAmount = ko.computed(function() {
var total = self.totals.rawSubtotal(); var total = self.totals.rawSubtotal();
var discount = self.totals.rawDiscounted();
total -= discount;
/*
var discount = parseFloat(self.discount()); var discount = parseFloat(self.discount());
if (discount > 0) { if (discount > 0) {
total = roundToTwo(total * ((100 - discount)/100)); total = roundToTwo(total * ((100 - discount)/100));
} }
*/
var customValue1 = roundToTwo(self.custom_value1()); var customValue1 = roundToTwo(self.custom_value1());
var customValue2 = roundToTwo(self.custom_value2()); var customValue2 = roundToTwo(self.custom_value2());
@ -1178,11 +1192,15 @@
this.totals.total = ko.computed(function() { this.totals.total = ko.computed(function() {
var total = accounting.toFixed(self.totals.rawSubtotal(),2); var total = accounting.toFixed(self.totals.rawSubtotal(),2);
var discount = self.totals.rawDiscounted();
total -= discount;
/*
var discount = parseFloat(self.discount()); var discount = parseFloat(self.discount());
if (discount > 0) { if (discount > 0) {
total = roundToTwo(total * ((100 - discount)/100)); total = roundToTwo(total * ((100 - discount)/100));
} }
*/
var customValue1 = roundToTwo(self.custom_value1()); var customValue1 = roundToTwo(self.custom_value1());
var customValue2 = roundToTwo(self.custom_value2()); var customValue2 = roundToTwo(self.custom_value2());
@ -1577,12 +1595,12 @@
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(NINJA.parseFloat(item.cost()) > 0 ? roundToTwo(item.cost(), true) : ''); item.cost(NINJA.parseFloat(item.cost()) != 0 ? roundToTwo(item.cost(), true) : '');
} }
onTaxRateChange(); onTaxRateChange();
// display blank instead of '0' // display blank instead of '0'
if (!model.invoice().discount()) model.invoice().discount(''); if (!NINJA.parseFloat(model.invoice().discount())) model.invoice().discount('');
if (!model.invoice().custom_value1()) model.invoice().custom_value1(''); if (!model.invoice().custom_value1()) model.invoice().custom_value1('');
if (!model.invoice().custom_value2()) model.invoice().custom_value2(''); if (!model.invoice().custom_value2()) model.invoice().custom_value2('');

View File

@ -41,6 +41,7 @@
window.invoice = {{ $invoice->toJson() }}; window.invoice = {{ $invoice->toJson() }};
invoice.is_pro = {{ $invoice->client->account->isPro() ? 'true' : 'false' }}; invoice.is_pro = {{ $invoice->client->account->isPro() ? 'true' : 'false' }};
invoice.is_quote = {{ $invoice->is_quote ? 'true' : 'false' }}; invoice.is_quote = {{ $invoice->is_quote ? 'true' : 'false' }};
invoice.contact = {{ $contact->toJson() }};
function getPDFString() { function getPDFString() {
var doc = generatePDF(invoice, invoice.invoice_design.javascript); var doc = generatePDF(invoice, invoice.invoice_design.javascript);

View File

@ -3343,6 +3343,15 @@ body {
transition: all 0.5s ease; transition: all 0.5s ease;
} }
div.discount-group span {
padding: 0px;
border: none;
}
#is_amount_discount {
min-width: 120px;
}
/*********************************************** /***********************************************
New/edit invoice page New/edit invoice page
************************************************/ ************************************************/

View File

@ -31627,7 +31627,7 @@ function displayClient(doc, invoice, x, y, layout) {
concatStrings(client.address1, client.address2), concatStrings(client.address1, client.address2),
concatStrings(client.city, client.state, client.postal_code), concatStrings(client.city, client.state, client.postal_code),
client.country ? client.country.name : false, client.country ? client.country.name : false,
client.contacts && getClientDisplayName(client) != client.contacts[0].email ? client.contacts[0].email : false, invoice.contact && getClientDisplayName(client) != invoice.contact.email ? invoice.contact.email : false,
invoice.client.custom_value1 ? invoice.account['custom_client_label1'] + ' ' + invoice.client.custom_value1 : false, invoice.client.custom_value1 ? invoice.account['custom_client_label1'] + ' ' + invoice.client.custom_value1 : false,
invoice.client.custom_value2 ? invoice.account['custom_client_label2'] + ' ' + invoice.client.custom_value2 : false, invoice.client.custom_value2 ? invoice.account['custom_client_label2'] + ' ' + invoice.client.custom_value2 : false,
]; ];
@ -31686,7 +31686,7 @@ function displaySubtotals(doc, layout, invoice, y, rightAlignTitleX)
var data = [ var data = [
{'subtotal': formatMoney(invoice.subtotal_amount, invoice.client.currency_id)}, {'subtotal': formatMoney(invoice.subtotal_amount, invoice.client.currency_id)},
{'discount': invoice.discount_amount > 0 ? formatMoney(invoice.discount_amount, invoice.client.currency_id) : false} {'discount': invoice.discount_amount != 0 ? formatMoney(invoice.discount_amount, invoice.client.currency_id) : false}
]; ];
if (NINJA.parseFloat(invoice.custom_value1) && invoice.custom_taxes1 == '1') { if (NINJA.parseFloat(invoice.custom_value1) && invoice.custom_taxes1 == '1') {
@ -31791,6 +31791,8 @@ function displayGrid(doc, invoice, data, x, y, layout, options) {
key = invoice.account[key]; key = invoice.account[key];
} else if (key === 'tax' && invoice.tax_rate) { } else if (key === 'tax' && invoice.tax_rate) {
key = invoiceLabels[key] + ' ' + (invoice.tax_rate*1).toString() + '%'; key = invoiceLabels[key] + ' ' + (invoice.tax_rate*1).toString() + '%';
} else if (key === 'discount' && NINJA.parseFloat(invoice.discount) && !parseInt(invoice.is_amount_discount)) {
key = invoiceLabels[key] + ' ' + parseFloat(invoice.discount) + '%';
} else { } else {
key = invoiceLabels[key]; key = invoiceLabels[key];
} }
@ -31863,8 +31865,13 @@ function calculateAmounts(invoice) {
invoice.subtotal_amount = total; invoice.subtotal_amount = total;
if (invoice.discount > 0) { var discount = 0;
var discount = roundToTwo(total * (invoice.discount/100)); if (invoice.discount != 0) {
if (parseInt(invoice.is_amount_discount)) {
discount = roundToTwo(invoice.discount);
} else {
discount = roundToTwo(total * (invoice.discount/100));
}
total -= discount; total -= discount;
} }

View File

@ -543,6 +543,15 @@ body {
transition: all 0.5s ease; transition: all 0.5s ease;
} }
div.discount-group span {
padding: 0px;
border: none;
}
#is_amount_discount {
min-width: 120px;
}
/*********************************************** /***********************************************
New/edit invoice page New/edit invoice page
************************************************/ ************************************************/

View File

@ -670,7 +670,7 @@ function displayClient(doc, invoice, x, y, layout) {
concatStrings(client.address1, client.address2), concatStrings(client.address1, client.address2),
concatStrings(client.city, client.state, client.postal_code), concatStrings(client.city, client.state, client.postal_code),
client.country ? client.country.name : false, client.country ? client.country.name : false,
client.contacts && getClientDisplayName(client) != client.contacts[0].email ? client.contacts[0].email : false, invoice.contact && getClientDisplayName(client) != invoice.contact.email ? invoice.contact.email : false,
invoice.client.custom_value1 ? invoice.account['custom_client_label1'] + ' ' + invoice.client.custom_value1 : false, invoice.client.custom_value1 ? invoice.account['custom_client_label1'] + ' ' + invoice.client.custom_value1 : false,
invoice.client.custom_value2 ? invoice.account['custom_client_label2'] + ' ' + invoice.client.custom_value2 : false, invoice.client.custom_value2 ? invoice.account['custom_client_label2'] + ' ' + invoice.client.custom_value2 : false,
]; ];
@ -729,7 +729,7 @@ function displaySubtotals(doc, layout, invoice, y, rightAlignTitleX)
var data = [ var data = [
{'subtotal': formatMoney(invoice.subtotal_amount, invoice.client.currency_id)}, {'subtotal': formatMoney(invoice.subtotal_amount, invoice.client.currency_id)},
{'discount': invoice.discount_amount > 0 ? formatMoney(invoice.discount_amount, invoice.client.currency_id) : false} {'discount': invoice.discount_amount != 0 ? formatMoney(invoice.discount_amount, invoice.client.currency_id) : false}
]; ];
if (NINJA.parseFloat(invoice.custom_value1) && invoice.custom_taxes1 == '1') { if (NINJA.parseFloat(invoice.custom_value1) && invoice.custom_taxes1 == '1') {
@ -834,6 +834,8 @@ function displayGrid(doc, invoice, data, x, y, layout, options) {
key = invoice.account[key]; key = invoice.account[key];
} else if (key === 'tax' && invoice.tax_rate) { } else if (key === 'tax' && invoice.tax_rate) {
key = invoiceLabels[key] + ' ' + (invoice.tax_rate*1).toString() + '%'; key = invoiceLabels[key] + ' ' + (invoice.tax_rate*1).toString() + '%';
} else if (key === 'discount' && NINJA.parseFloat(invoice.discount) && !parseInt(invoice.is_amount_discount)) {
key = invoiceLabels[key] + ' ' + parseFloat(invoice.discount) + '%';
} else { } else {
key = invoiceLabels[key]; key = invoiceLabels[key];
} }
@ -906,8 +908,13 @@ function calculateAmounts(invoice) {
invoice.subtotal_amount = total; invoice.subtotal_amount = total;
if (invoice.discount > 0) { var discount = 0;
var discount = roundToTwo(total * (invoice.discount/100)); if (invoice.discount != 0) {
if (parseInt(invoice.is_amount_discount)) {
discount = roundToTwo(invoice.discount);
} else {
discount = roundToTwo(total * (invoice.discount/100));
}
total -= discount; total -= discount;
} }