line item discounts

This commit is contained in:
Hillel Coren 2017-12-21 16:30:18 +02:00
parent f37559a239
commit 15b5860ffe
6 changed files with 150 additions and 137 deletions

View File

@ -40,6 +40,7 @@ class InvoiceItem extends EntityModel
'tax_name2', 'tax_name2',
'tax_rate2', 'tax_rate2',
'invoice_item_type_id', 'invoice_item_type_id',
'discount',
]; ];
/** /**

View File

@ -186,6 +186,7 @@ trait PresentsInvoice
'product.custom_value2', 'product.custom_value2',
'product.unit_cost', 'product.unit_cost',
'product.quantity', 'product.quantity',
'product.discount',
'product.tax', 'product.tax',
'product.line_total', 'product.line_total',
], ],
@ -196,6 +197,7 @@ trait PresentsInvoice
'product.custom_value2', 'product.custom_value2',
'product.rate', 'product.rate',
'product.hours', 'product.hours',
'product.discount',
'product.tax', 'product.tax',
'product.line_total', 'product.line_total',
], ],
@ -378,9 +380,9 @@ trait PresentsInvoice
return null; return null;
} }
public function hideQuantity() { public function hasInvoiceField($type, $field) {
$fields = $this->getInvoiceFields(); $fields = $this->getInvoiceFields();
return ! isset($fields['product_fields']['product.quantity']); return isset($fields[$type . '_fields'][$field]);
} }
} }

View File

@ -51,6 +51,10 @@ class AddRemember2faToken extends Migration
Schema::table('accounts', function ($table) { Schema::table('accounts', function ($table) {
$table->boolean('convert_products')->default(false); $table->boolean('convert_products')->default(false);
}); });
Schema::table('invoice_items', function ($table) {
$table->float('discount');
});
} }
/** /**
@ -82,5 +86,9 @@ class AddRemember2faToken extends Migration
Schema::table('accounts', function ($table) { Schema::table('accounts', function ($table) {
$table->dropColumn('convert_products'); $table->dropColumn('convert_products');
}); });
Schema::table('invoice_items', function ($table) {
$table->dropColumn('discount');
});
} }
} }

View File

@ -24,6 +24,25 @@
padding: 20px; padding: 20px;
} }
.subtotals-table {
min-width: 340px;
}
.subtotals-table tr {
border-bottom: solid #CCCCCC 1px;
}
.subtotals-table td {
padding-top: 20px;
padding-bottom: 12px;
}
.subtotals-table input {
float: right;
text-align: right;
max-width: 150px;
}
</style> </style>
@stop @stop
@ -284,152 +303,49 @@
<div class="table-responsive" style="padding-top:4px;"> <div class="table-responsive" style="padding-top:4px;">
<table class="table invoice-table">
@include('invoices.edit_table', ['isTasks' => false]) @include('invoices.edit_table', ['isTasks' => false])
@if ($account->isModuleEnabled(ENTITY_TASK) && ($invoice->has_tasks || ! empty($tasks))) @if ($account->isModuleEnabled(ENTITY_TASK) && ($invoice->has_tasks || ! empty($tasks)))
@include('invoices.edit_table', ['isTasks' => true]) @include('invoices.edit_table', ['isTasks' => true])
@endif @endif
<tfoot>
{{ Former::setOption('TwitterBootstrap3.labelWidths.large', 4) }}
{{ Former::setOption('TwitterBootstrap3.labelWidths.small', 4) }}
<table class="pull-right subtotals-table" style="margin-right:40px; margin-top:0px;">
<tr> <tr>
<td class="hide-border"/>
<td class="hide-border" colspan="{{ 2 + ($account->showCustomField('custom_invoice_item_label1') ? 1 : 0) + ($account->showCustomField('custom_invoice_item_label2') ? 1 : 0) }}" rowspan="10" style="vertical-align:top">
<br/>
<div role="tabpanel">
<ul class="nav nav-tabs" role="tablist" style="border: none">
<li role="presentation" class="active"><a href="#public_notes" aria-controls="notes" role="tab" data-toggle="tab">{{ trans('texts.public_notes') }}</a></li>
<li role="presentation"><a href="#private_notes" aria-controls="terms" role="tab" data-toggle="tab">{{ trans("texts.private_notes") }}</a></li>
<li role="presentation"><a href="#terms" aria-controls="terms" role="tab" data-toggle="tab">{{ trans("texts.terms") }}</a></li>
<li role="presentation"><a href="#footer" aria-controls="footer" role="tab" data-toggle="tab">{{ trans("texts.footer") }}</a></li>
@if ($account->hasFeature(FEATURE_DOCUMENTS))
<li role="presentation"><a href="#attached-documents" aria-controls="attached-documents" role="tab" data-toggle="tab">
{{ trans("texts.documents") }}
@if ($count = ($invoice->countDocuments($expenses)))
({{ $count }})
@endif
</a></li>
@endif
</ul>
{{ Former::setOption('TwitterBootstrap3.labelWidths.large', 0) }}
{{ Former::setOption('TwitterBootstrap3.labelWidths.small', 0) }}
<div class="tab-content" style="padding-right:12px;max-width:600px;">
<div role="tabpanel" class="tab-pane active" id="public_notes" style="padding-bottom:44px;">
{!! Former::textarea('public_notes')
->data_bind("value: public_notes, valueUpdate: 'afterkeydown'")
->label(null)->style('width: 100%')->rows(4)->label(null) !!}
</div>
<div role="tabpanel" class="tab-pane" id="private_notes" style="padding-bottom:44px">
{!! Former::textarea('private_notes')
->data_bind("value: private_notes, valueUpdate: 'afterkeydown'")
->label(null)->style('width: 100%')->rows(4) !!}
</div>
<div role="tabpanel" class="tab-pane" id="terms">
{!! Former::textarea('terms')
->data_bind("value:terms, placeholder: terms_placeholder, valueUpdate: 'afterkeydown'")
->label(false)->style('width: 100%')->rows(4)
->help('<div class="checkbox">
<label>
<input name="set_default_terms" type="checkbox" style="width: 16px" data-bind="checked: set_default_terms"/>'.trans('texts.save_as_default_terms').'
</label>
<div class="pull-right" data-bind="visible: showResetTerms()">
<a href="#" onclick="return resetTerms()" title="'. trans('texts.reset_terms_help') .'">' . trans("texts.reset_terms") . '</a>
</div>
</div>') !!}
</div>
<div role="tabpanel" class="tab-pane" id="footer">
{!! Former::textarea('invoice_footer')
->data_bind("value:invoice_footer, placeholder: footer_placeholder, valueUpdate: 'afterkeydown'")
->label(false)->style('width: 100%')->rows(4)
->help('<div class="checkbox">
<label>
<input name="set_default_footer" type="checkbox" style="width: 16px" data-bind="checked: set_default_footer"/>'.trans('texts.save_as_default_footer').'
</label>
<div class="pull-right" data-bind="visible: showResetFooter()">
<a href="#" onclick="return resetFooter()" title="'. trans('texts.reset_footer_help') .'">' . trans("texts.reset_footer") . '</a>
</div>
</div>') !!}
</div>
@if ($account->hasFeature(FEATURE_DOCUMENTS))
<div role="tabpanel" class="tab-pane" id="attached-documents" style="position:relative;z-index:9">
<div id="document-upload">
<div class="dropzone">
<div data-bind="foreach: documents">
<input type="hidden" name="document_ids[]" data-bind="value: public_id"/>
</div>
</div>
@if ($invoice->hasExpenseDocuments() || count($expenses))
<h4>{{trans('texts.documents_from_expenses')}}</h4>
@foreach($invoice->expenses as $expense)
@if ($expense->invoice_documents)
@foreach($expense->documents as $document)
<div>{{$document->name}}</div>
@endforeach
@endif
@endforeach
@foreach($expenses as $expense)
@if ($expense->invoice_documents)
@foreach($expense->documents as $document)
<div>{{$document->name}}</div>
@endforeach
@endif
@endforeach
@endif
</div>
</div>
@endif
</div>
</div>
{{ Former::setOption('TwitterBootstrap3.labelWidths.large', 4) }}
{{ Former::setOption('TwitterBootstrap3.labelWidths.small', 4) }}
</td>
<td class="hide-border" style="display:none" data-bind="visible: $root.invoice_item_taxes.show"/>
<td colspan="2">{{ trans('texts.subtotal') }}</td> <td colspan="2">{{ trans('texts.subtotal') }}</td>
<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 style="display:none" class="hide-border" data-bind="visible: $root.invoice_item_taxes.show"/>
<td colspan="2">{{ trans('texts.discount') }}</td> <td colspan="2">{{ trans('texts.discount') }}</td>
<td style="text-align: right"><span data-bind="text: totals.discounted"/></td> <td style="text-align: right"><span data-bind="text: totals.discounted"/></td>
</tr> </tr>
@if ($account->showCustomField('custom_invoice_label1', $invoice) && $invoice->custom_taxes1) @if ($account->showCustomField('custom_invoice_label1', $invoice) && $invoice->custom_taxes1)
<tr> <tr>
<td class="hide-border" colspan="3"/>
<td style="display:none" class="hide-border" data-bind="visible: $root.invoice_item_taxes.show"/>
<td colspan="2">{{ $account->custom_invoice_label1 ?: trans('texts.surcharge') }}</td> <td colspan="2">{{ $account->custom_invoice_label1 ?: trans('texts.surcharge') }}</td>
<td style="text-align: right;padding-right: 28px" colspan="2"><input name="custom_value1" class="form-control" data-bind="value: custom_value1, valueUpdate: 'afterkeydown'"/></td> <td><input name="custom_value1" class="form-control" data-bind="value: custom_value1, valueUpdate: 'afterkeydown'"/></td>
</tr> </tr>
@endif @endif
@if ($account->showCustomField('custom_invoice_label2', $invoice) && $invoice->custom_taxes2) @if ($account->showCustomField('custom_invoice_label2', $invoice) && $invoice->custom_taxes2)
<tr> <tr>
<td class="hide-border" colspan="3"/>
<td style="display:none" class="hide-border" data-bind="visible: $root.invoice_item_taxes.show"/>
<td colspan="2">{{ $account->custom_invoice_label2 ?: trans('texts.surcharge') }}</td> <td colspan="2">{{ $account->custom_invoice_label2 ?: trans('texts.surcharge') }}</td>
<td style="text-align: right;padding-right: 28px" colspan="2"><input name="custom_value2" class="form-control" data-bind="value: custom_value2, valueUpdate: 'afterkeydown'"/></td> <td><input name="custom_value2" class="form-control" data-bind="value: custom_value2, valueUpdate: 'afterkeydown'"/></td>
</tr> </tr>
@endif @endif
<tr style="display:none" data-bind="visible: $root.invoice_item_taxes.show &amp;&amp; totals.hasItemTaxes"> <tr style="display:none" data-bind="visible: $root.invoice_item_taxes.show &amp;&amp; totals.hasItemTaxes">
<td class="hide-border" colspan="3"/> <td>{{ trans('texts.tax') }}&nbsp;&nbsp;</td>
<td style="display:none" class="hide-border" data-bind="visible: $root.invoice_item_taxes.show"/>
<td>{{ trans('texts.tax') }}</td>
<td style="min-width:120px"><span data-bind="html: totals.itemTaxRates"/></td> <td style="min-width:120px"><span data-bind="html: totals.itemTaxRates"/></td>
<td style="text-align: right"><span data-bind="html: totals.itemTaxAmounts"/></td> <td style="text-align: right"><span data-bind="html: totals.itemTaxAmounts"/></td>
</tr> </tr>
<tr style="display:none" data-bind="visible: $root.invoice_taxes.show"> <tr style="display:none" data-bind="visible: $root.invoice_taxes.show">
<td class="hide-border" colspan="3"/> <td>{{ trans('texts.tax') }}&nbsp;&nbsp;</td>
<td style="display:none" class="hide-border" data-bind="visible: $root.invoice_item_taxes.show"/>
<td>{{ trans('texts.tax') }}</td>
<td style="min-width:120px"> <td style="min-width:120px">
{!! Former::select('') {!! Former::select('')
->id('taxRateSelect1') ->id('taxRateSelect1')
@ -456,52 +372,130 @@
@if ($account->showCustomField('custom_invoice_label1', $invoice) && !$invoice->custom_taxes1) @if ($account->showCustomField('custom_invoice_label1', $invoice) && !$invoice->custom_taxes1)
<tr> <tr>
<td class="hide-border" colspan="3"/>
<td style="display:none" class="hide-border" data-bind="visible: $root.invoice_item_taxes.show"/>
<td colspan="2">{{ $account->custom_invoice_label1 ?: trans('texts.surcharge') }}</td> <td colspan="2">{{ $account->custom_invoice_label1 ?: trans('texts.surcharge') }}</td>
<td style="text-align: right;padding-right: 28px" colspan="2"><input name="custom_value1" class="form-control" data-bind="value: custom_value1, valueUpdate: 'afterkeydown'"/></td> <td><input name="custom_value1" class="form-control" data-bind="value: custom_value1, valueUpdate: 'afterkeydown'"/></td>
</tr> </tr>
@endif @endif
@if ($account->showCustomField('custom_invoice_label2', $invoice) && !$invoice->custom_taxes2) @if ($account->showCustomField('custom_invoice_label2', $invoice) && !$invoice->custom_taxes2)
<tr> <tr>
<td class="hide-border" colspan="3"/>
<td style="display:none" class="hide-border" data-bind="visible: $root.invoice_item_taxes.show"/>
<td colspan="2">{{ $account->custom_invoice_label2 ?: trans('texts.surcharge') }}</td> <td colspan="2">{{ $account->custom_invoice_label2 ?: trans('texts.surcharge') }}</td>
<td style="text-align: right;padding-right: 28px" colspan="2"><input name="custom_value2" class="form-control" data-bind="value: custom_value2, valueUpdate: 'afterkeydown'"/></td> <td><input name="custom_value2" class="form-control" data-bind="value: custom_value2, valueUpdate: 'afterkeydown'"/></td>
</tr> </tr>
@endif @endif
@if (!$account->hide_paid_to_date) @if (!$account->hide_paid_to_date)
<tr> <tr>
<td class="hide-border" colspan="3"/>
<td style="display:none" class="hide-border" data-bind="visible: $root.invoice_item_taxes.show"/>
<td colspan="2">{{ trans('texts.paid_to_date') }}</td> <td colspan="2">{{ trans('texts.paid_to_date') }}</td>
<td style="text-align: right" data-bind="text: totals.paidToDate"></td> <td style="text-align: right" data-bind="text: totals.paidToDate"></td>
</tr> </tr>
@endif @endif
<tr data-bind="style: { 'font-weight': partial() ? 'normal' : 'bold', 'font-size': partial() ? '1em' : '1.05em' }"> <tr data-bind="style: { 'font-weight': partial() ? 'normal' : 'bold', 'font-size': partial() ? '1em' : '1.05em' }">
<td class="hide-border" colspan="3"/>
<td class="hide-border" style="display:none" data-bind="visible: $root.invoice_item_taxes.show"/>
<td class="hide-border" data-bind="css: {'hide-border': !partial()}" colspan="2">{{ $entityType == ENTITY_INVOICE ? $invoiceLabels['balance_due'] : trans('texts.total') }}</td> <td class="hide-border" data-bind="css: {'hide-border': !partial()}" colspan="2">{{ $entityType == ENTITY_INVOICE ? $invoiceLabels['balance_due'] : trans('texts.total') }}</td>
<td class="hide-border" data-bind="css: {'hide-border': !partial()}" style="text-align: right"><span data-bind="text: totals.total"></span></td> <td class="hide-border" data-bind="css: {'hide-border': !partial()}" style="text-align: right"><span data-bind="text: totals.total"></span></td>
</tr> </tr>
<tr style="font-size:1.05em; display:none; font-weight:bold" data-bind="visible: partial"> <tr style="font-size:1.05em; display:none; font-weight:bold" data-bind="visible: partial">
<td class="hide-border" colspan="3"/>
<td class="hide-border" style="display:none" data-bind="visible: $root.invoice_item_taxes.show"/>
<td class="hide-border" colspan="2">{{ $invoiceLabels['partial_due'] }}</td> <td class="hide-border" colspan="2">{{ $invoiceLabels['partial_due'] }}</td>
<td class="hide-border" style="text-align: right"><span data-bind="text: totals.partial"></span></td> <td class="hide-border" style="text-align: right"><span data-bind="text: totals.partial"></span></td>
</tr> </tr>
</table>
</tfoot>
</table> <div role="tabpanel" class="pull-left" style="margin-left:40px; margin-top:30px;">
<ul class="nav nav-tabs" role="tablist" style="border: none">
<li role="presentation" class="active"><a href="#public_notes" aria-controls="notes" role="tab" data-toggle="tab">{{ trans('texts.public_notes') }}</a></li>
<li role="presentation"><a href="#private_notes" aria-controls="terms" role="tab" data-toggle="tab">{{ trans("texts.private_notes") }}</a></li>
<li role="presentation"><a href="#terms" aria-controls="terms" role="tab" data-toggle="tab">{{ trans("texts.terms") }}</a></li>
<li role="presentation"><a href="#footer" aria-controls="footer" role="tab" data-toggle="tab">{{ trans("texts.footer") }}</a></li>
@if ($account->hasFeature(FEATURE_DOCUMENTS))
<li role="presentation"><a href="#attached-documents" aria-controls="attached-documents" role="tab" data-toggle="tab">
{{ trans("texts.documents") }}
@if ($count = ($invoice->countDocuments($expenses)))
({{ $count }})
@endif
</a></li>
@endif
</ul>
{{ Former::setOption('TwitterBootstrap3.labelWidths.large', 0) }}
{{ Former::setOption('TwitterBootstrap3.labelWidths.small', 0) }}
<div class="tab-content" style="padding-right:12px;max-width:600px;">
<div role="tabpanel" class="tab-pane active" id="public_notes" style="padding-bottom:44px;">
{!! Former::textarea('public_notes')
->data_bind("value: public_notes, valueUpdate: 'afterkeydown'")
->label(null)->style('width: 100%')->rows(4)->label(null) !!}
</div>
<div role="tabpanel" class="tab-pane" id="private_notes" style="padding-bottom:44px">
{!! Former::textarea('private_notes')
->data_bind("value: private_notes, valueUpdate: 'afterkeydown'")
->label(null)->style('width: 100%')->rows(4) !!}
</div>
<div role="tabpanel" class="tab-pane" id="terms">
{!! Former::textarea('terms')
->data_bind("value:terms, placeholder: terms_placeholder, valueUpdate: 'afterkeydown'")
->label(false)->style('width: 100%')->rows(4)
->help('<div class="checkbox">
<label>
<input name="set_default_terms" type="checkbox" style="width: 16px" data-bind="checked: set_default_terms"/>'.trans('texts.save_as_default_terms').'
</label>
<div class="pull-right" data-bind="visible: showResetTerms()">
<a href="#" onclick="return resetTerms()" title="'. trans('texts.reset_terms_help') .'">' . trans("texts.reset_terms") . '</a>
</div>
</div>') !!}
</div>
<div role="tabpanel" class="tab-pane" id="footer">
{!! Former::textarea('invoice_footer')
->data_bind("value:invoice_footer, placeholder: footer_placeholder, valueUpdate: 'afterkeydown'")
->label(false)->style('width: 100%')->rows(4)
->help('<div class="checkbox">
<label>
<input name="set_default_footer" type="checkbox" style="width: 16px" data-bind="checked: set_default_footer"/>'.trans('texts.save_as_default_footer').'
</label>
<div class="pull-right" data-bind="visible: showResetFooter()">
<a href="#" onclick="return resetFooter()" title="'. trans('texts.reset_footer_help') .'">' . trans("texts.reset_footer") . '</a>
</div>
</div>') !!}
</div>
@if ($account->hasFeature(FEATURE_DOCUMENTS))
<div role="tabpanel" class="tab-pane" id="attached-documents" style="position:relative;z-index:9">
<div id="document-upload">
<div class="dropzone">
<div data-bind="foreach: documents">
<input type="hidden" name="document_ids[]" data-bind="value: public_id"/>
</div>
</div>
@if ($invoice->hasExpenseDocuments() || count($expenses))
<h4>{{trans('texts.documents_from_expenses')}}</h4>
@foreach($invoice->expenses as $expense)
@if ($expense->invoice_documents)
@foreach($expense->documents as $document)
<div>{{$document->name}}</div>
@endforeach
@endif
@endforeach
@foreach($expenses as $expense)
@if ($expense->invoice_documents)
@foreach($expense->documents as $document)
<div>{{$document->name}}</div>
@endforeach
@endif
@endforeach
@endif
</div>
</div>
@endif
</div>
</div>
</div>
</div>
</div> </div>
</div>
</div>
<center class="buttons"> <center class="buttons">

View File

@ -1,3 +1,4 @@
<table class="table invoice-table">
<thead {!! $isTasks ? 'style="display:none;" data-bind="visible: $root.hasTasks"' : ($invoice->has_tasks || ! empty($tasks) ? 'data-bind="visible: $root.hasItems"' : '') !!}> <thead {!! $isTasks ? 'style="display:none;" data-bind="visible: $root.hasTasks"' : ($invoice->has_tasks || ! empty($tasks) ? 'data-bind="visible: $root.hasItems"' : '') !!}>
@if ($isTasks) @if ($isTasks)
<tr data-bind="visible: $root.hasItems"> <tr data-bind="visible: $root.hasItems">
@ -15,7 +16,8 @@
<th style="min-width:120px">{{ $account->custom_invoice_item_label2 }}</th> <th style="min-width:120px">{{ $account->custom_invoice_item_label2 }}</th>
@endif @endif
<th style="min-width:120px">{{ $invoiceLabels[$isTasks ? 'rate' : 'unit_cost'] }}</th> <th style="min-width:120px">{{ $invoiceLabels[$isTasks ? 'rate' : 'unit_cost'] }}</th>
<th style="min-width:120px">{{ $invoiceLabels[$isTasks ? 'hours' : 'quantity'] }}</th> <th style="min-width:120px;display:{{ $account->hasInvoiceField($isTasks ? 'task' : 'product', $isTasks ? 'product.hours' : 'product.quantity') ? 'table-cell' : 'none' }}">{{ $invoiceLabels[$isTasks ? 'hours' : 'quantity'] }}</th>
<th style="min-width:120px;display:{{ $account->hasInvoiceField($isTasks ? 'task' : 'product', 'product.discount') ? 'table-cell' : 'none' }}">{{ $invoiceLabels['discount'] }}</th>
<th style="min-width:{{ $account->enable_second_tax_rate ? 180 : 120 }}px;display:none;" data-bind="visible: $root.invoice_item_taxes.show">{{ trans('texts.tax') }}</th> <th style="min-width:{{ $account->enable_second_tax_rate ? 180 : 120 }}px;display:none;" data-bind="visible: $root.invoice_item_taxes.show">{{ trans('texts.tax') }}</th>
<th style="min-width:120px;">{{ trans('texts.line_total') }}</th> <th style="min-width:120px;">{{ trans('texts.line_total') }}</th>
<th style="min-width:32px;" class="hide-border"></th> <th style="min-width:32px;" class="hide-border"></th>
@ -54,10 +56,14 @@
<input data-bind="value: prettyCost, valueUpdate: 'afterkeydown', attr: {name: 'invoice_items[{{ $isTasks ? 'T' : '' }}' + $index() + '][cost]'}" <input data-bind="value: prettyCost, valueUpdate: 'afterkeydown', attr: {name: 'invoice_items[{{ $isTasks ? 'T' : '' }}' + $index() + '][cost]'}"
style="text-align: right" class="form-control invoice-item"/> style="text-align: right" class="form-control invoice-item"/>
</td> </td>
<td> <td style="display:{{ $account->hasInvoiceField($isTasks ? 'task' : 'product', $isTasks ? 'product.hours' : 'product.quantity') ? 'table-cell' : 'none' }}">
<input data-bind="value: prettyQty, valueUpdate: 'afterkeydown', attr: {name: 'invoice_items[{{ $isTasks ? 'T' : '' }}' + $index() + '][qty]'}" <input data-bind="value: prettyQty, valueUpdate: 'afterkeydown', attr: {name: 'invoice_items[{{ $isTasks ? 'T' : '' }}' + $index() + '][qty]'}"
style="text-align: right" class="form-control invoice-item" name="quantity"/> style="text-align: right" class="form-control invoice-item" name="quantity"/>
</td> </td>
<td style="display:{{ $account->hasInvoiceField($isTasks ? 'task' : 'product', 'product.discount') ? 'table-cell' : 'none' }}">
<input data-bind="value: discount, valueUpdate: 'afterkeydown', attr: {name: 'invoice_items[{{ $isTasks ? 'T' : '' }}' + $index() + '][discount]'}"
style="text-align: right" class="form-control invoice-item" name="discount"/>
</td>
<td style="display:none;" data-bind="visible: $root.invoice_item_taxes.show"> <td style="display:none;" data-bind="visible: $root.invoice_item_taxes.show">
{!! Former::select('') {!! Former::select('')
->addOption('', '') ->addOption('', '')
@ -87,3 +93,4 @@
</td> </td>
</tr> </tr>
</tbody> </tbody>
</table>

View File

@ -821,6 +821,7 @@ function ItemModel(data) {
self.notes = ko.observable(''); self.notes = ko.observable('');
self.cost = ko.observable(0); self.cost = ko.observable(0);
self.qty = ko.observable(0); self.qty = ko.observable(0);
self.discount = ko.observable();
self.custom_value1 = ko.observable(''); self.custom_value1 = ko.observable('');
self.custom_value2 = ko.observable(''); self.custom_value2 = ko.observable('');
self.tax_name1 = ko.observable(''); self.tax_name1 = ko.observable('');