diff --git a/README.md b/README.md index 3589f6cb4ef9..54775cd56426 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,8 @@ ## [Hosted](https://www.invoiceninja.com) | [Self-hosted](https://www.invoiceninja.org) +All Pro and Enterprise features from our hosted app are included in both the [self-host zip](https://www.invoiceninja.com/self-host/) and the GitHub repository. + [](https://www.youtube.com/watch?v=xHGKvadapbA) We're often asked to recommend Laravel/PHP developers to help setup our app and make small adjustments, email us at contact@invoiceninja.com if you're interested in taking on the work. @@ -30,6 +32,7 @@ We're often asked to recommend Laravel/PHP developers to help setup our app and * MySQL ## Recommended Providers +* [WePay](https://www.invoiceninja.com/wepay-accept-online-payments-instantly/) * [Stripe](https://stripe.com/) * [Postmark](https://postmarkapp.com/) @@ -39,6 +42,7 @@ We're often asked to recommend Laravel/PHP developers to help setup our app and * Integrates with 50+ payment providers with [Omnipay](https://github.com/thephpleague/omnipay) * Recurring invoices with auto-billing * Expenses and vendors +* Import bank statements with [OFX](http://www.ofxhome.com/) * Tasks with time-tracking * File Attachments * Multi-user/multi-company support diff --git a/app/Http/Controllers/AccountController.php b/app/Http/Controllers/AccountController.php index f9a3465fc8fb..501df2912044 100644 --- a/app/Http/Controllers/AccountController.php +++ b/app/Http/Controllers/AccountController.php @@ -547,6 +547,8 @@ class AccountController extends BaseController $invoice->terms = trim($account->invoice_terms); $invoice->invoice_footer = trim($account->invoice_footer); + $contact->first_name = 'Test'; + $contact->last_name = 'Contact'; $contact->email = 'contact@gmail.com'; $client->contacts = [$contact]; @@ -1030,7 +1032,7 @@ class AccountController extends BaseController $labels[$field] = Input::get("labels_{$field}"); } $account->invoice_labels = json_encode($labels); - $account->invoice_fields = Input::get('invoice_fields'); + $account->invoice_fields = Input::get('invoice_fields_json'); $account->save(); diff --git a/app/Http/Controllers/ExportController.php b/app/Http/Controllers/ExportController.php index c4467b4ac3d0..3f840bb5bb62 100644 --- a/app/Http/Controllers/ExportController.php +++ b/app/Http/Controllers/ExportController.php @@ -128,6 +128,7 @@ class ExportController extends BaseController if ($key === 'quotes') { $key = 'invoices'; $data['entityType'] = ENTITY_QUOTE; + $data['invoices'] = $data['quotes']; } $sheet->loadView("export.{$key}", $data); }); diff --git a/app/Http/routes.php b/app/Http/routes.php index 820ba07fcb63..6d3d6a23e0c1 100644 --- a/app/Http/routes.php +++ b/app/Http/routes.php @@ -826,7 +826,7 @@ if (!defined('CONTACT_EMAIL')) { define('INVOICE_FIELDS_CLIENT', 'client_fields'); define('INVOICE_FIELDS_INVOICE', 'invoice_fields'); - define('INVOICE_FIELDS_COMPANY', 'company_fields'); + define('INVOICE_FIELDS_ACCOUNT', 'account_fields'); $creditCards = [ 1 => ['card' => 'images/credit_cards/Test-Visa-Icon.png', 'text' => 'Visa'], diff --git a/app/Models/Invoice.php b/app/Models/Invoice.php index e353cc17280c..14b3d68a90c6 100644 --- a/app/Models/Invoice.php +++ b/app/Models/Invoice.php @@ -721,6 +721,7 @@ class Invoice extends EntityModel implements BalanceAffecting 'invoice_embed_documents', 'page_size', 'include_item_taxes_inline', + 'invoice_fields', ]); foreach ($this->invoice_items as $invoiceItem) { diff --git a/app/Models/Traits/PresentsInvoice.php b/app/Models/Traits/PresentsInvoice.php index 9a5d58986cef..dfa58ddbe3f3 100644 --- a/app/Models/Traits/PresentsInvoice.php +++ b/app/Models/Traits/PresentsInvoice.php @@ -9,63 +9,69 @@ trait PresentsInvoice { if ($this->invoice_fields) { $fields = json_decode($this->invoice_fields, true); + return $this->applyLabels($fields); } else { - $fields = [ - INVOICE_FIELDS_INVOICE => [ - 'invoice_number', - 'po_number', - 'invoice_date', - 'due_date', - 'balance_due', - 'partial_due', - ], - INVOICE_FIELDS_CLIENT => [ - 'client_name', - 'id_number', - 'vat_number', - 'address1', - 'address2', - 'city_state_postal', - 'country', - 'email', - ], - 'company_fields1' => [ - 'company_name', - 'id_number', - 'vat_number', - 'website', - 'email', - 'phone', - - ], - 'company_fields2' => [ - 'address1', - 'address2', - 'city_state_postal', - 'country', - ], - ]; - - if ($this->custom_invoice_text_label1) { - $fields[INVOICE_FIELDS_INVOICE][] = 'custom_invoice_text_label1'; - } - if ($this->custom_invoice_text_label2) { - $fields[INVOICE_FIELDS_INVOICE][] = 'custom_invoice_text_label2'; - } - if ($this->custom_client_label1) { - $fields[INVOICE_FIELDS_CLIENT][] = 'custom_client_label1'; - } - if ($this->custom_client_label2) { - $fields[INVOICE_FIELDS_CLIENT][] = 'custom_client_label2'; - } - if ($this->custom_label1) { - $fields['company_fields2'][] = 'custom_label1'; - } - if ($this->custom_label2) { - $fields['company_fields2'][] = 'custom_label2'; - } + return $this->getDefaultInvoiceFields(); } - + } + + public function getDefaultInvoiceFields() + { + $fields = [ + INVOICE_FIELDS_INVOICE => [ + 'invoice.invoice_number', + 'invoice.po_number', + 'invoice.invoice_date', + 'invoice.due_date', + 'invoice.balance_due', + 'invoice.partial_due', + ], + INVOICE_FIELDS_CLIENT => [ + 'client.client_name', + 'client.id_number', + 'client.vat_number', + 'client.address1', + 'client.address2', + 'client.city_state_postal', + 'client.country', + 'client.email', + ], + 'account_fields1' => [ + 'account.company_name', + 'account.id_number', + 'account.vat_number', + 'account.website', + 'account.email', + 'account.phone', + + ], + 'account_fields2' => [ + 'account.address1', + 'account.address2', + 'account.city_state_postal', + 'account.country', + ], + ]; + + if ($this->custom_invoice_text_label1) { + $fields[INVOICE_FIELDS_INVOICE][] = 'invoice.custom_text_value1'; + } + if ($this->custom_invoice_text_label2) { + $fields[INVOICE_FIELDS_INVOICE][] = 'invoice.custom_text_value2'; + } + if ($this->custom_client_label1) { + $fields[INVOICE_FIELDS_CLIENT][] = 'client.custom_value1'; + } + if ($this->custom_client_label2) { + $fields[INVOICE_FIELDS_CLIENT][] = 'client.custom_value2'; + } + if ($this->custom_label1) { + $fields['account_fields2'][] = 'account.custom_value1'; + } + if ($this->custom_label2) { + $fields['account_fields2'][] = 'account.custom_value2'; + } + return $this->applyLabels($fields); } @@ -73,41 +79,41 @@ trait PresentsInvoice { $fields = [ INVOICE_FIELDS_INVOICE => [ - 'invoice_number', - 'po_number', - 'invoice_date', - 'due_date', - 'balance_due', - 'partial_due', - 'custom_invoice_text_label1', - 'custom_invoice_text_label2', + 'invoice.invoice_number', + 'invoice.po_number', + 'invoice.invoice_date', + 'invoice.due_date', + 'invoice.balance_due', + 'invoice.partial_due', + 'invoice.custom_text_value1', + 'invoice.custom_text_value2', ], INVOICE_FIELDS_CLIENT => [ - 'client_name', - 'id_number', - 'vat_number', - 'address1', - 'address2', - 'city_state_postal', - 'country', - 'email', - 'contact_name', - 'custom_client_label1', - 'custom_client_label2', + 'client.client_name', + 'client.id_number', + 'client.vat_number', + 'client.address1', + 'client.address2', + 'client.city_state_postal', + 'client.country', + 'client.email', + 'client.contact_name', + 'client.custom_value1', + 'client.custom_value2', ], - INVOICE_FIELDS_COMPANY => [ - 'company_name', - 'id_number', - 'vat_number', - 'website', - 'email', - 'phone', - 'address1', - 'address2', - 'city_state_postal', - 'country', - 'custom_label1', - 'custom_label2', + INVOICE_FIELDS_ACCOUNT => [ + 'account.company_name', + 'account.id_number', + 'account.vat_number', + 'account.website', + 'account.email', + 'account.phone', + 'account.address1', + 'account.address2', + 'account.city_state_postal', + 'account.country', + 'account.custom_value1', + 'account.custom_value2', ] ]; @@ -120,7 +126,12 @@ trait PresentsInvoice foreach ($fields as $section => $sectionFields) { foreach ($sectionFields as $index => $field) { - $fields[$section][$field] = $labels[$field]; + list($entityType, $fieldName) = explode('.', $field); + if (substr($fieldName, 0, 6) == 'custom') { + $fields[$section][$field] = $labels[$field]; + } else { + $fields[$section][$field] = $labels[$fieldName]; + } unset($fields[$section][$index]); } } @@ -200,14 +211,14 @@ trait PresentsInvoice } foreach ([ - 'custom_label1', - 'custom_label2', - 'custom_client_label1', - 'custom_client_label2', - 'custom_invoice_text_label1', - 'custom_invoice_text_label2', - ] as $field) { - $data[$field] = $this->$field ?: trans('texts.custom_field'); + 'invoice.custom_text_value1' => 'custom_invoice_text_label1', + 'invoice.custom_text_value2' => 'custom_invoice_text_label2', + 'client.custom_value1' => 'custom_client_label1', + 'client.custom_value2' => 'custom_client_label2', + 'account.custom_value1' => 'custom_label1', + 'account.custom_value2' => 'custom_label2' + ] as $field => $property) { + $data[$field] = $this->$property ?: trans('texts.custom_field'); } return $data; diff --git a/app/Ninja/Repositories/AccountRepository.php b/app/Ninja/Repositories/AccountRepository.php index 90f26f2a429a..01eb49e70fac 100644 --- a/app/Ninja/Repositories/AccountRepository.php +++ b/app/Ninja/Repositories/AccountRepository.php @@ -203,7 +203,8 @@ class AccountRepository ['new_user', '/users/create'], ['custom_fields', '/settings/invoice_settings'], ['invoice_number', '/settings/invoice_settings'], - ['buy_now_buttons', '/settings/client_portal#buyNow'], + ['buy_now_buttons', '/settings/client_portal#buy_now'], + ['invoice_fields', '/settings/invoice_design#invoice_fields'], ]); $settings = array_merge(Account::$basicSettings, Account::$advancedSettings); diff --git a/gulpfile.js b/gulpfile.js index f51e87064294..6b9d52bd2e86 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -54,6 +54,7 @@ elixir(function(mix) { 'typeahead.js-bootstrap.css', 'style.css', 'sidebar.css', + 'colors.css', 'fonts.css' ], 'public/css/built.css'); diff --git a/resources/assets/css/colors.css b/resources/assets/css/colors.css new file mode 100644 index 000000000000..2c4f8fb013c0 --- /dev/null +++ b/resources/assets/css/colors.css @@ -0,0 +1,79 @@ +body { + background-color: #fcfcfc; +} + +.nav-tabs.nav-justified>.active>a, .nav-tabs.nav-justified>.active>a:hover, .nav-tabs.nav-justified>.active>a:focus { + background-color: #337ab7; +} + +.navbar .dropdown-menu { + border-top: 1px solid #337ab7; +} + +.active-clients { + background-color: #337ab7; +} + +.pagination>.active>a, .pagination>.active>span, .pagination>.active>a:hover, .pagination>.active>span:hover, .pagination>.active>a:focus, .pagination>.active>span:focus { + background-color: #337ab7; + border-color: #337ab7; +} + +.navbar { + background-color: #337ab7 !important; +} + +.navbar-collapse { + background-color: #337ab7 !important; +} + +.panel-heading { + background-color: #286090 !important; +} + + +table.dataTable thead > tr > th, +table.invoice-table thead > tr > th { + background-color: #777 !important; + color:#fff; +} + +thead th { + border-left: 1px solid #999; +} + +.sidebar-nav { + background-color: #313131; +} + +.sidebar-nav li { + border-bottom:solid 1px #4c4c4c; +} + +.sidebar-nav i.fa { + color: white; +} + +.menu-toggle i, +.sidebar-nav li > a { + color: #999999; +} + +.menu-toggle:hover i, +.sidebar-nav li:hover > a, +.sidebar-nav li > a.active { + color: #fff; +} + +.sidebar-nav li:hover, +.sidebar-nav li.active { + background: rgba(255,255,255,0.2); +} + +.menu-toggle { + color: #999 !important; +} + +.menu-toggle:hover { + color: #fff !important; +} diff --git a/resources/assets/css/style.css b/resources/assets/css/style.css index f9427c15c83f..a87d7d9ac144 100644 --- a/resources/assets/css/style.css +++ b/resources/assets/css/style.css @@ -7,7 +7,6 @@ html { /* overflow-y: scroll; */ } .bold { font-weight: 700; } -a {color:#34495E;} /*a:hover { text-decoration: none; color: #0a3857;}*/ .breadcrumb { padding: 8px 0!important; @@ -205,6 +204,7 @@ padding: 5px 10px; -webkit-box-shadow: none; box-shadow: none; } +/* .xbtn-primary { background-color: #34495E; border-color: #34495E; @@ -213,6 +213,7 @@ border-color: #34495E; background-color: #0a456c; border-color: #0a456c; } +*/ .btn-default {background-color: #808080; border-color: #808080; color: #fff; @@ -329,10 +330,6 @@ table.table thead > tr > th { table td { max-width: 250px; } -.pagination>.active>a, .pagination>.active>span, .pagination>.active>a:hover, .pagination>.active>span:hover, .pagination>.active>a:focus, .pagination>.active>span:focus { -background-color: #34495E; -border-color: #34495E; -} .pagination>li:first-child>a, .pagination>li:first-child>span { border-bottom-left-radius: 3px; border-top-left-radius: 3px; @@ -389,8 +386,7 @@ background-color: #9b9b9b; } .nav-tabs.nav-justified>.active>a, .nav-tabs.nav-justified>.active>a:hover, .nav-tabs.nav-justified>.active>a:focus { border: none; -background-color: #34495E; -font-weight: bold; + font-weight: bold; color: #fff; } .navbar { @@ -447,9 +443,6 @@ canvas { top: 11px; left: -6px; } -.navbar .dropdown-menu { - border-top: 1px solid #34495E; -} .navbar-brand { padding-top:20px; } @@ -498,7 +491,6 @@ background-clip: padding-box; .active-clients { - background-color: #34495E; background-image:url('../images/activeclients.png'); background-position:center; background-repeat: no-repeat; @@ -908,11 +900,6 @@ div.checkbox > label { color: white; } -.panel-heading { - /*background-color: #e37329 !important;*/ - background-color: #286090 !important; -} - div.alert { z-index: 1; } diff --git a/resources/assets/js/pdf.pdfmake.js b/resources/assets/js/pdf.pdfmake.js index 77338ea91b5f..516a88e6e392 100644 --- a/resources/assets/js/pdf.pdfmake.js +++ b/resources/assets/js/pdf.pdfmake.js @@ -563,122 +563,254 @@ NINJA.subtotalsBalance = function(invoice) { NINJA.accountDetails = function(invoice) { var account = invoice.account; - var data = [ - {text:account.name, style: ['accountName']}, - {text:account.id_number, style: ['idNumber']}, - {text:account.vat_number, style: ['vatNumber']}, - {text:account.website, style: ['website']}, - {text:account.work_email, style: ['email']}, - {text:account.work_phone, style: ['phone']} - ]; + if (invoice.features.invoice_settings && account.invoice_fields) { + var fields = JSON.parse(account.invoice_fields).account_fields1; + } else { + var fields = [ + 'account.company_name', + 'account.id_number', + 'account.vat_number', + 'account.website', + 'account.email', + 'account.phone', + ]; + } + + var data = []; + + for (var i=0; i < fields.length; i++) { + var field = fields[i]; + var value = NINJA.renderClientOrAccountField(invoice, field); + if (value) { + data.push(value); + } + } + return NINJA.prepareDataList(data, 'accountDetails'); } NINJA.accountAddress = function(invoice) { var account = invoice.account; - var cityStatePostal = ''; - if (account.city || account.state || account.postal_code) { - var swap = account.country && account.country.swap_postal_code; - cityStatePostal = formatAddress(account.city, account.state, account.postal_code, swap); + if (invoice.features.invoice_settings && account.invoice_fields) { + var fields = JSON.parse(account.invoice_fields).account_fields2; + } else { + var fields = [ + 'account.address1', + 'account.address2', + 'account.city_state_postal', + 'account.country', + 'account.custom_value1', + 'account.custom_value2', + ] } - var data = [ - {text: account.address1}, - {text: account.address2}, - {text: cityStatePostal}, - {text: account.country ? account.country.name : ''}, - ]; - if (invoice.features.invoice_settings) { - data.push({text: invoice.account.custom_value1 ? invoice.account.custom_label1 + ' ' + invoice.account.custom_value1 : false}); - data.push({text: invoice.account.custom_value2 ? invoice.account.custom_label2 + ' ' + invoice.account.custom_value2 : false}); + var data = []; + + for (var i=0; i < fields.length; i++) { + var field = fields[i]; + var value = NINJA.renderClientOrAccountField(invoice, field); + if (value) { + data.push(value); + } } return NINJA.prepareDataList(data, 'accountAddress'); } +NINJA.renderInvoiceField = function(invoice, field) { + + var account = invoice.account; + + if (field == 'invoice.invoice_number') { + return [ + {text: (invoice.is_quote ? invoiceLabels.quote_number : invoiceLabels.invoice_number), style: ['invoiceNumberLabel']}, + {text: invoice.invoice_number, style: ['invoiceNumber']} + ]; + } else if (field == 'invoice.po_number') { + return [ + {text: invoiceLabels.po_number}, + {text: invoice.po_number} + ]; + } else if (field == 'invoice.invoice_date') { + return [ + {text: (invoice.is_quote ? invoiceLabels.quote_date : invoiceLabels.invoice_date)}, + {text: invoice.invoice_date} + ]; + } else if (field == 'invoice.due_date') { + return [ + {text: (invoice.is_quote ? invoiceLabels.valid_until : invoiceLabels.due_date)}, + {text: invoice.is_recurring ? false : invoice.due_date} + ]; + } else if (field == 'invoice.custom_text_value1') { + if (invoice.custom_text_value1 && account.custom_invoice_text_label1) { + return [ + {text: invoice.account.custom_invoice_text_label1}, + {text: invoice.is_recurring ? processVariables(invoice.custom_text_value1) : invoice.custom_text_value1} + ]; + } else { + return false; + } + } else if (field == 'invoice.custom_text_value2') { + if (invoice.custom_text_value2 && account.custom_invoice_text_label2) { + return [ + {text: invoice.account.custom_invoice_text_label2}, + {text: invoice.is_recurring ? processVariables(invoice.custom_text_value2) : invoice.custom_text_value2} + ]; + } else { + return false; + } + } else if (field == 'invoice.balance_due') { + return [ + {text: invoiceLabels.balance_due, style: ['invoiceDetailBalanceDueLabel']}, + {text: formatMoneyInvoice(invoice.total_amount, invoice), style: ['invoiceDetailBalanceDue']} + ]; + } else if (field == invoice.partial_due) { + if (NINJA.parseFloat(invoice.partial)) { + return [ + {text: invoiceLabels.partial_due, style: ['invoiceDetailBalanceDueLabel']}, + {text: formatMoneyInvoice(invoice.balance_amount, invoice), style: ['invoiceDetailBalanceDue']} + ]; + } else { + return false; + } + } +} + NINJA.invoiceDetails = function(invoice) { - var data = [ - [ - {text: (invoice.is_quote ? invoiceLabels.quote_number : invoiceLabels.invoice_number), style: ['invoiceNumberLabel']}, - {text: invoice.invoice_number, style: ['invoiceNumber']} - ], - [ - {text: invoiceLabels.po_number}, - {text: invoice.po_number} - ], - [ - {text: (invoice.is_quote ? invoiceLabels.quote_date : invoiceLabels.invoice_date)}, - {text: invoice.invoice_date} - ], - [ - {text: (invoice.is_quote ? invoiceLabels.valid_until : invoiceLabels.due_date)}, - {text: invoice.is_recurring ? false : invoice.due_date} - ] - ]; - - if (invoice.custom_text_value1) { - data.push([ - {text: invoice.account.custom_invoice_text_label1}, - {text: invoice.is_recurring ? processVariables(invoice.custom_text_value1) : invoice.custom_text_value1} - ]) - } - if (invoice.custom_text_value2) { - data.push([ - {text: invoice.account.custom_invoice_text_label2}, - {text: invoice.is_recurring ? processVariables(invoice.custom_text_value2) : invoice.custom_text_value2} - ]) + var account = invoice.account; + if (invoice.features.invoice_settings && account.invoice_fields) { + var fields = JSON.parse(account.invoice_fields).invoice_fields; + } else { + var fields = [ + 'invoice.invoice_number', + 'invoice.po_number', + 'invoice.invoice_date', + 'invoice.due_date', + 'invoice.balance_due', + 'invoice.partial_due', + 'invoice.custom_text_value1', + 'invoice.custom_text_value2', + ]; } + var data = []; - data.push([ - {text: invoiceLabels.balance_due, style: ['invoiceDetailBalanceDueLabel']}, - {text: formatMoneyInvoice(invoice.total_amount, invoice), style: ['invoiceDetailBalanceDue']} - ]) - - if (NINJA.parseFloat(invoice.partial)) { - data.push([ - {text: invoiceLabels.partial_due, style: ['invoiceDetailBalanceDueLabel']}, - {text: formatMoneyInvoice(invoice.balance_amount, invoice), style: ['invoiceDetailBalanceDue']} - ]) + for (var i=0; i < fields.length; i++) { + var field = fields[i]; + var value = NINJA.renderInvoiceField(invoice, field); + if (value) { + data.push(value); + } } return NINJA.prepareDataPairs(data, 'invoiceDetails'); } -NINJA.clientDetails = function(invoice) { + +NINJA.renderClientOrAccountField = function(invoice, field) { var client = invoice.client; - var data; if (!client) { - return; + return false; } var account = invoice.account; var contact = client.contacts[0]; - var clientName = client.name || (contact.first_name || contact.last_name ? (contact.first_name + ' ' + contact.last_name) : contact.email); - var clientEmail = client.contacts[0].email == clientName ? '' : client.contacts[0].email; - var cityStatePostal = ''; - if (client.city || client.state || client.postal_code) { - var swap = client.country && client.country.swap_postal_code; - cityStatePostal = formatAddress(client.city, client.state, client.postal_code, swap); + if (field == 'client.client_name') { + var clientName = client.name || (contact.first_name || contact.last_name ? (contact.first_name + ' ' + contact.last_name) : contact.email); + return {text:clientName || ' ', style: ['clientName']}; + } else if (field == 'client.contact_name') { + return (contact.first_name || contact.last_name) ? {text:contact.first_name + ' ' + contact.last_name} : false; + } else if (field == 'client.id_number') { + return {text:client.id_number}; + } else if (field == 'client.vat_number') { + return {text:client.vat_number}; + } else if (field == 'client.address1') { + return {text:client.address1}; + } else if (field == 'client.address2') { + return {text:client.address2}; + } else if (field == 'client.city_state_postal') { + var cityStatePostal = ''; + if (client.city || client.state || client.postal_code) { + var swap = client.country && client.country.swap_postal_code; + cityStatePostal = formatAddress(client.city, client.state, client.postal_code, swap); + } + return {text:cityStatePostal}; + } else if (field == 'client.country') { + return {text:client.country ? client.country.name : ''}; + } else if (field == 'client.email') { + var clientEmail = contact.email == clientName ? '' : contact.email; + return {text:clientEmail}; + } else if (field == 'client.custom_value1') { + return {text: account.custom_client_label1 && client.custom_value1 ? account.custom_client_label1 + ' ' + client.custom_value1 : false}; + } else if (field == 'client.custom_value2') { + return {text: account.custom_client_label2 && client.custom_value2 ? account.custom_client_label2 + ' ' + client.custom_value2 : false}; } - // if a custom field is used in the invoice/quote number then we'll hide it from the PDF - var pattern = invoice.is_quote ? account.quote_number_pattern : account.invoice_number_pattern; - var custom1InPattern = (pattern && pattern.indexOf('{$custom1}') >= 0); - var custom2InPattern = (pattern && pattern.indexOf('{$custom2}') >= 0); + if (field == 'account.company_name') { + return {text:account.name, style: ['accountName']}; + } else if (field == 'account.id_number') { + return {text:account.id_number, style: ['idNumber']}; + } else if (field == 'account.vat_number') { + return {text:account.vat_number, style: ['vatNumber']}; + } else if (field == 'account.website') { + return {text:account.website, style: ['website']}; + } else if (field == 'account.email') { + return {text:account.work_email, style: ['email']}; + } else if (field == 'account.phone') { + return {text:account.work_phone, style: ['phone']}; + } else if (field == 'account.address1') { + return {text: account.address1}; + } else if (field == 'account.address2') { + return {text: account.address2}; + } else if (field == 'account.city_state_postal') { + var cityStatePostal = ''; + if (account.city || account.state || account.postal_code) { + var swap = account.country && account.country.swap_postal_code; + cityStatePostal = formatAddress(account.city, account.state, account.postal_code, swap); + } + return {text: cityStatePostal}; + } else if (field == 'account.country') { + return account.country ? {text: account.country.name} : false; + } else if (field == 'account.custom_value1') { + if (invoice.features.invoice_settings) { + return invoice.account.custom_label1 && invoice.account.custom_value1 ? {text: invoice.account.custom_label1 + ' ' + invoice.account.custom_value1} : false; + } + } else if (field == 'account.custom_value2') { + if (invoice.features.invoice_settings) { + return invoice.account.custom_label2 && invoice.account.custom_value2 ? {text: invoice.account.custom_label2 + ' ' + invoice.account.custom_value2} : false; + } + } - data = [ - {text:clientName || ' ', style: ['clientName']}, - {text:client.id_number}, - {text:client.vat_number}, - {text:client.address1}, - {text:client.address2}, - {text:cityStatePostal}, - {text:client.country ? client.country.name : ''}, - {text:clientEmail}, - {text: client.custom_value1 && !custom1InPattern ? account.custom_client_label1 + ' ' + client.custom_value1 : false}, - {text: client.custom_value2 && !custom2InPattern ? account.custom_client_label2 + ' ' + client.custom_value2 : false} - ]; + return false; +} + +NINJA.clientDetails = function(invoice) { + var account = invoice.account; + if (invoice.features.invoice_settings && account.invoice_fields) { + var fields = JSON.parse(account.invoice_fields).client_fields; + } else { + var fields = [ + 'client.client_name', + 'client.id_number', + 'client.vat_number', + 'client.address1', + 'client.address2', + 'client.city_state_postal', + 'client.country', + 'client.email', + 'client.custom_value1', + 'client.custom_value2', + ]; + } + var data = []; + + for (var i=0; i < fields.length; i++) { + var field = fields[i]; + var value = NINJA.renderClientOrAccountField(invoice, field); + if (value) { + data.push(value); + } + } return NINJA.prepareDataList(data, 'clientDetails'); } diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php index 4acd7cb075d2..f7d3dc07f3f4 100644 --- a/resources/lang/en/texts.php +++ b/resources/lang/en/texts.php @@ -2094,6 +2094,7 @@ $LANG = array( 'contact_name' => 'Contact Name', 'city_state_postal' => 'City/State/Postal', 'custom_field' => 'Custom Field', + 'account_fields' => 'Company Fields', // Limits 'limit' => 'Limit', diff --git a/resources/views/accounts/client_portal.blade.php b/resources/views/accounts/client_portal.blade.php index afd1b56cc1bf..b65f260ef2c9 100644 --- a/resources/views/accounts/client_portal.blade.php +++ b/resources/views/accounts/client_portal.blade.php @@ -79,7 +79,7 @@ -