From 15b5860ffe5e4d5e102aa0f6825129d296af51ce Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Thu, 21 Dec 2017 16:30:18 +0200 Subject: [PATCH] line item discounts --- app/Models/InvoiceItem.php | 1 + app/Models/Traits/PresentsInvoice.php | 6 +- ...17_12_13_074024_add_remember_2fa_token.php | 8 + resources/views/invoices/edit.blade.php | 260 +++++++++--------- resources/views/invoices/edit_table.blade.php | 11 +- resources/views/invoices/knockout.blade.php | 1 + 6 files changed, 150 insertions(+), 137 deletions(-) diff --git a/app/Models/InvoiceItem.php b/app/Models/InvoiceItem.php index ba12d00aeb74..e04ebe9e903f 100644 --- a/app/Models/InvoiceItem.php +++ b/app/Models/InvoiceItem.php @@ -40,6 +40,7 @@ class InvoiceItem extends EntityModel 'tax_name2', 'tax_rate2', 'invoice_item_type_id', + 'discount', ]; /** diff --git a/app/Models/Traits/PresentsInvoice.php b/app/Models/Traits/PresentsInvoice.php index 082f539bb0e2..d715121208d0 100644 --- a/app/Models/Traits/PresentsInvoice.php +++ b/app/Models/Traits/PresentsInvoice.php @@ -186,6 +186,7 @@ trait PresentsInvoice 'product.custom_value2', 'product.unit_cost', 'product.quantity', + 'product.discount', 'product.tax', 'product.line_total', ], @@ -196,6 +197,7 @@ trait PresentsInvoice 'product.custom_value2', 'product.rate', 'product.hours', + 'product.discount', 'product.tax', 'product.line_total', ], @@ -378,9 +380,9 @@ trait PresentsInvoice return null; } - public function hideQuantity() { + public function hasInvoiceField($type, $field) { $fields = $this->getInvoiceFields(); - return ! isset($fields['product_fields']['product.quantity']); + return isset($fields[$type . '_fields'][$field]); } } diff --git a/database/migrations/2017_12_13_074024_add_remember_2fa_token.php b/database/migrations/2017_12_13_074024_add_remember_2fa_token.php index 03104e0844cc..ec324a7671e9 100644 --- a/database/migrations/2017_12_13_074024_add_remember_2fa_token.php +++ b/database/migrations/2017_12_13_074024_add_remember_2fa_token.php @@ -51,6 +51,10 @@ class AddRemember2faToken extends Migration Schema::table('accounts', function ($table) { $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) { $table->dropColumn('convert_products'); }); + + Schema::table('invoice_items', function ($table) { + $table->dropColumn('discount'); + }); } } diff --git a/resources/views/invoices/edit.blade.php b/resources/views/invoices/edit.blade.php index 9d9628025d16..4964a9025393 100644 --- a/resources/views/invoices/edit.blade.php +++ b/resources/views/invoices/edit.blade.php @@ -24,6 +24,25 @@ 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; + } + @stop @@ -284,152 +303,49 @@
- - @include('invoices.edit_table', ['isTasks' => false]) + @include('invoices.edit_table', ['isTasks' => false]) - @if ($account->isModuleEnabled(ENTITY_TASK) && ($invoice->has_tasks || ! empty($tasks))) - @include('invoices.edit_table', ['isTasks' => true]) - @endif + @if ($account->isModuleEnabled(ENTITY_TASK) && ($invoice->has_tasks || ! empty($tasks))) + @include('invoices.edit_table', ['isTasks' => true]) + @endif - + + {{ Former::setOption('TwitterBootstrap3.labelWidths.large', 4) }} + {{ Former::setOption('TwitterBootstrap3.labelWidths.small', 4) }} + +
- - - @if ($account->showCustomField('custom_invoice_label1', $invoice) && $invoice->custom_taxes1) - - + @endif @if ($account->showCustomField('custom_invoice_label2', $invoice) && $invoice->custom_taxes2) - - + @endif - + - + - - + @endif @if ($account->showCustomField('custom_invoice_label2', $invoice) && !$invoice->custom_taxes2) - - + @endif @if (!$account->hide_paid_to_date) - @endif - - - - +
- -
-
- - - - {{ Former::setOption('TwitterBootstrap3.labelWidths.large', 0) }} - {{ Former::setOption('TwitterBootstrap3.labelWidths.small', 0) }} - -
-
- {!! Former::textarea('public_notes') - ->data_bind("value: public_notes, valueUpdate: 'afterkeydown'") - ->label(null)->style('width: 100%')->rows(4)->label(null) !!} -
-
- {!! Former::textarea('private_notes') - ->data_bind("value: private_notes, valueUpdate: 'afterkeydown'") - ->label(null)->style('width: 100%')->rows(4) !!} -
-
- {!! Former::textarea('terms') - ->data_bind("value:terms, placeholder: terms_placeholder, valueUpdate: 'afterkeydown'") - ->label(false)->style('width: 100%')->rows(4) - ->help('
- - -
') !!} -
- - @if ($account->hasFeature(FEATURE_DOCUMENTS)) -
-
-
-
- -
-
- @if ($invoice->hasExpenseDocuments() || count($expenses)) -

{{trans('texts.documents_from_expenses')}}

- @foreach($invoice->expenses as $expense) - @if ($expense->invoice_documents) - @foreach($expense->documents as $document) -
{{$document->name}}
- @endforeach - @endif - @endforeach - @foreach($expenses as $expense) - @if ($expense->invoice_documents) - @foreach($expense->documents as $document) -
{{$document->name}}
- @endforeach - @endif - @endforeach - @endif -
-
- @endif -
-
- - {{ Former::setOption('TwitterBootstrap3.labelWidths.large', 4) }} - {{ Former::setOption('TwitterBootstrap3.labelWidths.small', 4) }} - -
{{ trans('texts.subtotal') }}
- {{ trans('texts.discount') }}
- {{ $account->custom_invoice_label1 ?: trans('texts.surcharge') }}
- {{ $account->custom_invoice_label2 ?: trans('texts.surcharge') }}
- {{ trans('texts.tax') }}{{ trans('texts.tax') }}  
- {{ trans('texts.tax') }}{{ trans('texts.tax') }}   {!! Former::select('') ->id('taxRateSelect1') @@ -456,52 +372,130 @@ @if ($account->showCustomField('custom_invoice_label1', $invoice) && !$invoice->custom_taxes1)
- {{ $account->custom_invoice_label1 ?: trans('texts.surcharge') }}
- {{ $account->custom_invoice_label2 ?: trans('texts.surcharge') }}
- {{ trans('texts.paid_to_date') }}
- {{ $entityType == ENTITY_INVOICE ? $invoiceLabels['balance_due'] : trans('texts.total') }}
- {{ $invoiceLabels['partial_due'] }}
- +
+ + + + {{ Former::setOption('TwitterBootstrap3.labelWidths.large', 0) }} + {{ Former::setOption('TwitterBootstrap3.labelWidths.small', 0) }} + +
+
+ {!! Former::textarea('public_notes') + ->data_bind("value: public_notes, valueUpdate: 'afterkeydown'") + ->label(null)->style('width: 100%')->rows(4)->label(null) !!} +
+
+ {!! Former::textarea('private_notes') + ->data_bind("value: private_notes, valueUpdate: 'afterkeydown'") + ->label(null)->style('width: 100%')->rows(4) !!} +
+
+ {!! Former::textarea('terms') + ->data_bind("value:terms, placeholder: terms_placeholder, valueUpdate: 'afterkeydown'") + ->label(false)->style('width: 100%')->rows(4) + ->help('
+ + +
') !!} +
+ + @if ($account->hasFeature(FEATURE_DOCUMENTS)) +
+
+
+
+ +
+
+ @if ($invoice->hasExpenseDocuments() || count($expenses)) +

{{trans('texts.documents_from_expenses')}}

+ @foreach($invoice->expenses as $expense) + @if ($expense->invoice_documents) + @foreach($expense->documents as $document) +
{{$document->name}}
+ @endforeach + @endif + @endforeach + @foreach($expenses as $expense) + @if ($expense->invoice_documents) + @foreach($expense->documents as $document) +
{{$document->name}}
+ @endforeach + @endif + @endforeach + @endif +
+
+ @endif +
+
+ + + +
+ - -
diff --git a/resources/views/invoices/edit_table.blade.php b/resources/views/invoices/edit_table.blade.php index ba65b097ad51..5dd01d821e8e 100644 --- a/resources/views/invoices/edit_table.blade.php +++ b/resources/views/invoices/edit_table.blade.php @@ -1,3 +1,4 @@ +has_tasks || ! empty($tasks) ? 'data-bind="visible: $root.hasItems"' : '') !!}> @if ($isTasks) @@ -15,7 +16,8 @@ @endif - + + @@ -54,10 +56,14 @@ - + +
{{ $account->custom_invoice_item_label2 }}{{ $invoiceLabels[$isTasks ? 'rate' : 'unit_cost'] }}{{ $invoiceLabels[$isTasks ? 'hours' : 'quantity'] }}{{ $invoiceLabels[$isTasks ? 'hours' : 'quantity'] }}{{ $invoiceLabels['discount'] }} {{ trans('texts.tax') }} {{ trans('texts.line_total') }} + + + {!! Former::select('') ->addOption('', '') @@ -87,3 +93,4 @@
diff --git a/resources/views/invoices/knockout.blade.php b/resources/views/invoices/knockout.blade.php index 4e221c00c2af..b4bf356989c3 100644 --- a/resources/views/invoices/knockout.blade.php +++ b/resources/views/invoices/knockout.blade.php @@ -821,6 +821,7 @@ function ItemModel(data) { self.notes = ko.observable(''); self.cost = ko.observable(0); self.qty = ko.observable(0); + self.discount = ko.observable(); self.custom_value1 = ko.observable(''); self.custom_value2 = ko.observable(''); self.tax_name1 = ko.observable('');