mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
Working on multi-language support
This commit is contained in:
parent
b7061222e8
commit
6d6084728d
@ -48,7 +48,7 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Where Former should look for translations
|
||||
'translate_from' => 'texts',
|
||||
'translate_from' => 'fields',
|
||||
|
||||
// An array of attributes to automatically translate
|
||||
'translatable' => array(
|
||||
|
@ -223,6 +223,7 @@ class InvoiceController extends \BaseController {
|
||||
'paymentTerms' => PaymentTerm::remember(DEFAULT_QUERY_CACHE)->orderBy('num_days')->get(['name', 'num_days']),
|
||||
'industries' => Industry::remember(DEFAULT_QUERY_CACHE)->orderBy('id')->get(),
|
||||
'invoiceDesigns' => InvoiceDesign::remember(DEFAULT_QUERY_CACHE)->orderBy('id')->get(),
|
||||
'invoiceLabels' => Auth::user()->getInvoiceLabels(),
|
||||
'frequencies' => array(
|
||||
1 => 'Weekly',
|
||||
2 => 'Two weeks',
|
||||
|
@ -23,6 +23,7 @@ class AddLanguageSupport extends Migration {
|
||||
DB::table('languages')->insert(['name' => 'Italian', 'locale' => 'it']);
|
||||
DB::table('languages')->insert(['name' => 'German', 'locale' => 'de']);
|
||||
DB::table('languages')->insert(['name' => 'French', 'locale' => 'fr']);
|
||||
DB::table('languages')->insert(['name' => 'Brazilian Portuguese', 'locale' => 'pt_BR']);
|
||||
|
||||
Schema::table('accounts', function($table)
|
||||
{
|
||||
|
54
app/lang/en/fields.php
Normal file
54
app/lang/en/fields.php
Normal file
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
return array(
|
||||
|
||||
// client
|
||||
'organization' => 'Organization',
|
||||
'name' => 'Name',
|
||||
'website' => 'Website',
|
||||
'work_phone' => 'Phone',
|
||||
'address' => 'Address',
|
||||
'address1' => 'Street',
|
||||
'address2' => 'Apt/Suite',
|
||||
'city' => 'City',
|
||||
'state' => 'State/Province',
|
||||
'postal_code' => 'Postal Code',
|
||||
'country_id' => 'Country',
|
||||
'contacts' => 'Contacts',
|
||||
'first_name' => 'First Name',
|
||||
'last_name' => 'Last Name',
|
||||
'phone' => 'Phone',
|
||||
'email' => 'Email',
|
||||
'additional_info' => 'Additional Info',
|
||||
'payment_terms' => 'Payment Terms',
|
||||
'currency_id' => 'Currency',
|
||||
'size_id' => 'Size',
|
||||
'industry_id' => 'Industry',
|
||||
'private_notes' => 'Private Notes',
|
||||
|
||||
// invoice
|
||||
'invoice' => 'Invoice',
|
||||
'client' => 'Client',
|
||||
'invoice_date' => 'Invoice Date',
|
||||
'due_date' => 'Due Date',
|
||||
'invoice_number' => 'Invoice Number',
|
||||
'invoice_number_short' => 'Invoice #',
|
||||
'po_number' => 'PO Number',
|
||||
'po_number_short' => 'PO #',
|
||||
'frequency_id' => 'How often',
|
||||
'dicount' => 'Discount',
|
||||
'taxes' => 'Taxes',
|
||||
'tax' => 'Tax',
|
||||
'item' => 'Item',
|
||||
'description' => 'Description',
|
||||
'unit_cost' => 'Unit Cost',
|
||||
'quantity' => 'Quantity',
|
||||
'line_total' => 'Line Total',
|
||||
'subtotal' => 'Subtotal',
|
||||
'paid_to_date' => 'Paid to Date',
|
||||
'balance_due' => 'Balance Due',
|
||||
'invoice_design_id' => 'Design',
|
||||
'terms' => 'Terms',
|
||||
'your_invoice' => 'Your Invoice',
|
||||
|
||||
);
|
0
app/lang/en/messages.php
Normal file
0
app/lang/en/messages.php
Normal file
@ -1,28 +0,0 @@
|
||||
<?php
|
||||
|
||||
return array(
|
||||
|
||||
'organization' => 'Organization',
|
||||
'name' => 'Name',
|
||||
'website' => 'Website',
|
||||
'work_phone' => 'Phone',
|
||||
'address' => 'Address',
|
||||
'address1' => 'Street',
|
||||
'address2' => 'Apt/Suite',
|
||||
'city' => 'City',
|
||||
'state' => 'State/Province',
|
||||
'postal_code' => 'Postal Code',
|
||||
'country_id' => 'Country',
|
||||
'contacts' => 'Contacts',
|
||||
'first_name' => 'First Name',
|
||||
'last_name' => 'Last Name',
|
||||
'phone' => 'Phone',
|
||||
'email' => 'Email',
|
||||
'additional_info' => 'Additional Info',
|
||||
'payment_terms' => 'Payment Terms',
|
||||
'currency_id' => 'Currency',
|
||||
'size_id' => 'Size',
|
||||
'industry_id' => 'Industry',
|
||||
'private_notes' => 'Private Notes',
|
||||
|
||||
);
|
@ -110,6 +110,38 @@ class User extends ConfideUser implements UserInterface, RemindableInterface
|
||||
return $language->locale;
|
||||
}
|
||||
|
||||
public function getInvoiceLabels()
|
||||
{
|
||||
$data = [];
|
||||
$fields = [
|
||||
'invoice',
|
||||
'invoice_date',
|
||||
'due_date',
|
||||
'invoice_number',
|
||||
'po_number',
|
||||
'dicount',
|
||||
'taxes',
|
||||
'tax',
|
||||
'item',
|
||||
'description',
|
||||
'unit_cost',
|
||||
'quantity',
|
||||
'line_total',
|
||||
'subtotal',
|
||||
'paid_to_date',
|
||||
'balance_due',
|
||||
'terms',
|
||||
'your_invoice',
|
||||
];
|
||||
|
||||
foreach ($fields as $field)
|
||||
{
|
||||
$data[$field] = trans("fields.$field");
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function showGreyBackground()
|
||||
{
|
||||
return !$this->theme_id || in_array($this->theme_id, [2, 3, 5, 6, 7, 8, 10, 11, 12]);
|
||||
|
@ -70,7 +70,7 @@
|
||||
->data_date_format(Session::get(SESSION_DATE_PICKER_FORMAT))->append('<i class="glyphicon glyphicon-calendar" onclick="toggleDatePicker(\'due_date\')"></i>') }}
|
||||
</div>
|
||||
<div data-bind="visible: is_recurring" style="display: none">
|
||||
{{ Former::select('frequency_id')->label('How often')->options($frequencies)->data_bind("value: frequency_id") }}
|
||||
{{ Former::select('frequency_id')->options($frequencies)->data_bind("value: frequency_id") }}
|
||||
{{ Former::text('start_date')->data_bind("datePicker: start_date, valueUpdate: 'afterkeydown'")
|
||||
->data_date_format(Session::get(SESSION_DATE_PICKER_FORMAT))->append('<i class="glyphicon glyphicon-calendar" onclick="toggleDatePicker(\'start_date\')"></i>') }}
|
||||
{{ Former::text('end_date')->data_bind("datePicker: end_date, valueUpdate: 'afterkeydown'")
|
||||
@ -90,10 +90,10 @@
|
||||
</div>
|
||||
|
||||
<div class="col-md-4" id="col_2">
|
||||
{{ Former::text('invoice_number')->label('Invoice #')->data_bind("value: invoice_number, valueUpdate: 'afterkeydown'") }}
|
||||
{{ Former::text('po_number')->label('PO #')->data_bind("value: po_number, valueUpdate: 'afterkeydown'") }}
|
||||
{{ Former::text('invoice_number')->label(trans('fields.invoice_number_short'))->data_bind("value: invoice_number, valueUpdate: 'afterkeydown'") }}
|
||||
{{ Former::text('po_number')->label(trans('fields.po_number_short'))->data_bind("value: po_number, valueUpdate: 'afterkeydown'") }}
|
||||
{{ Former::text('discount')->data_bind("value: discount, valueUpdate: 'afterkeydown'")->append('%') }}
|
||||
{{-- Former::select('currency_id')->label('Currency')->addOption('', '')->fromQuery($currencies, 'name', 'id')->data_bind("value: currency_id") --}}
|
||||
{{-- Former::select('currency_id')->addOption('', '')->fromQuery($currencies, 'name', 'id')->data_bind("value: currency_id") --}}
|
||||
|
||||
<div class="form-group" style="margin-bottom: 8px">
|
||||
<label for="recurring" class="control-label col-lg-4 col-sm-4">Taxes</label>
|
||||
@ -210,7 +210,7 @@
|
||||
|
||||
|
||||
|
||||
{{ Former::select('invoice_design_id')->label('Design')->style('display:inline;width:120px')->raw()
|
||||
{{ Former::select('invoice_design_id')->style('display:inline;width:120px')->raw()
|
||||
->fromQuery($invoiceDesigns, 'name', 'id')->data_bind("value: invoice_design_id") }}
|
||||
|
||||
|
||||
@ -291,16 +291,16 @@
|
||||
{{ Former::legend('Organization') }}
|
||||
{{ Former::text('name')->data_bind("value: name, valueUpdate: 'afterkeydown', attr { placeholder: name.placeholder }") }}
|
||||
{{ Former::text('website')->data_bind("value: website, valueUpdate: 'afterkeydown'") }}
|
||||
{{ Former::text('work_phone')->data_bind("value: work_phone, valueUpdate: 'afterkeydown'")->label('Phone') }}
|
||||
{{ Former::text('work_phone')->data_bind("value: work_phone, valueUpdate: 'afterkeydown'") }}
|
||||
|
||||
|
||||
{{ Former::legend('Address') }}
|
||||
{{ Former::text('address1')->label('Street')->data_bind("value: address1, valueUpdate: 'afterkeydown'") }}
|
||||
{{ Former::text('address2')->label('Apt/Suite')->data_bind("value: address2, valueUpdate: 'afterkeydown'") }}
|
||||
{{ Former::text('address1')->data_bind("value: address1, valueUpdate: 'afterkeydown'") }}
|
||||
{{ Former::text('address2')->data_bind("value: address2, valueUpdate: 'afterkeydown'") }}
|
||||
{{ Former::text('city')->data_bind("value: city, valueUpdate: 'afterkeydown'") }}
|
||||
{{ Former::text('state')->label('State/Province')->data_bind("value: state, valueUpdate: 'afterkeydown'") }}
|
||||
{{ Former::text('state')->data_bind("value: state, valueUpdate: 'afterkeydown'") }}
|
||||
{{ Former::text('postal_code')->data_bind("value: postal_code, valueUpdate: 'afterkeydown'") }}
|
||||
{{ Former::select('country_id')->addOption('','')->label('Country')->addGroupClass('country_select')
|
||||
{{ Former::select('country_id')->addOption('','')->addGroupClass('country_select')
|
||||
->fromQuery($countries, 'name', 'id')->data_bind("dropdown: country_id") }}
|
||||
|
||||
</div>
|
||||
@ -332,11 +332,11 @@
|
||||
{{ Former::legend('Additional Info') }}
|
||||
{{ Former::select('payment_terms')->addOption('','0')->data_bind('value: payment_terms')
|
||||
->fromQuery($paymentTerms, 'name', 'num_days') }}
|
||||
{{ Former::select('currency_id')->addOption('','')->label('Currency')->data_bind('value: currency_id')
|
||||
{{ Former::select('currency_id')->addOption('','')->data_bind('value: currency_id')
|
||||
->fromQuery($currencies, 'name', 'id') }}
|
||||
{{ Former::select('size_id')->addOption('','')->label('Size')->data_bind('value: size_id')
|
||||
{{ Former::select('size_id')->addOption('','')->data_bind('value: size_id')
|
||||
->fromQuery($sizes, 'name', 'id') }}
|
||||
{{ Former::select('industry_id')->addOption('','')->label('Industry')->data_bind('value: industry_id')
|
||||
{{ Former::select('industry_id')->addOption('','')->data_bind('value: industry_id')
|
||||
->fromQuery($industries, 'name', 'id') }}
|
||||
{{ Former::textarea('private_notes')->data_bind('value: private_notes') }}
|
||||
|
||||
@ -616,9 +616,10 @@
|
||||
|
||||
var isRefreshing = false;
|
||||
var needsRefresh = false;
|
||||
|
||||
function getPDFString() {
|
||||
var invoice = createInvoiceModel();
|
||||
var doc = generatePDF(invoice);
|
||||
var doc = generatePDF(invoice, invoiceLabels);
|
||||
if (!doc) return;
|
||||
return doc.output('datauristring');
|
||||
}
|
||||
@ -1445,10 +1446,10 @@
|
||||
|
||||
var products = {{ $products }};
|
||||
var clients = {{ $clients }};
|
||||
var invoiceLabels = {{ json_encode($invoiceLabels) }};
|
||||
var clientMap = {};
|
||||
var $clientSelect = $('select#client');
|
||||
|
||||
|
||||
|
||||
for (var i=0; i<clients.length; i++) {
|
||||
var client = clients[i];
|
||||
for (var j=0; j<client.contacts.length; j++) {
|
||||
|
@ -716,7 +716,7 @@ function GetReportTemplate1(doc, invoice, layout, checkMath)
|
||||
|
||||
SetPdfColor('LightBlue',doc);
|
||||
doc.setFontSize('11');
|
||||
doc.text(50, layout.headerTop, 'INVOICE');
|
||||
doc.text(50, layout.headerTop, invoiceLabels.invoice.toUpperCase());
|
||||
|
||||
//doc.setDrawColor(220,220,220);
|
||||
//doc.line(30, y, 560, y); // horizontal line
|
||||
@ -896,7 +896,7 @@ function GetReportTemplate2(doc, invoice, layout, checkMath)
|
||||
SetPdfColor('SomeGreen',doc);
|
||||
doc.setFontSize('14');
|
||||
doc.setFontType("bold");
|
||||
doc.text(50, GlobalY, 'YOUR INVOICE');
|
||||
doc.text(50, GlobalY, invoiceLabels.your_invoice.toUpperCase());
|
||||
|
||||
|
||||
var z=GlobalY;
|
||||
@ -1306,11 +1306,11 @@ function displayInvoice(doc, invoice, x, y, layout, rightAlignX) {
|
||||
}
|
||||
|
||||
var data = [
|
||||
{'Invoice Number': invoice.invoice_number},
|
||||
{'PO Number': invoice.po_number},
|
||||
{'Invoice Date': invoice.invoice_date},
|
||||
{'Due Date': invoice.due_date},
|
||||
{'Balance Due': formatMoney(invoice.balance_amount, invoice.client.currency_id)}
|
||||
{'invoice_number': invoice.invoice_number},
|
||||
{'po_number': invoice.po_number},
|
||||
{'invoice_date': invoice.invoice_date},
|
||||
{'due_date': invoice.due_date},
|
||||
{'balance_due': formatMoney(invoice.balance_amount, invoice.client.currency_id)}
|
||||
];
|
||||
|
||||
displayGrid(doc, invoice, data, x, y, layout, true, rightAlignX);
|
||||
@ -1324,10 +1324,10 @@ function displaySubtotals(doc, layout, invoice, y, rightAlignTitleX)
|
||||
|
||||
//var taxTitle = 'Tax ' + getInvoiceTaxRate(invoice) + '%';
|
||||
var data = [
|
||||
{'Subtotal': formatMoney(invoice.subtotal_amount, invoice.client.currency_id)},
|
||||
{'Discount': invoice.discount_amount > 0 ? formatMoney(invoice.discount_amount, invoice.client.currency_id) : false},
|
||||
{'Tax': invoice.tax_amount > 0 ? formatMoney(invoice.tax_amount, invoice.client.currency_id) : false},
|
||||
{'Paid to Date': formatMoney(invoice.amount - invoice.balance, invoice.client.currency_id)}
|
||||
{'subtotal': formatMoney(invoice.subtotal_amount, invoice.client.currency_id)},
|
||||
{'discount': invoice.discount_amount > 0 ? formatMoney(invoice.discount_amount, invoice.client.currency_id) : false},
|
||||
{'tax': invoice.tax_amount > 0 ? formatMoney(invoice.tax_amount, invoice.client.currency_id) : false},
|
||||
{'paid_to_date': formatMoney(invoice.amount - invoice.balance, invoice.client.currency_id)}
|
||||
];
|
||||
|
||||
return displayGrid(doc, invoice, data, 300, y, layout, true, 550, rightAlignTitleX) + 10;
|
||||
@ -1396,6 +1396,7 @@ function displayGrid(doc, invoice, data, x, y, layout, hasheader, rightAlignX, r
|
||||
doc.setFontType('normal');
|
||||
}
|
||||
|
||||
key = invoiceLabels[key];
|
||||
if (rightAlignTitleX) {
|
||||
marginLeft = rightAlignTitleX - (doc.getStringUnitWidth(key) * doc.internal.getFontSize());
|
||||
} else {
|
||||
@ -1426,7 +1427,7 @@ function displayNotesAndTerms(doc, layout, invoice, y)
|
||||
|
||||
if (invoice.terms) {
|
||||
doc.setFontType("bold");
|
||||
doc.text(layout.marginLeft, y, "Terms");
|
||||
doc.text(layout.marginLeft, y, invoiceLabels.terms);
|
||||
y += 16;
|
||||
doc.setFontType("normal");
|
||||
doc.text(layout.marginLeft, y, invoice.terms);
|
||||
@ -1502,26 +1503,25 @@ function getInvoiceTaxRate(invoice) {
|
||||
|
||||
function displayInvoiceHeader(doc, invoice, layout) {
|
||||
|
||||
var costX = layout.unitCostRight - (doc.getStringUnitWidth('Unit Cost') * doc.internal.getFontSize());
|
||||
var qtyX = layout.qtyRight - (doc.getStringUnitWidth('Quantity') * doc.internal.getFontSize());
|
||||
var taxX = layout.taxRight - (doc.getStringUnitWidth('Tax') * doc.internal.getFontSize());
|
||||
var totalX = layout.lineTotalRight - (doc.getStringUnitWidth('Line Total') * doc.internal.getFontSize());
|
||||
var costX = layout.unitCostRight - (doc.getStringUnitWidth(invoiceLabels.unit_cost) * doc.internal.getFontSize());
|
||||
var qtyX = layout.qtyRight - (doc.getStringUnitWidth(invoiceLabels.quantity) * doc.internal.getFontSize());
|
||||
var taxX = layout.taxRight - (doc.getStringUnitWidth(invoiceLabels.tax) * doc.internal.getFontSize());
|
||||
var totalX = layout.lineTotalRight - (doc.getStringUnitWidth(invoiceLabels.line_total) * doc.internal.getFontSize());
|
||||
|
||||
doc.text(layout.marginLeft, layout.tableTop, 'Item');
|
||||
doc.text(layout.descriptionLeft, layout.tableTop, 'Description');
|
||||
doc.text(costX, layout.tableTop, 'Unit Cost');
|
||||
doc.text(qtyX, layout.tableTop, 'Quantity');
|
||||
doc.text(totalX, layout.tableTop, 'Line Total');
|
||||
doc.text(layout.marginLeft, layout.tableTop, invoiceLabels.item);
|
||||
doc.text(layout.descriptionLeft, layout.tableTop, invoiceLabels.description);
|
||||
doc.text(costX, layout.tableTop, invoiceLabels.unit_cost);
|
||||
doc.text(qtyX, layout.tableTop, invoiceLabels.quantity);
|
||||
doc.text(totalX, layout.tableTop, invoiceLabels.line_total);
|
||||
|
||||
if (invoice.has_taxes)
|
||||
{
|
||||
doc.text(taxX, layout.tableTop, 'Tax');
|
||||
doc.text(taxX, layout.tableTop, invoiceLabels.tax);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function displayInvoiceItems(doc, invoice, layout) {
|
||||
|
||||
doc.setFontType("normal");
|
||||
|
||||
var line = 1;
|
||||
|
Loading…
x
Reference in New Issue
Block a user