mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-09 20:52:56 +01:00
working on currency support
This commit is contained in:
parent
4ff55936d7
commit
ef24ac2c36
@ -57,4 +57,5 @@ Configure config/database.php and then initialize the database
|
|||||||
* [briannesbitt/Carbon](https://github.com/briannesbitt/Carbon) - A simple API extension for DateTime with PHP 5.3+
|
* [briannesbitt/Carbon](https://github.com/briannesbitt/Carbon) - A simple API extension for DateTime with PHP 5.3+
|
||||||
* [thomaspark/bootswatch](https://github.com/thomaspark/bootswatch) - Themes for Bootstrap
|
* [thomaspark/bootswatch](https://github.com/thomaspark/bootswatch) - Themes for Bootstrap
|
||||||
* [mozilla/pdf.js](https://github.com/mozilla/pdf.js) - PDF Reader in JavaScript
|
* [mozilla/pdf.js](https://github.com/mozilla/pdf.js) - PDF Reader in JavaScript
|
||||||
* [nnnick/Chart.js](https://github.com/nnnick/Chart.js) - Simple HTML5 Charts using the <canvas> tag
|
* [nnnick/Chart.js](https://github.com/nnnick/Chart.js) - Simple HTML5 Charts using the <canvas> tag
|
||||||
|
* [josscrowcroft/accounting.js](https://github.com/josscrowcroft/accounting.js) - A lightweight JavaScript library for number, money and currency formatting
|
@ -92,6 +92,7 @@ class AccountController extends \BaseController {
|
|||||||
'timezones' => Timezone::orderBy('location')->get(),
|
'timezones' => Timezone::orderBy('location')->get(),
|
||||||
'dateFormats' => DateFormat::all(),
|
'dateFormats' => DateFormat::all(),
|
||||||
'datetimeFormats' => DatetimeFormat::all(),
|
'datetimeFormats' => DatetimeFormat::all(),
|
||||||
|
'currencies' => Currency::orderBy('name')->get(),
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach ($data['gateways'] as $gateway)
|
foreach ($data['gateways'] as $gateway)
|
||||||
@ -406,6 +407,7 @@ class AccountController extends \BaseController {
|
|||||||
$account->timezone_id = Input::get('timezone_id') ? Input::get('timezone_id') : null;
|
$account->timezone_id = Input::get('timezone_id') ? Input::get('timezone_id') : null;
|
||||||
$account->date_format_id = Input::get('date_format_id') ? Input::get('date_format_id') : null;
|
$account->date_format_id = Input::get('date_format_id') ? Input::get('date_format_id') : null;
|
||||||
$account->datetime_format_id = Input::get('datetime_format_id') ? Input::get('datetime_format_id') : null;
|
$account->datetime_format_id = Input::get('datetime_format_id') ? Input::get('datetime_format_id') : null;
|
||||||
|
$account->currency_id = Input::get('currency_id') ? Input::get('currency_id') : null;
|
||||||
|
|
||||||
$account->invoice_terms = Input::get('invoice_terms');
|
$account->invoice_terms = Input::get('invoice_terms');
|
||||||
$account->save();
|
$account->save();
|
||||||
|
@ -9,7 +9,7 @@ class ActivityController extends \BaseController {
|
|||||||
return Datatable::collection(Activity::scope()->where('client_id','=',$clientId)->get())
|
return Datatable::collection(Activity::scope()->where('client_id','=',$clientId)->get())
|
||||||
->addColumn('date', function($model) { return Utils::timestampToDateTimeString(strtotime($model->created_at)); })
|
->addColumn('date', function($model) { return Utils::timestampToDateTimeString(strtotime($model->created_at)); })
|
||||||
->addColumn('message', function($model) { return $model->message; })
|
->addColumn('message', function($model) { return $model->message; })
|
||||||
->addColumn('balance', function($model) { return '$' . $model->balance; })
|
->addColumn('balance', function($model) { return Utils::formatMoney($model->balance, $model->account->currency_id); })
|
||||||
->orderColumns('date')
|
->orderColumns('date')
|
||||||
->make();
|
->make();
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ class ClientController extends \BaseController {
|
|||||||
->where('clients.account_id', '=', Auth::user()->account_id)
|
->where('clients.account_id', '=', Auth::user()->account_id)
|
||||||
->where('clients.deleted_at', '=', null)
|
->where('clients.deleted_at', '=', null)
|
||||||
->where('contacts.is_primary', '=', true)
|
->where('contacts.is_primary', '=', true)
|
||||||
->select('clients.public_id','clients.name','contacts.first_name','contacts.last_name','clients.balance','clients.last_login','clients.created_at','clients.work_phone','contacts.email');
|
->select('clients.public_id','clients.name','contacts.first_name','contacts.last_name','clients.balance','clients.last_login','clients.created_at','clients.work_phone','contacts.email','clients.currency_id');
|
||||||
|
|
||||||
$filter = Input::get('sSearch');
|
$filter = Input::get('sSearch');
|
||||||
if ($filter)
|
if ($filter)
|
||||||
@ -51,7 +51,7 @@ class ClientController extends \BaseController {
|
|||||||
->addColumn('email', function($model) { return $model->email ? HTML::mailto($model->email, $model->email) : ''; })
|
->addColumn('email', function($model) { return $model->email ? HTML::mailto($model->email, $model->email) : ''; })
|
||||||
->addColumn('work_phone', function($model) { return Utils::formatPhoneNumber($model->work_phone); })
|
->addColumn('work_phone', function($model) { return Utils::formatPhoneNumber($model->work_phone); })
|
||||||
->addColumn('last_login', function($model) { return Utils::timestampToDateString($model->last_login); })
|
->addColumn('last_login', function($model) { return Utils::timestampToDateString($model->last_login); })
|
||||||
->addColumn('balance', function($model) { return '$' . $model->balance; })
|
->addColumn('balance', function($model) { return Utils::formatMoney($model->balance, $model->currency_id); })
|
||||||
->addColumn('dropdown', function($model)
|
->addColumn('dropdown', function($model)
|
||||||
{
|
{
|
||||||
return '<div class="btn-group tr-action" style="visibility:hidden;">
|
return '<div class="btn-group tr-action" style="visibility:hidden;">
|
||||||
@ -139,6 +139,7 @@ class ClientController extends \BaseController {
|
|||||||
'title' => '- ' . $client->name,
|
'title' => '- ' . $client->name,
|
||||||
'clientSizes' => ClientSize::orderBy('id')->get(),
|
'clientSizes' => ClientSize::orderBy('id')->get(),
|
||||||
'clientIndustries' => ClientIndustry::orderBy('name')->get(),
|
'clientIndustries' => ClientIndustry::orderBy('name')->get(),
|
||||||
|
'currencies' => Currency::orderBy('name')->get(),
|
||||||
'countries' => Country::orderBy('name')->get());
|
'countries' => Country::orderBy('name')->get());
|
||||||
return View::make('clients.edit', $data);
|
return View::make('clients.edit', $data);
|
||||||
}
|
}
|
||||||
@ -184,6 +185,7 @@ class ClientController extends \BaseController {
|
|||||||
$client->notes = trim(Input::get('notes'));
|
$client->notes = trim(Input::get('notes'));
|
||||||
$client->client_size_id = Input::get('client_size_id') ? Input::get('client_size_id') : null;
|
$client->client_size_id = Input::get('client_size_id') ? Input::get('client_size_id') : null;
|
||||||
$client->client_industry_id = Input::get('client_industry_id') ? Input::get('client_industry_id') : null;
|
$client->client_industry_id = Input::get('client_industry_id') ? Input::get('client_industry_id') : null;
|
||||||
|
$client->currency_id = Input::get('currency_id') ? Input::get('currency_id') : null;
|
||||||
$client->website = trim(Input::get('website'));
|
$client->website = trim(Input::get('website'));
|
||||||
|
|
||||||
$client->save();
|
$client->save();
|
||||||
|
@ -23,7 +23,7 @@ class CreditController extends \BaseController {
|
|||||||
->where('clients.account_id', '=', Auth::user()->account_id)
|
->where('clients.account_id', '=', Auth::user()->account_id)
|
||||||
->where('clients.deleted_at', '=', null)
|
->where('clients.deleted_at', '=', null)
|
||||||
->where('credits.deleted_at', '=', null)
|
->where('credits.deleted_at', '=', null)
|
||||||
->select('credits.public_id', 'clients.name as client_name', 'clients.public_id as client_public_id', 'credits.amount', 'credits.credit_date');
|
->select('credits.public_id', 'clients.name as client_name', 'clients.public_id as client_public_id', 'credits.amount', 'credits.credit_date', 'credits.currency_id');
|
||||||
|
|
||||||
if ($clientPublicId) {
|
if ($clientPublicId) {
|
||||||
$query->where('clients.public_id', '=', $clientPublicId);
|
$query->where('clients.public_id', '=', $clientPublicId);
|
||||||
@ -45,8 +45,8 @@ class CreditController extends \BaseController {
|
|||||||
->addColumn('client_name', function($model) { return link_to('clients/' . $model->client_public_id, $model->client_name); });
|
->addColumn('client_name', function($model) { return link_to('clients/' . $model->client_public_id, $model->client_name); });
|
||||||
}
|
}
|
||||||
|
|
||||||
return $table->addColumn('amount', function($model){ return '$' . money_format('%i', $model->amount); })
|
return $table->addColumn('amount', function($model){ return Utils::formatMoney($model->amount, $model->currency_id); })
|
||||||
->addColumn('credit_date', function($model) { return Utils::timestampToDateString($model->credit_date); })
|
->addColumn('credit_date', function($model) { return Utils::fromSqlDate($model->credit_date); })
|
||||||
->addColumn('dropdown', function($model)
|
->addColumn('dropdown', function($model)
|
||||||
{
|
{
|
||||||
return '<div class="btn-group tr-action" style="visibility:hidden;">
|
return '<div class="btn-group tr-action" style="visibility:hidden;">
|
||||||
@ -79,6 +79,7 @@ class CreditController extends \BaseController {
|
|||||||
'method' => 'POST',
|
'method' => 'POST',
|
||||||
'url' => 'credits',
|
'url' => 'credits',
|
||||||
'title' => '- New Credit',
|
'title' => '- New Credit',
|
||||||
|
'currencies' => Currency::orderBy('name')->get(),
|
||||||
'clients' => Client::scope()->orderBy('name')->get());
|
'clients' => Client::scope()->orderBy('name')->get());
|
||||||
|
|
||||||
return View::make('credits.edit', $data);
|
return View::make('credits.edit', $data);
|
||||||
@ -93,6 +94,7 @@ class CreditController extends \BaseController {
|
|||||||
'method' => 'PUT',
|
'method' => 'PUT',
|
||||||
'url' => 'credits/' . $publicId,
|
'url' => 'credits/' . $publicId,
|
||||||
'title' => '- Edit Credit',
|
'title' => '- Edit Credit',
|
||||||
|
'currencies' => Currency::orderBy('name')->get(),
|
||||||
'clients' => Client::scope()->orderBy('name')->get());
|
'clients' => Client::scope()->orderBy('name')->get());
|
||||||
return View::make('credit.edit', $data);
|
return View::make('credit.edit', $data);
|
||||||
}
|
}
|
||||||
@ -130,6 +132,7 @@ class CreditController extends \BaseController {
|
|||||||
$credit->client_id = Input::get('client');
|
$credit->client_id = Input::get('client');
|
||||||
$credit->credit_date = Utils::toSqlDate(Input::get('credit_date'));
|
$credit->credit_date = Utils::toSqlDate(Input::get('credit_date'));
|
||||||
$credit->amount = floatval(Input::get('amount'));
|
$credit->amount = floatval(Input::get('amount'));
|
||||||
|
$credit->currency_id = Input::get('currency_id') ? Input::get('currency_id') : null;
|
||||||
$credit->save();
|
$credit->save();
|
||||||
|
|
||||||
$message = $publicId ? 'Successfully updated credit' : 'Successfully created credit';
|
$message = $publicId ? 'Successfully updated credit' : 'Successfully created credit';
|
||||||
|
@ -55,8 +55,8 @@ class InvoiceController extends \BaseController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return $table->addColumn('invoice_date', function($model) { return Utils::fromSqlDate($model->invoice_date); })
|
return $table->addColumn('invoice_date', function($model) { return Utils::fromSqlDate($model->invoice_date); })
|
||||||
->addColumn('total', function($model) { return '$' . money_format('%i', $model->amount); })
|
->addColumn('total', function($model) { return Utils::formatMoney($model->amount, $model->currency_id); })
|
||||||
->addColumn('balance', function($model) { return '$' . money_format('%i', $model->balance); })
|
->addColumn('balance', function($model) { return Utils::formatMoney($model->balance, $model->currency_id); })
|
||||||
->addColumn('due_date', function($model) { return Utils::fromSqlDate($model->due_date); })
|
->addColumn('due_date', function($model) { return Utils::fromSqlDate($model->due_date); })
|
||||||
->addColumn('invoice_status_name', function($model) { return $model->invoice_status_name; })
|
->addColumn('invoice_status_name', function($model) { return $model->invoice_status_name; })
|
||||||
->addColumn('dropdown', function($model)
|
->addColumn('dropdown', function($model)
|
||||||
@ -94,7 +94,7 @@ class InvoiceController extends \BaseController {
|
|||||||
|
|
||||||
return $table->addColumn('start_date', function($model) { return Utils::fromSqlDate($model->start_date); })
|
return $table->addColumn('start_date', function($model) { return Utils::fromSqlDate($model->start_date); })
|
||||||
->addColumn('end_date', function($model) { return Utils::fromSqlDate($model->end_date); })
|
->addColumn('end_date', function($model) { return Utils::fromSqlDate($model->end_date); })
|
||||||
->addColumn('total', function($model) { return '$' . money_format('%i', $model->amount); })
|
->addColumn('total', function($model) { return Utils::formatMoney($model->amount, $model->currency_id); })
|
||||||
->addColumn('dropdown', function($model)
|
->addColumn('dropdown', function($model)
|
||||||
{
|
{
|
||||||
return '<div class="btn-group tr-action" style="visibility:hidden;">
|
return '<div class="btn-group tr-action" style="visibility:hidden;">
|
||||||
@ -352,6 +352,7 @@ class InvoiceController extends \BaseController {
|
|||||||
'countries' => Country::orderBy('name')->get(),
|
'countries' => Country::orderBy('name')->get(),
|
||||||
'clients' => Client::scope()->with('contacts')->orderBy('name')->get(),
|
'clients' => Client::scope()->with('contacts')->orderBy('name')->get(),
|
||||||
'taxRates' => TaxRate::scope()->orderBy('name')->get(),
|
'taxRates' => TaxRate::scope()->orderBy('name')->get(),
|
||||||
|
'currencies' => Currency::orderBy('name')->get(),
|
||||||
'frequencies' => array(
|
'frequencies' => array(
|
||||||
1 => 'Weekly',
|
1 => 'Weekly',
|
||||||
2 => 'Two weeks',
|
2 => 'Two weeks',
|
||||||
|
@ -19,7 +19,7 @@ class PaymentController extends \BaseController
|
|||||||
->where('payments.account_id', '=', Auth::user()->account_id)
|
->where('payments.account_id', '=', Auth::user()->account_id)
|
||||||
->where('payments.deleted_at', '=', null)
|
->where('payments.deleted_at', '=', null)
|
||||||
->where('clients.deleted_at', '=', null)
|
->where('clients.deleted_at', '=', null)
|
||||||
->select('payments.public_id', 'payments.transaction_reference', 'clients.name as client_name', 'clients.public_id as client_public_id', 'payments.amount', 'payments.payment_date', 'invoices.public_id as invoice_public_id', 'invoices.invoice_number');
|
->select('payments.public_id', 'payments.transaction_reference', 'clients.name as client_name', 'clients.public_id as client_public_id', 'payments.amount', 'payments.payment_date', 'invoices.public_id as invoice_public_id', 'invoices.invoice_number', 'payments.currency_id');
|
||||||
|
|
||||||
if ($clientPublicId) {
|
if ($clientPublicId) {
|
||||||
$query->where('clients.public_id', '=', $clientPublicId);
|
$query->where('clients.public_id', '=', $clientPublicId);
|
||||||
@ -47,7 +47,7 @@ class PaymentController extends \BaseController
|
|||||||
}
|
}
|
||||||
|
|
||||||
return $table->addColumn('invoice_number', function($model) { return $model->invoice_public_id ? link_to('invoices/' . $model->invoice_public_id . '/edit', $model->invoice_number) : ''; })
|
return $table->addColumn('invoice_number', function($model) { return $model->invoice_public_id ? link_to('invoices/' . $model->invoice_public_id . '/edit', $model->invoice_number) : ''; })
|
||||||
->addColumn('amount', function($model) { return '$' . $model->amount; })
|
->addColumn('amount', function($model) { return Utils::formatMoney($model->amount, $model->currency_id); })
|
||||||
->addColumn('payment_date', function($model) { return Utils::dateToString($model->payment_date); })
|
->addColumn('payment_date', function($model) { return Utils::dateToString($model->payment_date); })
|
||||||
->addColumn('dropdown', function($model)
|
->addColumn('dropdown', function($model)
|
||||||
{
|
{
|
||||||
@ -83,6 +83,7 @@ class PaymentController extends \BaseController
|
|||||||
'method' => 'POST',
|
'method' => 'POST',
|
||||||
'url' => 'payments',
|
'url' => 'payments',
|
||||||
'title' => '- New Payment',
|
'title' => '- New Payment',
|
||||||
|
'currencies' => Currency::orderBy('name')->get(),
|
||||||
'clients' => Client::scope()->orderBy('name')->get());
|
'clients' => Client::scope()->orderBy('name')->get());
|
||||||
|
|
||||||
return View::make('payments.edit', $data);
|
return View::make('payments.edit', $data);
|
||||||
@ -99,6 +100,7 @@ class PaymentController extends \BaseController
|
|||||||
'method' => 'PUT',
|
'method' => 'PUT',
|
||||||
'url' => 'payments/' . $publicId,
|
'url' => 'payments/' . $publicId,
|
||||||
'title' => '- Edit Payment',
|
'title' => '- Edit Payment',
|
||||||
|
'currencies' => Currency::orderBy('name')->get(),
|
||||||
'clients' => Client::scope()->orderBy('name')->get());
|
'clients' => Client::scope()->orderBy('name')->get());
|
||||||
return View::make('payments.edit', $data);
|
return View::make('payments.edit', $data);
|
||||||
}
|
}
|
||||||
@ -137,6 +139,7 @@ class PaymentController extends \BaseController
|
|||||||
|
|
||||||
$payment->client_id = Input::get('client');
|
$payment->client_id = Input::get('client');
|
||||||
$payment->invoice_id = $invoiceId;
|
$payment->invoice_id = $invoiceId;
|
||||||
|
$payment->currency_id = Input::get('currency_id') ? Input::get('currency_id') : null;
|
||||||
$payment->payment_date = Utils::toSqlDate(Input::get('payment_date'));
|
$payment->payment_date = Utils::toSqlDate(Input::get('payment_date'));
|
||||||
$payment->amount = floatval(Input::get('amount'));
|
$payment->amount = floatval(Input::get('amount'));
|
||||||
$payment->save();
|
$payment->save();
|
||||||
|
@ -9,7 +9,7 @@ class ConfideSetupUsersTable extends Migration {
|
|||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function up()
|
public function up()
|
||||||
{
|
{
|
||||||
Schema::dropIfExists('themes');
|
Schema::dropIfExists('themes');
|
||||||
Schema::dropIfExists('credits');
|
Schema::dropIfExists('credits');
|
||||||
Schema::dropIfExists('activities');
|
Schema::dropIfExists('activities');
|
||||||
@ -28,6 +28,7 @@ class ConfideSetupUsersTable extends Migration {
|
|||||||
Schema::dropIfExists('client_industries');
|
Schema::dropIfExists('client_industries');
|
||||||
Schema::dropIfExists('users');
|
Schema::dropIfExists('users');
|
||||||
Schema::dropIfExists('accounts');
|
Schema::dropIfExists('accounts');
|
||||||
|
Schema::dropIfExists('currencies');
|
||||||
Schema::dropIfExists('invoice_statuses');
|
Schema::dropIfExists('invoice_statuses');
|
||||||
Schema::dropIfExists('countries');
|
Schema::dropIfExists('countries');
|
||||||
Schema::dropIfExists('timezones');
|
Schema::dropIfExists('timezones');
|
||||||
@ -81,12 +82,24 @@ class ConfideSetupUsersTable extends Migration {
|
|||||||
$t->string('label');
|
$t->string('label');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Schema::create('currencies', function($t)
|
||||||
|
{
|
||||||
|
$t->increments('id');
|
||||||
|
|
||||||
|
$t->string('name');
|
||||||
|
$t->string('symbol');
|
||||||
|
$t->string('precision');
|
||||||
|
$t->string('thousand_separator');
|
||||||
|
$t->string('decimal_separator');
|
||||||
|
});
|
||||||
|
|
||||||
Schema::create('accounts', function($t)
|
Schema::create('accounts', function($t)
|
||||||
{
|
{
|
||||||
$t->increments('id');
|
$t->increments('id');
|
||||||
$t->unsignedInteger('timezone_id')->nullable();
|
$t->unsignedInteger('timezone_id')->nullable();
|
||||||
$t->unsignedInteger('date_format_id')->nullable();
|
$t->unsignedInteger('date_format_id')->nullable();
|
||||||
$t->unsignedInteger('datetime_format_id')->nullable();
|
$t->unsignedInteger('datetime_format_id')->nullable();
|
||||||
|
$t->unsignedInteger('currency_id')->nullable();
|
||||||
|
|
||||||
$t->timestamps();
|
$t->timestamps();
|
||||||
$t->softDeletes();
|
$t->softDeletes();
|
||||||
@ -108,6 +121,7 @@ class ConfideSetupUsersTable extends Migration {
|
|||||||
$t->foreign('date_format_id')->references('id')->on('date_formats');
|
$t->foreign('date_format_id')->references('id')->on('date_formats');
|
||||||
$t->foreign('datetime_format_id')->references('id')->on('datetime_formats');
|
$t->foreign('datetime_format_id')->references('id')->on('datetime_formats');
|
||||||
$t->foreign('country_id')->references('id')->on('countries');
|
$t->foreign('country_id')->references('id')->on('countries');
|
||||||
|
$t->foreign('currency_id')->references('id')->on('currencies');
|
||||||
});
|
});
|
||||||
|
|
||||||
Schema::create('gateways', function($t)
|
Schema::create('gateways', function($t)
|
||||||
@ -186,6 +200,7 @@ class ConfideSetupUsersTable extends Migration {
|
|||||||
$t->increments('id');
|
$t->increments('id');
|
||||||
$t->unsignedInteger('user_id');
|
$t->unsignedInteger('user_id');
|
||||||
$t->unsignedInteger('account_id')->index();
|
$t->unsignedInteger('account_id')->index();
|
||||||
|
$t->unsignedInteger('currency_id')->default(1)->nullable();
|
||||||
$t->timestamps();
|
$t->timestamps();
|
||||||
$t->softDeletes();
|
$t->softDeletes();
|
||||||
|
|
||||||
@ -198,8 +213,8 @@ class ConfideSetupUsersTable extends Migration {
|
|||||||
$t->unsignedInteger('country_id')->nullable();
|
$t->unsignedInteger('country_id')->nullable();
|
||||||
$t->string('work_phone');
|
$t->string('work_phone');
|
||||||
$t->text('notes');
|
$t->text('notes');
|
||||||
$t->decimal('balance', 10, 2);
|
$t->decimal('balance', 13, 4);
|
||||||
$t->decimal('paid_to_date', 10, 2);
|
$t->decimal('paid_to_date', 13, 4);
|
||||||
$t->timestamp('last_login')->nullable();
|
$t->timestamp('last_login')->nullable();
|
||||||
$t->string('website');
|
$t->string('website');
|
||||||
$t->unsignedInteger('client_industry_id')->nullable();
|
$t->unsignedInteger('client_industry_id')->nullable();
|
||||||
@ -211,7 +226,8 @@ class ConfideSetupUsersTable extends Migration {
|
|||||||
$t->foreign('country_id')->references('id')->on('countries');
|
$t->foreign('country_id')->references('id')->on('countries');
|
||||||
$t->foreign('client_industry_id')->references('id')->on('client_industries');
|
$t->foreign('client_industry_id')->references('id')->on('client_industries');
|
||||||
$t->foreign('client_size_id')->references('id')->on('client_sizes');
|
$t->foreign('client_size_id')->references('id')->on('client_sizes');
|
||||||
|
$t->foreign('currency_id')->references('id')->on('currencies');
|
||||||
|
|
||||||
$t->unsignedInteger('public_id')->index();
|
$t->unsignedInteger('public_id')->index();
|
||||||
$t->unique( array('account_id','public_id') );
|
$t->unique( array('account_id','public_id') );
|
||||||
});
|
});
|
||||||
@ -259,6 +275,7 @@ class ConfideSetupUsersTable extends Migration {
|
|||||||
$t->unsignedInteger('user_id');
|
$t->unsignedInteger('user_id');
|
||||||
$t->unsignedInteger('account_id')->index();
|
$t->unsignedInteger('account_id')->index();
|
||||||
$t->unsignedInteger('invoice_status_id')->default(1);
|
$t->unsignedInteger('invoice_status_id')->default(1);
|
||||||
|
$t->unsignedInteger('currency_id')->default(1);
|
||||||
$t->timestamps();
|
$t->timestamps();
|
||||||
$t->softDeletes();
|
$t->softDeletes();
|
||||||
|
|
||||||
@ -277,13 +294,14 @@ class ConfideSetupUsersTable extends Migration {
|
|||||||
$t->unsignedInteger('recurring_invoice_id')->index()->nullable();
|
$t->unsignedInteger('recurring_invoice_id')->index()->nullable();
|
||||||
|
|
||||||
|
|
||||||
$t->decimal('amount', 10, 2);
|
$t->decimal('amount', 13, 4);
|
||||||
$t->decimal('balance', 10, 2);
|
$t->decimal('balance', 13, 4);
|
||||||
|
|
||||||
$t->foreign('client_id')->references('id')->on('clients')->onDelete('cascade');
|
$t->foreign('client_id')->references('id')->on('clients')->onDelete('cascade');
|
||||||
$t->foreign('account_id')->references('id')->on('accounts');
|
$t->foreign('account_id')->references('id')->on('accounts');
|
||||||
$t->foreign('user_id')->references('id')->on('users');
|
$t->foreign('user_id')->references('id')->on('users');
|
||||||
$t->foreign('invoice_status_id')->references('id')->on('invoice_statuses');
|
$t->foreign('invoice_status_id')->references('id')->on('invoice_statuses');
|
||||||
|
$t->foreign('currency_id')->references('id')->on('currencies');
|
||||||
$t->foreign('recurring_invoice_id')->references('id')->on('invoices');
|
$t->foreign('recurring_invoice_id')->references('id')->on('invoices');
|
||||||
|
|
||||||
$t->unsignedInteger('public_id')->index();
|
$t->unsignedInteger('public_id')->index();
|
||||||
@ -322,7 +340,7 @@ class ConfideSetupUsersTable extends Migration {
|
|||||||
$t->softDeletes();
|
$t->softDeletes();
|
||||||
|
|
||||||
$t->string('name');
|
$t->string('name');
|
||||||
$t->decimal('rate', 10, 2);
|
$t->decimal('rate', 13, 4);
|
||||||
|
|
||||||
$t->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
|
$t->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
|
||||||
$t->foreign('user_id')->references('id')->on('users');
|
$t->foreign('user_id')->references('id')->on('users');
|
||||||
@ -341,8 +359,8 @@ class ConfideSetupUsersTable extends Migration {
|
|||||||
|
|
||||||
$t->string('product_key');
|
$t->string('product_key');
|
||||||
$t->string('notes');
|
$t->string('notes');
|
||||||
$t->decimal('cost', 10, 2);
|
$t->decimal('cost', 13, 4);
|
||||||
$t->decimal('qty', 10, 2);
|
$t->decimal('qty', 13, 4);
|
||||||
|
|
||||||
$t->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
|
$t->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
|
||||||
$t->foreign('user_id')->references('id')->on('users');
|
$t->foreign('user_id')->references('id')->on('users');
|
||||||
@ -364,11 +382,11 @@ class ConfideSetupUsersTable extends Migration {
|
|||||||
|
|
||||||
$t->string('product_key');
|
$t->string('product_key');
|
||||||
$t->string('notes');
|
$t->string('notes');
|
||||||
$t->decimal('cost', 10, 2);
|
$t->decimal('cost', 13, 4);
|
||||||
$t->decimal('qty', 10, 2);
|
$t->decimal('qty', 13, 4);
|
||||||
|
|
||||||
$t->string('tax_name');
|
$t->string('tax_name');
|
||||||
$t->decimal('tax_rate', 10, 2);
|
$t->decimal('tax_rate', 13, 4);
|
||||||
|
|
||||||
$t->foreign('invoice_id')->references('id')->on('invoices')->onDelete('cascade');
|
$t->foreign('invoice_id')->references('id')->on('invoices')->onDelete('cascade');
|
||||||
$t->foreign('product_id')->references('id')->on('products');
|
$t->foreign('product_id')->references('id')->on('products');
|
||||||
@ -387,11 +405,12 @@ class ConfideSetupUsersTable extends Migration {
|
|||||||
$t->unsignedInteger('contact_id')->nullable();
|
$t->unsignedInteger('contact_id')->nullable();
|
||||||
$t->unsignedInteger('invitation_id')->nullable();
|
$t->unsignedInteger('invitation_id')->nullable();
|
||||||
$t->unsignedInteger('user_id')->nullable();
|
$t->unsignedInteger('user_id')->nullable();
|
||||||
|
$t->unsignedInteger('currency_id')->default(1);
|
||||||
$t->timestamps();
|
$t->timestamps();
|
||||||
$t->softDeletes();
|
$t->softDeletes();
|
||||||
|
|
||||||
$t->boolean('is_deleted');
|
$t->boolean('is_deleted');
|
||||||
$t->decimal('amount', 10, 2);
|
$t->decimal('amount', 13, 4);
|
||||||
$t->date('payment_date');
|
$t->date('payment_date');
|
||||||
$t->string('transaction_reference');
|
$t->string('transaction_reference');
|
||||||
$t->string('payer_id');
|
$t->string('payer_id');
|
||||||
@ -401,7 +420,8 @@ class ConfideSetupUsersTable extends Migration {
|
|||||||
$t->foreign('client_id')->references('id')->on('clients')->onDelete('cascade');
|
$t->foreign('client_id')->references('id')->on('clients')->onDelete('cascade');
|
||||||
$t->foreign('contact_id')->references('id')->on('contacts');
|
$t->foreign('contact_id')->references('id')->on('contacts');
|
||||||
$t->foreign('user_id')->references('id')->on('users');
|
$t->foreign('user_id')->references('id')->on('users');
|
||||||
|
$t->foreign('currency_id')->references('id')->on('currencies');
|
||||||
|
|
||||||
$t->unsignedInteger('public_id')->index();
|
$t->unsignedInteger('public_id')->index();
|
||||||
$t->unique( array('account_id','public_id') );
|
$t->unique( array('account_id','public_id') );
|
||||||
});
|
});
|
||||||
@ -413,11 +433,12 @@ class ConfideSetupUsersTable extends Migration {
|
|||||||
$t->unsignedInteger('user_id');
|
$t->unsignedInteger('user_id');
|
||||||
$t->unsignedInteger('client_id')->index()->nullable();
|
$t->unsignedInteger('client_id')->index()->nullable();
|
||||||
$t->unsignedInteger('contact_id')->nullable();
|
$t->unsignedInteger('contact_id')->nullable();
|
||||||
|
$t->unsignedInteger('currency_id')->default(1);
|
||||||
$t->timestamps();
|
$t->timestamps();
|
||||||
$t->softDeletes();
|
$t->softDeletes();
|
||||||
|
|
||||||
$t->boolean('is_deleted');
|
$t->boolean('is_deleted');
|
||||||
$t->decimal('amount', 10, 2);
|
$t->decimal('amount', 13, 4);
|
||||||
$t->date('credit_date')->nullable();
|
$t->date('credit_date')->nullable();
|
||||||
$t->string('credit_number');
|
$t->string('credit_number');
|
||||||
|
|
||||||
@ -425,6 +446,7 @@ class ConfideSetupUsersTable extends Migration {
|
|||||||
$t->foreign('client_id')->references('id')->on('clients')->onDelete('cascade');
|
$t->foreign('client_id')->references('id')->on('clients')->onDelete('cascade');
|
||||||
$t->foreign('contact_id')->references('id')->on('contacts');
|
$t->foreign('contact_id')->references('id')->on('contacts');
|
||||||
$t->foreign('user_id')->references('id')->on('users');
|
$t->foreign('user_id')->references('id')->on('users');
|
||||||
|
$t->foreign('currency_id')->references('id')->on('currencies');
|
||||||
|
|
||||||
$t->unsignedInteger('public_id')->index();
|
$t->unsignedInteger('public_id')->index();
|
||||||
$t->unique( array('account_id','public_id') );
|
$t->unique( array('account_id','public_id') );
|
||||||
@ -443,14 +465,16 @@ class ConfideSetupUsersTable extends Migration {
|
|||||||
$t->unsignedInteger('invoice_id');
|
$t->unsignedInteger('invoice_id');
|
||||||
$t->unsignedInteger('credit_id');
|
$t->unsignedInteger('credit_id');
|
||||||
$t->unsignedInteger('invitation_id');
|
$t->unsignedInteger('invitation_id');
|
||||||
|
$t->unsignedInteger('currency_id')->default(1);
|
||||||
|
|
||||||
$t->text('message');
|
$t->text('message');
|
||||||
$t->integer('activity_type_id');
|
$t->integer('activity_type_id');
|
||||||
$t->decimal('adjustment', 10, 2);
|
$t->decimal('adjustment', 13, 4);
|
||||||
$t->decimal('balance', 10, 2);
|
$t->decimal('balance', 13, 4);
|
||||||
|
|
||||||
$t->foreign('account_id')->references('id')->on('accounts');
|
$t->foreign('account_id')->references('id')->on('accounts');
|
||||||
$t->foreign('client_id')->references('id')->on('clients')->onDelete('cascade');
|
$t->foreign('client_id')->references('id')->on('clients')->onDelete('cascade');
|
||||||
|
$t->foreign('currency_id')->references('id')->on('currencies');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -479,6 +503,7 @@ class ConfideSetupUsersTable extends Migration {
|
|||||||
Schema::dropIfExists('client_industries');
|
Schema::dropIfExists('client_industries');
|
||||||
Schema::dropIfExists('users');
|
Schema::dropIfExists('users');
|
||||||
Schema::dropIfExists('accounts');
|
Schema::dropIfExists('accounts');
|
||||||
|
Schema::dropIfExists('currencies');
|
||||||
Schema::dropIfExists('invoice_statuses');
|
Schema::dropIfExists('invoice_statuses');
|
||||||
Schema::dropIfExists('countries');
|
Schema::dropIfExists('countries');
|
||||||
Schema::dropIfExists('timezones');
|
Schema::dropIfExists('timezones');
|
||||||
|
@ -69,6 +69,10 @@ class ConstantsSeeder extends Seeder
|
|||||||
ClientSize::create(array('name' => '101 - 500'));
|
ClientSize::create(array('name' => '101 - 500'));
|
||||||
ClientSize::create(array('name' => '500+'));
|
ClientSize::create(array('name' => '500+'));
|
||||||
|
|
||||||
|
Currency::create(array('name' => 'US Dollar', 'symbol' => '$', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'));
|
||||||
|
Currency::create(array('name' => 'Pound Sterling', 'symbol' => '£', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'));
|
||||||
|
|
||||||
|
|
||||||
DatetimeFormat::create(array('format' => 'F j, Y, g:i a', 'label' => 'March 10, 2013, 6:15 pm'));
|
DatetimeFormat::create(array('format' => 'F j, Y, g:i a', 'label' => 'March 10, 2013, 6:15 pm'));
|
||||||
DatetimeFormat::create(array('format' => 'D M jS, Y g:ia', 'label' => 'Mon March 10th, 2013, 6:15 pm'));
|
DatetimeFormat::create(array('format' => 'D M jS, Y g:ia', 'label' => 'Mon March 10th, 2013, 6:15 pm'));
|
||||||
|
|
||||||
|
@ -33,5 +33,6 @@ class UserEventHandler
|
|||||||
Session::put(SESSION_DATE_FORMAT, $account->date_format ? $account->date_format->format : DEFAULT_DATE_FORMAT);
|
Session::put(SESSION_DATE_FORMAT, $account->date_format ? $account->date_format->format : DEFAULT_DATE_FORMAT);
|
||||||
Session::put(SESSION_DATE_PICKER_FORMAT, $account->date_format ? $account->date_format->picker_format : DEFAULT_DATE_PICKER_FORMAT);
|
Session::put(SESSION_DATE_PICKER_FORMAT, $account->date_format ? $account->date_format->picker_format : DEFAULT_DATE_PICKER_FORMAT);
|
||||||
Session::put(SESSION_DATETIME_FORMAT, $account->datetime_format ? $account->datetime_format->format : DEFAULT_DATETIME_FORMAT);
|
Session::put(SESSION_DATETIME_FORMAT, $account->datetime_format ? $account->datetime_format->format : DEFAULT_DATETIME_FORMAT);
|
||||||
|
Session::put(SESSION_CURRENCY, $account->currency_id ? $account->currency_id : DEFAULT_CURRENCY);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -35,6 +35,15 @@ class Utils
|
|||||||
return $phoneNumber;
|
return $phoneNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function formatMoney($value, $currencyId)
|
||||||
|
{
|
||||||
|
$currency = Currency::find($currencyId);
|
||||||
|
if (!$currency) {
|
||||||
|
$currency = Currency::find(1);
|
||||||
|
}
|
||||||
|
return $currency->symbol . number_format($value, $currency->precision, $currency->decimal_separator, $currency->thousand_separator);
|
||||||
|
}
|
||||||
|
|
||||||
public static function pluralize($string, $count)
|
public static function pluralize($string, $count)
|
||||||
{
|
{
|
||||||
$string = str_replace('?', $count, $string);
|
$string = str_replace('?', $count, $string);
|
||||||
|
@ -26,6 +26,12 @@ class Activity extends Eloquent
|
|||||||
return $query->whereAccountId(Auth::user()->account_id);
|
return $query->whereAccountId(Auth::user()->account_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function account()
|
||||||
|
{
|
||||||
|
return $this->belongsTo('Account');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private static function getBlank($entity = false)
|
private static function getBlank($entity = false)
|
||||||
{
|
{
|
||||||
$activity = new Activity;
|
$activity = new Activity;
|
||||||
@ -75,6 +81,7 @@ class Activity extends Eloquent
|
|||||||
$activity = Activity::getBlank($invoice);
|
$activity = Activity::getBlank($invoice);
|
||||||
$activity->invoice_id = $invoice->id;
|
$activity->invoice_id = $invoice->id;
|
||||||
$activity->client_id = $invoice->client_id;
|
$activity->client_id = $invoice->client_id;
|
||||||
|
$activity->currency_id = $invoice->currency_id;
|
||||||
$activity->activity_type_id = ACTIVITY_TYPE_CREATE_INVOICE;
|
$activity->activity_type_id = ACTIVITY_TYPE_CREATE_INVOICE;
|
||||||
$activity->message = $message;
|
$activity->message = $message;
|
||||||
$activity->save();
|
$activity->save();
|
||||||
@ -121,6 +128,7 @@ class Activity extends Eloquent
|
|||||||
$activity->invoice_id = $payment->invoice_id;
|
$activity->invoice_id = $payment->invoice_id;
|
||||||
}
|
}
|
||||||
$activity->client_id = $payment->client_id;
|
$activity->client_id = $payment->client_id;
|
||||||
|
$activity->currency_id = $payment->currency_id;
|
||||||
$activity->activity_type_id = ACTIVITY_TYPE_CREATE_PAYMENT;
|
$activity->activity_type_id = ACTIVITY_TYPE_CREATE_PAYMENT;
|
||||||
$activity->save();
|
$activity->save();
|
||||||
}
|
}
|
||||||
@ -132,6 +140,7 @@ class Activity extends Eloquent
|
|||||||
$activity->message = Auth::user()->getFullName() . ' created credit';
|
$activity->message = Auth::user()->getFullName() . ' created credit';
|
||||||
$activity->credit_id = $credit->id;
|
$activity->credit_id = $credit->id;
|
||||||
$activity->client_id = $credit->client_id;
|
$activity->client_id = $credit->client_id;
|
||||||
|
$activity->currency_id = $credit->currency_id;
|
||||||
$activity->activity_type_id = ACTIVITY_TYPE_CREATE_CREDIT;
|
$activity->activity_type_id = ACTIVITY_TYPE_CREATE_CREDIT;
|
||||||
$activity->save();
|
$activity->save();
|
||||||
}
|
}
|
||||||
|
7
app/models/Currency.php
Executable file
7
app/models/Currency.php
Executable file
@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Currency extends Eloquent
|
||||||
|
{
|
||||||
|
public $timestamps = false;
|
||||||
|
protected $softDelete = false;
|
||||||
|
}
|
@ -14,6 +14,7 @@ class AccountRepository
|
|||||||
$contacts = \DB::table('clients')
|
$contacts = \DB::table('clients')
|
||||||
->join('contacts', 'contacts.client_id', '=', 'clients.id')
|
->join('contacts', 'contacts.client_id', '=', 'clients.id')
|
||||||
->where('clients.deleted_at', '=', null)
|
->where('clients.deleted_at', '=', null)
|
||||||
|
->whereRaw("CONCAT(contacts.first_name, contacts.last_name) <> ''")
|
||||||
->select(\DB::raw("'Contacts' as type, clients.public_id, CONCAT(contacts.first_name, ' ', contacts.last_name, ': ', clients.name) as name, '' as token"));
|
->select(\DB::raw("'Contacts' as type, clients.public_id, CONCAT(contacts.first_name, ' ', contacts.last_name, ': ', clients.name) as name, '' as token"));
|
||||||
|
|
||||||
$invoices = \DB::table('clients')
|
$invoices = \DB::table('clients')
|
||||||
|
@ -30,6 +30,7 @@ class ClientRepository
|
|||||||
$client->notes = trim($data['notes']);
|
$client->notes = trim($data['notes']);
|
||||||
$client->client_size_id = $data['client_size_id'] ? $data['client_size_id'] : null;
|
$client->client_size_id = $data['client_size_id'] ? $data['client_size_id'] : null;
|
||||||
$client->client_industry_id = $data['client_industry_id'] ? $data['client_industry_id'] : null;
|
$client->client_industry_id = $data['client_industry_id'] ? $data['client_industry_id'] : null;
|
||||||
|
$client->currency_id = $data['currency_id'] ? $data['currency_id'] : null;
|
||||||
$client->website = trim($data['website']);
|
$client->website = trim($data['website']);
|
||||||
$client->save();
|
$client->save();
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ class InvoiceRepository
|
|||||||
->where('invoices.deleted_at', '=', null)
|
->where('invoices.deleted_at', '=', null)
|
||||||
->where('clients.deleted_at', '=', null)
|
->where('clients.deleted_at', '=', null)
|
||||||
->where('invoices.is_recurring', '=', false)
|
->where('invoices.is_recurring', '=', false)
|
||||||
->select('clients.public_id as client_public_id', 'invoice_number', 'clients.name as client_name', 'invoices.public_id', 'amount', 'invoices.balance', 'invoice_date', 'due_date', 'invoice_statuses.name as invoice_status_name');
|
->select('clients.public_id as client_public_id', 'invoice_number', 'clients.name as client_name', 'invoices.public_id', 'amount', 'invoices.balance', 'invoice_date', 'due_date', 'invoice_statuses.name as invoice_status_name', 'invoices.currency_id');
|
||||||
|
|
||||||
if ($clientPublicId)
|
if ($clientPublicId)
|
||||||
{
|
{
|
||||||
@ -45,7 +45,7 @@ class InvoiceRepository
|
|||||||
->where('invoices.account_id', '=', $accountId)
|
->where('invoices.account_id', '=', $accountId)
|
||||||
->where('invoices.deleted_at', '=', null)
|
->where('invoices.deleted_at', '=', null)
|
||||||
->where('invoices.is_recurring', '=', true)
|
->where('invoices.is_recurring', '=', true)
|
||||||
->select('clients.public_id as client_public_id', 'clients.name as client_name', 'invoices.public_id', 'amount', 'frequencies.name as frequency', 'start_date', 'end_date');
|
->select('clients.public_id as client_public_id', 'clients.name as client_name', 'invoices.public_id', 'amount', 'frequencies.name as frequency', 'start_date', 'end_date', 'invoices.currency_id');
|
||||||
|
|
||||||
if ($clientPublicId)
|
if ($clientPublicId)
|
||||||
{
|
{
|
||||||
@ -88,7 +88,8 @@ class InvoiceRepository
|
|||||||
$invoice->end_date = Utils::toSqlDate($data['end_date']);
|
$invoice->end_date = Utils::toSqlDate($data['end_date']);
|
||||||
$invoice->terms = trim($data['terms']);
|
$invoice->terms = trim($data['terms']);
|
||||||
$invoice->po_number = trim($data['po_number']);
|
$invoice->po_number = trim($data['po_number']);
|
||||||
|
$invoice->currency_id = $data['currency_id'];
|
||||||
|
|
||||||
$total = 0;
|
$total = 0;
|
||||||
|
|
||||||
foreach ($data['invoice_items'] as $item)
|
foreach ($data['invoice_items'] as $item)
|
||||||
|
@ -170,11 +170,13 @@ define('FREQUENCY_SIX_MONTHS', 6);
|
|||||||
define('FREQUENCY_ANNUALLY', 7);
|
define('FREQUENCY_ANNUALLY', 7);
|
||||||
|
|
||||||
define('SESSION_TIMEZONE', 'timezone');
|
define('SESSION_TIMEZONE', 'timezone');
|
||||||
|
define('SESSION_CURRENCY', 'currency');
|
||||||
define('SESSION_DATE_FORMAT', 'dateFormat');
|
define('SESSION_DATE_FORMAT', 'dateFormat');
|
||||||
define('SESSION_DATE_PICKER_FORMAT', 'datePickerFormat');
|
define('SESSION_DATE_PICKER_FORMAT', 'datePickerFormat');
|
||||||
define('SESSION_DATETIME_FORMAT', 'datetimeFormat');
|
define('SESSION_DATETIME_FORMAT', 'datetimeFormat');
|
||||||
|
|
||||||
define('DEFAULT_TIMEZONE', 'US/Eastern');
|
define('DEFAULT_TIMEZONE', 'US/Eastern');
|
||||||
|
define('DEFAULT_CURRENCY', 1); // US Dollar
|
||||||
define('DEFAULT_DATE_FORMAT', 'M j, Y');
|
define('DEFAULT_DATE_FORMAT', 'M j, Y');
|
||||||
define('DEFAULT_DATE_PICKER_FORMAT', 'yyyy-mm-dd');
|
define('DEFAULT_DATE_PICKER_FORMAT', 'yyyy-mm-dd');
|
||||||
define('DEFAULT_DATETIME_FORMAT', 'F j, Y, g:i a');
|
define('DEFAULT_DATETIME_FORMAT', 'F j, Y, g:i a');
|
||||||
|
@ -39,7 +39,9 @@
|
|||||||
@endforeach
|
@endforeach
|
||||||
|
|
||||||
|
|
||||||
{{ Former::legend('Date and Time') }}
|
{{ Former::legend('Localization') }}
|
||||||
|
{{ Former::select('currency_id')->addOption('','')->label('Currency')
|
||||||
|
->fromQuery($currencies, 'name', 'id')->select($account->currency_id) }}
|
||||||
{{ Former::select('timezone_id')->addOption('','')->label('Timezone')
|
{{ Former::select('timezone_id')->addOption('','')->label('Timezone')
|
||||||
->fromQuery($timezones, 'location', 'id')->select($account->timezone_id) }}
|
->fromQuery($timezones, 'location', 'id')->select($account->timezone_id) }}
|
||||||
{{ Former::select('date_format_id')->addOption('','')->label('Date Format')
|
{{ Former::select('date_format_id')->addOption('','')->label('Date Format')
|
||||||
|
@ -64,6 +64,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{ Former::legend('Additional Info') }}
|
{{ Former::legend('Additional Info') }}
|
||||||
|
{{ Former::select('currency_id')->addOption('','')->label('Currency')
|
||||||
|
->fromQuery($currencies, 'name', 'id')->select(Session::get(SESSION_CURRENCY, DEFAULT_CURRENCY)) }}
|
||||||
{{ Former::select('client_size_id')->addOption('','')->label('Size')
|
{{ Former::select('client_size_id')->addOption('','')->label('Size')
|
||||||
->fromQuery($clientSizes, 'name', 'id')->select($client ? $client->client_size_id : '') }}
|
->fromQuery($clientSizes, 'name', 'id')->select($client ? $client->client_size_id : '') }}
|
||||||
{{ Former::select('client_industry_id')->addOption('','')->label('Industry')
|
{{ Former::select('client_industry_id')->addOption('','')->label('Industry')
|
||||||
|
@ -28,6 +28,8 @@
|
|||||||
@endif
|
@endif
|
||||||
|
|
||||||
{{ Former::select('client')->fromQuery($clients, 'name', 'public_id')->select($client ? $client->public_id : '')->addOption('', '')->addGroupClass('client-select') }}
|
{{ Former::select('client')->fromQuery($clients, 'name', 'public_id')->select($client ? $client->public_id : '')->addOption('', '')->addGroupClass('client-select') }}
|
||||||
|
{{ Former::select('currency_id')->addOption('','')->label('Currency')
|
||||||
|
->fromQuery($currencies, 'name', 'id')->select(Session::get(SESSION_CURRENCY, DEFAULT_CURRENCY)) }}
|
||||||
{{ Former::text('amount') }}
|
{{ Former::text('amount') }}
|
||||||
{{ Former::text('credit_date')->data_date_format(DEFAULT_DATE_PICKER_FORMAT) }}
|
{{ Former::text('credit_date')->data_date_format(DEFAULT_DATE_PICKER_FORMAT) }}
|
||||||
|
|
||||||
@ -50,7 +52,8 @@
|
|||||||
|
|
||||||
var $input = $('select#client');
|
var $input = $('select#client');
|
||||||
$input.combobox();
|
$input.combobox();
|
||||||
|
$('#currency_id').combobox();
|
||||||
|
|
||||||
$('#credit_date').datepicker({
|
$('#credit_date').datepicker({
|
||||||
autoclose: true,
|
autoclose: true,
|
||||||
todayHighlight: true
|
todayHighlight: true
|
||||||
|
@ -36,7 +36,8 @@
|
|||||||
// dynamic table
|
// dynamic table
|
||||||
jQuery('.{{ $class }}').dataTable({
|
jQuery('.{{ $class }}').dataTable({
|
||||||
// Disable sorting on the first column
|
// Disable sorting on the first column
|
||||||
@if (isset($haeCheckboxes) && $hasCheckboxes)
|
"aaSorting": [],
|
||||||
|
@if (isset($hasCheckboxes) && $hasCheckboxes)
|
||||||
"aoColumnDefs" : [ {
|
"aoColumnDefs" : [ {
|
||||||
'bSortable' : false,
|
'bSortable' : false,
|
||||||
'aTargets' : [ 0 ]
|
'aTargets' : [ 0 ]
|
||||||
|
@ -33,7 +33,9 @@
|
|||||||
<link rel="stylesheet" type="text/css" href="{{ asset('css/typeahead.js-bootstrap.css') }}"/>
|
<link rel="stylesheet" type="text/css" href="{{ asset('css/typeahead.js-bootstrap.css') }}"/>
|
||||||
|
|
||||||
<script src="{{ asset('js/script.js') }}" type="text/javascript"></script>
|
<script src="{{ asset('js/script.js') }}" type="text/javascript"></script>
|
||||||
|
<script src="{{ asset('js/accounting.js') }}" type="text/javascript"></script>
|
||||||
|
|
||||||
|
<link rel="stylesheet" type="text/css" href="{{ asset('css/style.css') }}"/>
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
|
|
||||||
@if (!Auth::check() || Auth::user()->showGreyBackground())
|
@if (!Auth::check() || Auth::user()->showGreyBackground())
|
||||||
@ -42,191 +44,23 @@
|
|||||||
}
|
}
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
/*
|
|
||||||
body > div.container {
|
|
||||||
min-height: 600px;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
label.checkbox,
|
|
||||||
label.control-label {
|
|
||||||
font-weight: normal !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
div.panel {
|
|
||||||
padding-left: 0px !important;
|
|
||||||
padding-right: 0px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-actions {
|
|
||||||
margin: 0;
|
|
||||||
background-color: transparent;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
.form-horizontal {
|
|
||||||
max-width: 750px;
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
.form-group {
|
|
||||||
width: 50%;
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* DataTables and BootStrap */
|
|
||||||
.dataTables_wrapper {
|
|
||||||
padding-top: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
table.table thead > tr > th {
|
|
||||||
border-bottom-width: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#DataTables_Table_0_length label {
|
|
||||||
font-weight: normal;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.dataTables_paginate.paging_bootstrap {
|
|
||||||
margin-top: -30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
table.table tbody tr.odd {
|
|
||||||
background-color: #f9f9f9;
|
|
||||||
}
|
|
||||||
|
|
||||||
table.table tbody tr:hover {
|
|
||||||
background-color: #f0f0f0 !important;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/* table sorting indicators */
|
|
||||||
/*table.table thead .sorting { background: url('images/sort_both.png') no-repeat center right; }*/
|
|
||||||
/*
|
|
||||||
table.table thead .sorting,
|
|
||||||
table.table thead .sorting_asc,
|
|
||||||
table.table thead .sorting_desc,
|
|
||||||
table.table thead .sorting_asc_disabled,
|
|
||||||
table.table thead .sorting_desc_disabled {
|
|
||||||
cursor: pointer;
|
|
||||||
*cursor: hand;
|
|
||||||
}
|
|
||||||
|
|
||||||
table.table thead .sorting_asc { background: url('images/sort_asc.png') no-repeat center right; }
|
|
||||||
table.table thead .sorting_desc { background: url('images/sort_desc.png') no-repeat center right; }
|
|
||||||
|
|
||||||
|
|
||||||
table.table thead .sorting_asc_disabled { background: url('images/sort_asc_disabled.png') no-repeat center right; }
|
|
||||||
table.table thead .sorting_desc_disabled { background: url('images/sort_desc_disabled.png') no-repeat center right; }
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/* Hover nav */
|
|
||||||
.sidebar-nav {
|
|
||||||
padding: 9px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown-menu .sub-menu {
|
|
||||||
left: 100%;
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
visibility: hidden;
|
|
||||||
margin-top: -1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown-menu li:hover .sub-menu {
|
|
||||||
visibility: visible;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown:hover .dropdown-menu {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-tabs .dropdown-menu, .nav-pills .dropdown-menu, .navbar .dropdown-menu {
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar .sub-menu:before {
|
|
||||||
border-bottom: 7px solid transparent;
|
|
||||||
border-left: none;
|
|
||||||
border-right: 7px solid rgba(0, 0, 0, 0.2);
|
|
||||||
border-top: 7px solid transparent;
|
|
||||||
left: -7px;
|
|
||||||
top: 10px;
|
|
||||||
}
|
|
||||||
.navbar .sub-menu:after {
|
|
||||||
border-top: 6px solid transparent;
|
|
||||||
border-left: none;
|
|
||||||
border-right: 6px solid #fff;
|
|
||||||
border-bottom: 6px solid transparent;
|
|
||||||
left: 10px;
|
|
||||||
top: 11px;
|
|
||||||
left: -6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.invoice-table {
|
|
||||||
border-style: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
table.invoice-table tbody tr:hover {
|
|
||||||
background-color: #FFFFFF !important;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
.invoice-table td {
|
|
||||||
padding: 2px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.invoice-table td input,
|
|
||||||
.invoice-table td textarea {
|
|
||||||
border: none !important;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.invoice-table th {
|
|
||||||
border-top: 1px solid #ddd !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.invoice-table td.hide-border,
|
|
||||||
.invoice-table th.hide-border {
|
|
||||||
border-style: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.invoice-table td.td-icon {
|
|
||||||
vertical-align: middle !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fa-bars {
|
|
||||||
cursor: move !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.closer-row {
|
|
||||||
margin-bottom: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Animate col width changes */
|
|
||||||
.row div {
|
|
||||||
-webkit-transition: width 0.5s ease, margin 0.5s ease;
|
|
||||||
-moz-transition: width 0.5s ease, margin 0.5s ease;
|
|
||||||
-o-transition: width 0.5s ease, margin 0.5s ease;
|
|
||||||
transition: width 0.5s ease, margin 0.5s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
var currencies = {{ Currency::remember(120)->get(); }};
|
||||||
|
var currencyMap = {};
|
||||||
|
for (var i=0; i<currencies.length; i++) {
|
||||||
|
var currency = currencies[i];
|
||||||
|
currencyMap[currency.id] = currency;
|
||||||
|
}
|
||||||
|
function formatMoney(value, currency_id, hide_symbol) {
|
||||||
|
if (!currency_id) currency_id = {{ Session::get(SESSION_CURRENCY, DEFAULT_CURRENCY); }};
|
||||||
|
var currency = currencyMap[currency_id];
|
||||||
|
return accounting.formatMoney(value, hide_symbol ? '' : currency.symbol, currency.precision, currency.thousand_separator, currency.decimal_separator);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
@stop
|
@stop
|
||||||
|
|
||||||
@section('body')
|
@section('body')
|
||||||
|
@ -66,7 +66,7 @@
|
|||||||
<div class="col-md-3" id="col_2">
|
<div class="col-md-3" id="col_2">
|
||||||
{{ Former::text('po_number')->label('PO number')->data_bind("value: po_number, valueUpdate: 'afterkeydown'") }}
|
{{ Former::text('po_number')->label('PO number')->data_bind("value: po_number, valueUpdate: 'afterkeydown'") }}
|
||||||
{{ Former::text('discount')->data_bind("value: discount, valueUpdate: 'afterkeydown'") }}
|
{{ Former::text('discount')->data_bind("value: discount, valueUpdate: 'afterkeydown'") }}
|
||||||
{{ Former::text('currency')->data_bind("value: discount, valueUpdate: 'afterkeydown'") }}
|
{{ Former::select('currency_id')->label('Currency')->fromQuery($currencies, 'name', 'id')->data_bind("value: currency_id") }}
|
||||||
|
|
||||||
<div class="form-group" style="margin-bottom: 8px">
|
<div class="form-group" style="margin-bottom: 8px">
|
||||||
<label for="recurring" class="control-label col-lg-4 col-sm-4">Taxes</label>
|
<label for="recurring" class="control-label col-lg-4 col-sm-4">Taxes</label>
|
||||||
@ -241,6 +241,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{ Former::legend('Additional Info') }}
|
{{ Former::legend('Additional Info') }}
|
||||||
|
{{ Former::select('currency_id')->addOption('','')->label('Currency')->data_bind('value: currency_id')
|
||||||
|
->fromQuery($currencies, 'name', 'id') }}
|
||||||
{{ Former::select('client_size_id')->addOption('','')->label('Size')->data_bind('value: client_size_id')
|
{{ Former::select('client_size_id')->addOption('','')->label('Size')->data_bind('value: client_size_id')
|
||||||
->fromQuery($clientSizes, 'name', 'id')->select($client ? $client->client_size_id : '') }}
|
->fromQuery($clientSizes, 'name', 'id')->select($client ? $client->client_size_id : '') }}
|
||||||
{{ Former::select('client_industry_id')->addOption('','')->label('Industry')->data_bind('value: client_industry_id')
|
{{ Former::select('client_industry_id')->addOption('','')->label('Industry')->data_bind('value: client_industry_id')
|
||||||
@ -329,6 +331,10 @@
|
|||||||
todayHighlight: true
|
todayHighlight: true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@if ($client && !$invoice)
|
||||||
|
$('input[name=client]').val({{ $client->public_id }});
|
||||||
|
@endif
|
||||||
|
|
||||||
var $input = $('select#client');
|
var $input = $('select#client');
|
||||||
$input.combobox();
|
$input.combobox();
|
||||||
$('.client_select input.form-control').on('change', function(e) {
|
$('.client_select input.form-control').on('change', function(e) {
|
||||||
@ -513,6 +519,7 @@
|
|||||||
this.client = new ClientModel();
|
this.client = new ClientModel();
|
||||||
self.discount = ko.observable('');
|
self.discount = ko.observable('');
|
||||||
self.frequency_id = ko.observable('');
|
self.frequency_id = ko.observable('');
|
||||||
|
self.currency_id = ko.observable({{ Session::get(SESSION_CURRENCY, DEFAULT_CURRENCY) }});
|
||||||
self.terms = ko.observable('');
|
self.terms = ko.observable('');
|
||||||
self.po_number = ko.observable('');
|
self.po_number = ko.observable('');
|
||||||
self.invoice_date = ko.observable('');
|
self.invoice_date = ko.observable('');
|
||||||
@ -636,13 +643,13 @@
|
|||||||
|
|
||||||
this.subtotal = ko.computed(function() {
|
this.subtotal = ko.computed(function() {
|
||||||
var total = self.rawSubtotal();
|
var total = self.rawSubtotal();
|
||||||
return total > 0 ? formatMoney(total) : '';
|
return total > 0 ? formatMoney(total, self.currency_id()) : '';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
this.discounted = ko.computed(function() {
|
this.discounted = ko.computed(function() {
|
||||||
var total = self.rawSubtotal() * (self.discount()/100);
|
var total = self.rawSubtotal() * (self.discount()/100);
|
||||||
return formatMoney(total);
|
return formatMoney(total, self.currency_id());
|
||||||
});
|
});
|
||||||
|
|
||||||
this.total = ko.computed(function() {
|
this.total = ko.computed(function() {
|
||||||
@ -653,7 +660,7 @@
|
|||||||
total = total * ((100 - discount)/100);
|
total = total * ((100 - discount)/100);
|
||||||
}
|
}
|
||||||
|
|
||||||
return total > 0 ? formatMoney(total) : '';
|
return total > 0 ? formatMoney(total, self.currency_id()) : '';
|
||||||
});
|
});
|
||||||
|
|
||||||
self.onDragged = function(item) {
|
self.onDragged = function(item) {
|
||||||
@ -675,6 +682,7 @@
|
|||||||
self.country_id = ko.observable('');
|
self.country_id = ko.observable('');
|
||||||
self.client_size_id = ko.observable('');
|
self.client_size_id = ko.observable('');
|
||||||
self.client_industry_id = ko.observable('');
|
self.client_industry_id = ko.observable('');
|
||||||
|
self.currency_id = ko.observable('');
|
||||||
self.website = ko.observable('');
|
self.website = ko.observable('');
|
||||||
self.contacts = ko.observableArray();
|
self.contacts = ko.observableArray();
|
||||||
|
|
||||||
@ -778,7 +786,7 @@
|
|||||||
this.qty = ko.observable();
|
this.qty = ko.observable();
|
||||||
this.tax = ko.observable();
|
this.tax = ko.observable();
|
||||||
this.actionsVisible = ko.observable(false);
|
this.actionsVisible = ko.observable(false);
|
||||||
|
|
||||||
this.prettyQty = ko.computed({
|
this.prettyQty = ko.computed({
|
||||||
read: function () {
|
read: function () {
|
||||||
return this.qty() ? parseFloat(this.qty()) : '';
|
return this.qty() ? parseFloat(this.qty()) : '';
|
||||||
@ -791,6 +799,7 @@
|
|||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
ko.mapping.fromJS(data, {}, this);
|
ko.mapping.fromJS(data, {}, this);
|
||||||
|
if (this.cost()) this.cost(formatMoney(this.cost(), model.currency_id(), true));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i=0; i<model.tax_rates().length; i++) {
|
for (var i=0; i<model.tax_rates().length; i++) {
|
||||||
@ -839,7 +848,7 @@
|
|||||||
|
|
||||||
this.total = ko.computed(function() {
|
this.total = ko.computed(function() {
|
||||||
var total = self.rawTotal();
|
var total = self.rawTotal();
|
||||||
return total ? formatMoney(total) : '';
|
return total ? formatMoney(total, model.currency_id()) : '';
|
||||||
});
|
});
|
||||||
|
|
||||||
this.hideActions = function() {
|
this.hideActions = function() {
|
||||||
|
@ -29,6 +29,8 @@
|
|||||||
|
|
||||||
{{ Former::select('client')->addOption('', '')->addGroupClass('client-select') }}
|
{{ Former::select('client')->addOption('', '')->addGroupClass('client-select') }}
|
||||||
{{ Former::select('invoice')->addOption('', '')->addGroupClass('invoice-select') }}
|
{{ Former::select('invoice')->addOption('', '')->addGroupClass('invoice-select') }}
|
||||||
|
{{ Former::select('currency_id')->addOption('','')->label('Currency')
|
||||||
|
->fromQuery($currencies, 'name', 'id')->select(Session::get(SESSION_CURRENCY, DEFAULT_CURRENCY)) }}
|
||||||
{{ Former::text('amount') }}
|
{{ Former::text('amount') }}
|
||||||
{{ Former::text('payment_date')->data_date_format(DEFAULT_DATE_PICKER_FORMAT) }}
|
{{ Former::text('payment_date')->data_date_format(DEFAULT_DATE_PICKER_FORMAT) }}
|
||||||
|
|
||||||
@ -107,7 +109,7 @@
|
|||||||
var list = clientId ? (invoiceMap.hasOwnProperty(clientId) ? invoiceMap[clientId] : []) : invoices;
|
var list = clientId ? (invoiceMap.hasOwnProperty(clientId) ? invoiceMap[clientId] : []) : invoices;
|
||||||
for (var i=0; i<list.length; i++) {
|
for (var i=0; i<list.length; i++) {
|
||||||
var invoice = list[i];
|
var invoice = list[i];
|
||||||
$invoiceCombobox.append(new Option(invoice.invoice_number + ' - ' + invoice.invoice_date + ' - ' + invoice.client.name, invoice.public_id));
|
$invoiceCombobox.append(new Option(invoice.invoice_number + ' - ' + invoice.client.name, invoice.public_id));
|
||||||
}
|
}
|
||||||
$('select#invoice').combobox('refresh');
|
$('select#invoice').combobox('refresh');
|
||||||
}).trigger('change');
|
}).trigger('change');
|
||||||
@ -122,6 +124,8 @@
|
|||||||
});
|
});
|
||||||
$input.combobox();
|
$input.combobox();
|
||||||
|
|
||||||
|
$('#currency_id').combobox();
|
||||||
|
|
||||||
$('#payment_date').datepicker({
|
$('#payment_date').datepicker({
|
||||||
autoclose: true,
|
autoclose: true,
|
||||||
todayHighlight: true
|
todayHighlight: true
|
||||||
|
@ -1,20 +1,20 @@
|
|||||||
/*
|
/*
|
||||||
body > div.container {
|
body > div.container {
|
||||||
min-height: 600px;
|
min-height: 600px;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
label.checkbox,
|
label.checkbox,
|
||||||
label.control-label {
|
label.control-label {
|
||||||
font-weight: normal !important;
|
font-weight: normal !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
div.panel {
|
div.panel {
|
||||||
padding-left: 0px !important;
|
padding-left: 0px !important;
|
||||||
padding-right: 0px !important;
|
padding-right: 0px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-actions {
|
.form-actions {
|
||||||
@ -23,57 +23,52 @@ div.panel {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sides-padded {
|
|
||||||
margin-left: 8px !important;
|
|
||||||
margin-right: 8px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
.form-horizontal {
|
.form-horizontal {
|
||||||
max-width: 750px;
|
max-width: 750px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
.form-group {
|
.form-group {
|
||||||
width: 50%;
|
width: 50%;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* DataTables and BootStrap */
|
/* DataTables and BootStrap */
|
||||||
.dataTables_wrapper {
|
.dataTables_wrapper {
|
||||||
padding-top: 16px;
|
padding-top: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.table thead > tr > th {
|
table.table thead > tr > th {
|
||||||
border-bottom-width: 0px;
|
border-bottom-width: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#DataTables_Table_0_length label {
|
#DataTables_Table_0_length label {
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
padding-bottom: 10px;
|
padding-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.dataTables_paginate.paging_bootstrap {
|
div.dataTables_paginate.paging_bootstrap {
|
||||||
margin-top: -30px;
|
margin-top: -30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
table.table tbody tr.odd {
|
table.table tbody tr.odd {
|
||||||
background-color: #f9f9f9;
|
background-color: #f9f9f9;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.table tbody tr:hover {
|
table.table tbody tr:hover {
|
||||||
background-color: #f0f0f0 !important;
|
background-color: #f0f0f0 !important;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* table sorting indicators */
|
/* table sorting indicators */
|
||||||
/*table.table thead .sorting { background: url('images/sort_both.png') no-repeat center right; }*/
|
/*table.table thead .sorting { background: url('images/sort_both.png') no-repeat center right; }*/
|
||||||
/*
|
|
||||||
table.table thead .sorting,
|
table.table thead .sorting,
|
||||||
table.table thead .sorting_asc,
|
table.table thead .sorting_asc,
|
||||||
table.table thead .sorting_desc,
|
table.table thead .sorting_desc,
|
||||||
@ -83,14 +78,13 @@ table.table thead .sorting_desc_disabled {
|
|||||||
*cursor: hand;
|
*cursor: hand;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.table thead .sorting_asc { background: url('images/sort_asc.png') no-repeat center right; }
|
table.table thead .sorting_asc { background: url('../images/sort_asc.png') no-repeat center right; }
|
||||||
table.table thead .sorting_desc { background: url('images/sort_desc.png') no-repeat center right; }
|
table.table thead .sorting_desc { background: url('../images/sort_desc.png') no-repeat center right; }
|
||||||
|
|
||||||
|
|
||||||
table.table thead .sorting_asc_disabled { background: url('images/sort_asc_disabled.png') no-repeat center right; }
|
table.table thead .sorting_asc_disabled { background: url('../images/sort_asc_disabled.png') no-repeat center right; }
|
||||||
table.table thead .sorting_desc_disabled { background: url('images/sort_desc_disabled.png') no-repeat center right; }
|
table.table thead .sorting_desc_disabled { background: url('../images/sort_desc_disabled.png') no-repeat center right; }
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/* Hover nav */
|
/* Hover nav */
|
||||||
.sidebar-nav {
|
.sidebar-nav {
|
||||||
@ -137,44 +131,44 @@ table.table thead .sorting_desc_disabled { background: url('images/sort_desc_dis
|
|||||||
|
|
||||||
|
|
||||||
.invoice-table {
|
.invoice-table {
|
||||||
border-style: none !important;
|
border-style: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
table.invoice-table tbody tr:hover {
|
table.invoice-table tbody tr:hover {
|
||||||
background-color: #FFFFFF !important;
|
background-color: #FFFFFF !important;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.invoice-table td {
|
.invoice-table td {
|
||||||
padding: 2px !important;
|
padding: 2px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.invoice-table td input,
|
.invoice-table td input,
|
||||||
.invoice-table td textarea {
|
.invoice-table td textarea {
|
||||||
border: none !important;
|
border: none !important;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.invoice-table th {
|
.invoice-table th {
|
||||||
border-top: 1px solid #ddd !important;
|
border-top: 1px solid #ddd !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.invoice-table td.hide-border,
|
.invoice-table td.hide-border,
|
||||||
.invoice-table th.hide-border {
|
.invoice-table th.hide-border {
|
||||||
border-style: none !important;
|
border-style: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.invoice-table td.td-icon {
|
.invoice-table td.td-icon {
|
||||||
vertical-align: middle !important;
|
vertical-align: middle !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fa-bars {
|
.fa-bars {
|
||||||
cursor: move !important;
|
cursor: move !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.closer-row {
|
.closer-row {
|
||||||
margin-bottom: 2px;
|
margin-bottom: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -183,5 +177,5 @@ table.invoice-table tbody tr:hover {
|
|||||||
-webkit-transition: width 0.5s ease, margin 0.5s ease;
|
-webkit-transition: width 0.5s ease, margin 0.5s ease;
|
||||||
-moz-transition: width 0.5s ease, margin 0.5s ease;
|
-moz-transition: width 0.5s ease, margin 0.5s ease;
|
||||||
-o-transition: width 0.5s ease, margin 0.5s ease;
|
-o-transition: width 0.5s ease, margin 0.5s ease;
|
||||||
transition: width 0.5s ease, margin 0.5s ease;
|
transition: width 0.5s ease, margin 0.5s ease;
|
||||||
}
|
}
|
||||||
|
412
public/js/accounting.js
Executable file
412
public/js/accounting.js
Executable file
@ -0,0 +1,412 @@
|
|||||||
|
/*!
|
||||||
|
* accounting.js v0.3.2
|
||||||
|
* Copyright 2011, Joss Crowcroft
|
||||||
|
*
|
||||||
|
* Freely distributable under the MIT license.
|
||||||
|
* Portions of accounting.js are inspired or borrowed from underscore.js
|
||||||
|
*
|
||||||
|
* Full details and documentation:
|
||||||
|
* http://josscrowcroft.github.com/accounting.js/
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function(root, undefined) {
|
||||||
|
|
||||||
|
/* --- Setup --- */
|
||||||
|
|
||||||
|
// Create the local library object, to be exported or referenced globally later
|
||||||
|
var lib = {};
|
||||||
|
|
||||||
|
// Current version
|
||||||
|
lib.version = '0.3.2';
|
||||||
|
|
||||||
|
|
||||||
|
/* --- Exposed settings --- */
|
||||||
|
|
||||||
|
// The library's settings configuration object. Contains default parameters for
|
||||||
|
// currency and number formatting
|
||||||
|
lib.settings = {
|
||||||
|
currency: {
|
||||||
|
symbol : "$", // default currency symbol is '$'
|
||||||
|
format : "%s%v", // controls output: %s = symbol, %v = value (can be object, see docs)
|
||||||
|
decimal : ".", // decimal point separator
|
||||||
|
thousand : ",", // thousands separator
|
||||||
|
precision : 2, // decimal places
|
||||||
|
grouping : 3 // digit grouping (not implemented yet)
|
||||||
|
},
|
||||||
|
number: {
|
||||||
|
precision : 0, // default precision on numbers is 0
|
||||||
|
grouping : 3, // digit grouping (not implemented yet)
|
||||||
|
thousand : ",",
|
||||||
|
decimal : "."
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* --- Internal Helper Methods --- */
|
||||||
|
|
||||||
|
// Store reference to possibly-available ECMAScript 5 methods for later
|
||||||
|
var nativeMap = Array.prototype.map,
|
||||||
|
nativeIsArray = Array.isArray,
|
||||||
|
toString = Object.prototype.toString;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests whether supplied parameter is a string
|
||||||
|
* from underscore.js
|
||||||
|
*/
|
||||||
|
function isString(obj) {
|
||||||
|
return !!(obj === '' || (obj && obj.charCodeAt && obj.substr));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests whether supplied parameter is a string
|
||||||
|
* from underscore.js, delegates to ECMA5's native Array.isArray
|
||||||
|
*/
|
||||||
|
function isArray(obj) {
|
||||||
|
return nativeIsArray ? nativeIsArray(obj) : toString.call(obj) === '[object Array]';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests whether supplied parameter is a true object
|
||||||
|
*/
|
||||||
|
function isObject(obj) {
|
||||||
|
return obj && toString.call(obj) === '[object Object]';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extends an object with a defaults object, similar to underscore's _.defaults
|
||||||
|
*
|
||||||
|
* Used for abstracting parameter handling from API methods
|
||||||
|
*/
|
||||||
|
function defaults(object, defs) {
|
||||||
|
var key;
|
||||||
|
object = object || {};
|
||||||
|
defs = defs || {};
|
||||||
|
// Iterate over object non-prototype properties:
|
||||||
|
for (key in defs) {
|
||||||
|
if (defs.hasOwnProperty(key)) {
|
||||||
|
// Replace values with defaults only if undefined (allow empty/zero values):
|
||||||
|
if (object[key] == null) object[key] = defs[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of `Array.map()` for iteration loops
|
||||||
|
*
|
||||||
|
* Returns a new Array as a result of calling `iterator` on each array value.
|
||||||
|
* Defers to native Array.map if available
|
||||||
|
*/
|
||||||
|
function map(obj, iterator, context) {
|
||||||
|
var results = [], i, j;
|
||||||
|
|
||||||
|
if (!obj) return results;
|
||||||
|
|
||||||
|
// Use native .map method if it exists:
|
||||||
|
if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
|
||||||
|
|
||||||
|
// Fallback for native .map:
|
||||||
|
for (i = 0, j = obj.length; i < j; i++ ) {
|
||||||
|
results[i] = iterator.call(context, obj[i], i, obj);
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check and normalise the value of precision (must be positive integer)
|
||||||
|
*/
|
||||||
|
function checkPrecision(val, base) {
|
||||||
|
val = Math.round(Math.abs(val));
|
||||||
|
return isNaN(val)? base : val;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses a format string or object and returns format obj for use in rendering
|
||||||
|
*
|
||||||
|
* `format` is either a string with the default (positive) format, or object
|
||||||
|
* containing `pos` (required), `neg` and `zero` values (or a function returning
|
||||||
|
* either a string or object)
|
||||||
|
*
|
||||||
|
* Either string or format.pos must contain "%v" (value) to be valid
|
||||||
|
*/
|
||||||
|
function checkCurrencyFormat(format) {
|
||||||
|
var defaults = lib.settings.currency.format;
|
||||||
|
|
||||||
|
// Allow function as format parameter (should return string or object):
|
||||||
|
if ( typeof format === "function" ) format = format();
|
||||||
|
|
||||||
|
// Format can be a string, in which case `value` ("%v") must be present:
|
||||||
|
if ( isString( format ) && format.match("%v") ) {
|
||||||
|
|
||||||
|
// Create and return positive, negative and zero formats:
|
||||||
|
return {
|
||||||
|
pos : format,
|
||||||
|
neg : format.replace("-", "").replace("%v", "-%v"),
|
||||||
|
zero : format
|
||||||
|
};
|
||||||
|
|
||||||
|
// If no format, or object is missing valid positive value, use defaults:
|
||||||
|
} else if ( !format || !format.pos || !format.pos.match("%v") ) {
|
||||||
|
|
||||||
|
// If defaults is a string, casts it to an object for faster checking next time:
|
||||||
|
return ( !isString( defaults ) ) ? defaults : lib.settings.currency.format = {
|
||||||
|
pos : defaults,
|
||||||
|
neg : defaults.replace("%v", "-%v"),
|
||||||
|
zero : defaults
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
// Otherwise, assume format was fine:
|
||||||
|
return format;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* --- API Methods --- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes a string/array of strings, removes all formatting/cruft and returns the raw float value
|
||||||
|
* alias: accounting.`parse(string)`
|
||||||
|
*
|
||||||
|
* Decimal must be included in the regular expression to match floats (defaults to
|
||||||
|
* accounting.settings.number.decimal), so if the number uses a non-standard decimal
|
||||||
|
* separator, provide it as the second argument.
|
||||||
|
*
|
||||||
|
* Also matches bracketed negatives (eg. "$ (1.99)" => -1.99)
|
||||||
|
*
|
||||||
|
* Doesn't throw any errors (`NaN`s become 0) but this may change in future
|
||||||
|
*/
|
||||||
|
var unformat = lib.unformat = lib.parse = function(value, decimal) {
|
||||||
|
// Recursively unformat arrays:
|
||||||
|
if (isArray(value)) {
|
||||||
|
return map(value, function(val) {
|
||||||
|
return unformat(val, decimal);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fails silently (need decent errors):
|
||||||
|
value = value || 0;
|
||||||
|
|
||||||
|
// Return the value as-is if it's already a number:
|
||||||
|
if (typeof value === "number") return value;
|
||||||
|
|
||||||
|
// Default decimal point comes from settings, but could be set to eg. "," in opts:
|
||||||
|
decimal = decimal || lib.settings.number.decimal;
|
||||||
|
|
||||||
|
// Build regex to strip out everything except digits, decimal point and minus sign:
|
||||||
|
var regex = new RegExp("[^0-9-" + decimal + "]", ["g"]),
|
||||||
|
unformatted = parseFloat(
|
||||||
|
("" + value)
|
||||||
|
.replace(/\((.*)\)/, "-$1") // replace bracketed values with negatives
|
||||||
|
.replace(regex, '') // strip out any cruft
|
||||||
|
.replace(decimal, '.') // make sure decimal point is standard
|
||||||
|
);
|
||||||
|
|
||||||
|
// This will fail silently which may cause trouble, let's wait and see:
|
||||||
|
return !isNaN(unformatted) ? unformatted : 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of toFixed() that treats floats more like decimals
|
||||||
|
*
|
||||||
|
* Fixes binary rounding issues (eg. (0.615).toFixed(2) === "0.61") that present
|
||||||
|
* problems for accounting- and finance-related software.
|
||||||
|
*/
|
||||||
|
var toFixed = lib.toFixed = function(value, precision) {
|
||||||
|
precision = checkPrecision(precision, lib.settings.number.precision);
|
||||||
|
var power = Math.pow(10, precision);
|
||||||
|
|
||||||
|
// Multiply up by precision, round accurately, then divide and use native toFixed():
|
||||||
|
return (Math.round(lib.unformat(value) * power) / power).toFixed(precision);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format a number, with comma-separated thousands and custom precision/decimal places
|
||||||
|
*
|
||||||
|
* Localise by overriding the precision and thousand / decimal separators
|
||||||
|
* 2nd parameter `precision` can be an object matching `settings.number`
|
||||||
|
*/
|
||||||
|
var formatNumber = lib.formatNumber = function(number, precision, thousand, decimal) {
|
||||||
|
// Resursively format arrays:
|
||||||
|
if (isArray(number)) {
|
||||||
|
return map(number, function(val) {
|
||||||
|
return formatNumber(val, precision, thousand, decimal);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up number:
|
||||||
|
number = unformat(number);
|
||||||
|
|
||||||
|
// Build options object from second param (if object) or all params, extending defaults:
|
||||||
|
var opts = defaults(
|
||||||
|
(isObject(precision) ? precision : {
|
||||||
|
precision : precision,
|
||||||
|
thousand : thousand,
|
||||||
|
decimal : decimal
|
||||||
|
}),
|
||||||
|
lib.settings.number
|
||||||
|
),
|
||||||
|
|
||||||
|
// Clean up precision
|
||||||
|
usePrecision = checkPrecision(opts.precision),
|
||||||
|
|
||||||
|
// Do some calc:
|
||||||
|
negative = number < 0 ? "-" : "",
|
||||||
|
base = parseInt(toFixed(Math.abs(number || 0), usePrecision), 10) + "",
|
||||||
|
mod = base.length > 3 ? base.length % 3 : 0;
|
||||||
|
|
||||||
|
// Format the number:
|
||||||
|
return negative + (mod ? base.substr(0, mod) + opts.thousand : "") + base.substr(mod).replace(/(\d{3})(?=\d)/g, "$1" + opts.thousand) + (usePrecision ? opts.decimal + toFixed(Math.abs(number), usePrecision).split('.')[1] : "");
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format a number into currency
|
||||||
|
*
|
||||||
|
* Usage: accounting.formatMoney(number, symbol, precision, thousandsSep, decimalSep, format)
|
||||||
|
* defaults: (0, "$", 2, ",", ".", "%s%v")
|
||||||
|
*
|
||||||
|
* Localise by overriding the symbol, precision, thousand / decimal separators and format
|
||||||
|
* Second param can be an object matching `settings.currency` which is the easiest way.
|
||||||
|
*
|
||||||
|
* To do: tidy up the parameters
|
||||||
|
*/
|
||||||
|
var formatMoney = lib.formatMoney = function(number, symbol, precision, thousand, decimal, format) {
|
||||||
|
// Resursively format arrays:
|
||||||
|
if (isArray(number)) {
|
||||||
|
return map(number, function(val){
|
||||||
|
return formatMoney(val, symbol, precision, thousand, decimal, format);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up number:
|
||||||
|
number = unformat(number);
|
||||||
|
|
||||||
|
// Build options object from second param (if object) or all params, extending defaults:
|
||||||
|
var opts = defaults(
|
||||||
|
(isObject(symbol) ? symbol : {
|
||||||
|
symbol : symbol,
|
||||||
|
precision : precision,
|
||||||
|
thousand : thousand,
|
||||||
|
decimal : decimal,
|
||||||
|
format : format
|
||||||
|
}),
|
||||||
|
lib.settings.currency
|
||||||
|
),
|
||||||
|
|
||||||
|
// Check format (returns object with pos, neg and zero):
|
||||||
|
formats = checkCurrencyFormat(opts.format),
|
||||||
|
|
||||||
|
// Choose which format to use for this value:
|
||||||
|
useFormat = number > 0 ? formats.pos : number < 0 ? formats.neg : formats.zero;
|
||||||
|
|
||||||
|
// Return with currency symbol added:
|
||||||
|
return useFormat.replace('%s', opts.symbol).replace('%v', formatNumber(Math.abs(number), checkPrecision(opts.precision), opts.thousand, opts.decimal));
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format a list of numbers into an accounting column, padding with whitespace
|
||||||
|
* to line up currency symbols, thousand separators and decimals places
|
||||||
|
*
|
||||||
|
* List should be an array of numbers
|
||||||
|
* Second parameter can be an object containing keys that match the params
|
||||||
|
*
|
||||||
|
* Returns array of accouting-formatted number strings of same length
|
||||||
|
*
|
||||||
|
* NB: `white-space:pre` CSS rule is required on the list container to prevent
|
||||||
|
* browsers from collapsing the whitespace in the output strings.
|
||||||
|
*/
|
||||||
|
lib.formatColumn = function(list, symbol, precision, thousand, decimal, format) {
|
||||||
|
if (!list) return [];
|
||||||
|
|
||||||
|
// Build options object from second param (if object) or all params, extending defaults:
|
||||||
|
var opts = defaults(
|
||||||
|
(isObject(symbol) ? symbol : {
|
||||||
|
symbol : symbol,
|
||||||
|
precision : precision,
|
||||||
|
thousand : thousand,
|
||||||
|
decimal : decimal,
|
||||||
|
format : format
|
||||||
|
}),
|
||||||
|
lib.settings.currency
|
||||||
|
),
|
||||||
|
|
||||||
|
// Check format (returns object with pos, neg and zero), only need pos for now:
|
||||||
|
formats = checkCurrencyFormat(opts.format),
|
||||||
|
|
||||||
|
// Whether to pad at start of string or after currency symbol:
|
||||||
|
padAfterSymbol = formats.pos.indexOf("%s") < formats.pos.indexOf("%v") ? true : false,
|
||||||
|
|
||||||
|
// Store value for the length of the longest string in the column:
|
||||||
|
maxLength = 0,
|
||||||
|
|
||||||
|
// Format the list according to options, store the length of the longest string:
|
||||||
|
formatted = map(list, function(val, i) {
|
||||||
|
if (isArray(val)) {
|
||||||
|
// Recursively format columns if list is a multi-dimensional array:
|
||||||
|
return lib.formatColumn(val, opts);
|
||||||
|
} else {
|
||||||
|
// Clean up the value
|
||||||
|
val = unformat(val);
|
||||||
|
|
||||||
|
// Choose which format to use for this value (pos, neg or zero):
|
||||||
|
var useFormat = val > 0 ? formats.pos : val < 0 ? formats.neg : formats.zero,
|
||||||
|
|
||||||
|
// Format this value, push into formatted list and save the length:
|
||||||
|
fVal = useFormat.replace('%s', opts.symbol).replace('%v', formatNumber(Math.abs(val), checkPrecision(opts.precision), opts.thousand, opts.decimal));
|
||||||
|
|
||||||
|
if (fVal.length > maxLength) maxLength = fVal.length;
|
||||||
|
return fVal;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Pad each number in the list and send back the column of numbers:
|
||||||
|
return map(formatted, function(val, i) {
|
||||||
|
// Only if this is a string (not a nested array, which would have already been padded):
|
||||||
|
if (isString(val) && val.length < maxLength) {
|
||||||
|
// Depending on symbol position, pad after symbol or at index 0:
|
||||||
|
return padAfterSymbol ? val.replace(opts.symbol, opts.symbol+(new Array(maxLength - val.length + 1).join(" "))) : (new Array(maxLength - val.length + 1).join(" ")) + val;
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* --- Module Definition --- */
|
||||||
|
|
||||||
|
// Export accounting for CommonJS. If being loaded as an AMD module, define it as such.
|
||||||
|
// Otherwise, just add `accounting` to the global object
|
||||||
|
if (typeof exports !== 'undefined') {
|
||||||
|
if (typeof module !== 'undefined' && module.exports) {
|
||||||
|
exports = module.exports = lib;
|
||||||
|
}
|
||||||
|
exports.accounting = lib;
|
||||||
|
} else if (typeof define === 'function' && define.amd) {
|
||||||
|
// Return the library as an AMD module:
|
||||||
|
define([], function() {
|
||||||
|
return lib;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Use accounting.noConflict to restore `accounting` back to its original value.
|
||||||
|
// Returns a reference to the library's `accounting` object;
|
||||||
|
// e.g. `var numbers = accounting.noConflict();`
|
||||||
|
lib.noConflict = (function(oldAccounting) {
|
||||||
|
return function() {
|
||||||
|
// Reset the value of the root's `accounting` variable:
|
||||||
|
root.accounting = oldAccounting;
|
||||||
|
// Delete the noConflict method:
|
||||||
|
lib.noConflict = undefined;
|
||||||
|
// Return reference to the library to re-assign it:
|
||||||
|
return lib;
|
||||||
|
};
|
||||||
|
})(root.accounting);
|
||||||
|
|
||||||
|
// Declare `fx` on the root (global/window) object:
|
||||||
|
root['accounting'] = lib;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Root will be `window` in browser or `global` on the server:
|
||||||
|
}(this));
|
@ -1,4 +1,5 @@
|
|||||||
function generatePDF(invoice) {
|
function generatePDF(invoice) {
|
||||||
|
var currencyId = invoice.currency_id;
|
||||||
var invoiceNumber = invoice.invoice_number;
|
var invoiceNumber = invoice.invoice_number;
|
||||||
var issuedOn = invoice.invoice_date ? invoice.invoice_date : '';
|
var issuedOn = invoice.invoice_date ? invoice.invoice_date : '';
|
||||||
var amount = '$0.00';
|
var amount = '$0.00';
|
||||||
@ -128,7 +129,7 @@ function generatePDF(invoice) {
|
|||||||
|
|
||||||
for (var i=0; i<invoice.invoice_items.length; i++) {
|
for (var i=0; i<invoice.invoice_items.length; i++) {
|
||||||
var item = invoice.invoice_items[i];
|
var item = invoice.invoice_items[i];
|
||||||
var cost = formatNumber(item.cost);
|
var cost = formatMoney(item.cost, currencyId, true);
|
||||||
var qty = item.qty ? parseFloat(item.qty) + '' : '';
|
var qty = item.qty ? parseFloat(item.qty) + '' : '';
|
||||||
var notes = item.notes;
|
var notes = item.notes;
|
||||||
var productKey = item.product_key;
|
var productKey = item.product_key;
|
||||||
@ -151,7 +152,7 @@ function generatePDF(invoice) {
|
|||||||
if (lineTotal) {
|
if (lineTotal) {
|
||||||
total += lineTotal;
|
total += lineTotal;
|
||||||
}
|
}
|
||||||
lineTotal = formatNumber(lineTotal);
|
lineTotal = formatMoney(lineTotal, currencyId, true);
|
||||||
|
|
||||||
var costX = unitCostRight - (doc.getStringUnitWidth(cost) * doc.internal.getFontSize());
|
var costX = unitCostRight - (doc.getStringUnitWidth(cost) * doc.internal.getFontSize());
|
||||||
var qtyX = qtyRight - (doc.getStringUnitWidth(qty) * doc.internal.getFontSize());
|
var qtyX = qtyRight - (doc.getStringUnitWidth(qty) * doc.internal.getFontSize());
|
||||||
@ -181,7 +182,7 @@ function generatePDF(invoice) {
|
|||||||
|
|
||||||
x += 16;
|
x += 16;
|
||||||
doc.text(footerLeft, x, 'Subtotal');
|
doc.text(footerLeft, x, 'Subtotal');
|
||||||
var total = formatNumber(total);
|
var total = formatMoney(total, currencyId, true);
|
||||||
var totalX = headerRight - (doc.getStringUnitWidth(total) * doc.internal.getFontSize());
|
var totalX = headerRight - (doc.getStringUnitWidth(total) * doc.internal.getFontSize());
|
||||||
doc.text(totalX, x, total);
|
doc.text(totalX, x, total);
|
||||||
|
|
||||||
@ -189,7 +190,7 @@ function generatePDF(invoice) {
|
|||||||
|
|
||||||
x += 16;
|
x += 16;
|
||||||
doc.text(footerLeft, x, 'Discount');
|
doc.text(footerLeft, x, 'Discount');
|
||||||
var discount = formatNumber(total * (invoice.discount/100));
|
var discount = formatMoney(total * (invoice.discount/100), currencyId, true);
|
||||||
total -= discount;
|
total -= discount;
|
||||||
var discountX = headerRight - (doc.getStringUnitWidth(discount) * doc.internal.getFontSize());
|
var discountX = headerRight - (doc.getStringUnitWidth(discount) * doc.internal.getFontSize());
|
||||||
doc.text(discountX, x, discount);
|
doc.text(discountX, x, discount);
|
||||||
@ -197,7 +198,7 @@ function generatePDF(invoice) {
|
|||||||
|
|
||||||
x += 16;
|
x += 16;
|
||||||
doc.text(footerLeft, x, 'Paid to Date');
|
doc.text(footerLeft, x, 'Paid to Date');
|
||||||
var paid = formatNumber(0);
|
var paid = formatMoney(0, currencyId, true);
|
||||||
var paidX = headerRight - (doc.getStringUnitWidth(paid) * doc.internal.getFontSize());
|
var paidX = headerRight - (doc.getStringUnitWidth(paid) * doc.internal.getFontSize());
|
||||||
doc.text(paidX, x, paid);
|
doc.text(paidX, x, paid);
|
||||||
|
|
||||||
@ -206,7 +207,7 @@ function generatePDF(invoice) {
|
|||||||
doc.setFontType("bold");
|
doc.setFontType("bold");
|
||||||
doc.text(footerLeft, x, 'Total');
|
doc.text(footerLeft, x, 'Total');
|
||||||
|
|
||||||
var total = formatMoney(total);
|
var total = formatMoney(total, currencyId);
|
||||||
var totalX = headerRight - (doc.getStringUnitWidth(total) * doc.internal.getFontSize());
|
var totalX = headerRight - (doc.getStringUnitWidth(total) * doc.internal.getFontSize());
|
||||||
doc.text(totalX, x, total);
|
doc.text(totalX, x, total);
|
||||||
|
|
||||||
@ -345,26 +346,6 @@ function getQuarter(offset) {
|
|||||||
return 'Q' + quarter;
|
return 'Q' + quarter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function formatMoney(num) {
|
|
||||||
num = parseFloat(num);
|
|
||||||
if (!num) return '$0.00';
|
|
||||||
return '$' + formatNumber(num);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function formatNumber(num) {
|
|
||||||
num = parseFloat(num);
|
|
||||||
if (!num) num = 0;
|
|
||||||
var p = num.toFixed(2).split(".");
|
|
||||||
return p[0].split("").reverse().reduce(function(acc, num, i, orig) {
|
|
||||||
return num + (i && !(i % 3) ? "," : "") + acc;
|
|
||||||
}, "") + "." + p[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Set the defaults for DataTables initialisation */
|
/* Set the defaults for DataTables initialisation */
|
||||||
$.extend( true, $.fn.dataTable.defaults, {
|
$.extend( true, $.fn.dataTable.defaults, {
|
||||||
"sDom": "t<'row-fluid'<'span6'i><'span6'p>>",
|
"sDom": "t<'row-fluid'<'span6'i><'span6'p>>",
|
||||||
|
Loading…
Reference in New Issue
Block a user