mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
Merge remote-tracking branch 'upstream/develop' into 2016-09-payments-changes
This commit is contained in:
commit
30fcf0e363
@ -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
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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);
|
||||
});
|
||||
|
@ -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'],
|
||||
|
@ -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) {
|
||||
|
@ -9,61 +9,67 @@ trait PresentsInvoice
|
||||
{
|
||||
if ($this->invoice_fields) {
|
||||
$fields = json_decode($this->invoice_fields, true);
|
||||
return $this->applyLabels($fields);
|
||||
} else {
|
||||
return $this->getDefaultInvoiceFields();
|
||||
}
|
||||
}
|
||||
|
||||
public function getDefaultInvoiceFields()
|
||||
{
|
||||
$fields = [
|
||||
INVOICE_FIELDS_INVOICE => [
|
||||
'invoice_number',
|
||||
'po_number',
|
||||
'invoice_date',
|
||||
'due_date',
|
||||
'balance_due',
|
||||
'partial_due',
|
||||
'invoice.invoice_number',
|
||||
'invoice.po_number',
|
||||
'invoice.invoice_date',
|
||||
'invoice.due_date',
|
||||
'invoice.balance_due',
|
||||
'invoice.partial_due',
|
||||
],
|
||||
INVOICE_FIELDS_CLIENT => [
|
||||
'client_name',
|
||||
'id_number',
|
||||
'vat_number',
|
||||
'address1',
|
||||
'address2',
|
||||
'city_state_postal',
|
||||
'country',
|
||||
'email',
|
||||
'client.client_name',
|
||||
'client.id_number',
|
||||
'client.vat_number',
|
||||
'client.address1',
|
||||
'client.address2',
|
||||
'client.city_state_postal',
|
||||
'client.country',
|
||||
'client.email',
|
||||
],
|
||||
'company_fields1' => [
|
||||
'company_name',
|
||||
'id_number',
|
||||
'vat_number',
|
||||
'website',
|
||||
'email',
|
||||
'phone',
|
||||
'account_fields1' => [
|
||||
'account.company_name',
|
||||
'account.id_number',
|
||||
'account.vat_number',
|
||||
'account.website',
|
||||
'account.email',
|
||||
'account.phone',
|
||||
|
||||
],
|
||||
'company_fields2' => [
|
||||
'address1',
|
||||
'address2',
|
||||
'city_state_postal',
|
||||
'country',
|
||||
'account_fields2' => [
|
||||
'account.address1',
|
||||
'account.address2',
|
||||
'account.city_state_postal',
|
||||
'account.country',
|
||||
],
|
||||
];
|
||||
|
||||
if ($this->custom_invoice_text_label1) {
|
||||
$fields[INVOICE_FIELDS_INVOICE][] = 'custom_invoice_text_label1';
|
||||
$fields[INVOICE_FIELDS_INVOICE][] = 'invoice.custom_text_value1';
|
||||
}
|
||||
if ($this->custom_invoice_text_label2) {
|
||||
$fields[INVOICE_FIELDS_INVOICE][] = 'custom_invoice_text_label2';
|
||||
$fields[INVOICE_FIELDS_INVOICE][] = 'invoice.custom_text_value2';
|
||||
}
|
||||
if ($this->custom_client_label1) {
|
||||
$fields[INVOICE_FIELDS_CLIENT][] = 'custom_client_label1';
|
||||
$fields[INVOICE_FIELDS_CLIENT][] = 'client.custom_value1';
|
||||
}
|
||||
if ($this->custom_client_label2) {
|
||||
$fields[INVOICE_FIELDS_CLIENT][] = 'custom_client_label2';
|
||||
$fields[INVOICE_FIELDS_CLIENT][] = 'client.custom_value2';
|
||||
}
|
||||
if ($this->custom_label1) {
|
||||
$fields['company_fields2'][] = 'custom_label1';
|
||||
$fields['account_fields2'][] = 'account.custom_value1';
|
||||
}
|
||||
if ($this->custom_label2) {
|
||||
$fields['company_fields2'][] = '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) {
|
||||
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;
|
||||
|
@ -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);
|
||||
|
@ -54,6 +54,7 @@ elixir(function(mix) {
|
||||
'typeahead.js-bootstrap.css',
|
||||
'style.css',
|
||||
'sidebar.css',
|
||||
'colors.css',
|
||||
'fonts.css'
|
||||
], 'public/css/built.css');
|
||||
|
||||
|
79
resources/assets/css/colors.css
vendored
Normal file
79
resources/assets/css/colors.css
vendored
Normal file
@ -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;
|
||||
}
|
19
resources/assets/css/style.css
vendored
19
resources/assets/css/style.css
vendored
@ -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;
|
||||
}
|
||||
|
@ -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.invoiceDetails = function(invoice) {
|
||||
NINJA.renderInvoiceField = function(invoice, field) {
|
||||
|
||||
var data = [
|
||||
[
|
||||
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}
|
||||
]
|
||||
];
|
||||
|
||||
if (invoice.custom_text_value1) {
|
||||
data.push([
|
||||
} 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;
|
||||
}
|
||||
if (invoice.custom_text_value2) {
|
||||
data.push([
|
||||
} 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;
|
||||
}
|
||||
|
||||
data.push([
|
||||
} 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)) {
|
||||
data.push([
|
||||
return [
|
||||
{text: invoiceLabels.partial_due, style: ['invoiceDetailBalanceDueLabel']},
|
||||
{text: formatMoneyInvoice(invoice.balance_amount, invoice), style: ['invoiceDetailBalanceDue']}
|
||||
])
|
||||
];
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NINJA.invoiceDetails = function(invoice) {
|
||||
|
||||
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 = [];
|
||||
|
||||
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;
|
||||
|
||||
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');
|
||||
}
|
||||
|
@ -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',
|
||||
|
@ -79,7 +79,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel panel-default" id="buyNow">
|
||||
<div class="panel panel-default" id="buy_now">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">{!! trans('texts.buy_now_buttons') !!}</h3>
|
||||
</div>
|
||||
|
@ -58,6 +58,7 @@
|
||||
invoice.account.hide_paid_to_date = $('#hide_paid_to_date').is(":checked");
|
||||
invoice.invoice_design_id = $('#invoice_design_id').val();
|
||||
invoice.account.page_size = $('#page_size option:selected').text();
|
||||
invoice.account.invoice_fields = ko.mapping.toJSON(model);
|
||||
|
||||
NINJA.primaryColor = $('#primary_color').val();
|
||||
NINJA.secondaryColor = $('#secondary_color').val();
|
||||
@ -105,7 +106,6 @@
|
||||
$('#header_font_id').change(function(){loadFont($('#header_font_id').val())});
|
||||
$('#body_font_id').change(function(){loadFont($('#body_font_id').val())});
|
||||
|
||||
|
||||
refreshPDF();
|
||||
});
|
||||
|
||||
@ -136,7 +136,7 @@
|
||||
@endforeach
|
||||
|
||||
<div style="display:none">
|
||||
{!! Former::text('invoice_fields')->data_bind('value: ko.mapping.toJSON(model)') !!}
|
||||
{!! Former::text('invoice_fields_json')->data_bind('value: ko.mapping.toJSON(model)') !!}
|
||||
</div>
|
||||
|
||||
|
||||
@ -145,18 +145,18 @@
|
||||
<h3 class="panel-title">{!! trans('texts.invoice_design') !!}</h3>
|
||||
</div>
|
||||
|
||||
<div class="panel-body form-padding-right">
|
||||
<div class="panel-body">
|
||||
<div role="tabpanel">
|
||||
<ul class="nav nav-tabs" role="tablist" style="border: none">
|
||||
<li role="presentation" class="active"><a href="#generalSettings" aria-controls="generalSettings" role="tab" data-toggle="tab">{{ trans('texts.general_settings') }}</a></li>
|
||||
<li role="presentation"><a href="#invoiceLabels" aria-controls="invoiceLabels" role="tab" data-toggle="tab">{{ trans('texts.invoice_labels') }}</a></li>
|
||||
<li role="presentation"><a href="#invoiceFields" aria-controls="invoiceFields" role="tab" data-toggle="tab">{{ trans('texts.invoice_fields') }}</a></li>
|
||||
<li role="presentation"><a href="#invoiceOptions" aria-controls="invoiceOptions" role="tab" data-toggle="tab">{{ trans('texts.invoice_options') }}</a></li>
|
||||
<li role="presentation"><a href="#headerFooter" aria-controls="headerFooter" role="tab" data-toggle="tab">{{ trans('texts.header_footer') }}</a></li>
|
||||
<li role="presentation" class="active"><a href="#general_settings" aria-controls="general_settings" role="tab" data-toggle="tab">{{ trans('texts.general_settings') }}</a></li>
|
||||
<li role="presentation"><a href="#invoice_labels" aria-controls="invoice_labels" role="tab" data-toggle="tab">{{ trans('texts.invoice_labels') }}</a></li>
|
||||
<li role="presentation"><a href="#invoice_fields" aria-controls="invoice_fields" role="tab" data-toggle="tab">{{ trans('texts.invoice_fields') }}</a></li>
|
||||
<li role="presentation"><a href="#invoice_options" aria-controls="invoice_options" role="tab" data-toggle="tab">{{ trans('texts.invoice_options') }}</a></li>
|
||||
<li role="presentation"><a href="#header_footer" aria-controls="header_footer" role="tab" data-toggle="tab">{{ trans('texts.header_footer') }}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="tab-content">
|
||||
<div role="tabpanel" class="tab-pane active" id="generalSettings">
|
||||
<div role="tabpanel" class="tab-pane active" id="general_settings">
|
||||
<div class="panel-body">
|
||||
|
||||
<div class="row">
|
||||
@ -207,7 +207,7 @@
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane" id="invoiceLabels">
|
||||
<div role="tabpanel" class="tab-pane" id="invoice_labels">
|
||||
<div class="panel-body">
|
||||
|
||||
<div class="row">
|
||||
@ -231,17 +231,26 @@
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane" id="invoiceFields">
|
||||
<div role="tabpanel" class="tab-pane" id="invoice_fields">
|
||||
<div class="panel-body">
|
||||
<div class="row">
|
||||
@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' => 'company_fields1', 'fields' => INVOICE_FIELDS_COMPANY])
|
||||
@include('accounts.partials.invoice_fields_selector', ['section' => 'company_fields2', 'fields' => INVOICE_FIELDS_COMPANY])
|
||||
@include('accounts.partials.invoice_fields_selector', ['section' => 'account_fields1', 'fields' => INVOICE_FIELDS_ACCOUNT])
|
||||
@include('accounts.partials.invoice_fields_selector', ['section' => 'account_fields2', 'fields' => INVOICE_FIELDS_ACCOUNT])
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="pull-right" style="padding-top:18px;padding-right:14px">
|
||||
{!! Button::normal(trans('texts.reset'))
|
||||
->withAttributes(['onclick' => 'sweetConfirm(function() {
|
||||
resetFields();
|
||||
})'])
|
||||
->small() !!}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane" id="invoiceOptions">
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane" id="invoice_options">
|
||||
<div class="panel-body">
|
||||
|
||||
{!! Former::checkbox('hide_quantity')->text(trans('texts.hide_quantity_help')) !!}
|
||||
@ -250,7 +259,7 @@
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane" id="headerFooter">
|
||||
<div role="tabpanel" class="tab-pane" id="header_footer">
|
||||
<div class="panel-body">
|
||||
|
||||
{!! Former::inline_radios('all_pages_header')
|
||||
|
@ -36,18 +36,18 @@
|
||||
<div role="tabpanel">
|
||||
<ul class="nav nav-tabs" role="tablist" style="border: none">
|
||||
<li role="presentation" class="active">
|
||||
<a href="#invoiceNumber" aria-controls="invoiceNumber" role="tab" data-toggle="tab">{{ trans('texts.invoice_number') }}</a>
|
||||
<a href="#invoice_number" aria-controls="invoice_number" role="tab" data-toggle="tab">{{ trans('texts.invoice_number') }}</a>
|
||||
</li>
|
||||
<li role="presentation">
|
||||
<a href="#quoteNumber" aria-controls="quoteNumber" role="tab" data-toggle="tab">{{ trans('texts.quote_number') }}</a>
|
||||
<a href="#quote_number" aria-controls="quote_number" role="tab" data-toggle="tab">{{ trans('texts.quote_number') }}</a>
|
||||
</li>
|
||||
<li role="presentation">
|
||||
<a href="#recurringInvoiceNumber" aria-controls="recurringInvoiceNumber" role="tab" data-toggle="tab">{{ trans('texts.recurring_invoice_number') }}</a>
|
||||
<a href="#recurring_invoice_number" aria-controls="recurring_invoice_number" role="tab" data-toggle="tab">{{ trans('texts.recurring_invoice_number') }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="tab-content">
|
||||
<div role="tabpanel" class="tab-pane active" id="invoiceNumber">
|
||||
<div role="tabpanel" class="tab-pane active" id="invoice_number">
|
||||
<div class="panel-body">
|
||||
{!! Former::inline_radios('invoice_number_type')
|
||||
->onchange('onInvoiceNumberTypeChange()')
|
||||
@ -73,7 +73,7 @@
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane" id="quoteNumber">
|
||||
<div role="tabpanel" class="tab-pane" id="quote_number">
|
||||
<div class="panel-body">
|
||||
{!! Former::inline_radios('quote_number_type')
|
||||
->onchange('onQuoteNumberTypeChange()')
|
||||
@ -102,7 +102,7 @@
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane" id="recurringInvoiceNumber">
|
||||
<div role="tabpanel" class="tab-pane" id="recurring_invoice_number">
|
||||
<div class="panel-body">
|
||||
|
||||
{!! Former::text('recurring_invoice_number_prefix')
|
||||
@ -126,24 +126,24 @@
|
||||
<div role="tabpanel">
|
||||
<ul class="nav nav-tabs" role="tablist" style="border: none">
|
||||
<li role="presentation" class="active">
|
||||
<a href="#clientFields" aria-controls="clientFields" role="tab" data-toggle="tab">{{ trans('texts.client_fields') }}</a>
|
||||
<a href="#client_fields" aria-controls="client_fields" role="tab" data-toggle="tab">{{ trans('texts.client_fields') }}</a>
|
||||
</li>
|
||||
<li role="presentation">
|
||||
<a href="#companyFields" aria-controls="companyFields" role="tab" data-toggle="tab">{{ trans('texts.company_fields') }}</a>
|
||||
<a href="#company_fields" aria-controls="company_fields" role="tab" data-toggle="tab">{{ trans('texts.company_fields') }}</a>
|
||||
</li>
|
||||
<li role="presentation">
|
||||
<a href="#invoiceFields" aria-controls="invoiceFields" role="tab" data-toggle="tab">{{ trans('texts.invoice_fields') }}</a>
|
||||
<a href="#invoice_fields" aria-controls="invoice_fields" role="tab" data-toggle="tab">{{ trans('texts.invoice_fields') }}</a>
|
||||
</li>
|
||||
<li role="presentation">
|
||||
<a href="#invoiceItemFields" aria-controls="invoiceItemFields" role="tab" data-toggle="tab">{{ trans('texts.invoice_item_fields') }}</a>
|
||||
<a href="#invoice_item_fields" aria-controls="invoice_item_fields" role="tab" data-toggle="tab">{{ trans('texts.invoice_item_fields') }}</a>
|
||||
</li>
|
||||
<li role="presentation">
|
||||
<a href="#invoiceCharges" aria-controls="invoiceCharges" role="tab" data-toggle="tab">{{ trans('texts.invoice_charges') }}</a>
|
||||
<a href="#invoice_charges" aria-controls="invoice_charges" role="tab" data-toggle="tab">{{ trans('texts.invoice_charges') }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="tab-content">
|
||||
<div role="tabpanel" class="tab-pane active" id="clientFields">
|
||||
<div role="tabpanel" class="tab-pane active" id="client_fields">
|
||||
<div class="panel-body">
|
||||
|
||||
{!! Former::text('custom_client_label1')
|
||||
@ -154,7 +154,7 @@
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane" id="companyFields">
|
||||
<div role="tabpanel" class="tab-pane" id="company_fields">
|
||||
<div class="panel-body">
|
||||
|
||||
{!! Former::text('custom_label1')
|
||||
@ -170,7 +170,7 @@
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane" id="invoiceFields">
|
||||
<div role="tabpanel" class="tab-pane" id="invoice_fields">
|
||||
<div class="panel-body">
|
||||
|
||||
{!! Former::text('custom_invoice_text_label1')
|
||||
@ -181,7 +181,7 @@
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane" id="invoiceItemFields">
|
||||
<div role="tabpanel" class="tab-pane" id="invoice_item_fields">
|
||||
<div class="panel-body">
|
||||
|
||||
{!! Former::text('custom_invoice_item_label1')
|
||||
@ -192,7 +192,7 @@
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane" id="invoiceCharges">
|
||||
<div role="tabpanel" class="tab-pane" id="invoice_charges">
|
||||
<div class="panel-body">
|
||||
|
||||
{!! Former::text('custom_invoice_label1')
|
||||
@ -232,27 +232,27 @@
|
||||
|
||||
<div role="tabpanel">
|
||||
<ul class="nav nav-tabs" role="tablist" style="border: none">
|
||||
<li role="presentation" class="active"><a href="#invoiceTerms" aria-controls="invoiceTerms" role="tab" data-toggle="tab">{{ trans('texts.invoice_terms') }}</a></li>
|
||||
<li role="presentation"><a href="#invoiceFooter" aria-controls="invoiceFooter" role="tab" data-toggle="tab">{{ trans('texts.invoice_footer') }}</a></li>
|
||||
<li role="presentation"><a href="#quoteTerms" aria-controls="quoteTerms" role="tab" data-toggle="tab">{{ trans('texts.quote_terms') }}</a></li>
|
||||
<li role="presentation" class="active"><a href="#invoice_terms" aria-controls="invoice_terms" role="tab" data-toggle="tab">{{ trans('texts.invoice_terms') }}</a></li>
|
||||
<li role="presentation"><a href="#invoice_footer" aria-controls="invoice_footer" role="tab" data-toggle="tab">{{ trans('texts.invoice_footer') }}</a></li>
|
||||
<li role="presentation"><a href="#quote_terms" aria-controls="quote_terms" role="tab" data-toggle="tab">{{ trans('texts.quote_terms') }}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="tab-content">
|
||||
<div role="tabpanel" class="tab-pane active" id="invoiceTerms">
|
||||
<div role="tabpanel" class="tab-pane active" id="invoice_terms">
|
||||
<div class="panel-body">
|
||||
{!! Former::textarea('invoice_terms')
|
||||
->label(trans('texts.default_invoice_terms'))
|
||||
->rows(4) !!}
|
||||
</div>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane" id="invoiceFooter">
|
||||
<div role="tabpanel" class="tab-pane" id="invoice_footer">
|
||||
<div class="panel-body">
|
||||
{!! Former::textarea('invoice_footer')
|
||||
->label(trans('texts.default_invoice_footer'))
|
||||
->rows(4) !!}
|
||||
</div>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane" id="quoteTerms">
|
||||
<div role="tabpanel" class="tab-pane" id="quote_terms">
|
||||
<div class="panel-body">
|
||||
{!! Former::textarea('quote_terms')
|
||||
->label(trans('texts.default_quote_terms'))
|
||||
|
@ -5,26 +5,48 @@ function ViewModel(data) {
|
||||
|
||||
self.invoice_fields = ko.observableArray();
|
||||
self.client_fields = ko.observableArray();
|
||||
self.company_fields1 = ko.observableArray();
|
||||
self.company_fields2 = ko.observableArray();
|
||||
self.account_fields1 = ko.observableArray();
|
||||
self.account_fields2 = ko.observableArray();
|
||||
window.field_map = [];
|
||||
|
||||
self.addField = function(section, field, label) {
|
||||
if (self[section].indexOf(field) < 0) {
|
||||
self[section].push(field);
|
||||
window.field_map[field] = label;
|
||||
}
|
||||
}
|
||||
|
||||
self.resetFields = function() {
|
||||
console.log('herey');
|
||||
self.invoice_fields.removeAll();
|
||||
self.client_fields.removeAll();
|
||||
self.account_fields1.removeAll();
|
||||
self.account_fields2.removeAll();
|
||||
}
|
||||
|
||||
self.onChange = function() {
|
||||
refreshPDF();
|
||||
NINJA.formIsChanged = true;
|
||||
}
|
||||
|
||||
self.onDragged = function() {
|
||||
self.onChange();
|
||||
}
|
||||
|
||||
self.removeInvoiceFields = function(item) {
|
||||
self.invoice_fields.remove(item);
|
||||
self.onChange();
|
||||
}
|
||||
self.removeClientFields = function(item) {
|
||||
self.client_fields.remove(item);
|
||||
self.onChange();
|
||||
}
|
||||
self.removeCompanyFields1 = function(item) {
|
||||
self.company_fields1.remove(item);
|
||||
self.removeAccountFields1 = function(item) {
|
||||
self.account_fields1.remove(item);
|
||||
self.onChange();
|
||||
}
|
||||
self.removeCompanyFields2 = function(item) {
|
||||
self.company_fields2.remove(item);
|
||||
self.removeAccountFields2 = function(item) {
|
||||
self.account_fields2.remove(item);
|
||||
self.onChange();
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,6 +62,38 @@ $(function() {
|
||||
window.model = new ViewModel();
|
||||
|
||||
var selectedFields = {!! json_encode($account->getInvoiceFields()) !!};
|
||||
var allFields = {!! json_encode($account->getAllInvoiceFields()) !!};
|
||||
|
||||
loadFields(selectedFields);
|
||||
loadMap(allFields);
|
||||
|
||||
ko.applyBindings(model);
|
||||
})
|
||||
|
||||
function resetFields() {
|
||||
var defaultFields = {!! json_encode($account->getDefaultInvoiceFields()) !!};
|
||||
window.model.resetFields();
|
||||
loadFields(defaultFields);
|
||||
}
|
||||
|
||||
function loadMap(allFields) {
|
||||
for (var section in allFields) {
|
||||
if ( ! allFields.hasOwnProperty(section)) {
|
||||
continue;
|
||||
}
|
||||
var fields = allFields[section];
|
||||
for (var field in fields) {
|
||||
if ( ! fields.hasOwnProperty(field)) {
|
||||
continue;
|
||||
}
|
||||
var label = fields[field];
|
||||
window.field_map[field] = label;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function loadFields(selectedFields)
|
||||
{
|
||||
for (var section in selectedFields) {
|
||||
if ( ! selectedFields.hasOwnProperty(section)) {
|
||||
continue;
|
||||
@ -53,12 +107,7 @@ $(function() {
|
||||
model.addField(section, field, label);
|
||||
}
|
||||
}
|
||||
|
||||
console.log(selectedFields);
|
||||
|
||||
|
||||
ko.applyBindings(model);
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
@ -89,7 +138,8 @@ $(function() {
|
||||
|
||||
.field-list td div {
|
||||
float: left;
|
||||
width: 146px;
|
||||
xwidth: 146px;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
@ -103,7 +153,6 @@ $(function() {
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
|
||||
.field-list .fa {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
<div class="col-md-3">
|
||||
<div class="col-lg-3 col-md-6">
|
||||
|
||||
{!! Former::select("{$section}_select")
|
||||
->placeholder(trans("texts.{$fields}"))
|
||||
@ -7,11 +7,11 @@
|
||||
->raw() !!}
|
||||
|
||||
<table class="field-list">
|
||||
<tbody data-bind="sortable: { data: {{ $section }}, as: 'field' }">
|
||||
<tbody data-bind="sortable: { data: {{ $section }}, as: 'field', afterMove: onDragged }">
|
||||
<tr>
|
||||
<td>
|
||||
<i class="fa fa-close" data-bind="click: $root.{{ Utils::toCamelCase('remove' . ucwords($section)) }}"></i>
|
||||
<div data-bind="text: window.field_map[field]"></div>
|
||||
<span data-bind="text: window.field_map[field]"></span>
|
||||
<i class="fa fa-bars"></i>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -1,6 +1,5 @@
|
||||
@extends('header')
|
||||
|
||||
|
||||
@section('onReady')
|
||||
$('input#name').focus();
|
||||
@stop
|
||||
@ -31,7 +30,7 @@
|
||||
<div class="col-md-6">
|
||||
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel panel-default" style="min-height: 380px">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">{!! trans('texts.organization') !!}</h3>
|
||||
</div>
|
||||
@ -54,7 +53,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel panel-default" style="min-height: 500px">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">{!! trans('texts.address') !!}</h3>
|
||||
</div>
|
||||
@ -74,7 +73,7 @@
|
||||
<div class="col-md-6">
|
||||
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel panel-default" style="min-height: 380px">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">{!! trans('texts.contacts') !!}</h3>
|
||||
</div>
|
||||
@ -112,7 +111,7 @@
|
||||
</div>
|
||||
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel panel-default" style="min-height: 500px">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">{!! trans('texts.additional_info') !!}</h3>
|
||||
</div>
|
||||
|
@ -7,149 +7,6 @@
|
||||
|
||||
<style type="text/css">
|
||||
|
||||
body {
|
||||
background-color: #fcfcfc;
|
||||
}
|
||||
|
||||
.navbar {
|
||||
background-color: #337ab7 !important;
|
||||
}
|
||||
|
||||
.navbar-collapse {
|
||||
background-color: #337ab7 !important;
|
||||
}
|
||||
|
||||
|
||||
table.dataTable thead > tr > th,
|
||||
table.invoice-table thead > tr > th {
|
||||
background-color: #777 !important;
|
||||
xbackground-color: #8f8f8f !important;
|
||||
xbackground-color: #34495E !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;
|
||||
}
|
||||
|
||||
|
||||
.menu-toggle {
|
||||
text-decoration: none;
|
||||
}
|
||||
.menu-toggle:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.icon-footer {
|
||||
text-align: center;
|
||||
position:fixed;
|
||||
bottom:12px;
|
||||
left:16px;
|
||||
color:white;
|
||||
font-size:16px
|
||||
}
|
||||
|
||||
.icon-footer i {
|
||||
width: 40px;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.icon-footer i:hover {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
body {
|
||||
background: white;
|
||||
}
|
||||
|
||||
div.panel-body {
|
||||
background-color: #f2f5fe;
|
||||
}
|
||||
|
||||
table.dataTable thead > tr > th,
|
||||
table.invoice-table thead > tr > th {
|
||||
background-color: #0b4d78 !important;
|
||||
color:#fff;
|
||||
}
|
||||
|
||||
thead th {
|
||||
border-left: 1px solid #7a8799;
|
||||
}
|
||||
|
||||
.sidebar-nav {
|
||||
background-color: #f2f5fe;
|
||||
}
|
||||
|
||||
.sidebar-nav i.fa {
|
||||
color: #7a8799;
|
||||
}
|
||||
|
||||
.sidebar-nav li {
|
||||
border-bottom:solid 1px #7a8799;
|
||||
}
|
||||
|
||||
.sidebar-nav li > a {
|
||||
color: #7a8799;
|
||||
}
|
||||
|
||||
.sidebar-nav li:hover > a,
|
||||
.sidebar-nav li > a.active {
|
||||
color: #2b435d;
|
||||
}
|
||||
|
||||
.sidebar-nav li:hover,
|
||||
.sidebar-nav li.active {
|
||||
background: rgba(255,255,255,1);
|
||||
}
|
||||
|
||||
.menu-toggle {
|
||||
color: #999 !important;
|
||||
}
|
||||
|
||||
.menu-toggle:hover {
|
||||
color: #fff !important;
|
||||
}
|
||||
*/
|
||||
|
||||
@if (Auth::check() && Auth::user()->dark_mode)
|
||||
body {
|
||||
background: #000 !important;
|
||||
@ -489,6 +346,19 @@ thead th {
|
||||
$.get('{{ url('save_sidebar_state') }}?show_right=' + toggled);
|
||||
});
|
||||
|
||||
if (window.location.hash) {
|
||||
setTimeout(function() {
|
||||
$('.nav-tabs a[href="' + window.location.hash + '"]').tab('show');
|
||||
}, 1);
|
||||
}
|
||||
|
||||
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
|
||||
var target = $(e.target).attr("href") // activated tab
|
||||
var scrollmem = $('html,body').scrollTop();
|
||||
window.location.hash = target;
|
||||
$('html,body').scrollTop(scrollmem);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
|
4
resources/views/vendors/edit.blade.php
vendored
4
resources/views/vendors/edit.blade.php
vendored
@ -32,7 +32,7 @@
|
||||
<div class="col-md-6">
|
||||
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel panel-default" style="min-height: 380px">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">{!! trans('texts.organization') !!}</h3>
|
||||
</div>
|
||||
@ -67,7 +67,7 @@
|
||||
<div class="col-md-6">
|
||||
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel panel-default" style="min-height: 380px">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">{!! trans('texts.contacts') !!}</h3>
|
||||
</div>
|
||||
|
Loading…
x
Reference in New Issue
Block a user