diff --git a/app/Constants.php b/app/Constants.php index 81c6785b12c6..bd48656cd5fe 100644 --- a/app/Constants.php +++ b/app/Constants.php @@ -556,6 +556,8 @@ if (! defined('APP_NAME')) { define('INVOICE_FIELDS_CLIENT', 'client_fields'); define('INVOICE_FIELDS_INVOICE', 'invoice_fields'); define('INVOICE_FIELDS_ACCOUNT', 'account_fields'); + define('INVOICE_FIELDS_PRODUCT', 'product_fields'); + define('INVOICE_FIELDS_TASK', 'task_fields'); $creditCards = [ 1 => ['card' => 'images/credit_cards/Test-Visa-Icon.png', 'text' => 'Visa'], diff --git a/app/Models/Traits/PresentsInvoice.php b/app/Models/Traits/PresentsInvoice.php index 53647cf9675a..1eb4e3d785b5 100644 --- a/app/Models/Traits/PresentsInvoice.php +++ b/app/Models/Traits/PresentsInvoice.php @@ -12,6 +12,29 @@ trait PresentsInvoice if ($this->invoice_fields) { $fields = json_decode($this->invoice_fields, true); + if (! isset($fields['product_fields'])) { + $fields['product_fields'] = [ + 'product.item', + 'product.description', + 'product.custom_value1', + 'product.custom_value2', + 'product.unit_cost', + 'product.quantity', + 'product.tax', + 'product.line_total', + ]; + $fields['task_fields'] = [ + 'product.service', + 'product.description', + 'product.custom_value1', + 'product.custom_value2', + 'product.rate', + 'product.hours', + 'product.tax', + 'product.line_total', + ]; + } + return $this->applyLabels($fields); } else { return $this->getDefaultInvoiceFields(); @@ -54,6 +77,26 @@ trait PresentsInvoice 'account.city_state_postal', 'account.country', ], + 'product_fields' => [ + 'product.item', + 'product.description', + 'product.custom_value1', + 'product.custom_value2', + 'product.unit_cost', + 'product.quantity', + 'product.tax', + 'product.line_total', + ], + 'task_fields' => [ + 'product.service', + 'product.description', + 'product.custom_value1', + 'product.custom_value2', + 'product.rate', + 'product.hours', + 'product.tax', + 'product.line_total', + ] ]; if ($this->custom_invoice_text_label1) { @@ -136,6 +179,26 @@ trait PresentsInvoice 'account.custom_value2', '.blank', ], + INVOICE_FIELDS_PRODUCT => [ + 'product.item', + 'product.description', + 'product.custom_value1', + 'product.custom_value2', + 'product.unit_cost', + 'product.quantity', + 'product.tax', + 'product.line_total', + ], + INVOICE_FIELDS_TASK => [ + 'product.service', + 'product.description', + 'product.custom_value1', + 'product.custom_value2', + 'product.rate', + 'product.hours', + 'product.tax', + 'product.line_total', + ], ]; return $this->applyLabels($fields); @@ -264,6 +327,10 @@ trait PresentsInvoice 'invoice_due_date', 'quote_due_date', 'service', + 'product_key', + 'unit_cost', + 'tax1', + 'tax2', ]; foreach ($fields as $field) { @@ -289,6 +356,8 @@ trait PresentsInvoice 'client.custom_value2' => 'custom_client_label2', 'contact.custom_value1' => 'custom_contact_label1', 'contact.custom_value2' => 'custom_contact_label2', + 'product.custom_value1' => 'custom_invoice_item_label1', + 'product.custom_value2' => 'custom_invoice_item_label2', ] as $field => $property) { $data[$field] = e($this->$property) ?: trans('texts.custom_field'); } diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php index 61ea182ec90b..3340c8b0ad3f 100644 --- a/resources/lang/en/texts.php +++ b/resources/lang/en/texts.php @@ -2508,6 +2508,8 @@ $LANG = array( 'return_to_invoice' => 'Return to Invoice', 'gateway_help_13' => 'To use ITN leave the PDT Key field blank.', 'partial_due_date' => 'Partial Due Date', + 'task_fields' => 'Task Fields', + 'product_fields_help' => 'Drag and drop fields to change their order', ); diff --git a/resources/views/accounts/invoice_design.blade.php b/resources/views/accounts/invoice_design.blade.php index 4536b52af9f5..cffac1f44e76 100644 --- a/resources/views/accounts/invoice_design.blade.php +++ b/resources/views/accounts/invoice_design.blade.php @@ -102,7 +102,6 @@ var id = $select.val(); $select.val(null).blur(); $('.' + id + '-label-group').fadeIn(); - console.log(id); } $(function() { @@ -166,8 +165,8 @@
  • {{ trans('texts.invoice_labels') }}
  • {{ trans('texts.invoice_fields') }}
  • +
  • {{ trans('texts.product_fields') }}
  • {{ trans('texts.invoice_options') }}
  • -
  • {{ trans('texts.header_footer') }}
  • @@ -242,7 +241,7 @@
    -
    +
    @include('accounts.partials.invoice_fields_selector', ['section' => 'invoice_fields', 'fields' => INVOICE_FIELDS_INVOICE]) @include('accounts.partials.invoice_fields_selector', ['section' => 'client_fields', 'fields' => INVOICE_FIELDS_CLIENT]) @include('accounts.partials.invoice_fields_selector', ['section' => 'account_fields1', 'fields' => INVOICE_FIELDS_ACCOUNT]) @@ -250,43 +249,61 @@
    - {{ trans('texts.invoice_fields_help') }} + {{ trans('texts.invoice_fields_help') }}
    -
    - {!! Button::normal(trans('texts.reset')) +
    + {!! Button::normal(trans('texts.reset'))->small() ->withAttributes(['onclick' => 'sweetConfirm(function() { resetFields(); - })']) - ->small() !!} + })']) !!}
    +
    +
    +
    + @include('accounts.partials.invoice_fields_selector', ['section' => 'product_fields', 'fields' => INVOICE_FIELDS_PRODUCT, 'colWidth' => 6]) + @include('accounts.partials.invoice_fields_selector', ['section' => 'task_fields', 'fields' => INVOICE_FIELDS_TASK, 'colWidth' => 6]) +
    +
    +
    + {{ trans('texts.product_fields_help') }} +
    +
    + {!! Button::normal(trans('texts.reset'))->small() + ->withAttributes(['onclick' => 'sweetConfirm(function() { + resetFields(); + })']) !!} +
    +
    +
    +
    + + {!! Former::checkbox('hide_paid_to_date')->text(trans('texts.hide_paid_to_date_help'))->value(1) !!} {!! Former::checkbox('invoice_embed_documents')->text(trans('texts.invoice_embed_documents_help'))->value(1) !!} -
    -
    - diff --git a/resources/views/accounts/partials/invoice_fields.blade.php b/resources/views/accounts/partials/invoice_fields.blade.php index afc33185561f..9db90dacd11d 100644 --- a/resources/views/accounts/partials/invoice_fields.blade.php +++ b/resources/views/accounts/partials/invoice_fields.blade.php @@ -7,6 +7,8 @@ function ViewModel(data) { self.client_fields = ko.observableArray(); self.account_fields1 = ko.observableArray(); self.account_fields2 = ko.observableArray(); + self.product_fields = ko.observableArray(); + self.task_fields = ko.observableArray(); window.field_map = []; self.addField = function(section, field, label) { @@ -20,6 +22,8 @@ function ViewModel(data) { self.client_fields.removeAll(); self.account_fields1.removeAll(); self.account_fields2.removeAll(); + self.product_fields.removeAll(); + self.task_fields.removeAll(); } self.onChange = function() { @@ -29,17 +33,28 @@ function ViewModel(data) { } self.updateSelects = function() { - var usedFields = [].concat(self.invoice_fields(), self.client_fields(), self.account_fields1(), self.account_fields2()); + var usedFields = [].concat( + self.invoice_fields(), + self.client_fields(), + self.account_fields1(), + self.account_fields2()); var selects = [ 'invoice_fields', 'client_fields', 'account_fields1', 'account_fields2', + 'product_fields', + 'task_fields', ]; for (var i=0; i option').each(function() { + if (select == 'product_fields') { + usedFields = self.product_fields(); + } else if (select == 'task_fields') { + usedFields = self.task_fields(); + } var isUsed = usedFields.indexOf(this.value) >= 0; $(this).css('color', isUsed ? '#888' : 'black'); }); @@ -66,6 +81,14 @@ function ViewModel(data) { self.account_fields2.remove(item); self.onChange(); } + self.removeProductFields = function(item) { + self.product_fields.remove(item); + self.onChange(); + } + self.removeTaskFields = function(item) { + self.task_fields.remove(item); + self.onChange(); + } } function addField(section) { diff --git a/resources/views/accounts/partials/invoice_fields_selector.blade.php b/resources/views/accounts/partials/invoice_fields_selector.blade.php index ac9dcb6b39e8..297fcba44613 100644 --- a/resources/views/accounts/partials/invoice_fields_selector.blade.php +++ b/resources/views/accounts/partials/invoice_fields_selector.blade.php @@ -1,4 +1,4 @@ -
    +
    {!! Former::select("{$section}_select") ->placeholder(trans("texts.{$fields}"))