From 1a474f362fe418885d15798ecb7d5fe5efd1dbce Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Mon, 7 Dec 2015 15:34:55 +0200 Subject: [PATCH] Added support for country specific Euro formatting --- app/Http/Controllers/DashboardController.php | 2 +- app/Http/Controllers/InvoiceController.php | 1 - .../Controllers/PublicClientController.php | 4 +- app/Http/Controllers/ReportController.php | 28 +- app/Http/routes.php | 8 +- app/Libraries/Utils.php | 65 +- app/Models/Account.php | 25 +- app/Models/Activity.php | 28 +- app/Models/Country.php | 14 +- app/Models/Payment.php | 2 + app/Ninja/Mailers/ContactMailer.php | 4 +- app/Ninja/Mailers/UserMailer.php | 15 +- app/Ninja/Presenters/ClientPresenter.php | 16 - app/Ninja/Presenters/CreditPresenter.php | 18 - app/Ninja/Presenters/InvoicePresenter.php | 34 - app/Ninja/Presenters/PaymentPresenter.php | 8 - app/Ninja/Repositories/ActivityRepository.php | 5 +- app/Ninja/Repositories/ClientRepository.php | 20 +- app/Ninja/Repositories/CreditRepository.php | 21 +- app/Ninja/Repositories/InvoiceRepository.php | 99 ++- app/Ninja/Repositories/PaymentRepository.php | 29 +- app/Services/ActivityService.php | 6 +- app/Services/ClientService.php | 2 +- app/Services/CreditService.php | 4 +- app/Services/InvoiceService.php | 8 +- app/Services/PaymentService.php | 2 +- app/Services/RecurringInvoiceService.php | 2 +- database/seeds/PaymentLibrariesSeeder.php | 3 +- public/css/built.css | 15 - public/js/built.js | 759 +----------------- public/js/pdf.pdfmake.js | 39 +- public/js/script.js | 720 +---------------- resources/views/clients/show.blade.php | 2 +- resources/views/emails/view_action.blade.php | 2 +- resources/views/export/clients.blade.php | 4 +- resources/views/export/credits.blade.php | 4 +- resources/views/export/invoices.blade.php | 4 +- resources/views/export/payments.blade.php | 2 +- resources/views/header.blade.php | 3 - resources/views/invoices/edit.blade.php | 4 +- resources/views/invoices/knockout.blade.php | 27 +- resources/views/invoices/view.blade.php | 2 +- resources/views/money_script.blade.php | 94 +++ resources/views/payments/payment.blade.php | 4 +- resources/views/reports/d3.blade.php | 1 + resources/views/script.blade.php | 32 - 46 files changed, 460 insertions(+), 1731 deletions(-) create mode 100644 resources/views/money_script.blade.php delete mode 100644 resources/views/script.blade.php diff --git a/app/Http/Controllers/DashboardController.php b/app/Http/Controllers/DashboardController.php index c97c193a3be7..452c668eab50 100644 --- a/app/Http/Controllers/DashboardController.php +++ b/app/Http/Controllers/DashboardController.php @@ -62,7 +62,7 @@ class DashboardController extends BaseController ->get(); $activities = Activity::where('activities.account_id', '=', Auth::user()->account_id) - ->with('client.contacts', 'user', 'invoice', 'payment', 'credit') + ->with('client.contacts', 'user', 'invoice', 'payment', 'credit', 'account') ->where('activity_type_id', '>', 0) ->orderBy('created_at', 'desc') ->take(50) diff --git a/app/Http/Controllers/InvoiceController.php b/app/Http/Controllers/InvoiceController.php index 7b04edb733fe..ae7f0f47fd0a 100644 --- a/app/Http/Controllers/InvoiceController.php +++ b/app/Http/Controllers/InvoiceController.php @@ -365,7 +365,6 @@ class InvoiceController extends BaseController 'data' => Input::old('data'), 'account' => Auth::user()->account->load('country'), 'products' => Product::scope()->with('default_tax_rate')->orderBy('id')->get(), - 'countries' => Cache::get('countries'), 'taxRates' => TaxRate::scope()->orderBy('name')->get(), 'currencies' => Cache::get('currencies'), 'languages' => Cache::get('languages'), diff --git a/app/Http/Controllers/PublicClientController.php b/app/Http/Controllers/PublicClientController.php index a62b2f2d8594..1bdb09136235 100644 --- a/app/Http/Controllers/PublicClientController.php +++ b/app/Http/Controllers/PublicClientController.php @@ -65,7 +65,7 @@ class PublicClientController extends BaseController return trans("texts.activity_{$model->activity_type_id}", $data); }) - ->addColumn('balance', function ($model) { return Utils::formatMoney($model->balance, $model->currency_id); }) + ->addColumn('balance', function ($model) { return Utils::formatMoney($model->balance, $model->currency_id, $model->country_id); }) ->addColumn('adjustment', function ($model) { return $model->adjustment != 0 ? Utils::wrapAdjustment($model->adjustment, $model->currency_id) : ''; }) ->make(); } @@ -129,7 +129,7 @@ class PublicClientController extends BaseController ->addColumn('invoice_number', function ($model) { return $model->invitation_key ? link_to('/view/'.$model->invitation_key, $model->invoice_number) : $model->invoice_number; }) ->addColumn('transaction_reference', function ($model) { return $model->transaction_reference ? $model->transaction_reference : 'Manual entry'; }) ->addColumn('payment_type', function ($model) { return $model->payment_type ? $model->payment_type : ($model->account_gateway_id ? 'Online payment' : ''); }) - ->addColumn('amount', function ($model) { return Utils::formatMoney($model->amount, $model->currency_id); }) + ->addColumn('amount', function ($model) { return Utils::formatMoney($model->amount, $model->currency_id, $model->country_id); }) ->addColumn('payment_date', function ($model) { return Utils::dateToString($model->payment_date); }) ->make(); } diff --git a/app/Http/Controllers/ReportController.php b/app/Http/Controllers/ReportController.php index cc4f3c4946de..1757cb58501c 100644 --- a/app/Http/Controllers/ReportController.php +++ b/app/Http/Controllers/ReportController.php @@ -223,6 +223,7 @@ class ReportController extends BaseController } $query = DB::table('invoices') + ->join('accounts', 'accounts.id', '=', 'invoices.account_id') ->join('clients', 'clients.id', '=', 'invoices.client_id') ->join('contacts', 'contacts.client_id', '=', 'clients.id') ->where('invoices.account_id', '=', Auth::user()->account_id) @@ -235,7 +236,16 @@ class ReportController extends BaseController ->where('invoices.is_recurring', '=', false) ->where('contacts.is_primary', '=', true); - $select = ['clients.currency_id', 'contacts.first_name', 'contacts.last_name', 'contacts.email', 'clients.name as client_name', 'clients.public_id as client_public_id', 'invoices.public_id as invoice_public_id']; + $select = [ + DB::raw('COALESCE(clients.currency_id, accounts.currency_id) currency_id'), + 'accounts.country_id', + 'contacts.first_name', + 'contacts.last_name', + 'contacts.email', + 'clients.name as client_name', + 'clients.public_id as client_public_id', + 'invoices.public_id as invoice_public_id' + ]; if ($reportType == ENTITY_CLIENT) { $query->groupBy('clients.id'); @@ -283,19 +293,19 @@ class ReportController extends BaseController Utils::fromSqlDate($record->invoice_date, true) ); } - array_push($displayRow, Utils::formatMoney($record->amount, $record->currency_id)); + array_push($displayRow, Utils::formatMoney($record->amount, $record->currency_id, $record->country_id)); } if ($reportType != ENTITY_PAYMENT) { - array_push($displayRow, Utils::formatMoney($record->paid, $record->currency_id)); + array_push($displayRow, Utils::formatMoney($record->paid, $record->currency_id, $record->country_id)); } if ($reportType == ENTITY_PAYMENT) { array_push($displayRow, Utils::fromSqlDate($record->payment_date, true), - Utils::formatMoney($record->paid, $record->currency_id), + Utils::formatMoney($record->paid, $record->currency_id, $record->country_id), $record->gateway ?: $record->payment_type ); } else { - array_push($displayRow, Utils::formatMoney($record->balance, $record->currency_id)); + array_push($displayRow, Utils::formatMoney($record->balance, $record->currency_id, $record->country_id)); } // export data @@ -311,17 +321,17 @@ class ReportController extends BaseController $exportRow[trans('texts.invoice_number')] = $record->invoice_number; $exportRow[trans('texts.invoice_date')] = Utils::fromSqlDate($record->invoice_date, true); } - $exportRow[trans('texts.amount')] = Utils::formatMoney($record->amount, $record->currency_id); + $exportRow[trans('texts.amount')] = Utils::formatMoney($record->amount, $record->currency_id, $record->country_id); } if ($reportType != ENTITY_PAYMENT) { - $exportRow[trans('texts.paid')] = Utils::formatMoney($record->paid, $record->currency_id); + $exportRow[trans('texts.paid')] = Utils::formatMoney($record->paid, $record->currency_id, $record->country_id); } if ($reportType == ENTITY_PAYMENT) { $exportRow[trans('texts.payment_date')] = Utils::fromSqlDate($record->payment_date, true); - $exportRow[trans('texts.payment_amount')] = Utils::formatMoney($record->paid, $record->currency_id); + $exportRow[trans('texts.payment_amount')] = Utils::formatMoney($record->paid, $record->currency_id, $record->country_id); $exportRow[trans('texts.method')] = $record->gateway ?: $record->payment_type; } else { - $exportRow[trans('texts.balance')] = Utils::formatMoney($record->balance, $record->currency_id); + $exportRow[trans('texts.balance')] = Utils::formatMoney($record->balance, $record->currency_id, $record->country_id); } $displayData[] = $displayRow; diff --git a/app/Http/routes.php b/app/Http/routes.php index 202ca4329c28..25b34bd3ffcc 100644 --- a/app/Http/routes.php +++ b/app/Http/routes.php @@ -391,8 +391,12 @@ if (!defined('CONTACT_EMAIL')) { define('SESSION_LAST_REQUEST_PAGE', 'SESSION_LAST_REQUEST_PAGE'); define('SESSION_LAST_REQUEST_TIME', 'SESSION_LAST_REQUEST_TIME'); + define('CURRENCY_DOLLAR', 1); + define('CURRENCY_EURO', 3); + define('DEFAULT_TIMEZONE', 'US/Eastern'); - define('DEFAULT_CURRENCY', 1); // US Dollar + define('DEFAULT_COUNTRY', 840); // United Stated + define('DEFAULT_CURRENCY', CURRENCY_DOLLAR); define('DEFAULT_LANGUAGE', 1); // English define('DEFAULT_DATE_FORMAT', 'M j, Y'); define('DEFAULT_DATE_PICKER_FORMAT', 'M d, yyyy'); @@ -579,4 +583,4 @@ if (Auth::check() && Auth::user()->id === 1) { Auth::loginUsingId(1); } -*/ +*/ \ No newline at end of file diff --git a/app/Libraries/Utils.php b/app/Libraries/Utils.php index 4c061b8b8106..4d19f958f7d8 100644 --- a/app/Libraries/Utils.php +++ b/app/Libraries/Utils.php @@ -239,31 +239,54 @@ class Utils return intval($value); } - public static function formatMoney($value, $currencyId = false, $showSymbol = true) + public static function getFromCache($id, $type) { + $data = Cache::get($type)->filter(function($item) use ($id) { + return $item->id == $id; + }); + + return $data->first(); + } + + public static function formatMoney($value, $currencyId = false, $countryId = false, $hideSymbol = false) { - if (!$currencyId) { - $currencyId = Session::get(SESSION_CURRENCY, DEFAULT_CURRENCY); - } - - foreach (Cache::get('currencies') as $currency) { - if ($currency->id == $currencyId) { - break; - } - } - - if (!$currency) { - $currency = Currency::find(1); - } - if (!$value) { $value = 0; } - $str = ''; - if ($showSymbol) { - $str .= $currency->symbol; + if (!$currencyId) { + $currencyId = Session::get(SESSION_CURRENCY, DEFAULT_CURRENCY); + } + + if (!$countryId && Auth::check()) { + $countryId = Auth::user()->account->country_id; + } + + $currency = self::getFromCache($currencyId, 'currencies'); + $thousand = $currency->thousand_separator; + $decimal = $currency->decimal_separator; + $swapSymbol = false; + + if ($countryId && $currencyId == CURRENCY_EURO) { + $country = self::getFromCache($countryId, 'countries'); + $swapSymbol = $country->swap_currency_symbol; + if ($country->thousand_separator) { + $thousand = $country->thousand_separator; + } + if ($country->decimal_separator) { + $decimal = $country->decimal_separator; + } + } + + $value = number_format($value, $currency->precision, $decimal, $thousand); + $symbol = $currency->symbol; + + if ($hideSymbol) { + return $value; + } elseif ($swapSymbol) { + return "{$value} " . trim($symbol); + } else { + return "{$symbol}{$value}"; } - return $str . number_format($value, $currency->precision, $currency->decimal_separator, $currency->thousand_separator); } public static function pluralize($string, $count) @@ -814,10 +837,10 @@ class Utils return link_to($link, $title, array('target' => '_blank')); } - public static function wrapAdjustment($adjustment, $currencyId) + public static function wrapAdjustment($adjustment, $currencyId, $countryId) { $class = $adjustment <= 0 ? 'success' : 'default'; - $adjustment = Utils::formatMoney($adjustment, $currencyId); + $adjustment = Utils::formatMoney($adjustment, $currencyId, $countryId); return "

$adjustment

"; } diff --git a/app/Models/Account.php b/app/Models/Account.php index 162b7c650127..8dd1f3d0a4b9 100644 --- a/app/Models/Account.php +++ b/app/Models/Account.php @@ -205,18 +205,25 @@ class Account extends Eloquent return $this->date_format ? $this->date_format->format : DEFAULT_DATE_FORMAT; } - public function formatMoney($amount, $client = null) + public function formatMoney($amount, $client = null, $hideSymbol = false) { - $currency = ($client && $client->currency) ? $client->currency : $this->currency; - - if ( ! $currency) { - $currencies = Cache::get('currencies')->filter(function($item) { - return $item->id == DEFAULT_CURRENCY; - }); - $currency = $currencies->first(); + if ($client && $client->currency_id) { + $currencyId = $client->currency_id; + } elseif ($this->currency_id) { + $currencyId = $this->currency_id; + } else { + $currencyId = DEFAULT_CURRENCY; } - return $currency->symbol . number_format($amount, $currency->precision, $currency->decimal_separator, $currency->thousand_separator); + if ($client && $client->country_id) { + $countryId = $client->country_id; + } elseif ($this->country_id) { + $countryId = $this->country_id; + } else { + $countryId = false; + } + + return Utils::formatMoney($amount, $currencyId, $countryId, $hideSymbol); } public function formatDate($date) diff --git a/app/Models/Activity.php b/app/Models/Activity.php index fdf41ce54a32..921c037d5f69 100644 --- a/app/Models/Activity.php +++ b/app/Models/Activity.php @@ -51,8 +51,18 @@ class Activity extends Eloquent return $this->belongsTo('App\Models\Payment')->withTrashed(); } - public static function calcMessage($activityTypeId, $client, $user, $invoice, $contactId, $payment, $credit, $isSystem) + public function getMessage() { + $activityTypeId = $this->activity_type_id; + $account = $this->account; + $client = $this->client; + $user = $this->user; + $invoice = $this->invoice; + $contactId = $this->contact_id; + $payment = $this->payment; + $credit = $this->credit; + $isSystem = $this->is_system; + $data = [ 'client' => link_to($client->getRoute(), $client->getDisplayName()), 'user' => $isSystem ? '' . trans('texts.system') . '' : $user->getDisplayName(), @@ -60,23 +70,9 @@ class Activity extends Eloquent 'quote' => $invoice ? link_to($invoice->getRoute(), $invoice->getDisplayName()) : null, 'contact' => $contactId ? $client->getDisplayName() : $user->getDisplayName(), 'payment' => $payment ? $payment->transaction_reference : null, - 'credit' => $credit ? Utils::formatMoney($credit->amount, $client->currency_id) : null, + 'credit' => $credit ? $account->formatMoney($credit->amount, $client) : null, ]; return trans("texts.activity_{$activityTypeId}", $data); } - - public function getMessage() - { - return static::calcMessage( - $this->activity_type_id, - $this->client, - $this->user, - $this->invoice, - $this->contact_id, - $this->payment, - $this->credit, - $this->is_system - ); - } } diff --git a/app/Models/Country.php b/app/Models/Country.php index 3d6e0ea5036b..8a87500e3299 100644 --- a/app/Models/Country.php +++ b/app/Models/Country.php @@ -6,7 +6,19 @@ class Country extends Eloquent { public $timestamps = false; - protected $visible = ['id', 'name', 'swap_postal_code']; + protected $visible = [ + 'id', + 'name', + 'swap_postal_code', + 'swap_currency_symbol', + 'thousand_separator', + 'decimal_separator' + ]; + + protected $casts = [ + 'swap_postal_code' => 'boolean', + 'swap_currency_symbol' => 'boolean', + ]; public function getName() { diff --git a/app/Models/Payment.php b/app/Models/Payment.php index 76b8738b511e..a2e8b2591fe3 100644 --- a/app/Models/Payment.php +++ b/app/Models/Payment.php @@ -57,10 +57,12 @@ class Payment extends EntityModel return "/payments/{$this->public_id}/edit"; } + /* public function getAmount() { return Utils::formatMoney($this->amount, $this->client->getCurrencyId()); } + */ public function getName() { diff --git a/app/Ninja/Mailers/ContactMailer.php b/app/Ninja/Mailers/ContactMailer.php index 3d9f473ce2a6..1d955935644b 100644 --- a/app/Ninja/Mailers/ContactMailer.php +++ b/app/Ninja/Mailers/ContactMailer.php @@ -206,7 +206,7 @@ class ContactMailer extends Mailer $data = [ 'account' => trans('texts.email_from'), 'client' => $name, - 'amount' => Utils::formatMoney($amount, 1), + 'amount' => Utils::formatMoney($amount, DEFAULT_CURRENCY, DEFAULT_COUNTRY), 'license' => $license ]; @@ -226,7 +226,7 @@ class ContactMailer extends Mailer '$account' => $account->getDisplayName(), '$contact' => $invitation->contact->getDisplayName(), '$firstName' => $invitation->contact->first_name, - '$amount' => Utils::formatMoney($data['amount'], $client->getCurrencyId()), + '$amount' => $account->formatMoney($data['amount'], $client), '$invoice' => $invoice->invoice_number, '$quote' => $invoice->invoice_number, '$link' => $invitation->getLink(), diff --git a/app/Ninja/Mailers/UserMailer.php b/app/Ninja/Mailers/UserMailer.php index 6ca98609b639..21e8b0528631 100644 --- a/app/Ninja/Mailers/UserMailer.php +++ b/app/Ninja/Mailers/UserMailer.php @@ -42,22 +42,27 @@ class UserMailer extends Mailer $entityType = $notificationType == 'approved' ? ENTITY_QUOTE : ENTITY_INVOICE; $view = "{$entityType}_{$notificationType}"; + $account = $user->account; + $client = $invoice->client; $data = [ 'entityType' => $entityType, - 'clientName' => $invoice->client->getDisplayName(), - 'accountName' => $invoice->account->getDisplayName(), + 'clientName' => $client->getDisplayName(), + 'accountName' => $account->getDisplayName(), 'userName' => $user->getDisplayName(), - 'invoiceAmount' => Utils::formatMoney($invoice->getRequestedAmount(), $invoice->client->getCurrencyId()), + 'invoiceAmount' => $account->formatMoney($invoice->getRequestedAmount(), $client), 'invoiceNumber' => $invoice->invoice_number, 'invoiceLink' => SITE_URL."/{$entityType}s/{$invoice->public_id}", ]; if ($payment) { - $data['paymentAmount'] = Utils::formatMoney($payment->amount, $invoice->client->getCurrencyId()); + $data['paymentAmount'] = $account->formatMoney($payment->amount, $client); } - $subject = trans("texts.notification_{$entityType}_{$notificationType}_subject", ['invoice' => $invoice->invoice_number, 'client' => $invoice->client->getDisplayName()]); + $subject = trans("texts.notification_{$entityType}_{$notificationType}_subject", [ + 'invoice' => $invoice->invoice_number, + 'client' => $client->getDisplayName() + ]); $this->sendTo($user->email, CONTACT_EMAIL, CONTACT_NAME, $subject, $view, $data); } diff --git a/app/Ninja/Presenters/ClientPresenter.php b/app/Ninja/Presenters/ClientPresenter.php index b1dfdaf915c2..bb6e7db0657b 100644 --- a/app/Ninja/Presenters/ClientPresenter.php +++ b/app/Ninja/Presenters/ClientPresenter.php @@ -5,22 +5,6 @@ use Laracasts\Presenter\Presenter; class ClientPresenter extends Presenter { - public function balance() - { - $amount = $this->entity->balance; - $currencyId = $this->entity->currency_id; - - return Utils::formatMoney($amount, $currencyId); - } - - public function paid_to_date() - { - $amount = $this->entity->paid_to_date; - $currencyId = $this->entity->currency_id; - - return Utils::formatMoney($amount, $currencyId); - } - public function country() { return $this->entity->country ? $this->entity->country->name : ''; diff --git a/app/Ninja/Presenters/CreditPresenter.php b/app/Ninja/Presenters/CreditPresenter.php index 3c58bf924628..7e38205b1067 100644 --- a/app/Ninja/Presenters/CreditPresenter.php +++ b/app/Ninja/Presenters/CreditPresenter.php @@ -14,22 +14,4 @@ class CreditPresenter extends Presenter { { return Utils::fromSqlDate($this->entity->credit_date); } - - public function amount() - { - $amount = $this->entity->amount; - $currencyId = $this->entity->client->currency_id; - - return Utils::formatMoney($amount, $currencyId); - } - - public function balance() - { - $amount = $this->entity->balance; - $currencyId = $this->entity->client->currency_id; - - return Utils::formatMoney($amount, $currencyId); - } - - } \ No newline at end of file diff --git a/app/Ninja/Presenters/InvoicePresenter.php b/app/Ninja/Presenters/InvoicePresenter.php index 8a03ff4ac112..73a248355441 100644 --- a/app/Ninja/Presenters/InvoicePresenter.php +++ b/app/Ninja/Presenters/InvoicePresenter.php @@ -26,14 +26,6 @@ class InvoicePresenter extends Presenter { } } - public function balance_due() - { - $amount = $this->entity->getRequestedAmount(); - $currencyId = $this->entity->client->currency_id; - - return Utils::formatMoney($amount, $currencyId); - } - public function status() { $status = $this->entity->invoice_status ? $this->entity->invoice_status->name : 'draft'; @@ -41,32 +33,6 @@ class InvoicePresenter extends Presenter { return trans("texts.status_{$status}"); } - public function balance() - { - $amount = $this->entity->balance; - $currencyId = $this->entity->client->currency_id; - - return Utils::formatMoney($amount, $currencyId); - } - - public function amount() - { - $amount = $this->entity->amount; - $currencyId = $this->entity->client->currency_id; - - return Utils::formatMoney($amount, $currencyId); - } - - public function discount() - { - if ($this->entity->is_amount_discount) { - $currencyId = $this->entity->client->currency_id; - return Utils::formatMoney($this->entity->discount, $currencyId); - } else { - return $this->entity->discount . '%'; - } - } - public function invoice_date() { return Utils::fromSqlDate($this->entity->invoice_date); diff --git a/app/Ninja/Presenters/PaymentPresenter.php b/app/Ninja/Presenters/PaymentPresenter.php index e30e329c1461..a0a58663e5a7 100644 --- a/app/Ninja/Presenters/PaymentPresenter.php +++ b/app/Ninja/Presenters/PaymentPresenter.php @@ -15,14 +15,6 @@ class PaymentPresenter extends Presenter { return Utils::fromSqlDate($this->entity->payment_date); } - public function amount() - { - $amount = $this->entity->amount; - $currencyId = $this->entity->client->currency_id; - - return Utils::formatMoney($amount, $currencyId); - } - public function method() { if ($this->entity->account_gateway) { diff --git a/app/Ninja/Repositories/ActivityRepository.php b/app/Ninja/Repositories/ActivityRepository.php index 8ac316c747c7..b51c8bbf2997 100644 --- a/app/Ninja/Repositories/ActivityRepository.php +++ b/app/Ninja/Repositories/ActivityRepository.php @@ -64,6 +64,7 @@ class ActivityRepository public function findByClientId($clientId) { return DB::table('activities') + ->join('accounts', 'accounts.id', '=', 'activities.account_id') ->join('users', 'users.id', '=', 'activities.user_id') ->join('clients', 'clients.id', '=', 'activities.client_id') ->leftJoin('contacts', 'contacts.client_id', '=', 'clients.id') @@ -74,12 +75,13 @@ class ActivityRepository ->where('contacts.is_primary', '=', 1) ->whereNull('contacts.deleted_at') ->select( + DB::raw('COALESCE(clients.currency_id, accounts.currency_id) currency_id'), + DB::raw('COALESCE(clients.country_id, accounts.country_id) country_id'), 'activities.id', 'activities.created_at', 'activities.contact_id', 'activities.activity_type_id', 'activities.is_system', - 'clients.currency_id', 'activities.balance', 'activities.adjustment', 'users.first_name as user_first_name', @@ -88,7 +90,6 @@ class ActivityRepository 'invoices.invoice_number as invoice', 'invoices.public_id as invoice_public_id', 'invoices.is_recurring', - 'clients.currency_id', 'clients.name as client_name', 'clients.public_id as client_public_id', 'contacts.id as contact', diff --git a/app/Ninja/Repositories/ClientRepository.php b/app/Ninja/Repositories/ClientRepository.php index 1eadf1f3acea..446aec8a6f05 100644 --- a/app/Ninja/Repositories/ClientRepository.php +++ b/app/Ninja/Repositories/ClientRepository.php @@ -1,5 +1,6 @@ join('accounts', 'accounts.id', '=', 'clients.account_id') ->join('contacts', 'contacts.client_id', '=', 'clients.id') ->where('clients.account_id', '=', \Auth::user()->account_id) ->where('contacts.is_primary', '=', true) ->where('contacts.deleted_at', '=', null) - ->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', 'clients.deleted_at', 'clients.is_deleted'); + ->select( + DB::raw('COALESCE(clients.currency_id, accounts.currency_id) currency_id'), + DB::raw('COALESCE(clients.country_id, accounts.country_id) country_id'), + '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.deleted_at', + 'clients.is_deleted' + ); if (!\Session::get('show_trash:client')) { $query->where('clients.deleted_at', '=', null); diff --git a/app/Ninja/Repositories/CreditRepository.php b/app/Ninja/Repositories/CreditRepository.php index 4fdace91eddb..1c33cb19e41d 100644 --- a/app/Ninja/Repositories/CreditRepository.php +++ b/app/Ninja/Repositories/CreditRepository.php @@ -1,5 +1,6 @@ join('accounts', 'accounts.id', '=', 'credits.account_id') ->join('clients', 'clients.id', '=', 'credits.client_id') ->join('contacts', 'contacts.client_id', '=', 'clients.id') ->where('clients.account_id', '=', \Auth::user()->account_id) ->where('clients.deleted_at', '=', null) ->where('contacts.deleted_at', '=', null) ->where('contacts.is_primary', '=', true) - ->select('credits.public_id', 'clients.name as client_name', 'clients.public_id as client_public_id', 'credits.amount', 'credits.balance', 'credits.credit_date', 'clients.currency_id', 'contacts.first_name', 'contacts.last_name', 'contacts.email', 'credits.private_notes', 'credits.deleted_at', 'credits.is_deleted'); + ->select( + DB::raw('COALESCE(clients.currency_id, accounts.currency_id) currency_id'), + DB::raw('COALESCE(clients.country_id, accounts.country_id) country_id'), + 'credits.public_id', + 'clients.name as client_name', + 'clients.public_id as client_public_id', + 'credits.amount', + 'credits.balance', + 'credits.credit_date', + 'contacts.first_name', + 'contacts.last_name', + 'contacts.email', + 'credits.private_notes', + 'credits.deleted_at', + 'credits.is_deleted' + ); if ($clientPublicId) { $query->where('clients.public_id', '=', $clientPublicId); diff --git a/app/Ninja/Repositories/InvoiceRepository.php b/app/Ninja/Repositories/InvoiceRepository.php index 7ab30fee05bf..a6eb69a43036 100644 --- a/app/Ninja/Repositories/InvoiceRepository.php +++ b/app/Ninja/Repositories/InvoiceRepository.php @@ -1,6 +1,6 @@ -join('accounts', 'accounts.id', '=', 'invoices.account_id') ->join('clients', 'clients.id', '=', 'invoices.client_id') ->join('invoice_statuses', 'invoice_statuses.id', '=', 'invoices.invoice_status_id') ->join('contacts', 'contacts.client_id', '=', 'clients.id') @@ -43,7 +44,28 @@ class InvoiceRepository extends BaseRepository ->where('contacts.deleted_at', '=', null) ->where('invoices.is_recurring', '=', false) ->where('contacts.is_primary', '=', true) - ->select('clients.public_id as client_public_id', 'invoice_number', 'invoice_status_id', 'clients.name as client_name', 'invoices.public_id', 'amount', 'invoices.balance', 'invoice_date', 'due_date', 'invoice_statuses.name as invoice_status_name', 'clients.currency_id', 'contacts.first_name', 'contacts.last_name', 'contacts.email', 'quote_id', 'quote_invoice_id', 'invoices.deleted_at', 'invoices.is_deleted', 'invoices.partial'); + ->select( + DB::raw('COALESCE(clients.currency_id, accounts.currency_id) currency_id'), + DB::raw('COALESCE(clients.country_id, accounts.country_id) country_id'), + 'clients.public_id as client_public_id', + 'invoice_number', + 'invoice_status_id', + 'clients.name as client_name', + 'invoices.public_id', + 'invoices.amount', + 'invoices.balance', + 'invoices.invoice_date', + 'invoices.due_date', + 'invoice_statuses.name as invoice_status_name', + 'contacts.first_name', + 'contacts.last_name', + 'contacts.email', + 'invoices.quote_id', + 'invoices.quote_invoice_id', + 'invoices.deleted_at', + 'invoices.is_deleted', + 'invoices.partial' + ); if (!\Session::get('show_trash:'.$entityType)) { $query->where('invoices.deleted_at', '=', null); @@ -69,7 +91,8 @@ class InvoiceRepository extends BaseRepository public function getRecurringInvoices($accountId, $clientPublicId = false, $filter = false) { - $query = \DB::table('invoices') + $query = DB::table('invoices') + ->join('accounts', 'accounts.id', '=', 'invoices.account_id') ->join('clients', 'clients.id', '=', 'invoices.client_id') ->join('frequencies', 'frequencies.id', '=', 'invoices.frequency_id') ->join('contacts', 'contacts.client_id', '=', 'clients.id') @@ -79,7 +102,22 @@ class InvoiceRepository extends BaseRepository ->where('invoices.is_recurring', '=', true) ->where('contacts.is_primary', '=', true) ->where('clients.deleted_at', '=', null) - ->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', 'clients.currency_id', 'contacts.first_name', 'contacts.last_name', 'contacts.email', 'invoices.deleted_at', 'invoices.is_deleted'); + ->select( + DB::raw('COALESCE(clients.currency_id, accounts.currency_id) currency_id'), + DB::raw('COALESCE(clients.country_id, accounts.country_id) country_id'), + 'clients.public_id as client_public_id', + 'clients.name as client_name', + 'invoices.public_id', + 'invoices.amount', + 'frequencies.name as frequency', + 'invoices.start_date', + 'invoices.end_date', + 'contacts.first_name', + 'contacts.last_name', + 'contacts.email', + 'invoices.deleted_at', + 'invoices.is_deleted' + ); if ($clientPublicId) { $query->where('clients.public_id', '=', $clientPublicId); @@ -101,7 +139,8 @@ class InvoiceRepository extends BaseRepository public function getClientDatatable($contactId, $entityType, $search) { - $query = \DB::table('invitations') + $query = DB::table('invitations') + ->join('accounts', 'accounts.id', '=', 'invitations.account_id') ->join('invoices', 'invoices.id', '=', 'invitations.invoice_id') ->join('clients', 'clients.id', '=', 'invoices.client_id') ->where('invitations.contact_id', '=', $contactId) @@ -110,18 +149,36 @@ class InvoiceRepository extends BaseRepository ->where('invoices.is_deleted', '=', false) ->where('clients.deleted_at', '=', null) ->where('invoices.is_recurring', '=', false) - ->select('invitation_key', 'invoice_number', 'invoice_date', 'invoices.balance as balance', 'due_date', 'clients.public_id as client_public_id', 'clients.name as client_name', 'invoices.public_id', 'amount', 'start_date', 'end_date', 'clients.currency_id', 'invoices.partial'); + ->select( + DB::raw('COALESCE(clients.currency_id, accounts.currency_id) currency_id'), + DB::raw('COALESCE(clients.country_id, accounts.country_id) country_id'), + 'invitations.invitation_key', + 'invoices.invoice_number', + 'invoices.invoice_date', + 'invoices.balance as balance', + 'invoices.due_date', + 'clients.public_id as client_public_id', + 'clients.name as client_name', + 'invoices.public_id', + 'invoices.amount', + 'invoices.start_date', + 'invoices.end_date', + 'invoices.partial' + ); $table = \Datatable::query($query) ->addColumn('invoice_number', function ($model) use ($entityType) { return link_to('/view/'.$model->invitation_key, $model->invoice_number); }) ->addColumn('invoice_date', function ($model) { return Utils::fromSqlDate($model->invoice_date); }) - ->addColumn('amount', function ($model) { return Utils::formatMoney($model->amount, $model->currency_id); }); + ->addColumn('amount', function ($model) { return Utils::formatMoney($model->amount, $model->currency_id, $model->country_id); }); if ($entityType == ENTITY_INVOICE) { $table->addColumn('balance', function ($model) { return $model->partial > 0 ? - trans('texts.partial_remaining', ['partial' => Utils::formatMoney($model->partial, $model->currency_id), 'balance' => Utils::formatMoney($model->balance, $model->currency_id)]) : - Utils::formatMoney($model->balance, $model->currency_id); + trans('texts.partial_remaining', [ + 'partial' => Utils::formatMoney($model->partial, $model->currency_id, $model->country_id), + 'balance' => Utils::formatMoney($model->balance, $model->currency_id, $model->country_id) + ]) : + Utils::formatMoney($model->balance, $model->currency_id, $model->country_id); }); } @@ -133,7 +190,7 @@ class InvoiceRepository extends BaseRepository { $account = \Auth::user()->account; $publicId = isset($data['public_id']) ? $data['public_id'] : false; - + $isNew = !$publicId || $publicId == '-1'; if ($isNew) { @@ -259,7 +316,7 @@ class InvoiceRepository extends BaseRepository $total *= (100 - $invoice->discount) / 100; } } - + if (isset($data['custom_value1'])) { $invoice->custom_value1 = round($data['custom_value1'], 2); if ($isNew) { @@ -272,7 +329,7 @@ class InvoiceRepository extends BaseRepository $invoice->custom_taxes2 = $account->custom_invoice_taxes2 ?: false; } } - + if (isset($data['custom_text_value1'])) { $invoice->custom_text_value1 = trim($data['custom_text_value1']); } @@ -324,7 +381,7 @@ class InvoiceRepository extends BaseRepository $task->invoice_id = $invoice->id; $task->client_id = $invoice->client_id; $task->save(); - } else if (isset($item['product_key']) && $item['product_key'] && !$invoice->has_tasks) { + } elseif (isset($item['product_key']) && $item['product_key'] && !$invoice->has_tasks) { $product = Product::findProductByKey(trim($item['product_key'])); if (\Auth::user()->account->update_products) { @@ -373,7 +430,7 @@ class InvoiceRepository extends BaseRepository if ($account->quote_number_prefix && strpos($invoiceNumber, $account->quote_number_prefix) === 0) { $invoiceNumber = substr($invoiceNumber, strlen($account->quote_number_prefix)); } - $invoiceNumber = $account->invoice_number_prefix . $invoiceNumber; + $invoiceNumber = $account->invoice_number_prefix.$invoiceNumber; if (Invoice::scope()->withTrashed()->whereInvoiceNumber($invoiceNumber)->first()) { $invoiceNumber = false; } @@ -405,7 +462,7 @@ class InvoiceRepository extends BaseRepository 'custom_taxes2', 'partial', 'custom_text_value1', - 'custom_text_value2'] as $field) { + 'custom_text_value2', ] as $field) { $clone->$field = $invoice->$field; } @@ -508,7 +565,7 @@ class InvoiceRepository extends BaseRepository $invoice = Invoice::createNew($recurInvoice); $invoice->client_id = $recurInvoice->client_id; $invoice->recurring_invoice_id = $recurInvoice->id; - $invoice->invoice_number = 'R' . $recurInvoice->account->getNextInvoiceNumber($recurInvoice); + $invoice->invoice_number = 'R'.$recurInvoice->account->getNextInvoiceNumber($recurInvoice); $invoice->amount = $recurInvoice->amount; $invoice->balance = $recurInvoice->amount; $invoice->invoice_date = date_create()->format('Y-m-d'); @@ -572,19 +629,19 @@ class InvoiceRepository extends BaseRepository public function findNeedingReminding($account) { $dates = []; - for ($i=1; $i<=3; $i++) { + for ($i = 1; $i <= 3; $i++) { $field = "enable_reminder{$i}"; if (!$account->$field) { continue; } $field = "num_days_reminder{$i}"; - $dates[] = "due_date = '" . date('Y-m-d', strtotime("- {$account->$field} days")) . "'"; + $dates[] = "due_date = '".date('Y-m-d', strtotime("- {$account->$field} days"))."'"; } $sql = implode(' OR ', $dates); $invoices = Invoice::whereAccountId($account->id) ->where('balance', '>', 0) - ->whereRaw('(' . $sql . ')') + ->whereRaw('('.$sql.')') ->get(); return $invoices; diff --git a/app/Ninja/Repositories/PaymentRepository.php b/app/Ninja/Repositories/PaymentRepository.php index 158dd0637fd8..e0f4ba10ef58 100644 --- a/app/Ninja/Repositories/PaymentRepository.php +++ b/app/Ninja/Repositories/PaymentRepository.php @@ -1,5 +1,6 @@ join('accounts', 'accounts.id', '=', 'payments.account_id') ->join('clients', 'clients.id', '=', 'payments.client_id') ->join('invoices', 'invoices.id', '=', 'payments.invoice_id') ->join('contacts', 'contacts.client_id', '=', 'clients.id') @@ -29,6 +31,8 @@ class PaymentRepository extends BaseRepository ->where('contacts.deleted_at', '=', null) ->where('invoices.is_deleted', '=', false) ->select('payments.public_id', + DB::raw('COALESCE(clients.currency_id, accounts.currency_id) currency_id'), + DB::raw('COALESCE(clients.country_id, accounts.country_id) country_id'), 'payments.transaction_reference', 'clients.name as client_name', 'clients.public_id as client_public_id', @@ -36,7 +40,6 @@ class PaymentRepository extends BaseRepository 'payments.payment_date', 'invoices.public_id as invoice_public_id', 'invoices.invoice_number', - 'clients.currency_id', 'contacts.first_name', 'contacts.last_name', 'contacts.email', @@ -67,7 +70,8 @@ class PaymentRepository extends BaseRepository public function findForContact($contactId = null, $filter = null) { - $query = \DB::table('payments') + $query = DB::table('payments') + ->join('accounts', 'accounts.id', '=', 'payments.account_id') ->join('clients', 'clients.id', '=', 'payments.client_id') ->join('invoices', 'invoices.id', '=', 'payments.invoice_id') ->join('contacts', 'contacts.client_id', '=', 'clients.id') @@ -81,7 +85,24 @@ class PaymentRepository extends BaseRepository ->where('invitations.deleted_at', '=', null) ->where('invoices.deleted_at', '=', null) ->where('invitations.contact_id', '=', $contactId) - ->select('invitations.invitation_key', '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', 'clients.currency_id', 'contacts.first_name', 'contacts.last_name', 'contacts.email', 'payment_types.name as payment_type', 'payments.account_gateway_id'); + ->select( + DB::raw('COALESCE(clients.currency_id, accounts.currency_id) currency_id'), + DB::raw('COALESCE(clients.country_id, accounts.country_id) country_id'), + 'invitations.invitation_key', + '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', + 'contacts.first_name', + 'contacts.last_name', + 'contacts.email', + 'payment_types.name as payment_type', + 'payments.account_gateway_id' + ); if ($filter) { $query->where(function ($query) use ($filter) { diff --git a/app/Services/ActivityService.php b/app/Services/ActivityService.php index 8458d93b5479..8718f3ee72b9 100644 --- a/app/Services/ActivityService.php +++ b/app/Services/ActivityService.php @@ -44,7 +44,7 @@ class ActivityService extends BaseService 'quote' => $model->invoice ? link_to('/quotes/' . $model->invoice_public_id, $model->invoice) : null, 'contact' => $model->contact_id ? link_to('/clients/' . $model->client_public_id, Utils::getClientDisplayName($model)) : Utils::getPersonDisplayName($model->user_first_name, $model->user_last_name, $model->user_email), 'payment' => $model->payment ?: '', - 'credit' => Utils::formatMoney($model->credit, $model->currency_id) + 'credit' => Utils::formatMoney($model->credit, $model->currency_id, $model->country_id) ]; return trans("texts.activity_{$model->activity_type_id}", $data); @@ -53,13 +53,13 @@ class ActivityService extends BaseService [ 'balance', function ($model) { - return Utils::formatMoney($model->balance, $model->currency_id); + return Utils::formatMoney($model->balance, $model->currency_id, $model->country_id); } ], [ 'adjustment', function ($model) { - return $model->adjustment != 0 ? Utils::wrapAdjustment($model->adjustment, $model->currency_id) : ''; + return $model->adjustment != 0 ? Utils::wrapAdjustment($model->adjustment, $model->currency_id, $model->country_id) : ''; } ] ]; diff --git a/app/Services/ClientService.php b/app/Services/ClientService.php index 3093df1f3ae6..7490dc8739b4 100644 --- a/app/Services/ClientService.php +++ b/app/Services/ClientService.php @@ -76,7 +76,7 @@ class ClientService extends BaseService [ 'balance', function ($model) { - return Utils::formatMoney($model->balance, $model->currency_id); + return Utils::formatMoney($model->balance, $model->currency_id, $model->country_id); } ] ]; diff --git a/app/Services/CreditService.php b/app/Services/CreditService.php index 0ee836ae76bb..87aa872c5dea 100644 --- a/app/Services/CreditService.php +++ b/app/Services/CreditService.php @@ -47,13 +47,13 @@ class CreditService extends BaseService [ 'amount', function ($model) { - return Utils::formatMoney($model->amount, $model->currency_id) . ''; + return Utils::formatMoney($model->amount, $model->currency_id, $model->country_id) . ''; } ], [ 'balance', function ($model) { - return Utils::formatMoney($model->balance, $model->currency_id); + return Utils::formatMoney($model->balance, $model->currency_id, $model->country_id); } ], [ diff --git a/app/Services/InvoiceService.php b/app/Services/InvoiceService.php index a40d3bb8fec3..d2f73f58f65c 100644 --- a/app/Services/InvoiceService.php +++ b/app/Services/InvoiceService.php @@ -116,7 +116,7 @@ class InvoiceService extends BaseService [ 'amount', function ($model) { - return Utils::formatMoney($model->amount, $model->currency_id); + return Utils::formatMoney($model->amount, $model->currency_id, $model->country_id); } ], [ @@ -124,10 +124,10 @@ class InvoiceService extends BaseService function ($model) { return $model->partial > 0 ? trans('texts.partial_remaining', [ - 'partial' => Utils::formatMoney($model->partial, $model->currency_id), - 'balance' => Utils::formatMoney($model->balance, $model->currency_id)] + 'partial' => Utils::formatMoney($model->partial, $model->currency_id, $model->country_id), + 'balance' => Utils::formatMoney($model->balance, $model->currency_id, $model->country_id)] ) : - Utils::formatMoney($model->balance, $model->currency_id); + Utils::formatMoney($model->balance, $model->currency_id, $model->country_id); }, $entityType == ENTITY_INVOICE ], diff --git a/app/Services/PaymentService.php b/app/Services/PaymentService.php index eee8c814f268..7f3d9c52d7a2 100644 --- a/app/Services/PaymentService.php +++ b/app/Services/PaymentService.php @@ -287,7 +287,7 @@ class PaymentService extends BaseService [ 'amount', function ($model) { - return Utils::formatMoney($model->amount, $model->currency_id); + return Utils::formatMoney($model->amount, $model->currency_id, $model->country_id); } ], [ diff --git a/app/Services/RecurringInvoiceService.php b/app/Services/RecurringInvoiceService.php index 25a9fb12dcb6..9adb344a137c 100644 --- a/app/Services/RecurringInvoiceService.php +++ b/app/Services/RecurringInvoiceService.php @@ -53,7 +53,7 @@ class RecurringInvoiceService extends BaseService [ 'amount', function ($model) { - return Utils::formatMoney($model->amount, $model->currency_id); + return Utils::formatMoney($model->amount, $model->currency_id, $model->country_id); } ] ]; diff --git a/database/seeds/PaymentLibrariesSeeder.php b/database/seeds/PaymentLibrariesSeeder.php index 83ab9f35b9f3..6a64774d6925 100644 --- a/database/seeds/PaymentLibrariesSeeder.php +++ b/database/seeds/PaymentLibrariesSeeder.php @@ -267,8 +267,9 @@ class PaymentLibrariesSeeder extends Seeder 'AR' => [ 'swap_postal_code' => true, ], - 'AT' => [ + 'AT' => [ // Austria 'swap_postal_code' => true, + 'swap_currency_symbol' => true, ], 'BE' => [ 'swap_postal_code' => true, diff --git a/public/css/built.css b/public/css/built.css index 94203d9c4b58..94e81164bd99 100644 --- a/public/css/built.css +++ b/public/css/built.css @@ -3381,19 +3381,4 @@ ul.user-accounts a:hover div.remove { div.panel-body div.panel-body { padding-bottom: 0px; -} - -.email-button { - border: 0 none; - border-radius: 36px; - - padding: 12px 45px; - margin: 0 10px; - - cursor: pointer; - display: inline-block; - - font-size: 14px; - color: #fff; - text-transform: none; } \ No newline at end of file diff --git a/public/js/built.js b/public/js/built.js index 82cf121b6a69..e01ee5ea0aa9 100644 --- a/public/js/built.js +++ b/public/js/built.js @@ -29911,15 +29911,7 @@ function generatePDF(invoice, javascript, force, cb) { return; } invoiceOld = invoice; - pdfmakeMarker = "{"; - if(javascript.slice(0, pdfmakeMarker.length) === pdfmakeMarker) { - doc = GetPdfMake(invoice, javascript, cb); - } else { - doc = GetPdf(invoice, javascript); - doc.getDataUrl = function(cb) { - cb( this.output("datauristring")); - }; - } + doc = GetPdfMake(invoice, javascript, cb); if (cb) { doc.getDataUrl(cb); @@ -29933,135 +29925,6 @@ function copyObject(orig) { return JSON.parse(JSON.stringify(orig)); } - -function GetPdf(invoice, javascript){ - var layout = { - accountTop: 40, - marginLeft: 50, - marginRight: 550, - headerTop: 150, - headerLeft: 360, - headerRight: 550, - rowHeight: 15, - tableRowHeight: 10, - footerLeft: 420, - tablePadding: 12, - tableTop: 250, - descriptionLeft: 150, - unitCostRight: 410, - qtyRight: 480, - taxRight: 480, - lineTotalRight: 550 - }; - - /* - if (invoice.has_taxes) - { - layout.descriptionLeft -= 20; - layout.unitCostRight -= 40; - layout.qtyRight -= 40; - } - */ - - /* - @param orientation One of "portrait" or "landscape" (or shortcuts "p" (Default), "l") - @param unit Measurement unit to be used when coordinates are specified. One of "pt" (points), "mm" (Default), "cm", "in" - @param format One of 'a3', 'a4' (Default),'a5' ,'letter' ,'legal' - @returns {jsPDF} - */ - var doc = new jsPDF('portrait', 'pt', 'a4'); - - //doc.getStringUnitWidth = function(param) { console.log('getStringUnitWidth: %s', param); return 0}; - - //Set PDF properities - doc.setProperties({ - title: 'Invoice ' + invoice.invoice_number, - subject: '', - author: 'InvoiceNinja.com', - keywords: 'pdf, invoice', - creator: 'InvoiceNinja.com' - }); - - //set default style for report - doc.setFont('Helvetica',''); - - // For partial payments show "Amount Due" rather than "Balance Due" - if (!invoiceLabels.balance_due_orig) { - invoiceLabels.balance_due_orig = invoiceLabels.balance_due; - } - invoiceLabels.balance_due = NINJA.parseFloat(invoice.partial) ? invoiceLabels.amount_due : invoiceLabels.balance_due_orig; - - eval(javascript); - - // add footer - if (invoice.invoice_footer) { - doc.setFontType('normal'); - doc.setFontSize('8'); - SetPdfColor(invoice.invoice_design_id == 2 || invoice.invoice_design_id == 3 ? 'White' : 'Black',doc); - var top = doc.internal.pageSize.height - layout.marginLeft; - if (!invoice.is_pro) top -= 25; - var footer = doc.splitTextToSize(processVariables(invoice.invoice_footer), 500); - var numLines = footer.length - 1; - doc.text(layout.marginLeft, top - (numLines * 8), footer); - } - - return doc; -} - - -function SetPdfColor(color, doc, role) -{ - if (role === 'primary' && NINJA.primaryColor) { - return setDocHexColor(doc, NINJA.primaryColor); - } else if (role === 'secondary' && NINJA.secondaryColor) { - return setDocHexColor(doc, NINJA.secondaryColor); - } - - if (color=='LightBlue') { - return doc.setTextColor(41,156, 194); - } - - if (color=='Black') { - return doc.setTextColor(46,43,43);//select color black - } - if (color=='GrayLogo') { - return doc.setTextColor(207,241, 241);//select color Custom Report GRAY - } - - if (color=='GrayBackground') { - return doc.setTextColor(251,251, 251);//select color Custom Report GRAY - } - - if (color=='GrayText') { - return doc.setTextColor(161,160,160);//select color Custom Report GRAY Colour - } - - if (color=='White') { - return doc.setTextColor(255,255,255);//select color Custom Report GRAY Colour - } - - if (color=='SomeGreen') { - return doc.setTextColor(54,164,152);//select color Custom Report GRAY Colour - } - - if (color=='LightGrayReport2-gray') { - return doc.setTextColor(240,240,240);//select color Custom Report GRAY Colour - } - - if (color=='LightGrayReport2-white') { - return doc.setTextColor(251,251,251);//select color Custom Report GRAY Colour - } - - if (color=='orange') { - return doc.setTextColor(234,121,45);//select color Custom Report GRAY Colour - } - - if (color=='Green') { - return doc.setTextColor(55,109,69); - } -} - - /* Handle converting variables in the invoices (ie, MONTH+1) */ function processVariables(str) { if (!str) return ''; @@ -30494,8 +30357,8 @@ function populateInvoiceComboboxes(clientId, invoiceId) { var client = clientMap[invoice.client.public_id]; if (!client) continue; // client is deleted/archived $invoiceCombobox.append(new Option(invoice.invoice_number + ' - ' + invoice.invoice_status.name + ' - ' + - getClientDisplayName(client) + ' - ' + formatMoney(invoice.amount, client.currency_id) + ' | ' + - formatMoney(invoice.balance, client.currency_id), invoice.public_id)); + getClientDisplayName(client) + ' - ' + formatMoneyInvoice(invoice.amount, invoice) + ' | ' + + formatMoneyInvoice(invoice.balance, invoice), invoice.public_id)); } $('select#invoice').combobox('refresh'); }); @@ -30506,6 +30369,7 @@ function populateInvoiceComboboxes(clientId, invoiceId) { if (invoiceId) { var invoice = invoiceMap[invoiceId]; var client = clientMap[invoice.client.public_id]; + invoice.client = client; setComboboxValue($('.client-select'), client.public_id, getClientDisplayName(client)); if (!parseFloat($('#amount').val())) { $('#amount').val(parseFloat(invoice.balance).toFixed(2)); @@ -30518,9 +30382,10 @@ function populateInvoiceComboboxes(clientId, invoiceId) { if (invoiceId) { var invoice = invoiceMap[invoiceId]; var client = clientMap[invoice.client.public_id]; + invoice.client = client; setComboboxValue($('.invoice-select'), invoice.public_id, (invoice.invoice_number + ' - ' + invoice.invoice_status.name + ' - ' + getClientDisplayName(client) + ' - ' + - formatMoney(invoice.amount, client.currency_id) + ' | ' + formatMoney(invoice.balance, client.currency_id))); + formatMoneyInvoice(invoice.amount, invoice) + ' | ' + formatMoneyInvoice(invoice.balance, invoice))); $invoiceSelect.trigger('change'); } else if (clientId) { var client = clientMap[clientId]; @@ -30542,174 +30407,6 @@ CONSTS.INVOICE_STATUS_PAID = 5; $.fn.datepicker.defaults.autoclose = true; $.fn.datepicker.defaults.todayHighlight = true; - - - - -function displayAccount(doc, invoice, x, y, layout) { - var account = invoice.account; - - if (!account) { - return; - } - - var data1 = [ - account.name, - account.id_number, - account.vat_number, - account.work_email, - account.work_phone - ]; - - var data2 = [ - concatStrings(account.address1, account.address2), - concatStrings(account.city, account.state, account.postal_code), - account.country ? account.country.name : false, - invoice.account.custom_value1 ? invoice.account['custom_label1'] + ' ' + invoice.account.custom_value1 : false, - invoice.account.custom_value2 ? invoice.account['custom_label2'] + ' ' + invoice.account.custom_value2 : false, - ]; - - if (layout.singleColumn) { - - displayGrid(doc, invoice, data1.concat(data2), x, y, layout, {hasHeader:true}); - - } else { - - displayGrid(doc, invoice, data1, x, y, layout, {hasHeader:true}); - - var nameWidth = account.name ? (doc.getStringUnitWidth(account.name) * doc.internal.getFontSize() * 1.1) : 0; - var emailWidth = account.work_email ? (doc.getStringUnitWidth(account.work_email) * doc.internal.getFontSize() * 1.1) : 0; - width = Math.max(emailWidth, nameWidth, 120); - x += width; - - displayGrid(doc, invoice, data2, x, y, layout); - } -} - - -function displayClient(doc, invoice, x, y, layout) { - var client = invoice.client; - if (!client) { - return; - } - var data = [ - getClientDisplayName(client), - client.id_number, - client.vat_number, - concatStrings(client.address1, client.address2), - concatStrings(client.city, client.state, client.postal_code), - client.country ? client.country.name : false, - invoice.contact && getClientDisplayName(client) != invoice.contact.email ? invoice.contact.email : false, - invoice.client.custom_value1 ? invoice.account['custom_client_label1'] + ' ' + invoice.client.custom_value1 : false, - invoice.client.custom_value2 ? invoice.account['custom_client_label2'] + ' ' + invoice.client.custom_value2 : false, - ]; - return displayGrid(doc, invoice, data, x, y, layout, {hasheader:true}); -} - -function displayInvoice(doc, invoice, x, y, layout, rightAlignX) { - if (!invoice) { - return; - } - - var data = getInvoiceDetails(invoice); - var options = { - hasheader: true, - rightAlignX: rightAlignX, - }; - - return displayGrid(doc, invoice, data, x, y, layout, options); -} - -function getInvoiceDetails(invoice) { - var fields = [ - {'invoice_number': invoice.invoice_number}, - {'po_number': invoice.po_number}, - {'invoice_date': invoice.invoice_date}, - {'due_date': invoice.due_date}, - ]; - - if (NINJA.parseFloat(invoice.balance) < NINJA.parseFloat(invoice.amount)) { - fields.push({'total': formatMoney(invoice.amount, invoice.client.currency_id)}); - } - - if (NINJA.parseFloat(invoice.partial)) { - fields.push({'balance': formatMoney(invoice.total_amount, invoice.client.currency_id)}); - } - - fields.push({'balance_due': formatMoney(invoice.balance_amount, invoice.client.currency_id)}) - - return fields; -} - -function getInvoiceDetailsHeight(invoice, layout) { - var data = getInvoiceDetails(invoice); - var count = 0; - for (var key in data) { - if (!data.hasOwnProperty(key)) { - continue; - } - var obj = data[key]; - for (var subKey in obj) { - if (!obj.hasOwnProperty(subKey)) { - continue; - } - if (obj[subKey]) { - count++; - } - } - } - return count * layout.rowHeight; -} - -function displaySubtotals(doc, layout, invoice, y, rightAlignTitleX) -{ - if (!invoice) { - return; - } - - 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} - ]; - - if (NINJA.parseFloat(invoice.custom_value1) && invoice.custom_taxes1 == '1') { - data.push({'custom_invoice_label1': formatMoney(invoice.custom_value1, invoice.client.currency_id) }) - } - if (NINJA.parseFloat(invoice.custom_value2) && invoice.custom_taxes2 == '1') { - data.push({'custom_invoice_label2': formatMoney(invoice.custom_value2, invoice.client.currency_id) }) - } - - data.push({'tax': (invoice.tax && invoice.tax.name) || invoice.tax_name ? formatMoney(invoice.tax_amount, invoice.client.currency_id) : false}); - - if (NINJA.parseFloat(invoice.custom_value1) && invoice.custom_taxes1 != '1') { - data.push({'custom_invoice_label1': formatMoney(invoice.custom_value1, invoice.client.currency_id) }) - } - if (NINJA.parseFloat(invoice.custom_value2) && invoice.custom_taxes2 != '1') { - data.push({'custom_invoice_label2': formatMoney(invoice.custom_value2, invoice.client.currency_id) }) - } - - var paid = invoice.amount - invoice.balance; - if (paid) { - data.push({'total': formatMoney(invoice.amount, invoice.client.currency_id)}); - } - - if (invoice.account.hide_paid_to_date != '1' || paid) { - data.push({'paid_to_date': formatMoney(paid, invoice.client.currency_id)}); - } - - if (NINJA.parseFloat(invoice.partial) && invoice.total_amount != invoice.subtotal_amount) { - data.push({'balance': formatMoney(invoice.total_amount, invoice.client.currency_id)}); - } - - var options = { - hasheader: true, - rightAlignX: 550, - rightAlignTitleX: rightAlignTitleX - }; - - return displayGrid(doc, invoice, data, 300, y, layout, options) + 10; -} - function formatAddress(city, state, zip, swap) { var str = ''; if (swap) { @@ -30745,106 +30442,6 @@ function concatStrings() { return data.length ? concatStr : ""; } -function displayGrid(doc, invoice, data, x, y, layout, options) { - var numLines = 0; - var origY = y; - for (var i=0; i 0 && origY === layout.accountTop) { - SetPdfColor('GrayText',doc); - } - - var row = data[i]; - if (!row) { - continue; - } - - if (options && (options.hasheader && i === 0 && !options.rightAlignTitleX)) { - doc.setFontType('bold'); - } - - if (typeof row === 'object') { - for (var key in row) { - if (row.hasOwnProperty(key)) { - var value = row[key] ? row[key] + '' : false; - } - } - if (!value) { - continue; - } - - var marginLeft; - if (options.rightAlignX) { - marginLeft = options.rightAlignX - (doc.getStringUnitWidth(value) * doc.internal.getFontSize()); - } else { - marginLeft = x + 80; - } - doc.text(marginLeft, y, value); - - doc.setFontType('normal'); - if (invoice.is_quote) { - if (key == 'invoice_number') { - key = 'quote_number'; - } else if (key == 'invoice_date') { - key = 'quote_date'; - } else if (key == 'balance_due') { - key = 'total'; - } - } - - if (key.substring(0, 6) === 'custom') { - key = invoice.account[key]; - } else if (key === 'tax' && invoice.tax_name) { - key = invoice.tax_name + ' ' + (invoice.tax_rate*1).toString() + '%'; - } else if (key === 'discount' && NINJA.parseFloat(invoice.discount) && !parseInt(invoice.is_amount_discount)) { - key = invoiceLabels[key] + ' ' + parseFloat(invoice.discount) + '%'; - } else { - key = invoiceLabels[key]; - } - - if (options.rightAlignTitleX) { - marginLeft = options.rightAlignTitleX - (doc.getStringUnitWidth(key) * doc.internal.getFontSize()); - } else { - marginLeft = x; - } - - doc.text(marginLeft, y, key); - } else { - doc.text(x, y, row); - } - - numLines++; - y += layout.rowHeight; - } - - return numLines * layout.rowHeight; -} - -function displayNotesAndTerms(doc, layout, invoice, y) -{ - doc.setFontType("normal"); - var origY = y; - - if (invoice.public_notes) { - var notes = doc.splitTextToSize(processVariables(invoice.public_notes), 260); - doc.text(layout.marginLeft, y, notes); - y += 16 + (notes.length * doc.internal.getFontSize()); - } - - if (invoice.terms) { - var terms = doc.splitTextToSize(processVariables(invoice.terms), 260); - doc.setFontType("bold"); - doc.text(layout.marginLeft, y, invoiceLabels.terms); - y += 16; - doc.setFontType("normal"); - doc.text(layout.marginLeft, y, terms); - y += 16 + (terms.length * doc.internal.getFontSize()); - } - - return y - origY; -} - function calculateAmounts(invoice) { var total = 0; var hasTaxes = false; @@ -30968,311 +30565,6 @@ function getInvoiceTaxRate(invoice) { return tax; } -function displayInvoiceHeader(doc, invoice, layout) { - - if (invoice.invoice_design_id == 6 || invoice.invoice_design_id == 8 || invoice.invoice_design_id == 10) { - invoiceLabels.item = invoiceLabels.item.toUpperCase(); - invoiceLabels.description = invoiceLabels.description.toUpperCase(); - invoiceLabels.unit_cost = invoiceLabels.unit_cost.toUpperCase(); - invoiceLabels.quantity = invoiceLabels.quantity.toUpperCase(); - invoiceLabels.line_total = invoiceLabels.total.toUpperCase(); - invoiceLabels.tax = invoiceLabels.tax.toUpperCase(); - } - - 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, invoiceLabels.item); - doc.text(layout.descriptionLeft, layout.tableTop, invoiceLabels.description); - doc.text(costX, layout.tableTop, invoiceLabels.unit_cost); - if (invoice.account.hide_quantity != '1') { - doc.text(qtyX, layout.tableTop, invoiceLabels.quantity); - } - doc.text(totalX, layout.tableTop, invoiceLabels.line_total); - - /* - if (invoice.has_taxes) - { - doc.text(taxX, layout.tableTop, invoiceLabels.tax); - } - */ -} - -function displayInvoiceItems(doc, invoice, layout) { - doc.setFontType("normal"); - - var line = 1; - var total = 0; - var shownItem = false; - var currencyId = invoice && invoice.client ? invoice.client.currency_id : 1; - var tableTop = layout.tableTop; - var hideQuantity = invoice.account.hide_quantity == '1'; - - doc.setFontSize(8); - for (var i=0; i 770) { - line = 0; - tableTop = layout.accountTop + layout.tablePadding; - y = tableTop + (2 * layout.tablePadding); - top = y - layout.tablePadding; - newTop = top + (numLines * layout.tableRowHeight); - doc.addPage(); - } - - var left = layout.marginLeft - layout.tablePadding; - var width = layout.marginRight + layout.tablePadding; - - // process date variables - if (invoice.is_recurring) { - notes = processVariables(notes); - productKey = processVariables(productKey); - } - - var lineTotal = roundToTwo(NINJA.parseFloat(item.cost)) * roundToTwo(NINJA.parseFloat(item.qty)); - if (tax) { - lineTotal += lineTotal * tax / 100; - } - if (lineTotal) { - total += lineTotal; - } - lineTotal = formatMoney(lineTotal, currencyId); - - - var costX = layout.unitCostRight - (doc.getStringUnitWidth(cost) * doc.internal.getFontSize()); - var qtyX = layout.qtyRight - (doc.getStringUnitWidth(qty) * doc.internal.getFontSize()); - var taxX = layout.taxRight - (doc.getStringUnitWidth(tax+'%') * doc.internal.getFontSize()); - var totalX = layout.lineTotalRight - (doc.getStringUnitWidth(lineTotal) * doc.internal.getFontSize()); - //if (i==0) y -= 4; - - line += numLines; - - - if (invoice.invoice_design_id == 1) { - if (i%2 == 0) { - doc.setDrawColor(255,255,255); - doc.setFillColor(246,246,246); - doc.rect(left, top, width-left, newTop-top, 'FD'); - - doc.setLineWidth(0.3); - doc.setDrawColor(200,200,200); - doc.line(left, top, width, top); - doc.line(left, newTop, width, newTop); - } - } else if (invoice.invoice_design_id == 2) { - if (i%2 == 0) { - left = 0; - width = 1000; - - doc.setDrawColor(255,255,255); - doc.setFillColor(235,235,235); - doc.rect(left, top, width-left, newTop-top, 'FD'); - - } - } else if (invoice.invoice_design_id == 5) { - if (i%2 == 0) { - doc.setDrawColor(255,255,255); - doc.setFillColor(247,247,247); - doc.rect(left, top, width-left+17, newTop-top, 'FD'); - } else { - doc.setDrawColor(255,255,255); - doc.setFillColor(232,232,232); - doc.rect(left, top, width-left+17, newTop-top, 'FD'); - } - } else if (invoice.invoice_design_id == 6) { - if (i%2 == 0) { - doc.setDrawColor(232,232,232); - doc.setFillColor(232,232,232); - doc.rect(left, top, width-left, newTop-top, 'FD'); - } else { - doc.setDrawColor(255,255,255); - doc.setFillColor(255,255,255); - doc.rect(left, top, width-left, newTop-top, 'FD'); - } - } else if (invoice.invoice_design_id == 7) { - doc.setLineWidth(1); - doc.setDrawColor(45,35,32); - for(var k = 1; k<=width-20; k++) { - doc.line(left+4+k,newTop,left+4+1+k,newTop); - k = k+3; - } - } else if (invoice.invoice_design_id == 8) { - - } else if (invoice.invoice_design_id == 9) { - doc.setLineWidth(1); - doc.setDrawColor(0,157,145); - for(var j = 1; j<=width-40; j++) { - doc.line(left+j,newTop,left+2+j,newTop); - j = j+5; - } - } else if (invoice.invoice_design_id == 10) { - doc.setLineWidth(0.3); - doc.setDrawColor(63,60,60); - doc.line(left, newTop, width, newTop); - } else { - doc.setLineWidth(0.3); - doc.setDrawColor(150,150,150); - doc.line(left, newTop, width, newTop); - } - - y += 4; - - if (invoice.invoice_design_id == 1) { - SetPdfColor('LightBlue', doc, 'primary'); - } else if (invoice.invoice_design_id == 2) { - SetPdfColor('SomeGreen', doc, 'primary'); - } else if (invoice.invoice_design_id == 3) { - doc.setFontType('bold'); - } else if (invoice.invoice_design_id == 4) { - SetPdfColor('Black', doc); - } else if (invoice.invoice_design_id == 5) { - SetPdfColor('Black', doc); - } else if (invoice.invoice_design_id == 6) { - SetPdfColor('Black', doc); - } - - - var splitTitle = doc.splitTextToSize(productKey, 60); - if(invoice.invoice_design_id == 6) { - doc.setFontType('bold'); - } - if(invoice.invoice_design_id == 9) { - doc.setTextColor(187,51,40); - } - if(invoice.invoice_design_id == 10) { - doc.setTextColor(205,81,56); - } - doc.text(layout.marginLeft, y+2, splitTitle); - - if (invoice.invoice_design_id == 5) { - - doc.setDrawColor(255, 255, 255); - doc.setLineWidth(1); - doc.line(layout.descriptionLeft-8, y-16,layout.descriptionLeft-8, y+55); - - doc.line(costX-30, y-16,costX-30, y+55); - - doc.line(qtyX-45, y-16,qtyX-45, y+55); - - /* - if (invoice.has_taxes) { - doc.line(taxX-15, y-16,taxX-15, y+55); - } - */ - doc.line(totalX-27, y-16,totalX-27, y+55); - - } - /* - if (invoice.invoice_design_id == 8) { - - doc.setDrawColor(30, 30, 30); - doc.setLineWidth(0.5); - doc.line(layout.marginLeft-10, y-60,layout.marginLeft-10, y+20); - - doc.line(layout.descriptionLeft-8, y-60,layout.descriptionLeft-8, y+20); - - doc.line(costX-30, y-60,costX-30, y+20); - console.log('CostX: %s', costX); - doc.line(qtyX-45, y-60,qtyX-45, y+20); - - if (invoice.has_taxes) { - doc.line(taxX-10, y-60,taxX-10, y+20); - } - - doc.line(totalX-27, y-60,totalX-27, y+120); - - doc.line(totalX+35, y-60,totalX+35, y+120); - - } - */ - - SetPdfColor('Black', doc); - doc.setFontType('normal'); - - var splitDescription = doc.splitTextToSize(notes, 190); - doc.text(layout.descriptionLeft, y+2, splitDescription); - doc.text(costX, y+2, cost); - if (!hideQuantity) { - doc.text(qtyX, y+2, qty); - } - if(invoice.invoice_design_id == 9) { - doc.setTextColor(187,51,40); - doc.setFontType('bold'); - } - if(invoice.invoice_design_id == 10) { - doc.setTextColor(205,81,56); - } - doc.text(totalX, y+2, lineTotal); - doc.setFontType('normal'); - SetPdfColor('Black', doc); - if (tax) { - doc.text(taxX, y+2, tax+'%'); - } - } - - y = tableTop + (line * layout.tableRowHeight) + (3 * layout.tablePadding); - - if (invoice.invoice_design_id == 8) { - doc.setDrawColor(30, 30, 30); - doc.setLineWidth(0.5); - - var topX = tableTop - 14; - doc.line(layout.marginLeft-10, topX,layout.marginLeft-10, y); - doc.line(layout.descriptionLeft-8, topX,layout.descriptionLeft-8, y); - doc.line(layout.unitCostRight-55, topX,layout.unitCostRight-55, y); - doc.line(layout.qtyRight-50, topX,layout.qtyRight-50, y); - /* - if (invoice.has_taxes) { - doc.line(layout.taxRight-28, topX,layout.taxRight-28, y); - } - */ - doc.line(totalX-25, topX,totalX-25, y+90); - doc.line(totalX+45, topX,totalX+45, y+90); - } - - var cutoff = 700; - if (invoice.terms) { - cutoff -= 50; - } - if (invoice.public_notes) { - cutoff -= 50; - } - - if (y > cutoff) { - doc.addPage(); - return layout.marginLeft; - } - - return y; -} - - // http://stackoverflow.com/questions/11941876/correctly-suppressing-warnings-in-datatables window.alert = (function() { var nativeAlert = window.alert; @@ -31719,7 +31011,7 @@ NINJA.decodeJavascript = function(invoice, javascript) 'subtotalsHeight': (NINJA.subtotals(invoice).length * 16) + 16, 'subtotalsWithoutBalance': NINJA.subtotals(invoice, true), 'subtotalsBalance': NINJA.subtotalsBalance(invoice), - 'balanceDue': formatMoney(invoice.balance_amount, invoice.client.currency_id), + 'balanceDue': formatMoneyInvoice(invoice.balance_amount, invoice), 'invoiceFooter': NINJA.invoiceFooter(invoice), 'invoiceNumber': invoice.invoice_number || ' ', 'entityType': invoice.is_quote ? invoiceLabels.quote : invoiceLabels.invoice, @@ -31849,7 +31141,6 @@ NINJA.taxWidth = function(invoice) NINJA.invoiceLines = function(invoice) { var total = 0; var shownItem = false; - var currencyId = invoice && invoice.client ? invoice.client.currency_id : 1; var hideQuantity = invoice.account.hide_quantity == '1'; var showItemTaxes = invoice.account.show_item_taxes == '1'; @@ -31872,7 +31163,7 @@ NINJA.invoiceLines = function(invoice) { var row = []; var item = invoice.invoice_items[i]; - var cost = formatMoney(item.cost, currencyId, true); + var cost = formatMoneyInvoice(item.cost, invoice, true); var qty = NINJA.parseFloat(item.qty) ? roundToTwo(NINJA.parseFloat(item.qty)) + '' : ''; var notes = item.notes; var productKey = item.product_key; @@ -31903,7 +31194,7 @@ NINJA.invoiceLines = function(invoice) { if (showItemTaxes && tax) { lineTotal += lineTotal * tax / 100; } - lineTotal = formatMoney(lineTotal, currencyId); + lineTotal = formatMoneyInvoice(lineTotal, invoice); rowStyle = (i % 2 == 0) ? 'odd' : 'even'; @@ -31932,49 +31223,49 @@ NINJA.subtotals = function(invoice, hideBalance) var account = invoice.account; var data = []; - data.push([{text: invoiceLabels.subtotal}, {text: formatMoney(invoice.subtotal_amount, invoice.client.currency_id)}]); + data.push([{text: invoiceLabels.subtotal}, {text: formatMoneyInvoice(invoice.subtotal_amount, invoice)}]); if (invoice.discount_amount != 0) { - data.push([{text: invoiceLabels.discount}, {text: formatMoney(invoice.discount_amount, invoice.client.currency_id)}]); + data.push([{text: invoiceLabels.discount}, {text: formatMoneyInvoice(invoice.discount_amount, invoice)}]); } if (NINJA.parseFloat(invoice.custom_value1) && invoice.custom_taxes1 == '1') { - data.push([{text: account.custom_invoice_label1}, {text: formatMoney(invoice.custom_value1, invoice.client.currency_id)}]); + data.push([{text: account.custom_invoice_label1}, {text: formatMoneyInvoice(invoice.custom_value1, invoice)}]); } if (NINJA.parseFloat(invoice.custom_value2) && invoice.custom_taxes2 == '1') { - data.push([{text: account.custom_invoice_label2}, {text: formatMoney(invoice.custom_value2, invoice.client.currency_id)}]); + data.push([{text: account.custom_invoice_label2}, {text: formatMoneyInvoice(invoice.custom_value2, invoice)}]); } for (var key in invoice.item_taxes) { if (invoice.item_taxes.hasOwnProperty(key)) { var taxRate = invoice.item_taxes[key]; var taxStr = taxRate.name + ' ' + (taxRate.rate*1).toString() + '%'; - data.push([{text: taxStr}, {text: formatMoney(taxRate.amount, invoice.client.currency_id)}]); + data.push([{text: taxStr}, {text: formatMoneyInvoice(taxRate.amount, invoice)}]); } } if (invoice.tax && invoice.tax.name || invoice.tax_name) { var taxStr = invoice.tax_name + ' ' + (invoice.tax_rate*1).toString() + '%'; - data.push([{text: taxStr}, {text: formatMoney(invoice.tax_amount, invoice.client.currency_id)}]); + data.push([{text: taxStr}, {text: formatMoneyInvoice(invoice.tax_amount, invoice)}]); } if (NINJA.parseFloat(invoice.custom_value1) && invoice.custom_taxes1 != '1') { - data.push([{text: account.custom_invoice_label1}, {text: formatMoney(invoice.custom_value1, invoice.client.currency_id)}]); + data.push([{text: account.custom_invoice_label1}, {text: formatMoneyInvoice(invoice.custom_value1, invoice)}]); } if (NINJA.parseFloat(invoice.custom_value2) && invoice.custom_taxes2 != '1') { - data.push([{text: account.custom_invoice_label2}, {text: formatMoney(invoice.custom_value2, invoice.client.currency_id)}]); + data.push([{text: account.custom_invoice_label2}, {text: formatMoneyInvoice(invoice.custom_value2, invoice)}]); } var paid = invoice.amount - invoice.balance; if (invoice.account.hide_paid_to_date != '1' || paid) { - data.push([{text:invoiceLabels.paid_to_date}, {text:formatMoney(paid, invoice.client.currency_id)}]); + data.push([{text:invoiceLabels.paid_to_date}, {text:formatMoneyInvoice(paid, invoice)}]); } if (!hideBalance) { var isPartial = NINJA.parseFloat(invoice.partial); data.push([ {text: isPartial ? invoiceLabels.amount_due : invoiceLabels.balance_due, style:['balanceDueLabel']}, - {text: formatMoney(invoice.balance_amount, invoice.client.currency_id), style:['balanceDue']} + {text: formatMoneyInvoice(invoice.balance_amount, invoice), style:['balanceDue']} ]); } @@ -31985,7 +31276,7 @@ NINJA.subtotalsBalance = function(invoice) { var isPartial = NINJA.parseFloat(invoice.partial); return [[ {text: isPartial ? invoiceLabels.amount_due : invoiceLabels.balance_due, style:['balanceDueLabel']}, - {text: formatMoney(invoice.balance_amount, invoice.client.currency_id), style:['balanceDue']} + {text: formatMoneyInvoice(invoice.balance_amount, invoice), style:['balanceDue']} ]]; } @@ -32005,7 +31296,7 @@ NINJA.accountAddress = function(invoice) { var account = invoice.account; var cityStatePostal = ''; if (account.city || account.state || account.postal_code) { - var swap = account.country && account.country.swap_postal_code == '1'; + var swap = account.country && account.country.swap_postal_code; cityStatePostal = formatAddress(account.city, account.state, account.postal_code, swap); } var data = [ @@ -32062,18 +31353,18 @@ NINJA.invoiceDetails = function(invoice) { if (NINJA.parseFloat(invoice.balance) < NINJA.parseFloat(invoice.amount)) { data.push([ {text: invoiceLabels.total}, - {text: formatMoney(invoice.amount, invoice.client.currency_id)} + {text: formatMoneyInvoice(invoice.amount, invoice)} ]); } else if (isPartial) { data.push([ {text: invoiceLabels.total}, - {text: formatMoney(invoice.total_amount, invoice.client.currency_id)} + {text: formatMoneyInvoice(invoice.total_amount, invoice)} ]); } data.push([ {text: isPartial ? invoiceLabels.amount_due : invoiceLabels.balance_due, style: ['invoiceDetailBalanceDueLabel']}, - {text: formatMoney(invoice.balance_amount, invoice.client.currency_id), style: ['invoiceDetailBalanceDue']} + {text: formatMoneyInvoice(invoice.balance_amount, invoice), style: ['invoiceDetailBalanceDue']} ]) return NINJA.prepareDataPairs(data, 'invoiceDetails'); @@ -32092,7 +31383,7 @@ NINJA.clientDetails = function(invoice) { var cityStatePostal = ''; if (client.city || client.state || client.postal_code) { - var swap = client.country && client.country.swap_postal_code == '1'; + var swap = client.country && client.country.swap_postal_code; cityStatePostal = formatAddress(client.city, client.state, client.postal_code, swap); } diff --git a/public/js/pdf.pdfmake.js b/public/js/pdf.pdfmake.js index 49c0b579cd5e..ca40528a4516 100644 --- a/public/js/pdf.pdfmake.js +++ b/public/js/pdf.pdfmake.js @@ -132,7 +132,7 @@ NINJA.decodeJavascript = function(invoice, javascript) 'subtotalsHeight': (NINJA.subtotals(invoice).length * 16) + 16, 'subtotalsWithoutBalance': NINJA.subtotals(invoice, true), 'subtotalsBalance': NINJA.subtotalsBalance(invoice), - 'balanceDue': formatMoney(invoice.balance_amount, invoice.client.currency_id), + 'balanceDue': formatMoneyInvoice(invoice.balance_amount, invoice), 'invoiceFooter': NINJA.invoiceFooter(invoice), 'invoiceNumber': invoice.invoice_number || ' ', 'entityType': invoice.is_quote ? invoiceLabels.quote : invoiceLabels.invoice, @@ -262,7 +262,6 @@ NINJA.taxWidth = function(invoice) NINJA.invoiceLines = function(invoice) { var total = 0; var shownItem = false; - var currencyId = invoice && invoice.client ? invoice.client.currency_id : 1; var hideQuantity = invoice.account.hide_quantity == '1'; var showItemTaxes = invoice.account.show_item_taxes == '1'; @@ -285,7 +284,7 @@ NINJA.invoiceLines = function(invoice) { var row = []; var item = invoice.invoice_items[i]; - var cost = formatMoney(item.cost, currencyId, true); + var cost = formatMoneyInvoice(item.cost, invoice, true); var qty = NINJA.parseFloat(item.qty) ? roundToTwo(NINJA.parseFloat(item.qty)) + '' : ''; var notes = item.notes; var productKey = item.product_key; @@ -316,7 +315,7 @@ NINJA.invoiceLines = function(invoice) { if (showItemTaxes && tax) { lineTotal += lineTotal * tax / 100; } - lineTotal = formatMoney(lineTotal, currencyId); + lineTotal = formatMoneyInvoice(lineTotal, invoice); rowStyle = (i % 2 == 0) ? 'odd' : 'even'; @@ -345,49 +344,49 @@ NINJA.subtotals = function(invoice, hideBalance) var account = invoice.account; var data = []; - data.push([{text: invoiceLabels.subtotal}, {text: formatMoney(invoice.subtotal_amount, invoice.client.currency_id)}]); + data.push([{text: invoiceLabels.subtotal}, {text: formatMoneyInvoice(invoice.subtotal_amount, invoice)}]); if (invoice.discount_amount != 0) { - data.push([{text: invoiceLabels.discount}, {text: formatMoney(invoice.discount_amount, invoice.client.currency_id)}]); + data.push([{text: invoiceLabels.discount}, {text: formatMoneyInvoice(invoice.discount_amount, invoice)}]); } if (NINJA.parseFloat(invoice.custom_value1) && invoice.custom_taxes1 == '1') { - data.push([{text: account.custom_invoice_label1}, {text: formatMoney(invoice.custom_value1, invoice.client.currency_id)}]); + data.push([{text: account.custom_invoice_label1}, {text: formatMoneyInvoice(invoice.custom_value1, invoice)}]); } if (NINJA.parseFloat(invoice.custom_value2) && invoice.custom_taxes2 == '1') { - data.push([{text: account.custom_invoice_label2}, {text: formatMoney(invoice.custom_value2, invoice.client.currency_id)}]); + data.push([{text: account.custom_invoice_label2}, {text: formatMoneyInvoice(invoice.custom_value2, invoice)}]); } for (var key in invoice.item_taxes) { if (invoice.item_taxes.hasOwnProperty(key)) { var taxRate = invoice.item_taxes[key]; var taxStr = taxRate.name + ' ' + (taxRate.rate*1).toString() + '%'; - data.push([{text: taxStr}, {text: formatMoney(taxRate.amount, invoice.client.currency_id)}]); + data.push([{text: taxStr}, {text: formatMoneyInvoice(taxRate.amount, invoice)}]); } } if (invoice.tax && invoice.tax.name || invoice.tax_name) { var taxStr = invoice.tax_name + ' ' + (invoice.tax_rate*1).toString() + '%'; - data.push([{text: taxStr}, {text: formatMoney(invoice.tax_amount, invoice.client.currency_id)}]); + data.push([{text: taxStr}, {text: formatMoneyInvoice(invoice.tax_amount, invoice)}]); } if (NINJA.parseFloat(invoice.custom_value1) && invoice.custom_taxes1 != '1') { - data.push([{text: account.custom_invoice_label1}, {text: formatMoney(invoice.custom_value1, invoice.client.currency_id)}]); + data.push([{text: account.custom_invoice_label1}, {text: formatMoneyInvoice(invoice.custom_value1, invoice)}]); } if (NINJA.parseFloat(invoice.custom_value2) && invoice.custom_taxes2 != '1') { - data.push([{text: account.custom_invoice_label2}, {text: formatMoney(invoice.custom_value2, invoice.client.currency_id)}]); + data.push([{text: account.custom_invoice_label2}, {text: formatMoneyInvoice(invoice.custom_value2, invoice)}]); } var paid = invoice.amount - invoice.balance; if (invoice.account.hide_paid_to_date != '1' || paid) { - data.push([{text:invoiceLabels.paid_to_date}, {text:formatMoney(paid, invoice.client.currency_id)}]); + data.push([{text:invoiceLabels.paid_to_date}, {text:formatMoneyInvoice(paid, invoice)}]); } if (!hideBalance) { var isPartial = NINJA.parseFloat(invoice.partial); data.push([ {text: isPartial ? invoiceLabels.amount_due : invoiceLabels.balance_due, style:['balanceDueLabel']}, - {text: formatMoney(invoice.balance_amount, invoice.client.currency_id), style:['balanceDue']} + {text: formatMoneyInvoice(invoice.balance_amount, invoice), style:['balanceDue']} ]); } @@ -398,7 +397,7 @@ NINJA.subtotalsBalance = function(invoice) { var isPartial = NINJA.parseFloat(invoice.partial); return [[ {text: isPartial ? invoiceLabels.amount_due : invoiceLabels.balance_due, style:['balanceDueLabel']}, - {text: formatMoney(invoice.balance_amount, invoice.client.currency_id), style:['balanceDue']} + {text: formatMoneyInvoice(invoice.balance_amount, invoice), style:['balanceDue']} ]]; } @@ -418,7 +417,7 @@ NINJA.accountAddress = function(invoice) { var account = invoice.account; var cityStatePostal = ''; if (account.city || account.state || account.postal_code) { - var swap = account.country && account.country.swap_postal_code == '1'; + var swap = account.country && account.country.swap_postal_code; cityStatePostal = formatAddress(account.city, account.state, account.postal_code, swap); } var data = [ @@ -475,18 +474,18 @@ NINJA.invoiceDetails = function(invoice) { if (NINJA.parseFloat(invoice.balance) < NINJA.parseFloat(invoice.amount)) { data.push([ {text: invoiceLabels.total}, - {text: formatMoney(invoice.amount, invoice.client.currency_id)} + {text: formatMoneyInvoice(invoice.amount, invoice)} ]); } else if (isPartial) { data.push([ {text: invoiceLabels.total}, - {text: formatMoney(invoice.total_amount, invoice.client.currency_id)} + {text: formatMoneyInvoice(invoice.total_amount, invoice)} ]); } data.push([ {text: isPartial ? invoiceLabels.amount_due : invoiceLabels.balance_due, style: ['invoiceDetailBalanceDueLabel']}, - {text: formatMoney(invoice.balance_amount, invoice.client.currency_id), style: ['invoiceDetailBalanceDue']} + {text: formatMoneyInvoice(invoice.balance_amount, invoice), style: ['invoiceDetailBalanceDue']} ]) return NINJA.prepareDataPairs(data, 'invoiceDetails'); @@ -505,7 +504,7 @@ NINJA.clientDetails = function(invoice) { var cityStatePostal = ''; if (client.city || client.state || client.postal_code) { - var swap = client.country && client.country.swap_postal_code == '1'; + var swap = client.country && client.country.swap_postal_code; cityStatePostal = formatAddress(client.city, client.state, client.postal_code, swap); } diff --git a/public/js/script.js b/public/js/script.js index 291d1fd5ad03..8e9649c9a471 100644 --- a/public/js/script.js +++ b/public/js/script.js @@ -33,15 +33,7 @@ function generatePDF(invoice, javascript, force, cb) { return; } invoiceOld = invoice; - pdfmakeMarker = "{"; - if(javascript.slice(0, pdfmakeMarker.length) === pdfmakeMarker) { - doc = GetPdfMake(invoice, javascript, cb); - } else { - doc = GetPdf(invoice, javascript); - doc.getDataUrl = function(cb) { - cb( this.output("datauristring")); - }; - } + doc = GetPdfMake(invoice, javascript, cb); if (cb) { doc.getDataUrl(cb); @@ -55,135 +47,6 @@ function copyObject(orig) { return JSON.parse(JSON.stringify(orig)); } - -function GetPdf(invoice, javascript){ - var layout = { - accountTop: 40, - marginLeft: 50, - marginRight: 550, - headerTop: 150, - headerLeft: 360, - headerRight: 550, - rowHeight: 15, - tableRowHeight: 10, - footerLeft: 420, - tablePadding: 12, - tableTop: 250, - descriptionLeft: 150, - unitCostRight: 410, - qtyRight: 480, - taxRight: 480, - lineTotalRight: 550 - }; - - /* - if (invoice.has_taxes) - { - layout.descriptionLeft -= 20; - layout.unitCostRight -= 40; - layout.qtyRight -= 40; - } - */ - - /* - @param orientation One of "portrait" or "landscape" (or shortcuts "p" (Default), "l") - @param unit Measurement unit to be used when coordinates are specified. One of "pt" (points), "mm" (Default), "cm", "in" - @param format One of 'a3', 'a4' (Default),'a5' ,'letter' ,'legal' - @returns {jsPDF} - */ - var doc = new jsPDF('portrait', 'pt', 'a4'); - - //doc.getStringUnitWidth = function(param) { console.log('getStringUnitWidth: %s', param); return 0}; - - //Set PDF properities - doc.setProperties({ - title: 'Invoice ' + invoice.invoice_number, - subject: '', - author: 'InvoiceNinja.com', - keywords: 'pdf, invoice', - creator: 'InvoiceNinja.com' - }); - - //set default style for report - doc.setFont('Helvetica',''); - - // For partial payments show "Amount Due" rather than "Balance Due" - if (!invoiceLabels.balance_due_orig) { - invoiceLabels.balance_due_orig = invoiceLabels.balance_due; - } - invoiceLabels.balance_due = NINJA.parseFloat(invoice.partial) ? invoiceLabels.amount_due : invoiceLabels.balance_due_orig; - - eval(javascript); - - // add footer - if (invoice.invoice_footer) { - doc.setFontType('normal'); - doc.setFontSize('8'); - SetPdfColor(invoice.invoice_design_id == 2 || invoice.invoice_design_id == 3 ? 'White' : 'Black',doc); - var top = doc.internal.pageSize.height - layout.marginLeft; - if (!invoice.is_pro) top -= 25; - var footer = doc.splitTextToSize(processVariables(invoice.invoice_footer), 500); - var numLines = footer.length - 1; - doc.text(layout.marginLeft, top - (numLines * 8), footer); - } - - return doc; -} - - -function SetPdfColor(color, doc, role) -{ - if (role === 'primary' && NINJA.primaryColor) { - return setDocHexColor(doc, NINJA.primaryColor); - } else if (role === 'secondary' && NINJA.secondaryColor) { - return setDocHexColor(doc, NINJA.secondaryColor); - } - - if (color=='LightBlue') { - return doc.setTextColor(41,156, 194); - } - - if (color=='Black') { - return doc.setTextColor(46,43,43);//select color black - } - if (color=='GrayLogo') { - return doc.setTextColor(207,241, 241);//select color Custom Report GRAY - } - - if (color=='GrayBackground') { - return doc.setTextColor(251,251, 251);//select color Custom Report GRAY - } - - if (color=='GrayText') { - return doc.setTextColor(161,160,160);//select color Custom Report GRAY Colour - } - - if (color=='White') { - return doc.setTextColor(255,255,255);//select color Custom Report GRAY Colour - } - - if (color=='SomeGreen') { - return doc.setTextColor(54,164,152);//select color Custom Report GRAY Colour - } - - if (color=='LightGrayReport2-gray') { - return doc.setTextColor(240,240,240);//select color Custom Report GRAY Colour - } - - if (color=='LightGrayReport2-white') { - return doc.setTextColor(251,251,251);//select color Custom Report GRAY Colour - } - - if (color=='orange') { - return doc.setTextColor(234,121,45);//select color Custom Report GRAY Colour - } - - if (color=='Green') { - return doc.setTextColor(55,109,69); - } -} - - /* Handle converting variables in the invoices (ie, MONTH+1) */ function processVariables(str) { if (!str) return ''; @@ -616,8 +479,8 @@ function populateInvoiceComboboxes(clientId, invoiceId) { var client = clientMap[invoice.client.public_id]; if (!client) continue; // client is deleted/archived $invoiceCombobox.append(new Option(invoice.invoice_number + ' - ' + invoice.invoice_status.name + ' - ' + - getClientDisplayName(client) + ' - ' + formatMoney(invoice.amount, client.currency_id) + ' | ' + - formatMoney(invoice.balance, client.currency_id), invoice.public_id)); + getClientDisplayName(client) + ' - ' + formatMoneyInvoice(invoice.amount, invoice) + ' | ' + + formatMoneyInvoice(invoice.balance, invoice), invoice.public_id)); } $('select#invoice').combobox('refresh'); }); @@ -628,6 +491,7 @@ function populateInvoiceComboboxes(clientId, invoiceId) { if (invoiceId) { var invoice = invoiceMap[invoiceId]; var client = clientMap[invoice.client.public_id]; + invoice.client = client; setComboboxValue($('.client-select'), client.public_id, getClientDisplayName(client)); if (!parseFloat($('#amount').val())) { $('#amount').val(parseFloat(invoice.balance).toFixed(2)); @@ -640,9 +504,10 @@ function populateInvoiceComboboxes(clientId, invoiceId) { if (invoiceId) { var invoice = invoiceMap[invoiceId]; var client = clientMap[invoice.client.public_id]; + invoice.client = client; setComboboxValue($('.invoice-select'), invoice.public_id, (invoice.invoice_number + ' - ' + invoice.invoice_status.name + ' - ' + getClientDisplayName(client) + ' - ' + - formatMoney(invoice.amount, client.currency_id) + ' | ' + formatMoney(invoice.balance, client.currency_id))); + formatMoneyInvoice(invoice.amount, invoice) + ' | ' + formatMoneyInvoice(invoice.balance, invoice))); $invoiceSelect.trigger('change'); } else if (clientId) { var client = clientMap[clientId]; @@ -664,174 +529,6 @@ CONSTS.INVOICE_STATUS_PAID = 5; $.fn.datepicker.defaults.autoclose = true; $.fn.datepicker.defaults.todayHighlight = true; - - - - -function displayAccount(doc, invoice, x, y, layout) { - var account = invoice.account; - - if (!account) { - return; - } - - var data1 = [ - account.name, - account.id_number, - account.vat_number, - account.work_email, - account.work_phone - ]; - - var data2 = [ - concatStrings(account.address1, account.address2), - concatStrings(account.city, account.state, account.postal_code), - account.country ? account.country.name : false, - invoice.account.custom_value1 ? invoice.account['custom_label1'] + ' ' + invoice.account.custom_value1 : false, - invoice.account.custom_value2 ? invoice.account['custom_label2'] + ' ' + invoice.account.custom_value2 : false, - ]; - - if (layout.singleColumn) { - - displayGrid(doc, invoice, data1.concat(data2), x, y, layout, {hasHeader:true}); - - } else { - - displayGrid(doc, invoice, data1, x, y, layout, {hasHeader:true}); - - var nameWidth = account.name ? (doc.getStringUnitWidth(account.name) * doc.internal.getFontSize() * 1.1) : 0; - var emailWidth = account.work_email ? (doc.getStringUnitWidth(account.work_email) * doc.internal.getFontSize() * 1.1) : 0; - width = Math.max(emailWidth, nameWidth, 120); - x += width; - - displayGrid(doc, invoice, data2, x, y, layout); - } -} - - -function displayClient(doc, invoice, x, y, layout) { - var client = invoice.client; - if (!client) { - return; - } - var data = [ - getClientDisplayName(client), - client.id_number, - client.vat_number, - concatStrings(client.address1, client.address2), - concatStrings(client.city, client.state, client.postal_code), - client.country ? client.country.name : false, - invoice.contact && getClientDisplayName(client) != invoice.contact.email ? invoice.contact.email : false, - invoice.client.custom_value1 ? invoice.account['custom_client_label1'] + ' ' + invoice.client.custom_value1 : false, - invoice.client.custom_value2 ? invoice.account['custom_client_label2'] + ' ' + invoice.client.custom_value2 : false, - ]; - return displayGrid(doc, invoice, data, x, y, layout, {hasheader:true}); -} - -function displayInvoice(doc, invoice, x, y, layout, rightAlignX) { - if (!invoice) { - return; - } - - var data = getInvoiceDetails(invoice); - var options = { - hasheader: true, - rightAlignX: rightAlignX, - }; - - return displayGrid(doc, invoice, data, x, y, layout, options); -} - -function getInvoiceDetails(invoice) { - var fields = [ - {'invoice_number': invoice.invoice_number}, - {'po_number': invoice.po_number}, - {'invoice_date': invoice.invoice_date}, - {'due_date': invoice.due_date}, - ]; - - if (NINJA.parseFloat(invoice.balance) < NINJA.parseFloat(invoice.amount)) { - fields.push({'total': formatMoney(invoice.amount, invoice.client.currency_id)}); - } - - if (NINJA.parseFloat(invoice.partial)) { - fields.push({'balance': formatMoney(invoice.total_amount, invoice.client.currency_id)}); - } - - fields.push({'balance_due': formatMoney(invoice.balance_amount, invoice.client.currency_id)}) - - return fields; -} - -function getInvoiceDetailsHeight(invoice, layout) { - var data = getInvoiceDetails(invoice); - var count = 0; - for (var key in data) { - if (!data.hasOwnProperty(key)) { - continue; - } - var obj = data[key]; - for (var subKey in obj) { - if (!obj.hasOwnProperty(subKey)) { - continue; - } - if (obj[subKey]) { - count++; - } - } - } - return count * layout.rowHeight; -} - -function displaySubtotals(doc, layout, invoice, y, rightAlignTitleX) -{ - if (!invoice) { - return; - } - - 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} - ]; - - if (NINJA.parseFloat(invoice.custom_value1) && invoice.custom_taxes1 == '1') { - data.push({'custom_invoice_label1': formatMoney(invoice.custom_value1, invoice.client.currency_id) }) - } - if (NINJA.parseFloat(invoice.custom_value2) && invoice.custom_taxes2 == '1') { - data.push({'custom_invoice_label2': formatMoney(invoice.custom_value2, invoice.client.currency_id) }) - } - - data.push({'tax': (invoice.tax && invoice.tax.name) || invoice.tax_name ? formatMoney(invoice.tax_amount, invoice.client.currency_id) : false}); - - if (NINJA.parseFloat(invoice.custom_value1) && invoice.custom_taxes1 != '1') { - data.push({'custom_invoice_label1': formatMoney(invoice.custom_value1, invoice.client.currency_id) }) - } - if (NINJA.parseFloat(invoice.custom_value2) && invoice.custom_taxes2 != '1') { - data.push({'custom_invoice_label2': formatMoney(invoice.custom_value2, invoice.client.currency_id) }) - } - - var paid = invoice.amount - invoice.balance; - if (paid) { - data.push({'total': formatMoney(invoice.amount, invoice.client.currency_id)}); - } - - if (invoice.account.hide_paid_to_date != '1' || paid) { - data.push({'paid_to_date': formatMoney(paid, invoice.client.currency_id)}); - } - - if (NINJA.parseFloat(invoice.partial) && invoice.total_amount != invoice.subtotal_amount) { - data.push({'balance': formatMoney(invoice.total_amount, invoice.client.currency_id)}); - } - - var options = { - hasheader: true, - rightAlignX: 550, - rightAlignTitleX: rightAlignTitleX - }; - - return displayGrid(doc, invoice, data, 300, y, layout, options) + 10; -} - function formatAddress(city, state, zip, swap) { var str = ''; if (swap) { @@ -867,106 +564,6 @@ function concatStrings() { return data.length ? concatStr : ""; } -function displayGrid(doc, invoice, data, x, y, layout, options) { - var numLines = 0; - var origY = y; - for (var i=0; i 0 && origY === layout.accountTop) { - SetPdfColor('GrayText',doc); - } - - var row = data[i]; - if (!row) { - continue; - } - - if (options && (options.hasheader && i === 0 && !options.rightAlignTitleX)) { - doc.setFontType('bold'); - } - - if (typeof row === 'object') { - for (var key in row) { - if (row.hasOwnProperty(key)) { - var value = row[key] ? row[key] + '' : false; - } - } - if (!value) { - continue; - } - - var marginLeft; - if (options.rightAlignX) { - marginLeft = options.rightAlignX - (doc.getStringUnitWidth(value) * doc.internal.getFontSize()); - } else { - marginLeft = x + 80; - } - doc.text(marginLeft, y, value); - - doc.setFontType('normal'); - if (invoice.is_quote) { - if (key == 'invoice_number') { - key = 'quote_number'; - } else if (key == 'invoice_date') { - key = 'quote_date'; - } else if (key == 'balance_due') { - key = 'total'; - } - } - - if (key.substring(0, 6) === 'custom') { - key = invoice.account[key]; - } else if (key === 'tax' && invoice.tax_name) { - key = invoice.tax_name + ' ' + (invoice.tax_rate*1).toString() + '%'; - } else if (key === 'discount' && NINJA.parseFloat(invoice.discount) && !parseInt(invoice.is_amount_discount)) { - key = invoiceLabels[key] + ' ' + parseFloat(invoice.discount) + '%'; - } else { - key = invoiceLabels[key]; - } - - if (options.rightAlignTitleX) { - marginLeft = options.rightAlignTitleX - (doc.getStringUnitWidth(key) * doc.internal.getFontSize()); - } else { - marginLeft = x; - } - - doc.text(marginLeft, y, key); - } else { - doc.text(x, y, row); - } - - numLines++; - y += layout.rowHeight; - } - - return numLines * layout.rowHeight; -} - -function displayNotesAndTerms(doc, layout, invoice, y) -{ - doc.setFontType("normal"); - var origY = y; - - if (invoice.public_notes) { - var notes = doc.splitTextToSize(processVariables(invoice.public_notes), 260); - doc.text(layout.marginLeft, y, notes); - y += 16 + (notes.length * doc.internal.getFontSize()); - } - - if (invoice.terms) { - var terms = doc.splitTextToSize(processVariables(invoice.terms), 260); - doc.setFontType("bold"); - doc.text(layout.marginLeft, y, invoiceLabels.terms); - y += 16; - doc.setFontType("normal"); - doc.text(layout.marginLeft, y, terms); - y += 16 + (terms.length * doc.internal.getFontSize()); - } - - return y - origY; -} - function calculateAmounts(invoice) { var total = 0; var hasTaxes = false; @@ -1090,311 +687,6 @@ function getInvoiceTaxRate(invoice) { return tax; } -function displayInvoiceHeader(doc, invoice, layout) { - - if (invoice.invoice_design_id == 6 || invoice.invoice_design_id == 8 || invoice.invoice_design_id == 10) { - invoiceLabels.item = invoiceLabels.item.toUpperCase(); - invoiceLabels.description = invoiceLabels.description.toUpperCase(); - invoiceLabels.unit_cost = invoiceLabels.unit_cost.toUpperCase(); - invoiceLabels.quantity = invoiceLabels.quantity.toUpperCase(); - invoiceLabels.line_total = invoiceLabels.total.toUpperCase(); - invoiceLabels.tax = invoiceLabels.tax.toUpperCase(); - } - - 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, invoiceLabels.item); - doc.text(layout.descriptionLeft, layout.tableTop, invoiceLabels.description); - doc.text(costX, layout.tableTop, invoiceLabels.unit_cost); - if (invoice.account.hide_quantity != '1') { - doc.text(qtyX, layout.tableTop, invoiceLabels.quantity); - } - doc.text(totalX, layout.tableTop, invoiceLabels.line_total); - - /* - if (invoice.has_taxes) - { - doc.text(taxX, layout.tableTop, invoiceLabels.tax); - } - */ -} - -function displayInvoiceItems(doc, invoice, layout) { - doc.setFontType("normal"); - - var line = 1; - var total = 0; - var shownItem = false; - var currencyId = invoice && invoice.client ? invoice.client.currency_id : 1; - var tableTop = layout.tableTop; - var hideQuantity = invoice.account.hide_quantity == '1'; - - doc.setFontSize(8); - for (var i=0; i 770) { - line = 0; - tableTop = layout.accountTop + layout.tablePadding; - y = tableTop + (2 * layout.tablePadding); - top = y - layout.tablePadding; - newTop = top + (numLines * layout.tableRowHeight); - doc.addPage(); - } - - var left = layout.marginLeft - layout.tablePadding; - var width = layout.marginRight + layout.tablePadding; - - // process date variables - if (invoice.is_recurring) { - notes = processVariables(notes); - productKey = processVariables(productKey); - } - - var lineTotal = roundToTwo(NINJA.parseFloat(item.cost)) * roundToTwo(NINJA.parseFloat(item.qty)); - if (tax) { - lineTotal += lineTotal * tax / 100; - } - if (lineTotal) { - total += lineTotal; - } - lineTotal = formatMoney(lineTotal, currencyId); - - - var costX = layout.unitCostRight - (doc.getStringUnitWidth(cost) * doc.internal.getFontSize()); - var qtyX = layout.qtyRight - (doc.getStringUnitWidth(qty) * doc.internal.getFontSize()); - var taxX = layout.taxRight - (doc.getStringUnitWidth(tax+'%') * doc.internal.getFontSize()); - var totalX = layout.lineTotalRight - (doc.getStringUnitWidth(lineTotal) * doc.internal.getFontSize()); - //if (i==0) y -= 4; - - line += numLines; - - - if (invoice.invoice_design_id == 1) { - if (i%2 == 0) { - doc.setDrawColor(255,255,255); - doc.setFillColor(246,246,246); - doc.rect(left, top, width-left, newTop-top, 'FD'); - - doc.setLineWidth(0.3); - doc.setDrawColor(200,200,200); - doc.line(left, top, width, top); - doc.line(left, newTop, width, newTop); - } - } else if (invoice.invoice_design_id == 2) { - if (i%2 == 0) { - left = 0; - width = 1000; - - doc.setDrawColor(255,255,255); - doc.setFillColor(235,235,235); - doc.rect(left, top, width-left, newTop-top, 'FD'); - - } - } else if (invoice.invoice_design_id == 5) { - if (i%2 == 0) { - doc.setDrawColor(255,255,255); - doc.setFillColor(247,247,247); - doc.rect(left, top, width-left+17, newTop-top, 'FD'); - } else { - doc.setDrawColor(255,255,255); - doc.setFillColor(232,232,232); - doc.rect(left, top, width-left+17, newTop-top, 'FD'); - } - } else if (invoice.invoice_design_id == 6) { - if (i%2 == 0) { - doc.setDrawColor(232,232,232); - doc.setFillColor(232,232,232); - doc.rect(left, top, width-left, newTop-top, 'FD'); - } else { - doc.setDrawColor(255,255,255); - doc.setFillColor(255,255,255); - doc.rect(left, top, width-left, newTop-top, 'FD'); - } - } else if (invoice.invoice_design_id == 7) { - doc.setLineWidth(1); - doc.setDrawColor(45,35,32); - for(var k = 1; k<=width-20; k++) { - doc.line(left+4+k,newTop,left+4+1+k,newTop); - k = k+3; - } - } else if (invoice.invoice_design_id == 8) { - - } else if (invoice.invoice_design_id == 9) { - doc.setLineWidth(1); - doc.setDrawColor(0,157,145); - for(var j = 1; j<=width-40; j++) { - doc.line(left+j,newTop,left+2+j,newTop); - j = j+5; - } - } else if (invoice.invoice_design_id == 10) { - doc.setLineWidth(0.3); - doc.setDrawColor(63,60,60); - doc.line(left, newTop, width, newTop); - } else { - doc.setLineWidth(0.3); - doc.setDrawColor(150,150,150); - doc.line(left, newTop, width, newTop); - } - - y += 4; - - if (invoice.invoice_design_id == 1) { - SetPdfColor('LightBlue', doc, 'primary'); - } else if (invoice.invoice_design_id == 2) { - SetPdfColor('SomeGreen', doc, 'primary'); - } else if (invoice.invoice_design_id == 3) { - doc.setFontType('bold'); - } else if (invoice.invoice_design_id == 4) { - SetPdfColor('Black', doc); - } else if (invoice.invoice_design_id == 5) { - SetPdfColor('Black', doc); - } else if (invoice.invoice_design_id == 6) { - SetPdfColor('Black', doc); - } - - - var splitTitle = doc.splitTextToSize(productKey, 60); - if(invoice.invoice_design_id == 6) { - doc.setFontType('bold'); - } - if(invoice.invoice_design_id == 9) { - doc.setTextColor(187,51,40); - } - if(invoice.invoice_design_id == 10) { - doc.setTextColor(205,81,56); - } - doc.text(layout.marginLeft, y+2, splitTitle); - - if (invoice.invoice_design_id == 5) { - - doc.setDrawColor(255, 255, 255); - doc.setLineWidth(1); - doc.line(layout.descriptionLeft-8, y-16,layout.descriptionLeft-8, y+55); - - doc.line(costX-30, y-16,costX-30, y+55); - - doc.line(qtyX-45, y-16,qtyX-45, y+55); - - /* - if (invoice.has_taxes) { - doc.line(taxX-15, y-16,taxX-15, y+55); - } - */ - doc.line(totalX-27, y-16,totalX-27, y+55); - - } - /* - if (invoice.invoice_design_id == 8) { - - doc.setDrawColor(30, 30, 30); - doc.setLineWidth(0.5); - doc.line(layout.marginLeft-10, y-60,layout.marginLeft-10, y+20); - - doc.line(layout.descriptionLeft-8, y-60,layout.descriptionLeft-8, y+20); - - doc.line(costX-30, y-60,costX-30, y+20); - console.log('CostX: %s', costX); - doc.line(qtyX-45, y-60,qtyX-45, y+20); - - if (invoice.has_taxes) { - doc.line(taxX-10, y-60,taxX-10, y+20); - } - - doc.line(totalX-27, y-60,totalX-27, y+120); - - doc.line(totalX+35, y-60,totalX+35, y+120); - - } - */ - - SetPdfColor('Black', doc); - doc.setFontType('normal'); - - var splitDescription = doc.splitTextToSize(notes, 190); - doc.text(layout.descriptionLeft, y+2, splitDescription); - doc.text(costX, y+2, cost); - if (!hideQuantity) { - doc.text(qtyX, y+2, qty); - } - if(invoice.invoice_design_id == 9) { - doc.setTextColor(187,51,40); - doc.setFontType('bold'); - } - if(invoice.invoice_design_id == 10) { - doc.setTextColor(205,81,56); - } - doc.text(totalX, y+2, lineTotal); - doc.setFontType('normal'); - SetPdfColor('Black', doc); - if (tax) { - doc.text(taxX, y+2, tax+'%'); - } - } - - y = tableTop + (line * layout.tableRowHeight) + (3 * layout.tablePadding); - - if (invoice.invoice_design_id == 8) { - doc.setDrawColor(30, 30, 30); - doc.setLineWidth(0.5); - - var topX = tableTop - 14; - doc.line(layout.marginLeft-10, topX,layout.marginLeft-10, y); - doc.line(layout.descriptionLeft-8, topX,layout.descriptionLeft-8, y); - doc.line(layout.unitCostRight-55, topX,layout.unitCostRight-55, y); - doc.line(layout.qtyRight-50, topX,layout.qtyRight-50, y); - /* - if (invoice.has_taxes) { - doc.line(layout.taxRight-28, topX,layout.taxRight-28, y); - } - */ - doc.line(totalX-25, topX,totalX-25, y+90); - doc.line(totalX+45, topX,totalX+45, y+90); - } - - var cutoff = 700; - if (invoice.terms) { - cutoff -= 50; - } - if (invoice.public_notes) { - cutoff -= 50; - } - - if (y > cutoff) { - doc.addPage(); - return layout.marginLeft; - } - - return y; -} - - // http://stackoverflow.com/questions/11941876/correctly-suppressing-warnings-in-datatables window.alert = (function() { var nativeAlert = window.alert; diff --git a/resources/views/clients/show.blade.php b/resources/views/clients/show.blade.php index c81cfa3fcc0c..a7939f12e487 100644 --- a/resources/views/clients/show.blade.php +++ b/resources/views/clients/show.blade.php @@ -328,7 +328,7 @@ } }); var tab = localStorage.getItem('client_tab'); - if (tab) { + if (tab && tab != 'activity') { $('.nav-tabs a[href="#' + tab.replace('#', '') + '"]').tab('show'); } else { window['load_activity'](); diff --git a/resources/views/emails/view_action.blade.php b/resources/views/emails/view_action.blade.php index 1a4abf04c318..30a3025ce56c 100644 --- a/resources/views/emails/view_action.blade.php +++ b/resources/views/emails/view_action.blade.php @@ -19,7 +19,7 @@ }, "totalPaymentDue": { "@type": "PriceSpecification", - "price": "{{ $invoice->present()->balance_due }}" + "price": "{{ $account->formatMoney($invoice->getRequestedAmount(), $client) }}" }, "action": { "@type": "ViewAction", diff --git a/resources/views/export/clients.blade.php b/resources/views/export/clients.blade.php index 226d00e8c671..f0d2a05b75fe 100644 --- a/resources/views/export/clients.blade.php +++ b/resources/views/export/clients.blade.php @@ -25,8 +25,8 @@ @if ($multiUser) {{ $client->user->getDisplayName() }} @endif - {{ $client->present()->balance }} - {{ $client->present()->paid_to_date }} + {{ $account->formatMoney($client->balance, $client) }} + {{ $account->formatMoney($client->paid_to_date, $client) }} {{ $client->address1 }} {{ $client->address2 }} {{ $client->city }} diff --git a/resources/views/export/credits.blade.php b/resources/views/export/credits.blade.php index 28d53a5e7fc8..d47eba057042 100644 --- a/resources/views/export/credits.blade.php +++ b/resources/views/export/credits.blade.php @@ -15,8 +15,8 @@ @if ($multiUser) {{ $credit->user->getDisplayName() }} @endif - {{ $credit->present()->amount }} - {{ $credit->present()->balance }} + {{ $account->formatMoney($credit->amount, $credit->client) }} + {{ $account->formatMoney($credit->balance, $credit->client) }} {{ $credit->present()->credit_date }} @endif diff --git a/resources/views/export/invoices.blade.php b/resources/views/export/invoices.blade.php index 018e5b096ecb..fab37fbf8cb7 100644 --- a/resources/views/export/invoices.blade.php +++ b/resources/views/export/invoices.blade.php @@ -32,8 +32,8 @@ {{ $invoice->present()->user }} @endif {{ $invoice->invoice_number }} - {{ $invoice->present()->balance }} - {{ $invoice->present()->amount }} + {{ $account->formatMoney($invoice->balance, $invoice->client) }} + {{ $account->formatMoney($invoice->amount, $invoice->client) }} {{ $invoice->po_number }} {{ $invoice->present()->status }} {{ $invoice->present()->invoice_date }} diff --git a/resources/views/export/payments.blade.php b/resources/views/export/payments.blade.php index 0d07d6e2e058..66a51f8179dd 100644 --- a/resources/views/export/payments.blade.php +++ b/resources/views/export/payments.blade.php @@ -18,7 +18,7 @@ {{ $payment->user->getDisplayName() }} @endif {{ $payment->invoice->invoice_number }} - {{ $payment->present()->amount }} + {{ $account->formatMoney($payment->amount, $payment->client) }} {{ $payment->present()->payment_date }} {{ $payment->present()->method }} {{ $payment->transaction_reference }} diff --git a/resources/views/header.blade.php b/resources/views/header.blade.php index 90abd2aa114a..cc20ef0de34d 100644 --- a/resources/views/header.blade.php +++ b/resources/views/header.blade.php @@ -41,11 +41,8 @@ } @endif - - @include('script') -