From 3fdad48179a669e76c3f09a4d4f806a5f6817b0b Mon Sep 17 00:00:00 2001
From: Hillel Coren
Date: Mon, 7 Sep 2015 12:07:55 +0300
Subject: [PATCH] API improvements
---
app/Http/Controllers/AccountController.php | 5 +-
app/Http/Controllers/DashboardController.php | 4 +-
app/Http/Controllers/HomeController.php | 2 +-
app/Http/Controllers/InvoiceApiController.php | 14 +-
app/Http/Controllers/InvoiceController.php | 13 +-
app/Http/Controllers/PaymentApiController.php | 14 +-
app/Http/Controllers/PaymentController.php | 12 +-
app/Http/Controllers/QuoteApiController.php | 14 +-
app/Http/Controllers/QuoteController.php | 2 +-
app/Http/Controllers/TaskApiController.php | 56 ++++++++
app/Http/Controllers/TaskController.php | 2 +-
app/Http/Middleware/VerifyCsrfToken.php | 1 +
app/Http/routes.php | 7 +-
app/Models/Account.php | 12 +-
app/Models/Country.php | 2 +-
app/Models/Invoice.php | 1 +
app/Ninja/Mailers/ContactMailer.php | 8 +-
app/Ninja/Repositories/InvoiceRepository.php | 4 +-
app/Ninja/Repositories/TaskRepository.php | 20 +--
.../2014_05_17_175626_add_quotes.php | 4 +-
..._add_formats_to_datetime_formats_table.php | 2 +-
...2015_09_04_080604_add_swap_postal_code.php | 38 ++++++
database/seeds/PaymentLibrariesSeeder.php | 36 +++++
public/apple-touch-icon-120x120.png | Bin 0 -> 4389 bytes
public/js/built.js | 126 +++++++++++++-----
public/js/pdf.pdfmake.js | 111 ++++++++++-----
public/js/script.js | 15 +++
resources/lang/da/texts.php | 13 ++
resources/lang/de/texts.php | 18 ++-
resources/lang/en/texts.php | 20 ++-
resources/lang/es/texts.php | 15 ++-
resources/lang/es_ES/texts.php | 15 ++-
resources/lang/fr/texts.php | 15 ++-
resources/lang/fr_CA/texts.php | 16 ++-
resources/lang/it/texts.php | 15 ++-
resources/lang/lt/texts.php | 15 ++-
resources/lang/nb_NO/texts.php | 15 ++-
resources/lang/nl/texts.php | 15 ++-
resources/lang/pt_BR/texts.php | 14 +-
resources/lang/sv/texts.php | 15 ++-
.../views/accounts/invoice_design.blade.php | 19 +--
resources/views/clients/show.blade.php | 2 +-
resources/views/credits/edit.blade.php | 8 +-
resources/views/dashboard.blade.php | 2 +-
resources/views/invoices/edit.blade.php | 73 ++++++----
resources/views/invoices/pdf.blade.php | 2 +-
resources/views/invoices/view.blade.php | 2 +-
resources/views/master.blade.php | 1 +
resources/views/payments/edit.blade.php | 9 +-
resources/views/public/header.blade.php | 4 -
resources/views/public/invoice_now.blade.php | 37 +++++
.../views/reports/chart_builder.blade.php | 11 ++
.../views/users/account_management.blade.php | 4 +-
storage/templates/bold.js | 95 ++++++++-----
storage/templates/clean.js | 3 +
storage/templates/modern.js | 7 +-
56 files changed, 784 insertions(+), 221 deletions(-)
create mode 100644 app/Http/Controllers/TaskApiController.php
create mode 100644 database/migrations/2015_09_04_080604_add_swap_postal_code.php
create mode 100644 public/apple-touch-icon-120x120.png
create mode 100644 resources/views/public/invoice_now.blade.php
diff --git a/app/Http/Controllers/AccountController.php b/app/Http/Controllers/AccountController.php
index cf647dcaa8c6..7577601404d8 100644
--- a/app/Http/Controllers/AccountController.php
+++ b/app/Http/Controllers/AccountController.php
@@ -387,11 +387,12 @@ class AccountController extends BaseController
$account->hide_paid_to_date = Input::get('hide_paid_to_date') ? true : false;
$account->primary_color = Input::get('primary_color');
$account->secondary_color = Input::get('secondary_color');
- $account->invoice_design_id = Input::get('invoice_design_id');
+ $account->invoice_design_id = Input::get('invoice_design_id');
+
if (Input::has('font_size')) {
$account->font_size = intval(Input::get('font_size'));
}
-
+
$labels = [];
foreach (['item', 'description', 'unit_cost', 'quantity'] as $field) {
$labels[$field] = trim(Input::get("labels_{$field}"));
diff --git a/app/Http/Controllers/DashboardController.php b/app/Http/Controllers/DashboardController.php
index 189b277c2c77..dfbd181d86db 100644
--- a/app/Http/Controllers/DashboardController.php
+++ b/app/Http/Controllers/DashboardController.php
@@ -74,7 +74,7 @@ class DashboardController extends BaseController
->where('clients.deleted_at', '=', null)
->where('contacts.deleted_at', '=', null)
->where('invoices.is_recurring', '=', false)
- ->where('invoices.is_quote', '=', false)
+ //->where('invoices.is_quote', '=', false)
->where('invoices.balance', '>', 0)
->where('invoices.is_deleted', '=', false)
->where('contacts.is_primary', '=', true)
@@ -91,7 +91,7 @@ class DashboardController extends BaseController
->where('clients.deleted_at', '=', null)
->where('contacts.deleted_at', '=', null)
->where('invoices.is_recurring', '=', false)
- ->where('invoices.is_quote', '=', false)
+ //->where('invoices.is_quote', '=', false)
->where('invoices.balance', '>', 0)
->where('invoices.is_deleted', '=', false)
->where('contacts.is_primary', '=', true)
diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php
index 1308a4378b26..565c637b0952 100644
--- a/app/Http/Controllers/HomeController.php
+++ b/app/Http/Controllers/HomeController.php
@@ -53,7 +53,7 @@ class HomeController extends BaseController
$redirectTo = Input::get('redirect_to', 'invoices/create');
return Redirect::to($redirectTo)->with('sign_up', Input::get('sign_up'));
} else {
- return View::make('public.header', ['invoiceNow' => true]);
+ return View::make('public.invoice_now');
}
}
diff --git a/app/Http/Controllers/InvoiceApiController.php b/app/Http/Controllers/InvoiceApiController.php
index 4c13259aecb2..c12e909edc88 100644
--- a/app/Http/Controllers/InvoiceApiController.php
+++ b/app/Http/Controllers/InvoiceApiController.php
@@ -24,13 +24,19 @@ class InvoiceApiController extends Controller
$this->mailer = $mailer;
}
- public function index()
+ public function index($clientPublicId = false)
{
$invoices = Invoice::scope()
->with('client', 'invitations.account')
- ->where('invoices.is_quote', '=', false)
- ->orderBy('created_at', 'desc')
- ->get();
+ ->where('invoices.is_quote', '=', false);
+
+ if ($clientPublicId) {
+ $invoices->whereHas('client', function($query) use ($clientPublicId) {
+ $query->where('public_id', '=', $clientPublicId);
+ });
+ }
+
+ $invoices = $invoices->orderBy('created_at', 'desc')->get();
// Add the first invitation link to the data
foreach ($invoices as $key => $invoice) {
diff --git a/app/Http/Controllers/InvoiceController.php b/app/Http/Controllers/InvoiceController.php
index b7e734ca14cd..6334d9f8cd93 100644
--- a/app/Http/Controllers/InvoiceController.php
+++ b/app/Http/Controllers/InvoiceController.php
@@ -246,8 +246,13 @@ class InvoiceController extends BaseController
$paymentURL = $paymentTypes[0]['url'];
}
+ $showApprove = $invoice->quote_invoice_id ? false : true;
+ if ($invoice->due_date) {
+ $showApprove = time() < strtotime($invoice->due_date);
+ }
+
$data = array(
- 'isConverted' => $invoice->quote_invoice_id ? true : false,
+ 'showApprove' => $showApprove,
'showBreadcrumbs' => false,
'hideLogo' => $account->isWhiteLabel(),
'invoice' => $invoice->hidePrivateFields(),
@@ -265,7 +270,7 @@ class InvoiceController extends BaseController
{
$invoice = Invoice::scope($publicId)->withTrashed()->with('invitations', 'account.country', 'client.contacts', 'client.country', 'invoice_items')->firstOrFail();
$entityType = $invoice->getEntityType();
-
+
$contactIds = DB::table('invitations')
->join('contacts', 'contacts.id', '=', 'invitations.contact_id')
->where('invitations.invoice_id', '=', $invoice->id)
@@ -472,10 +477,12 @@ class InvoiceController extends BaseController
$account = Auth::user()->account;
if ($account->invoice_taxes != $input->invoice_taxes
|| $account->invoice_item_taxes != $input->invoice_item_taxes
- || $account->invoice_design_id != $input->invoice->invoice_design_id) {
+ || $account->invoice_design_id != $input->invoice->invoice_design_id
+ || $account->show_item_taxes != $input->show_item_taxes) {
$account->invoice_taxes = $input->invoice_taxes;
$account->invoice_item_taxes = $input->invoice_item_taxes;
$account->invoice_design_id = $input->invoice->invoice_design_id;
+ $account->show_item_taxes = $input->show_item_taxes;
$account->save();
}
diff --git a/app/Http/Controllers/PaymentApiController.php b/app/Http/Controllers/PaymentApiController.php
index 1fb81bf78283..17d2e548f7cb 100644
--- a/app/Http/Controllers/PaymentApiController.php
+++ b/app/Http/Controllers/PaymentApiController.php
@@ -16,12 +16,18 @@ class PaymentApiController extends Controller
$this->paymentRepo = $paymentRepo;
}
- public function index()
+ public function index($clientPublicId = false)
{
$payments = Payment::scope()
- ->with('client', 'contact', 'invitation', 'user', 'invoice')
- ->orderBy('created_at', 'desc')
- ->get();
+ ->with('client', 'contact', 'invitation', 'user', 'invoice');
+
+ if ($clientPublicId) {
+ $payments->whereHas('client', function($query) use ($clientPublicId) {
+ $query->where('public_id', '=', $clientPublicId);
+ });
+ }
+
+ $payments = $payments->orderBy('created_at', 'desc')->get();
$payments = Utils::remapPublicIds($payments);
$response = json_encode($payments, JSON_PRETTY_PRINT);
diff --git a/app/Http/Controllers/PaymentController.php b/app/Http/Controllers/PaymentController.php
index 81e102d3fec4..0fec34184c45 100644
--- a/app/Http/Controllers/PaymentController.php
+++ b/app/Http/Controllers/PaymentController.php
@@ -447,7 +447,7 @@ class PaymentController extends BaseController
if (!$response->isSuccessful()) {
Session::flash('error', $response->getMessage());
- Utils::logError($response->getMessage());
+ Utils::logError('Payment Error [license]: ' . $response->getMessage());
return Redirect::to('license')->withInput();
}
@@ -484,7 +484,7 @@ class PaymentController extends BaseController
} catch (\Exception $e) {
$errorMessage = trans('texts.payment_error');
Session::flash('error', $errorMessage);
- Utils::logError(Utils::getErrorString($e));
+ Utils::logError('Payment Error [license-uncaught]: ' . Utils::getErrorString($e));
return Redirect::to('license')->withInput();
}
@@ -543,7 +543,7 @@ class PaymentController extends BaseController
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails()) {
- Utils::logError('Payment Error [invalid]');
+ //Utils::logError('Payment Error [invalid]');
return Redirect::to('payment/'.$invitationKey)
->withErrors($validator)
->withInput();
@@ -711,7 +711,7 @@ class PaymentController extends BaseController
if ($accountGateway->isGateway(GATEWAY_DWOLLA) && Input::get('error')) {
$errorMessage = trans('texts.payment_error')."\n\n".Input::get('error_description');
Session::flash('error', $errorMessage);
- Utils::logError($errorMessage);
+ Utils::logError('Payment Error [dwolla]: ' . $errorMessage);
return Redirect::to('view/'.$invitation->invitation_key);
}
@@ -729,7 +729,7 @@ class PaymentController extends BaseController
} else {
$errorMessage = trans('texts.payment_error')."\n\n".$response->getMessage();
Session::flash('error', $errorMessage);
- Utils::logError($errorMessage);
+ Utils::logError('Payment Error [offsite]: ' . $errorMessage);
return Redirect::to('view/'.$invitation->invitation_key);
}
@@ -742,7 +742,7 @@ class PaymentController extends BaseController
} catch (\Exception $e) {
$errorMessage = trans('texts.payment_error');
Session::flash('error', $errorMessage);
- Utils::logError($errorMessage."\n\n".$e->getMessage());
+ Utils::logError('Payment Error [offsite-uncaught]: ' . $errorMessage."\n\n".$e->getMessage());
return Redirect::to('view/'.$invitation->invitation_key);
}
diff --git a/app/Http/Controllers/QuoteApiController.php b/app/Http/Controllers/QuoteApiController.php
index 83e5e8781179..24fd1639215f 100644
--- a/app/Http/Controllers/QuoteApiController.php
+++ b/app/Http/Controllers/QuoteApiController.php
@@ -14,13 +14,19 @@ class QuoteApiController extends Controller
$this->invoiceRepo = $invoiceRepo;
}
- public function index()
+ public function index($clientPublicId = false)
{
$invoices = Invoice::scope()
->with('client', 'user')
- ->where('invoices.is_quote', '=', true)
- ->orderBy('created_at', 'desc')
- ->get();
+ ->where('invoices.is_quote', '=', true);
+
+ if ($clientPublicId) {
+ $invoices->whereHas('client', function($query) use ($clientPublicId) {
+ $query->where('public_id', '=', $clientPublicId);
+ });
+ }
+
+ $invoices = $invoices->orderBy('created_at', 'desc')->get();
$invoices = Utils::remapPublicIds($invoices);
$response = json_encode($invoices, JSON_PRETTY_PRINT);
diff --git a/app/Http/Controllers/QuoteController.php b/app/Http/Controllers/QuoteController.php
index d84ce2fece65..ba1db21ad9cf 100644
--- a/app/Http/Controllers/QuoteController.php
+++ b/app/Http/Controllers/QuoteController.php
@@ -53,7 +53,7 @@ class QuoteController extends BaseController
$data = [
'title' => trans('texts.quotes'),
'entityType' => ENTITY_QUOTE,
- 'columns' => Utils::trans(['checkbox', 'quote_number', 'client', 'quote_date', 'quote_total', 'due_date', 'status', 'action']),
+ 'columns' => Utils::trans(['checkbox', 'quote_number', 'client', 'quote_date', 'quote_total', 'valid_until', 'status', 'action']),
];
/*
diff --git a/app/Http/Controllers/TaskApiController.php b/app/Http/Controllers/TaskApiController.php
new file mode 100644
index 000000000000..c15ea9fb659a
--- /dev/null
+++ b/app/Http/Controllers/TaskApiController.php
@@ -0,0 +1,56 @@
+taskRepo = $taskRepo;
+ }
+
+ public function index($clientPublicId = false)
+ {
+ $tasks = Task::scope()->with('client');
+
+ if ($clientPublicId) {
+ $tasks->whereHas('client', function($query) use ($clientPublicId) {
+ $query->where('public_id', '=', $clientPublicId);
+ });
+ }
+
+ $tasks = $tasks->orderBy('created_at', 'desc')->get();
+ $tasks = Utils::remapPublicIds($tasks);
+
+ $response = json_encode($tasks, JSON_PRETTY_PRINT);
+ $headers = Utils::getApiHeaders(count($tasks));
+
+ return Response::make($response, 200, $headers);
+ }
+
+ public function store()
+ {
+ $data = Input::all();
+ $taskId = isset($data['id']) ? $data['id'] : false;
+
+ if (isset($data['client_id']) && $data['client_id']) {
+ $data['client'] = $data['client_id'];
+ }
+
+ $task = $this->taskRepo->save($taskId, $data);
+ $task = Task::scope($task->public_id)->with('client')->first();
+ $task = Utils::remapPublicIds([$task]);
+
+ $response = json_encode($task, JSON_PRETTY_PRINT);
+ $headers = Utils::getApiHeaders();
+
+ return Response::make($response, 200, $headers);
+ }
+
+}
diff --git a/app/Http/Controllers/TaskController.php b/app/Http/Controllers/TaskController.php
index 9d15eb5f9278..3312b914f764 100644
--- a/app/Http/Controllers/TaskController.php
+++ b/app/Http/Controllers/TaskController.php
@@ -155,7 +155,7 @@ class TaskController extends BaseController
if ($task->invoice) {
$actions[] = ['url' => URL::to("inovices/{$task->invoice->public_id}/edit"), 'label' => trans("texts.view_invoice")];
} else {
- $actions[] = ['url' => 'javascript:submitAction("invoice")', 'label' => trans("texts.create_invoice")];
+ $actions[] = ['url' => 'javascript:submitAction("invoice")', 'label' => trans("texts.invoice_task")];
// check for any open invoices
$invoices = $task->client_id ? $this->invoiceRepo->findOpenInvoices($task->client_id) : [];
diff --git a/app/Http/Middleware/VerifyCsrfToken.php b/app/Http/Middleware/VerifyCsrfToken.php
index bc70cdf6a810..33f62d417d81 100644
--- a/app/Http/Middleware/VerifyCsrfToken.php
+++ b/app/Http/Middleware/VerifyCsrfToken.php
@@ -11,6 +11,7 @@ class VerifyCsrfToken extends BaseVerifier {
'api/v1/invoices',
'api/v1/quotes',
'api/v1/payments',
+ 'api/v1/tasks',
'api/v1/email_invoice',
'api/v1/hooks',
];
diff --git a/app/Http/routes.php b/app/Http/routes.php
index 12377947f698..128e1f34cd2d 100644
--- a/app/Http/routes.php
+++ b/app/Http/routes.php
@@ -182,9 +182,14 @@ Route::group(['middleware' => 'api', 'prefix' => 'api/v1'], function()
{
Route::resource('ping', 'ClientApiController@ping');
Route::resource('clients', 'ClientApiController');
- Route::resource('invoices', 'InvoiceApiController');
+ Route::get('quotes/{client_id?}', 'QuoteApiController@index');
Route::resource('quotes', 'QuoteApiController');
+ Route::get('invoices/{client_id?}', 'InvoiceApiController@index');
+ Route::resource('invoices', 'InvoiceApiController');
+ Route::get('payments/{client_id?}', 'PaymentApiController@index');
Route::resource('payments', 'PaymentApiController');
+ Route::get('tasks/{client_id?}', 'TaskApiController@index');
+ Route::resource('tasks', 'TaskApiController');
Route::post('hooks', 'IntegrationController@subscribe');
Route::post('email_invoice', 'InvoiceApiController@emailInvoice');
});
diff --git a/app/Models/Account.php b/app/Models/Account.php
index fbd10efcd9b6..24884436f8b7 100644
--- a/app/Models/Account.php
+++ b/app/Models/Account.php
@@ -16,7 +16,7 @@ class Account extends Eloquent
/*
protected $casts = [
- 'hide_quantity' => 'boolean',
+ 'invoice_settings' => 'object',
];
*/
@@ -282,6 +282,7 @@ class Account extends Eloquent
'invoice_to',
'details',
'invoice_no',
+ 'valid_until',
];
foreach ($fields as $field) {
@@ -394,11 +395,8 @@ class Account extends Eloquent
}
$template = "\$client,
\r\n\r\n" .
- trans("texts.{$entityType}_message", ['amount' => '$amount']) . "
\r\n\r\n";
-
- if ($entityType != ENTITY_PAYMENT) {
- $template .= "\$link
\r\n\r\n";
- }
+ trans("texts.{$entityType}_message", ['amount' => '$amount']) . "
\r\n\r\n" .
+ "\$link
\r\n\r\n";
if ($message) {
$template .= "$message
\r\n\r\n";
@@ -411,7 +409,7 @@ class Account extends Eloquent
{
if ($this->email_footer) {
// Add line breaks if HTML isn't already being used
- return strip_tags($this->email_footer) == $this->email_footer ? nl2br($this->email_footer) : $this->email_footer;
+ return strip_tags($this->email_footer) == $this->email_footer ? nl2br($this->email_footer) : $this->email_footer;
} else {
return "" . trans('texts.email_signature') . " \$account
";
}
diff --git a/app/Models/Country.php b/app/Models/Country.php
index 219251a44cc4..3d6e0ea5036b 100644
--- a/app/Models/Country.php
+++ b/app/Models/Country.php
@@ -6,7 +6,7 @@ class Country extends Eloquent
{
public $timestamps = false;
- protected $visible = ['id', 'name'];
+ protected $visible = ['id', 'name', 'swap_postal_code'];
public function getName()
{
diff --git a/app/Models/Invoice.php b/app/Models/Invoice.php
index aeebfaed6ab0..c4f4e82c7c41 100644
--- a/app/Models/Invoice.php
+++ b/app/Models/Invoice.php
@@ -184,6 +184,7 @@ class Invoice extends EntityModel
'custom_invoice_label1',
'custom_invoice_label2',
'pdf_email_attachment',
+ 'show_item_taxes',
]);
foreach ($this->invoice_items as $invoiceItem) {
diff --git a/app/Ninja/Mailers/ContactMailer.php b/app/Ninja/Mailers/ContactMailer.php
index f68633e83414..08cfb65b7490 100644
--- a/app/Ninja/Mailers/ContactMailer.php
+++ b/app/Ninja/Mailers/ContactMailer.php
@@ -92,16 +92,20 @@ class ContactMailer extends Mailer
'$amount' => Utils::formatMoney($payment->amount, $payment->client->getCurrencyId())
];
- $data = ['body' => str_replace(array_keys($variables), array_values($variables), $emailTemplate)];
-
if ($payment->invitation) {
$user = $payment->invitation->user;
$contact = $payment->contact;
+ $variables['$link'] = $payment->invitation->getLink();
} else {
$user = $payment->user;
$contact = $payment->client->contacts[0];
+ $variables['$link'] = $payment->invoice->invitations[0]->getLink();
}
+ $data = ['body' => str_replace(array_keys($variables), array_values($variables), $emailTemplate)];
+
+ //$data['invoice_id'] = $payment->invoice->id;
+
if ($user->email && $contact->email) {
$this->sendTo($contact->email, $user->email, $accountName, $subject, $view, $data);
}
diff --git a/app/Ninja/Repositories/InvoiceRepository.php b/app/Ninja/Repositories/InvoiceRepository.php
index df73c6f6a1e6..6e43993f34d2 100644
--- a/app/Ninja/Repositories/InvoiceRepository.php
+++ b/app/Ninja/Repositories/InvoiceRepository.php
@@ -190,7 +190,7 @@ class InvoiceRepository
}
private function getStatusLabel($statusId, $statusName) {
- $label = trans("texts.{$statusName}");
+ $label = trans("texts.status_" . strtolower($statusName));
$class = 'default';
switch ($statusId) {
case INVOICE_STATUS_SENT:
@@ -206,7 +206,7 @@ class InvoiceRepository
$class = 'success';
break;
}
- return "$statusName
";
+ return "$label
";
}
public function getErrors($input)
diff --git a/app/Ninja/Repositories/TaskRepository.php b/app/Ninja/Repositories/TaskRepository.php
index 47761900e1e6..d47a1165cd94 100644
--- a/app/Ninja/Repositories/TaskRepository.php
+++ b/app/Ninja/Repositories/TaskRepository.php
@@ -68,15 +68,17 @@ class TaskRepository
$timeLog = [];
}
- if ($data['action'] == 'start') {
- $task->is_running = true;
- $timeLog[] = [strtotime('now'), false];
- } else if ($data['action'] == 'resume') {
- $task->is_running = true;
- $timeLog[] = [strtotime('now'), false];
- } else if ($data['action'] == 'stop' && $task->is_running) {
- $timeLog[count($timeLog)-1][1] = time();
- $task->is_running = false;
+ if (isset($data['action'])) {
+ if ($data['action'] == 'start') {
+ $task->is_running = true;
+ $timeLog[] = [strtotime('now'), false];
+ } else if ($data['action'] == 'resume') {
+ $task->is_running = true;
+ $timeLog[] = [strtotime('now'), false];
+ } else if ($data['action'] == 'stop' && $task->is_running) {
+ $timeLog[count($timeLog)-1][1] = time();
+ $task->is_running = false;
+ }
}
$task->time_log = json_encode($timeLog);
diff --git a/database/migrations/2014_05_17_175626_add_quotes.php b/database/migrations/2014_05_17_175626_add_quotes.php
index 6299ad124dc0..96ae916cafae 100644
--- a/database/migrations/2014_05_17_175626_add_quotes.php
+++ b/database/migrations/2014_05_17_175626_add_quotes.php
@@ -28,8 +28,8 @@ class AddQuotes extends Migration {
public function down()
{
Schema::table('invoices', function($table)
- {
- $table->dropColumn('is_quote');
+ {
+ $table->dropColumn('is_quote');
$table->dropColumn('quote_id');
$table->dropColumn('quote_invoice_id');
});
diff --git a/database/migrations/2015_08_13_084041_add_formats_to_datetime_formats_table.php b/database/migrations/2015_08_13_084041_add_formats_to_datetime_formats_table.php
index a61c5d52024d..e01127023c4e 100644
--- a/database/migrations/2015_08_13_084041_add_formats_to_datetime_formats_table.php
+++ b/database/migrations/2015_08_13_084041_add_formats_to_datetime_formats_table.php
@@ -36,4 +36,4 @@ class AddFormatsToDatetimeFormatsTable extends Migration
$table->dropColumn('format_moment');
});
}
-}
\ No newline at end of file
+}
diff --git a/database/migrations/2015_09_04_080604_add_swap_postal_code.php b/database/migrations/2015_09_04_080604_add_swap_postal_code.php
new file mode 100644
index 000000000000..a80a50b48539
--- /dev/null
+++ b/database/migrations/2015_09_04_080604_add_swap_postal_code.php
@@ -0,0 +1,38 @@
+boolean('swap_postal_code')->default(0);
+ });
+
+ Schema::table('accounts', function ($table) {
+ $table->boolean('show_item_taxes')->default(0);
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::table('countries', function ($table) {
+ $table->dropColumn('swap_postal_code');
+ });
+
+ Schema::table('accounts', function ($table) {
+ $table->dropColumn('show_item_taxes');
+ });
+ }
+}
diff --git a/database/seeds/PaymentLibrariesSeeder.php b/database/seeds/PaymentLibrariesSeeder.php
index 71ffd2ac4c25..4dd8a7cd2e94 100644
--- a/database/seeds/PaymentLibrariesSeeder.php
+++ b/database/seeds/PaymentLibrariesSeeder.php
@@ -6,6 +6,7 @@ use App\Models\Currency;
use App\Models\DateFormat;
use App\Models\DatetimeFormat;
use App\Models\InvoiceDesign;
+use App\Models\Country;
class PaymentLibrariesSeeder extends Seeder
{
@@ -18,6 +19,7 @@ class PaymentLibrariesSeeder extends Seeder
$this->createDateFormats();
$this->createDatetimeFormats();
$this->createInvoiceDesigns();
+ $this->updateSwapPostalCode();
}
private function createGateways() {
@@ -224,4 +226,38 @@ class PaymentLibrariesSeeder extends Seeder
}
}
+ private function updateSwapPostalCode() {
+ // Source: http://www.bitboost.com/ref/international-address-formats.html
+ $countries = [
+ 'AR',
+ 'AT',
+ 'CH',
+ 'BE',
+ 'DE',
+ 'DK',
+ 'ES',
+ 'FI',
+ 'FR',
+ 'GL',
+ 'IL',
+ 'IS',
+ 'IT',
+ 'LU',
+ 'MY',
+ 'MX',
+ 'NL',
+ 'PL',
+ 'PT',
+ 'SE',
+ 'UY',
+ ];
+
+ for ($i=0; $ifirst();
+ $country->swap_postal_code = true;
+ $country->save();
+ }
+ }
+
}
diff --git a/public/apple-touch-icon-120x120.png b/public/apple-touch-icon-120x120.png
new file mode 100644
index 0000000000000000000000000000000000000000..46bb79d000a769aee48bfea29b4a03950b86954f
GIT binary patch
literal 4389
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
F`8U-nk1YTI
literal 0
HcmV?d00001
diff --git a/public/js/built.js b/public/js/built.js
index c3dfc49f9d53..9ba59e134b8c 100644
--- a/public/js/built.js
+++ b/public/js/built.js
@@ -30685,6 +30685,21 @@ function displaySubtotals(doc, layout, invoice, y, rightAlignTitleX)
return displayGrid(doc, invoice, data, 300, y, layout, options) + 10;
}
+function formatAddress(city, state, zip, swap) {
+ var str = '';
+ if (swap) {
+ str += zip ? zip + ' ' : '';
+ str += city ? city : '';
+ str += (city && state) ? ', ' : (city ? ' ' : '');
+ str += state;
+ } else {
+ str += city ? city : '';
+ str += (city && state) ? ', ' : (state ? ' ' : '');
+ str += state + ' ' + zip;
+ }
+ return str;
+}
+
function concatStrings() {
var concatStr = '';
var data = [];
@@ -31613,15 +31628,16 @@ NINJA.decodeJavascript = function(invoice, javascript)
'accountDetails': NINJA.accountDetails(invoice),
'accountAddress': NINJA.accountAddress(invoice),
'invoiceDetails': NINJA.invoiceDetails(invoice),
- 'invoiceDetailsHeight': NINJA.invoiceDetails(invoice).length * 22,
+ 'invoiceDetailsHeight': (NINJA.invoiceDetails(invoice).length * 16) + 16,
'invoiceLineItems': NINJA.invoiceLines(invoice),
'invoiceLineItemColumns': NINJA.invoiceColumns(invoice),
'quantityWidth': NINJA.quantityWidth(invoice),
'clientDetails': NINJA.clientDetails(invoice),
'notesAndTerms': NINJA.notesAndTerms(invoice),
'subtotals': NINJA.subtotals(invoice),
- 'subtotalsHeight': NINJA.subtotals(invoice).length * 22,
+ '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),
'invoiceFooter': invoice.invoice_footer || ' ',
'invoiceNumber': invoice.invoice_number || ' ',
@@ -31715,16 +31731,24 @@ NINJA.notesAndTerms = function(invoice)
NINJA.invoiceColumns = function(invoice)
{
- if (invoice.account.hide_quantity == '1') {
- return ["15%", "*", "15%", "15%"];
- } else {
- return ["15%", "*", "14%", "14%", "14%"];
+ var account = invoice.account;
+ var columns = ["15%", "*"];
+ var count = 3;
+ if (account.hide_quantity == '1') {
+ count--;
}
+ if (account.show_item_taxes == '1') {
+ count++;
+ }
+ for (var i=0; iFor at tilgå under indstillingerne ved hjælp af dot notation. For eksempel kan man for at vise klient navnet bruge $client.nameValue
.
Hvis du mangler svar på nogen spørgsmål så post et spørgsmål i vores support forum .
',
+ 'invoice_due_date' => 'Due Date',
+ 'quote_due_date' => 'Valid Until',
+ 'valid_until' => 'Valid Until',
+ 'reset_terms' => 'Reset terms',
+ 'reset_footer' => 'Reset footer',
+ 'invoices_sent' => ':count invoice sent|:count invoices sent',
+ 'status_draft' => 'Draft',
+ 'status_sent' => 'Sent',
+ 'status_viewed' => 'Viewed',
+ 'status_partial' => 'Partial',
+ 'status_paid' => 'Paid',
+ 'show_line_item_tax' => 'Display line item taxes inline',
+
);
\ No newline at end of file
diff --git a/resources/lang/de/texts.php b/resources/lang/de/texts.php
index 26dd8210cf52..0aa939ee4776 100644
--- a/resources/lang/de/texts.php
+++ b/resources/lang/de/texts.php
@@ -752,7 +752,21 @@ return array(
'customize_help' => 'We use pdfmake to define the invoice designs declaratively. The pdfmake playground provide\'s a great way to see the library in action.
You can access any invoice field by adding Value
to the end. For example $invoiceNumberValue
displays the invoice number.
To access a child property using dot notation. For example to show the client name you could use $client.nameValue
.
- If you need help figuring something out post a question to our support forum .
'
-
+ If you need help figuring something out post a question to our support forum .
',
+
+ 'invoice_due_date' => 'Due Date',
+ 'quote_due_date' => 'Valid Until',
+ 'valid_until' => 'Valid Until',
+ 'reset_terms' => 'Reset terms',
+ 'reset_footer' => 'Reset footer',
+ 'invoices_sent' => ':count invoice sent|:count invoices sent',
+ 'status_draft' => 'Draft',
+ 'status_sent' => 'Sent',
+ 'status_viewed' => 'Viewed',
+ 'status_partial' => 'Partial',
+ 'status_paid' => 'Paid',
+ 'show_line_item_tax' => 'Display line item taxes inline',
+
+
);
diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php
index 85bfc7395ac5..0e7e605bddb2 100644
--- a/resources/lang/en/texts.php
+++ b/resources/lang/en/texts.php
@@ -58,8 +58,8 @@ return array(
'enable' => 'Enable',
'learn_more' => 'Learn more',
'manage_rates' => 'Manage rates',
- 'note_to_client' => 'Note to client',
- 'invoice_terms' => 'Invoice terms',
+ 'note_to_client' => 'Note to Client',
+ 'invoice_terms' => 'Invoice Terms',
'save_as_default_terms' => 'Save as default terms',
'download_pdf' => 'Download PDF',
'pay_now' => 'Pay Now',
@@ -536,7 +536,7 @@ return array(
'click_once' => '*Please click "PAY NOW" only once - transaction may take up to 1 minute to process.',
'default_invoice_footer' => 'Set default invoice footer ',
- 'invoice_footer' => 'Invoice footer',
+ 'invoice_footer' => 'Invoice Footer',
'save_as_default_footer' => 'Save as default footer',
'token_management' => 'Token Management',
@@ -752,8 +752,20 @@ return array(
'customize_help' => 'We use pdfmake to define the invoice designs declaratively. The pdfmake playground provide\'s a great way to see the library in action.
You can access any invoice field by adding Value
to the end. For example $invoiceNumberValue
displays the invoice number.
To access a child property using dot notation. For example to show the client name you could use $client.nameValue
.
- If you need help figuring something out post a question to our support forum .
'
+ If you need help figuring something out post a question to our support forum .
',
+ 'invoice_due_date' => 'Due Date',
+ 'quote_due_date' => 'Valid Until',
+ 'valid_until' => 'Valid Until',
+ 'reset_terms' => 'Reset terms',
+ 'reset_footer' => 'Reset footer',
+ 'invoices_sent' => ':count invoice sent|:count invoices sent',
+ 'status_draft' => 'Draft',
+ 'status_sent' => 'Sent',
+ 'status_viewed' => 'Viewed',
+ 'status_partial' => 'Partial',
+ 'status_paid' => 'Paid',
+ 'show_line_item_tax' => 'Display line item taxes inline',
);
diff --git a/resources/lang/es/texts.php b/resources/lang/es/texts.php
index eb3b960c436d..4ead48f37a8e 100644
--- a/resources/lang/es/texts.php
+++ b/resources/lang/es/texts.php
@@ -730,7 +730,20 @@ return array(
'customize_help' => 'Nosotros usamos pdfmake para definir los diseños de las cuentas de cobro de manera declarativa. El playground de pdfmake es una excelente manera de ver a la librería en acción.
Puede acceder cualquier campo de una factura agregando Value
al final. Por ejemplo, $invoiceNumberValue
muestra el número de factura.
Para acceder a una propiedad hija usando notación de punto.Por ejemplo, para mostrar el nombre de un cliente se puede usar $client.nameValue
.
- Si necesita ayuda entendiendo algo puede preguntar en nuestro foro de soporte .
'
+ Si necesita ayuda entendiendo algo puede preguntar en nuestro foro de soporte .
',
+
+ 'invoice_due_date' => 'Due Date',
+ 'quote_due_date' => 'Valid Until',
+ 'valid_until' => 'Valid Until',
+ 'reset_terms' => 'Reset terms',
+ 'reset_footer' => 'Reset footer',
+ 'invoices_sent' => ':count invoice sent|:count invoices sent',
+ 'status_draft' => 'Draft',
+ 'status_sent' => 'Sent',
+ 'status_viewed' => 'Viewed',
+ 'status_partial' => 'Partial',
+ 'status_paid' => 'Paid',
+ 'show_line_item_tax' => 'Display line item taxes inline',
diff --git a/resources/lang/es_ES/texts.php b/resources/lang/es_ES/texts.php
index abac45b8f600..e46005f97a44 100644
--- a/resources/lang/es_ES/texts.php
+++ b/resources/lang/es_ES/texts.php
@@ -752,7 +752,20 @@ return array(
'customize_help' => 'We use pdfmake to define the invoice designs declaratively. The pdfmake playground provide\'s a great way to see the library in action.
You can access any invoice field by adding Value
to the end. For example $invoiceNumberValue
displays the invoice number.
To access a child property using dot notation. For example to show the client name you could use $client.nameValue
.
- If you need help figuring something out post a question to our support forum .
'
+ If you need help figuring something out post a question to our support forum .
',
+
+ 'invoice_due_date' => 'Due Date',
+ 'quote_due_date' => 'Valid Until',
+ 'valid_until' => 'Valid Until',
+ 'reset_terms' => 'Reset terms',
+ 'reset_footer' => 'Reset footer',
+ 'invoices_sent' => ':count invoice sent|:count invoices sent',
+ 'status_draft' => 'Draft',
+ 'status_sent' => 'Sent',
+ 'status_viewed' => 'Viewed',
+ 'status_partial' => 'Partial',
+ 'status_paid' => 'Paid',
+ 'show_line_item_tax' => 'Display line item taxes inline',
diff --git a/resources/lang/fr/texts.php b/resources/lang/fr/texts.php
index fb2c63f5d2dc..5a6005dfae0d 100644
--- a/resources/lang/fr/texts.php
+++ b/resources/lang/fr/texts.php
@@ -744,7 +744,20 @@ return array(
'customize_help' => 'Nous utilisons pdfmake pour définir le design des factures. Le bac à sable de pdfmake est une bonne façon de voir cette bibliothèque en action.
Vous pouvez accéder à n\'importe quel champ de facture en ajoutant Value
à la fin. Par exemple $invoiceNumberValue
affiche le numéro de facture.
Pour accéder à une propriété héritée avec la notation par point. Par exemple pour montrer le nom du client vous pouvez utiliser $client.nameValue
.
- Si vous avez besoin d\'aide pour comprendre quelque chose envoyez une question à notre forum de support .
'
+ Si vous avez besoin d\'aide pour comprendre quelque chose envoyez une question à notre forum de support .
',
+
+ 'invoice_due_date' => 'Due Date',
+ 'quote_due_date' => 'Valid Until',
+ 'valid_until' => 'Valid Until',
+ 'reset_terms' => 'Reset terms',
+ 'reset_footer' => 'Reset footer',
+ 'invoices_sent' => ':count invoice sent|:count invoices sent',
+ 'status_draft' => 'Draft',
+ 'status_sent' => 'Sent',
+ 'status_viewed' => 'Viewed',
+ 'status_partial' => 'Partial',
+ 'status_paid' => 'Paid',
+ 'show_line_item_tax' => 'Display line item taxes inline',
diff --git a/resources/lang/fr_CA/texts.php b/resources/lang/fr_CA/texts.php
index 9ccbfb13080d..224f6f21137a 100644
--- a/resources/lang/fr_CA/texts.php
+++ b/resources/lang/fr_CA/texts.php
@@ -745,7 +745,21 @@ return array(
'customize_help' => 'We use pdfmake to define the invoice designs declaratively. The pdfmake playground provide\'s a great way to see the library in action.
You can access any invoice field by adding Value
to the end. For example $invoiceNumberValue
displays the invoice number.
To access a child property using dot notation. For example to show the client name you could use $client.nameValue
.
- If you need help figuring something out post a question to our support forum .
'
+ If you need help figuring something out post a question to our support forum .
',
+
+ 'invoice_due_date' => 'Due Date',
+ 'quote_due_date' => 'Valid Until',
+ 'valid_until' => 'Valid Until',
+ 'reset_terms' => 'Reset terms',
+ 'reset_footer' => 'Reset footer',
+ 'invoices_sent' => ':count invoice sent|:count invoices sent',
+ 'status_draft' => 'Draft',
+ 'status_sent' => 'Sent',
+ 'status_viewed' => 'Viewed',
+ 'status_partial' => 'Partial',
+ 'status_paid' => 'Paid',
+ 'show_line_item_tax' => 'Display line item taxes inline',
+
diff --git a/resources/lang/it/texts.php b/resources/lang/it/texts.php
index 996c4672da8f..b999643fff33 100644
--- a/resources/lang/it/texts.php
+++ b/resources/lang/it/texts.php
@@ -747,7 +747,20 @@ return array(
'customize_help' => 'We use pdfmake to define the invoice designs declaratively. The pdfmake playground provide\'s a great way to see the library in action.
You can access any invoice field by adding Value
to the end. For example $invoiceNumberValue
displays the invoice number.
To access a child property using dot notation. For example to show the client name you could use $client.nameValue
.
- If you need help figuring something out post a question to our support forum .
'
+ If you need help figuring something out post a question to our support forum .
',
+
+ 'invoice_due_date' => 'Due Date',
+ 'quote_due_date' => 'Valid Until',
+ 'valid_until' => 'Valid Until',
+ 'reset_terms' => 'Reset terms',
+ 'reset_footer' => 'Reset footer',
+ 'invoices_sent' => ':count invoice sent|:count invoices sent',
+ 'status_draft' => 'Draft',
+ 'status_sent' => 'Sent',
+ 'status_viewed' => 'Viewed',
+ 'status_partial' => 'Partial',
+ 'status_paid' => 'Paid',
+ 'show_line_item_tax' => 'Display line item taxes inline',
diff --git a/resources/lang/lt/texts.php b/resources/lang/lt/texts.php
index 1bbf6a1ddd9a..a0957572f616 100644
--- a/resources/lang/lt/texts.php
+++ b/resources/lang/lt/texts.php
@@ -754,7 +754,20 @@ return array(
'customize_help' => 'We use pdfmake to define the invoice designs declaratively. The pdfmake playground provide\'s a great way to see the library in action.
You can access any invoice field by adding Value
to the end. For example $invoiceNumberValue
displays the invoice number.
To access a child property using dot notation. For example to show the client name you could use $client.nameValue
.
- If you need help figuring something out post a question to our support forum .
'
+ If you need help figuring something out post a question to our support forum .
',
+
+ 'invoice_due_date' => 'Due Date',
+ 'quote_due_date' => 'Valid Until',
+ 'valid_until' => 'Valid Until',
+ 'reset_terms' => 'Reset terms',
+ 'reset_footer' => 'Reset footer',
+ 'invoices_sent' => ':count invoice sent|:count invoices sent',
+ 'status_draft' => 'Draft',
+ 'status_sent' => 'Sent',
+ 'status_viewed' => 'Viewed',
+ 'status_partial' => 'Partial',
+ 'status_paid' => 'Paid',
+ 'show_line_item_tax' => 'Display line item taxes inline',
diff --git a/resources/lang/nb_NO/texts.php b/resources/lang/nb_NO/texts.php
index bdea61343590..12fb585562c1 100644
--- a/resources/lang/nb_NO/texts.php
+++ b/resources/lang/nb_NO/texts.php
@@ -752,7 +752,20 @@ return array(
'customize_help' => 'We use pdfmake to define the invoice designs declaratively. The pdfmake playground provide\'s a great way to see the library in action.
You can access any invoice field by adding Value
to the end. For example $invoiceNumberValue
displays the invoice number.
To access a child property using dot notation. For example to show the client name you could use $client.nameValue
.
- If you need help figuring something out post a question to our support forum .
'
+ If you need help figuring something out post a question to our support forum .
',
+
+ 'invoice_due_date' => 'Due Date',
+ 'quote_due_date' => 'Valid Until',
+ 'valid_until' => 'Valid Until',
+ 'reset_terms' => 'Reset terms',
+ 'reset_footer' => 'Reset footer',
+ 'invoices_sent' => ':count invoice sent|:count invoices sent',
+ 'status_draft' => 'Draft',
+ 'status_sent' => 'Sent',
+ 'status_viewed' => 'Viewed',
+ 'status_partial' => 'Partial',
+ 'status_paid' => 'Paid',
+ 'show_line_item_tax' => 'Display line item taxes inline',
diff --git a/resources/lang/nl/texts.php b/resources/lang/nl/texts.php
index 273739466a78..7c452a446a85 100644
--- a/resources/lang/nl/texts.php
+++ b/resources/lang/nl/texts.php
@@ -747,7 +747,20 @@ return array(
'customize_help' => 'We gebruiken pdfmake om de factuur ontwerpen declaratief te definieren. De pdfmake playground is een interessante manier om de library in actie te zien.
Je kan elk factuur veld gebruiken door Veld
toe te voegen op het einde. Bijvoorbeeld $invoiceNumberValue
toont de factuur nummer.
Gebruik dot notatie om een "kind eigenschap" te gebruiken. Bijvoorbeeld voor de klant naam te tonen gebruik je $client.nameValue
.
- Als je ergens hulp bij nodig hebt, post dan een vraag op ons support forum .
'
+ Als je ergens hulp bij nodig hebt, post dan een vraag op ons support forum .
',
+
+ 'invoice_due_date' => 'Due Date',
+ 'quote_due_date' => 'Valid Until',
+ 'valid_until' => 'Valid Until',
+ 'reset_terms' => 'Reset terms',
+ 'reset_footer' => 'Reset footer',
+ 'invoices_sent' => ':count invoice sent|:count invoices sent',
+ 'status_draft' => 'Draft',
+ 'status_sent' => 'Sent',
+ 'status_viewed' => 'Viewed',
+ 'status_partial' => 'Partial',
+ 'status_paid' => 'Paid',
+ 'show_line_item_tax' => 'Display line item taxes inline',
diff --git a/resources/lang/pt_BR/texts.php b/resources/lang/pt_BR/texts.php
index b3e9389e7d0d..083919ab7482 100644
--- a/resources/lang/pt_BR/texts.php
+++ b/resources/lang/pt_BR/texts.php
@@ -747,8 +747,20 @@ return array(
'customize_help' => 'We use pdfmake to define the invoice designs declaratively. The pdfmake playground provide\'s a great way to see the library in action.
You can access any invoice field by adding Value
to the end. For example $invoiceNumberValue
displays the invoice number.
To access a child property using dot notation. For example to show the client name you could use $client.nameValue
.
- If you need help figuring something out post a question to our support forum .
'
+ If you need help figuring something out post a question to our support forum .
',
+ 'invoice_due_date' => 'Due Date',
+ 'quote_due_date' => 'Valid Until',
+ 'valid_until' => 'Valid Until',
+ 'reset_terms' => 'Reset terms',
+ 'reset_footer' => 'Reset footer',
+ 'invoices_sent' => ':count invoice sent|:count invoices sent',
+ 'status_draft' => 'Draft',
+ 'status_sent' => 'Sent',
+ 'status_viewed' => 'Viewed',
+ 'status_partial' => 'Partial',
+ 'status_paid' => 'Paid',
+ 'show_line_item_tax' => 'Display line item taxes inline',
);
diff --git a/resources/lang/sv/texts.php b/resources/lang/sv/texts.php
index 4cac8ff4c2ef..96cdb1e885a0 100644
--- a/resources/lang/sv/texts.php
+++ b/resources/lang/sv/texts.php
@@ -750,7 +750,20 @@ return array(
'customize_help' => 'We use pdfmake to define the invoice designs declaratively. The pdfmake playground provide\'s a great way to see the library in action.
You can access any invoice field by adding Value
to the end. For example $invoiceNumberValue
displays the invoice number.
To access a child property using dot notation. For example to show the client name you could use $client.nameValue
.
- If you need help figuring something out post a question to our support forum .
'
+ If you need help figuring something out post a question to our support forum .
',
+
+ 'invoice_due_date' => 'Due Date',
+ 'quote_due_date' => 'Valid Until',
+ 'valid_until' => 'Valid Until',
+ 'reset_terms' => 'Reset terms',
+ 'reset_footer' => 'Reset footer',
+ 'invoices_sent' => ':count invoice sent|:count invoices sent',
+ 'status_draft' => 'Draft',
+ 'status_sent' => 'Sent',
+ 'status_viewed' => 'Viewed',
+ 'status_partial' => 'Partial',
+ 'status_paid' => 'Paid',
+ 'show_line_item_tax' => 'Display line item taxes inline',
diff --git a/resources/views/accounts/invoice_design.blade.php b/resources/views/accounts/invoice_design.blade.php
index 0e93c4727115..d152914f68e0 100644
--- a/resources/views/accounts/invoice_design.blade.php
+++ b/resources/views/accounts/invoice_design.blade.php
@@ -35,7 +35,7 @@
invoice.account.hide_quantity = $('#hide_quantity').is(":checked");
invoice.account.hide_paid_to_date = $('#hide_paid_to_date').is(":checked");
invoice.invoice_design_id = $('#invoice_design_id').val();
-
+
NINJA.primaryColor = $('#primary_color').val();
NINJA.secondaryColor = $('#secondary_color').val();
NINJA.fontSize = parseInt($('#font_size').val());
@@ -82,6 +82,7 @@
{!! Former::populate($account) !!}
{!! Former::populateField('hide_quantity', intval($account->hide_quantity)) !!}
{!! Former::populateField('hide_paid_to_date', intval($account->hide_paid_to_date)) !!}
+
@foreach ($invoiceLabels as $field => $value)
{!! Former::populateField("labels_{$field}", $value) !!}
@endforeach
@@ -136,14 +137,14 @@
- @if (Auth::user()->isPro())
- {!! Former::actions( Button::success(trans('texts.save'))->submit()->large()->appendIcon(Icon::create('floppy-disk'))) !!}
- @else
-
+ @if (Auth::user()->isPro())
+ {!! Former::actions( Button::success(trans('texts.save'))->submit()->large()->appendIcon(Icon::create('floppy-disk'))) !!}
+ @else
+
@endif
{!! Former::close() !!}
diff --git a/resources/views/clients/show.blade.php b/resources/views/clients/show.blade.php
index 2c507d504048..2eb8c85937cb 100644
--- a/resources/views/clients/show.blade.php
+++ b/resources/views/clients/show.blade.php
@@ -200,7 +200,7 @@
trans('texts.quote_number'),
trans('texts.quote_date'),
trans('texts.total'),
- trans('texts.due_date'),
+ trans('texts.valid_until'),
trans('texts.status'))
->setUrl(url('api/quotes/'. $client->public_id))
->setOptions('sPaginationType', 'bootstrap')
diff --git a/resources/views/credits/edit.blade.php b/resources/views/credits/edit.blade.php
index 3cb86b89fed9..5c8377038f21 100644
--- a/resources/views/credits/edit.blade.php
+++ b/resources/views/credits/edit.blade.php
@@ -16,7 +16,10 @@
{!! Former::select('client')->addOption('', '')->addGroupClass('client-select') !!}
{!! Former::text('amount') !!}
- {!! Former::text('credit_date')->data_date_format(Session::get(SESSION_DATE_PICKER_FORMAT, DEFAULT_DATE_PICKER_FORMAT))->append(' ') !!}
+ {!! Former::text('credit_date')
+ ->data_date_format(Session::get(SESSION_DATE_PICKER_FORMAT, DEFAULT_DATE_PICKER_FORMAT))
+ ->addGroupClass('credit_date')
+ ->append(' ') !!}
{!! Former::textarea('private_notes') !!}
@@ -61,6 +64,9 @@
$('#amount').focus();
@endif
+ $('.credit_date .input-group-addon').click(function() {
+ toggleDatePicker('credit_date');
+ });
});
diff --git a/resources/views/dashboard.blade.php b/resources/views/dashboard.blade.php
index f4e52f16e67f..637a7e4430dc 100644
--- a/resources/views/dashboard.blade.php
+++ b/resources/views/dashboard.blade.php
@@ -72,7 +72,7 @@
{{ trans('texts.notifications') }}
- {{ $invoicesSent }} {{ Utils::pluralize('invoice', $invoicesSent) }} {{ trans('texts.sent') }}
+ {{ trans_choice('texts.invoices_sent', $invoicesSent) }}
diff --git a/resources/views/invoices/edit.blade.php b/resources/views/invoices/edit.blade.php
index 2bccd8a79849..f1bb1dc7fc52 100644
--- a/resources/views/invoices/edit.blade.php
+++ b/resources/views/invoices/edit.blade.php
@@ -81,8 +81,8 @@
{!! Former::text('invoice_date')->data_bind("datePicker: invoice_date, valueUpdate: 'afterkeydown'")->label(trans("texts.{$entityType}_date"))
->data_date_format(Session::get(SESSION_DATE_PICKER_FORMAT, DEFAULT_DATE_PICKER_FORMAT))->appendIcon('calendar')->addGroupClass('invoice_date') !!}
- {!! Former::text('due_date')->data_bind("datePicker: due_date, valueUpdate: 'afterkeydown'")
- ->data_date_format(Session::get(SESSION_DATE_PICKER_FORMAT, DEFAULT_DATE_PICKER_FORMAT))->appendIcon('calendar')->addGroupClass('due_date') !!}
+ {!! Former::text('due_date')->data_bind("datePicker: due_date, valueUpdate: 'afterkeydown'")->label(trans("texts.{$entityType}_due_date"))
+ ->data_date_format(Session::get(SESSION_DATE_PICKER_FORMAT, DEFAULT_DATE_PICKER_FORMAT))->appendIcon('calendar')->addGroupClass('due_date') !!}
{!! Former::text('partial')->data_bind("value: partial, valueUpdate: 'afterkeydown'")->onchange('onPartialChange()')
->rel('tooltip')->data_toggle('tooltip')->data_placement('bottom')->title(trans('texts.partial_value')) !!}
@@ -202,16 +202,24 @@
->label(null)->style('resize: none; min-width: 450px;')->rows(3) !!}
- {!! Former::textarea('terms')->data_bind("value:wrapped_terms, placeholder: default_terms, valueUpdate: 'afterkeydown'")
+ {!! Former::textarea('terms')->data_bind("value:wrapped_terms, placeholder: terms_placeholder, valueUpdate: 'afterkeydown'")
->label(false)->style('resize: none; min-width: 450px')->rows(3)
- ->help('
- '.trans('texts.save_as_default_terms').' ') !!}
+ ->help('
+
+ '.trans('texts.save_as_default_terms').'
+
+
+
') !!}
@@ -500,6 +508,8 @@
->label(trans('texts.settings'))->data_bind('checked: $root.invoice_taxes, enable: $root.tax_rates().length > 1') !!}
{!! Former::checkbox('invoice_item_taxes')->text(trans('texts.enable_line_item_tax'))
->label(' ')->data_bind('checked: $root.invoice_item_taxes, enable: $root.tax_rates().length > 1') !!}
+ {!! Former::checkbox('show_item_taxes')->text(trans('texts.show_line_item_tax'))
+ ->label(' ')->data_bind('checked: $root.show_item_taxes, enable: $root.tax_rates().length > 1') !!}
@@ -546,19 +556,12 @@
$(function() {
$('#country_id').combobox().on('change', function(e) {
- var countryId = parseInt($('input[name=country_id]').val(), 10);
- var foundMatch = false;
- $('#country_id option').each(function() {
- var itemId = parseInt($(this).val(), 10);
- if (countryId === itemId) {
- foundMatch = true;
- var country = {id:countryId, name:$(this).text()};
- model.invoice().client().country = country;
- model.invoice().client().country_id(countryId);
- return;
- }
- });
- if (!foundMatch) {
+ var countryId = $('input[name=country_id]').val();
+ var country = _.findWhere(countries, {id: countryId});
+ if (country) {
+ model.invoice().client().country = country;
+ model.invoice().client().country_id(countryId);
+ } else {
model.invoice().client().country = false;
model.invoice().client().country_id(0);
}
@@ -702,10 +705,11 @@
}
function createInvoiceModel() {
- var invoice = ko.toJS(model).invoice;
+ var invoice = ko.toJS(model).invoice;
invoice.is_pro = {{ Auth::user()->isPro() ? 'true' : 'false' }};
invoice.is_quote = {{ $entityType == ENTITY_QUOTE ? 'true' : 'false' }};
invoice.contact = _.findWhere(invoice.client.contacts, {send_invoice: true});
+ invoice.account.show_item_taxes = $('#show_item_taxes').is(':checked');
if (invoice.is_recurring) {
invoice.invoice_number = '0000';
@@ -752,6 +756,18 @@
}
}
+ function resetTerms() {
+ model.invoice().terms(model.invoice().default_terms());
+ refreshPDF();
+ return false;
+ }
+
+ function resetFooter() {
+ model.invoice().invoice_footer(model.invoice().default_footer());
+ refreshPDF();
+ return false;
+ }
+
function onDownloadClick() {
trackEvent('/activity', '/download_pdf');
var invoice = createInvoiceModel();
@@ -952,6 +968,7 @@
self.invoice_taxes = ko.observable({{ Auth::user()->account->invoice_taxes ? 'true' : 'false' }});
self.invoice_item_taxes = ko.observable({{ Auth::user()->account->invoice_item_taxes ? 'true' : 'false' }});
+ self.show_item_taxes = ko.observable({{ Auth::user()->account->show_item_taxes ? 'true' : 'false' }});
self.mapping = {
'invoice': {
@@ -1056,7 +1073,8 @@
self.taxFormComplete = function() {
model.taxBackup = false;
- $('#taxModal').modal('hide');
+ $('#taxModal').modal('hide');
+ refreshPDF();
}
self.showClientForm = function() {
@@ -1143,10 +1161,12 @@
self.is_amount_discount = ko.observable(0);
self.frequency_id = ko.observable(4); // default to monthly
self.terms = ko.observable('');
- self.default_terms = ko.observable({{ !$invoice && $account->invoice_terms ? 'true' : 'false' }} ? wordWrapText('{!! str_replace(["\r\n","\r","\n"], '\n', addslashes($account->invoice_terms)) !!}', 300) : '');
+ self.default_terms = ko.observable("{{ str_replace(["\r\n","\r","\n"], '\n', addslashes($account->invoice_terms)) }}");
+ self.terms_placeholder = ko.observable({{ !$invoice && $account->invoice_terms ? 'true' : 'false' }} ? self.default_terms() : '');
self.set_default_terms = ko.observable(false);
self.invoice_footer = ko.observable('');
- self.default_footer = ko.observable({{ !$invoice && $account->invoice_footer ? 'true' : 'false' }} ? wordWrapText('{!! str_replace(["\r\n","\r","\n"], '\n', addslashes($account->invoice_footer)) !!}', 600) : '');
+ self.default_footer = ko.observable("{{ str_replace(["\r\n","\r","\n"], '\n', addslashes($account->invoice_footer)) }}");
+ self.footer_placeholder = ko.observable({{ !$invoice && $account->invoice_footer ? 'true' : 'false' }} ? self.default_footer() : '');
self.set_default_footer = ko.observable(false);
self.public_notes = ko.observable('');
self.po_number = ko.observable('');
@@ -1786,7 +1806,8 @@
var products = {!! $products !!};
var clients = {!! $clients !!};
-
+ var countries = {!! $countries !!};
+
var clientMap = {};
var $clientSelect = $('select#client');
var invoiceDesigns = {!! $invoiceDesigns !!};
diff --git a/resources/views/invoices/pdf.blade.php b/resources/views/invoices/pdf.blade.php
index f60e7ac096d2..53dcfbee7bef 100644
--- a/resources/views/invoices/pdf.blade.php
+++ b/resources/views/invoices/pdf.blade.php
@@ -81,7 +81,7 @@
if (window.invoice) {
invoiceLabels.item = invoice.has_tasks ? invoiceLabels.date : invoiceLabels.item_orig;
invoiceLabels.quantity = invoice.has_tasks ? invoiceLabels.hours : invoiceLabels.quantity_orig;
- invoiceLabels.unit_cost = invoice.has_tasks ? invoiceLabels.rate : invoiceLabels.unit_cost_orig;
+ invoiceLabels.unit_cost = invoice.has_tasks ? invoiceLabels.rate : invoiceLabels.unit_cost_orig;
}
var isRefreshing = false;
diff --git a/resources/views/invoices/view.blade.php b/resources/views/invoices/view.blade.php
index 0d01cbd3c779..873c06cb8205 100644
--- a/resources/views/invoices/view.blade.php
+++ b/resources/views/invoices/view.blade.php
@@ -25,7 +25,7 @@
@if ($invoice->is_quote)
{!! Button::normal(trans('texts.download_pdf'))->withAttributes(['onclick' => 'onDownloadClick()'])->large() !!}
- @if (!$isConverted)
+ @if ($showApprove)
{!! Button::success(trans('texts.approve'))->asLinkTo(URL::to('/approve/' . $invitation->invitation_key))->large() !!}
@endif
@elseif ($invoice->client->account->isGatewayConfigured() && !$invoice->isPaid() && !$invoice->is_recurring)
diff --git a/resources/views/master.blade.php b/resources/views/master.blade.php
index 895fd93b439e..adadb5578e05 100644
--- a/resources/views/master.blade.php
+++ b/resources/views/master.blade.php
@@ -17,6 +17,7 @@
+
diff --git a/resources/views/payments/edit.blade.php b/resources/views/payments/edit.blade.php
index b36be5428d68..611751ceba21 100644
--- a/resources/views/payments/edit.blade.php
+++ b/resources/views/payments/edit.blade.php
@@ -32,7 +32,10 @@
->addGroupClass('payment-type-select') !!}
@endif
- {!! Former::text('payment_date')->data_date_format(Session::get(SESSION_DATE_PICKER_FORMAT))->append('
') !!}
+ {!! Former::text('payment_date')
+ ->data_date_format(Session::get(SESSION_DATE_PICKER_FORMAT))
+ ->addGroupClass('payment_date')
+ ->append('
') !!}
{!! Former::text('transaction_reference') !!}
@if (!$payment)
@@ -76,6 +79,10 @@
@elseif (!$payment)
$('#amount').focus();
@endif
+
+ $('.payment_date .input-group-addon').click(function() {
+ toggleDatePicker('payment_date');
+ });
});
diff --git a/resources/views/public/header.blade.php b/resources/views/public/header.blade.php
index cc6a59e4b269..1063e6cb83da 100644
--- a/resources/views/public/header.blade.php
+++ b/resources/views/public/header.blade.php
@@ -144,10 +144,6 @@ table.table thead .sorting_desc_disabled:after { content: '' !important }
$('[name="guest_key"]').val(localStorage.getItem('guest_key'));
}
- @if (isset($invoiceNow) && $invoiceNow)
- getStarted();
- @endif
-
function isStorageSupported() {
if ('localStorage' in window && window['localStorage'] !== null) {
var storage = window.localStorage;
diff --git a/resources/views/public/invoice_now.blade.php b/resources/views/public/invoice_now.blade.php
new file mode 100644
index 000000000000..b18c37965395
--- /dev/null
+++ b/resources/views/public/invoice_now.blade.php
@@ -0,0 +1,37 @@
+@extends('master')
+
+@section('body')
+
+{!! Form::open(array('url' => 'get_started', 'id' => 'startForm')) !!}
+{!! Form::hidden('guest_key') !!}
+{!! Form::hidden('sign_up', Input::get('sign_up')) !!}
+{!! Form::hidden('redirect_to', Input::get('redirect_to')) !!}
+{!! Form::close() !!}
+
+
+
+@stop
\ No newline at end of file
diff --git a/resources/views/reports/chart_builder.blade.php b/resources/views/reports/chart_builder.blade.php
index 361a4d6ad386..61e332d20157 100644
--- a/resources/views/reports/chart_builder.blade.php
+++ b/resources/views/reports/chart_builder.blade.php
@@ -40,8 +40,10 @@
{!! Former::populateField('enable_chart', intval($enableChart)) !!}
{!! Former::text('start_date')->data_date_format(Session::get(SESSION_DATE_PICKER_FORMAT))
+ ->addGroupClass('start_date')
->append('
') !!}
{!! Former::text('end_date')->data_date_format(Session::get(SESSION_DATE_PICKER_FORMAT))
+ ->addGroupClass('end_date')
->append('
') !!}
@@ -185,6 +187,15 @@
scaleLabel : "<%=value%>",
};
+ $(function() {
+ $('.start_date .input-group-addon').click(function() {
+ toggleDatePicker('start_date');
+ });
+ $('.end_date .input-group-addon').click(function() {
+ toggleDatePicker('end_date');
+ });
+ })
+
new Chart(ctx).{!! $chartType !!}(chart, options);
diff --git a/resources/views/users/account_management.blade.php b/resources/views/users/account_management.blade.php
index 3839a0bb4377..328ca9b920e2 100644
--- a/resources/views/users/account_management.blade.php
+++ b/resources/views/users/account_management.blade.php
@@ -4,7 +4,9 @@
- {!! Button::success(trans('texts.add_company'))->asLinkTo('/login?new_company=true') !!}
+ @if (!session(SESSION_USER_ACCOUNTS) || count(session(SESSION_USER_ACCOUNTS)) < 5)
+ {!! Button::success(trans('texts.add_company'))->asLinkTo('/login?new_company=true') !!}
+ @endif
diff --git a/storage/templates/bold.js b/storage/templates/bold.js
index 2a289f0f72f9..4784d1fe4367 100644
--- a/storage/templates/bold.js
+++ b/storage/templates/bold.js
@@ -3,17 +3,12 @@
{
"columns": [
{
- "image": "$accountLogo",
- "width": 80,
- "margin": [60, -40, 0, 0]
- },
- {
- "width": 300,
+ "width": 380,
"stack": [
{"text":"$yourInvoiceLabelUC", "style": "yourInvoice"},
"$clientDetails"
],
- "margin": [-32, 120, 0, 0]
+ "margin": [60, 100, 0, 10]
},
{
"canvas": [
@@ -29,14 +24,14 @@
}
],
"width":10,
- "margin":[-10,120,0,0]
+ "margin":[-10,100,0,10]
},
{
"table": {
"body": "$invoiceDetails"
},
"layout": "noBorders",
- "margin": [0, 130, 0, 0]
+ "margin": [0, 110, 0, 0]
}
]
},
@@ -44,7 +39,7 @@
"style": "invoiceLineItemsTable",
"table": {
"headerRows": 1,
- "widths": ["15%", "*", "12%", "$quantityWidth", "22%"],
+ "widths": ["15%", "*", "14%", "$quantityWidth", "22%"],
"body": "$invoiceLineItems"
},
"layout": {
@@ -80,36 +75,58 @@
}
],
"footer": [
- {"canvas": [{ "type": "line", "x1": 0, "y1": 0, "x2": 600, "y2": 0,"lineWidth": 100,"lineColor":"#2e2b2b"}]},
+ {"canvas": [{ "type": "line", "x1": 0, "y1": 0, "x2": 600, "y2": 0,"lineWidth": 100,"lineColor":"$secondaryColor:#2e2b2b"}]},
{
"text": "$invoiceFooter",
- "margin": [40, -20, 40, 0],
+ "margin": [40, 0, 40, 0],
"alignment": "left",
"color": "#FFFFFF"
}
],
"header": [
- {"canvas": [{ "type": "line", "x1": 0, "y1": 0, "x2": 50, "y2":0,"lineWidth": 200,"lineColor":"#2e2b2b"}],"width":100,"margin":[0,0,0,0]},
- {"canvas": [{ "type": "line", "x1": 0, "y1": 0, "x2": 150, "y2":0,"lineWidth": 60,"lineColor":"#2e2b2b"}],"width":100,"margin":[0,0,0,0]},
- {"canvas": [{ "type": "line", "x1": 149, "y1": 0, "x2": 600, "y2":0,"lineWidth": 200,"lineColor":"#2e2b2b"}],"width":10,"margin":[0,0,0,0]},
- {
+ {
+ "canvas": [
+ {
+ "type": "line",
+ "x1": 0,
+ "y1": 0,
+ "x2": 600,
+ "y2": 0,
+ "lineWidth": 200,
+ "lineColor": "$secondaryColor:#2e2b2b"
+ }
+ ],
+ "width": 10
+ },
+ {
"columns": [
- {
- "text": " ",
- "width": 260
- },
- {
- "stack": "$accountDetails",
- "margin": [0, 16, 0, 0],
- "width": 140
- },
- {
- "stack": "$accountAddress",
- "margin": [20, 16, 0, 0]
- }
+ {
+ "image": "$accountLogo",
+ "fit": [120, 80],
+ "margin": [30, 20, 0, 0]
+ },
+ {
+ "stack": "$accountDetails",
+ "margin": [
+ 0,
+ 16,
+ 0,
+ 0
+ ],
+ "width": 140
+ },
+ {
+ "stack": "$accountAddress",
+ "margin": [
+ 20,
+ 16,
+ 0,
+ 0
+ ]
+ }
]
- }
- ],
+ }
+ ],
"defaultStyle": {
"fontSize": "$fontSize",
"margin": [8, 4, 8, 4]
@@ -120,16 +137,19 @@
},
"accountName": {
"bold": true,
- "margin": [4, 2, 4, 2],
+ "margin": [4, 2, 4, 1],
"color": "$primaryColor:#36a498"
},
"accountDetails": {
- "margin": [4, 2, 4, 2],
- "color": "#AAA9A9"
+ "margin": [4, 2, 4, 1],
+ "color": "#FFFFFF"
},
"accountAddress": {
- "margin": [4, 2, 4, 2],
- "color": "#AAA9A9"
+ "margin": [4, 2, 4, 1],
+ "color": "#FFFFFF"
+ },
+ "clientDetails": {
+ "margin": [0, 2, 0, 1]
},
"odd": {
"fillColor": "#ebebeb",
@@ -169,6 +189,9 @@
"qtyTableHeader": {
"alignment": "right"
},
+ "taxTableHeader": {
+ "alignment": "right"
+ },
"lineTotalTableHeader": {
"alignment": "right",
"margin": [0, 0, 40, 0]
diff --git a/storage/templates/clean.js b/storage/templates/clean.js
index 8f4c70ee16cb..22b0b7149495 100644
--- a/storage/templates/clean.js
+++ b/storage/templates/clean.js
@@ -156,6 +156,9 @@
"qtyTableHeader": {
"alignment": "right"
},
+ "taxTableHeader": {
+ "alignment": "right"
+ },
"lineTotalTableHeader": {
"alignment": "right"
},
diff --git a/storage/templates/modern.js b/storage/templates/modern.js
index f37bc2acceb7..7471bbeb11b0 100644
--- a/storage/templates/modern.js
+++ b/storage/templates/modern.js
@@ -14,7 +14,7 @@
]
},
{
- "canvas": [{ "type": "rect", "x": 0, "y": 0, "w": 515, "h": 26, "r":0, "lineWidth": 1, "color":"#403d3d"}],"width":10,"margin":[0,25,0,-30]},
+ "canvas": [{ "type": "rect", "x": 0, "y": 0, "w": 515, "h": 26, "r":0, "lineWidth": 1, "color":"$secondaryColor:#403d3d"}],"width":10,"margin":[0,25,0,-30]},
{
"style": "invoiceLineItemsTable",
"table": {
@@ -63,7 +63,7 @@
"h": 26,
"r": 0,
"lineWidth": 1,
- "color": "#403d3d"
+ "color": "$secondaryColor:#403d3d"
}
],
"width": 10,
@@ -183,6 +183,9 @@
"qtyTableHeader": {
"alignment": "right"
},
+ "taxTableHeader": {
+ "alignment": "right"
+ },
"lineTotalTableHeader": {
"alignment": "right"
},