mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-07 19:04:41 -04:00
Merge remote-tracking branch 'upstream/master'
Conflicts: app/views/clients/edit.blade.php
This commit is contained in:
commit
7acb1a92c1
1
.gitignore
vendored
1
.gitignore
vendored
@ -10,6 +10,7 @@
|
|||||||
/bootstrap/compiled.php
|
/bootstrap/compiled.php
|
||||||
/bootstrap/environment.php
|
/bootstrap/environment.php
|
||||||
/vendor
|
/vendor
|
||||||
|
/.env.development.php
|
||||||
/composer.phar
|
/composer.phar
|
||||||
/composer.lock
|
/composer.lock
|
||||||
/.DS_Store
|
/.DS_Store
|
||||||
|
@ -6,7 +6,9 @@
|
|||||||
|
|
||||||
Most online invoicing sites are expensive. They shouldn't be. The aim of this project is to provide a free, open-source alternative. Additionally, the hope is the codebase will serve as a sample site for Laravel as well as other JavaScript technologies.
|
Most online invoicing sites are expensive. They shouldn't be. The aim of this project is to provide a free, open-source alternative. Additionally, the hope is the codebase will serve as a sample site for Laravel as well as other JavaScript technologies.
|
||||||
|
|
||||||
For updates follow [@invoiceninja](https://twitter.com/invoiceninja) and [@hillelcoren](https://twitter.com/hillelcoren)
|
The high level instructions for setting up the site are below but there's also a [setup guide](http://hillelcoren.com/invoice-ninja/laravel-ubuntu-virtualbox/). For discussion of the code please use the [Google Group](https://groups.google.com/d/forum/invoiceninja).
|
||||||
|
|
||||||
|
For updates follow [@invoiceninja](https://twitter.com/invoiceninja) or join the [Facebook Group](https://www.facebook.com/invoiceninja).
|
||||||
|
|
||||||
Site design by [kantorp-wegl.in](http://kantorp-wegl.in/)
|
Site design by [kantorp-wegl.in](http://kantorp-wegl.in/)
|
||||||
|
|
||||||
@ -65,4 +67,5 @@ Configure config/database.php and then initialize the database
|
|||||||
* [mozilla/pdf.js](https://github.com/mozilla/pdf.js) - PDF Reader in JavaScript
|
* [mozilla/pdf.js](https://github.com/mozilla/pdf.js) - PDF Reader in JavaScript
|
||||||
* [nnnick/Chart.js](https://github.com/nnnick/Chart.js) - Simple HTML5 Charts using the <canvas> tag
|
* [nnnick/Chart.js](https://github.com/nnnick/Chart.js) - Simple HTML5 Charts using the <canvas> tag
|
||||||
* [josscrowcroft/accounting.js](https://github.com/josscrowcroft/accounting.js) - A lightweight JavaScript library for number, money and currency formatting
|
* [josscrowcroft/accounting.js](https://github.com/josscrowcroft/accounting.js) - A lightweight JavaScript library for number, money and currency formatting
|
||||||
* [jashkenas/underscore](https://github.com/jashkenas/underscore) - JavaScript's utility _ belt
|
* [jashkenas/underscore](https://github.com/jashkenas/underscore) - JavaScript's utility _ belt
|
||||||
|
* [caouecs/Laravel4-long](https://github.com/caouecs/Laravel4-lang) - List of languages for Laravel4
|
@ -121,8 +121,7 @@ return array(
|
|||||||
'Barryvdh\Debugbar\ServiceProvider',
|
'Barryvdh\Debugbar\ServiceProvider',
|
||||||
'Chumper\Datatable\DatatableServiceProvider',
|
'Chumper\Datatable\DatatableServiceProvider',
|
||||||
'Intervention\Image\ImageServiceProvider',
|
'Intervention\Image\ImageServiceProvider',
|
||||||
'Webpatser\Countries\CountriesServiceProvider',
|
'Webpatser\Countries\CountriesServiceProvider'
|
||||||
'Rocketeer\RocketeerServiceProvider',
|
|
||||||
),
|
),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -48,7 +48,7 @@
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Where Former should look for translations
|
// Where Former should look for translations
|
||||||
'translate_from' => 'validation.attributes',
|
'translate_from' => 'texts',
|
||||||
|
|
||||||
// An array of attributes to automatically translate
|
// An array of attributes to automatically translate
|
||||||
'translatable' => array(
|
'translatable' => array(
|
||||||
|
@ -86,7 +86,8 @@ class AccountController extends \BaseController {
|
|||||||
'timezones' => Timezone::remember(DEFAULT_QUERY_CACHE)->orderBy('location')->get(),
|
'timezones' => Timezone::remember(DEFAULT_QUERY_CACHE)->orderBy('location')->get(),
|
||||||
'dateFormats' => DateFormat::remember(DEFAULT_QUERY_CACHE)->get(),
|
'dateFormats' => DateFormat::remember(DEFAULT_QUERY_CACHE)->get(),
|
||||||
'datetimeFormats' => DatetimeFormat::remember(DEFAULT_QUERY_CACHE)->get(),
|
'datetimeFormats' => DatetimeFormat::remember(DEFAULT_QUERY_CACHE)->get(),
|
||||||
'currencies' => Currency::remember(DEFAULT_QUERY_CACHE)->orderBy('name')->get(),
|
'currencies' => Currency::remember(DEFAULT_QUERY_CACHE)->orderBy('name')->get(),
|
||||||
|
'languages' => Language::remember(DEFAULT_QUERY_CACHE)->orderBy('name')->get(),
|
||||||
];
|
];
|
||||||
|
|
||||||
return View::make('accounts.details', $data);
|
return View::make('accounts.details', $data);
|
||||||
@ -442,7 +443,7 @@ class AccountController extends \BaseController {
|
|||||||
|
|
||||||
foreach ($fields as $field => $details)
|
foreach ($fields as $field => $details)
|
||||||
{
|
{
|
||||||
if (!in_array($field, ['testMode', 'developerMode', 'headerImageUrl', 'solutionType', 'landingPage']))
|
if (!in_array($field, ['testMode', 'developerMode', 'headerImageUrl', 'solutionType', 'landingPage', 'brandName']))
|
||||||
{
|
{
|
||||||
$rules[$gateway->id.'_'.$field] = 'required';
|
$rules[$gateway->id.'_'.$field] = 'required';
|
||||||
}
|
}
|
||||||
@ -460,7 +461,7 @@ class AccountController extends \BaseController {
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
$account = Account::findOrFail(Auth::user()->account_id);
|
$account = Account::findOrFail(Auth::user()->account_id);
|
||||||
$account->account_gateways()->forceDelete();
|
$account->account_gateways()->delete();
|
||||||
|
|
||||||
if ($gatewayId)
|
if ($gatewayId)
|
||||||
{
|
{
|
||||||
@ -499,7 +500,7 @@ class AccountController extends \BaseController {
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$account = Account::findOrFail(Auth::user()->account_id);
|
$account = Auth::user()->account;
|
||||||
$account->name = trim(Input::get('name'));
|
$account->name = trim(Input::get('name'));
|
||||||
$account->work_email = trim(Input::get('work_email'));
|
$account->work_email = trim(Input::get('work_email'));
|
||||||
$account->work_phone = trim(Input::get('work_phone'));
|
$account->work_phone = trim(Input::get('work_phone'));
|
||||||
@ -514,7 +515,8 @@ class AccountController extends \BaseController {
|
|||||||
$account->timezone_id = Input::get('timezone_id') ? Input::get('timezone_id') : null;
|
$account->timezone_id = Input::get('timezone_id') ? Input::get('timezone_id') : null;
|
||||||
$account->date_format_id = Input::get('date_format_id') ? Input::get('date_format_id') : null;
|
$account->date_format_id = Input::get('date_format_id') ? Input::get('date_format_id') : null;
|
||||||
$account->datetime_format_id = Input::get('datetime_format_id') ? Input::get('datetime_format_id') : null;
|
$account->datetime_format_id = Input::get('datetime_format_id') ? Input::get('datetime_format_id') : null;
|
||||||
$account->currency_id = Input::get('currency_id') ? Input::get('currency_id') : 1;
|
$account->currency_id = Input::get('currency_id') ? Input::get('currency_id') : 1; // US Dollar
|
||||||
|
$account->language_id = Input::get('language_id') ? Input::get('language_id') : 1; // English
|
||||||
$account->save();
|
$account->save();
|
||||||
|
|
||||||
$user = Auth::user();
|
$user = Auth::user();
|
||||||
@ -529,8 +531,8 @@ class AccountController extends \BaseController {
|
|||||||
if ($file = Input::file('logo'))
|
if ($file = Input::file('logo'))
|
||||||
{
|
{
|
||||||
$path = Input::file('logo')->getRealPath();
|
$path = Input::file('logo')->getRealPath();
|
||||||
File::delete('logo/' . $account->account_key . '.jpg');
|
File::delete('logo/' . $account->account_key . '.jpg');
|
||||||
Image::make($path)->resize(120, 80, true, false)->save('logo/' . $account->account_key . '.jpg');
|
Image::make($path)->resize(null, 120, true, false)->save('logo/' . $account->account_key . '.jpg');
|
||||||
}
|
}
|
||||||
|
|
||||||
Event::fire('user.refresh');
|
Event::fire('user.refresh');
|
||||||
@ -540,6 +542,14 @@ class AccountController extends \BaseController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function removeLogo() {
|
||||||
|
|
||||||
|
File::delete('logo/' . Auth::user()->account->account_key . '.jpg');
|
||||||
|
|
||||||
|
Session::flash('message', 'Successfully removed logo');
|
||||||
|
return Redirect::to('company/details');
|
||||||
|
}
|
||||||
|
|
||||||
public function checkEmail()
|
public function checkEmail()
|
||||||
{
|
{
|
||||||
$email = User::withTrashed()->where('email', '=', Input::get('email'))->where('id', '<>', Auth::user()->id)->first();
|
$email = User::withTrashed()->where('email', '=', Input::get('email'))->where('id', '<>', Auth::user()->id)->first();
|
||||||
|
@ -23,7 +23,7 @@ class ClientController extends \BaseController {
|
|||||||
return View::make('list', array(
|
return View::make('list', array(
|
||||||
'entityType'=>ENTITY_CLIENT,
|
'entityType'=>ENTITY_CLIENT,
|
||||||
'title' => '- Clients',
|
'title' => '- Clients',
|
||||||
'columns'=>['checkbox', 'Client', 'Contact', 'Email', 'Date Created', 'Last Login', 'Balance', 'Action']
|
'columns'=>Utils::trans(['checkbox', 'client', 'contact', 'email', 'date_created', 'last_login', 'balance', 'action'])
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,17 +43,17 @@ class ClientController extends \BaseController {
|
|||||||
{
|
{
|
||||||
return '<div class="btn-group tr-action" style="visibility:hidden;">
|
return '<div class="btn-group tr-action" style="visibility:hidden;">
|
||||||
<button type="button" class="btn btn-xs btn-default dropdown-toggle" data-toggle="dropdown">
|
<button type="button" class="btn btn-xs btn-default dropdown-toggle" data-toggle="dropdown">
|
||||||
Select <span class="caret"></span>
|
'.trans('texts.select').' <span class="caret"></span>
|
||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu" role="menu">
|
<ul class="dropdown-menu" role="menu">
|
||||||
<li><a href="' . URL::to('clients/'.$model->public_id.'/edit') . '">Edit Client</a></li>
|
<li><a href="' . URL::to('clients/'.$model->public_id.'/edit') . '">'.trans('texts.edit_client').'</a></li>
|
||||||
<li class="divider"></li>
|
<li class="divider"></li>
|
||||||
<li><a href="' . URL::to('invoices/create/'.$model->public_id) . '">New Invoice</a></li>
|
<li><a href="' . URL::to('invoices/create/'.$model->public_id) . '">'.trans('texts.new_invoice').'</a></li>
|
||||||
<li><a href="' . URL::to('payments/create/'.$model->public_id) . '">New Payment</a></li>
|
<li><a href="' . URL::to('payments/create/'.$model->public_id) . '">'.trans('texts.new_payment').'</a></li>
|
||||||
<li><a href="' . URL::to('credits/create/'.$model->public_id) . '">New Credit</a></li>
|
<li><a href="' . URL::to('credits/create/'.$model->public_id) . '">'.trans('texts.new_credit').'</a></li>
|
||||||
<li class="divider"></li>
|
<li class="divider"></li>
|
||||||
<li><a href="javascript:archiveEntity(' . $model->public_id. ')">Archive Client</a></li>
|
<li><a href="javascript:archiveEntity(' . $model->public_id. ')">'.trans('texts.archive_client').'</a></li>
|
||||||
<li><a href="javascript:deleteEntity(' . $model->public_id. ')">Delete Client</a></li>
|
<li><a href="javascript:deleteEntity(' . $model->public_id. ')">'.trans('texts.delete_client').'</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>';
|
</div>';
|
||||||
})
|
})
|
||||||
|
@ -23,7 +23,7 @@ class CreditController extends \BaseController {
|
|||||||
return View::make('list', array(
|
return View::make('list', array(
|
||||||
'entityType'=>ENTITY_CREDIT,
|
'entityType'=>ENTITY_CREDIT,
|
||||||
'title' => '- Credits',
|
'title' => '- Credits',
|
||||||
'columns'=>['checkbox', 'Client', 'Credit Amount', 'Credit Balance', 'Credit Date', 'Private Notes', 'Action']
|
'columns'=>Utils::trans(['checkbox', 'client', 'credit_amount', 'credit_balance', 'credit_date', 'private_notes', 'action'])
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,11 +47,11 @@ class CreditController extends \BaseController {
|
|||||||
{
|
{
|
||||||
return '<div class="btn-group tr-action" style="visibility:hidden;">
|
return '<div class="btn-group tr-action" style="visibility:hidden;">
|
||||||
<button type="button" class="btn btn-xs btn-default dropdown-toggle" data-toggle="dropdown">
|
<button type="button" class="btn btn-xs btn-default dropdown-toggle" data-toggle="dropdown">
|
||||||
Select <span class="caret"></span>
|
'.trans('texts.select').' <span class="caret"></span>
|
||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu" role="menu">
|
<ul class="dropdown-menu" role="menu">
|
||||||
<li><a href="javascript:archiveEntity(' . $model->public_id. ')">Archive Credit</a></li>
|
<li><a href="javascript:archiveEntity(' . $model->public_id. ')">'.trans('texts.archive_credit').'</a></li>
|
||||||
<li><a href="javascript:deleteEntity(' . $model->public_id. ')">Delete Credit</a></li>
|
<li><a href="javascript:deleteEntity(' . $model->public_id. ')">'.trans('texts.delete_credit').'</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>';
|
</div>';
|
||||||
})
|
})
|
||||||
|
@ -43,11 +43,11 @@ class DashboardController extends \BaseController {
|
|||||||
->orderBy('due_date', 'asc')->take(6)->get();
|
->orderBy('due_date', 'asc')->take(6)->get();
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
'totalIncome' => Utils::formatMoney($totalIncome->value, Session::get(SESSION_CURRENCY)),
|
'totalIncome' => Utils::formatMoney($totalIncome ? $totalIncome->value : 0, Session::get(SESSION_CURRENCY)),
|
||||||
'billedClients' => $metrics->billed_clients,
|
'billedClients' => $metrics ? $metrics->billed_clients : 0,
|
||||||
'invoicesSent' => $metrics->invoices_sent,
|
'invoicesSent' => $metrics ? $metrics->invoices_sent : 0,
|
||||||
'activeClients' => $metrics->active_clients,
|
'activeClients' => $metrics ? $metrics->active_clients : 0,
|
||||||
'invoiceAvg' => Utils::formatMoney($metrics->invoice_avg, Session::get(SESSION_CURRENCY)),
|
'invoiceAvg' => Utils::formatMoney(($metrics ? $metrics->invoice_avg : 0), Session::get(SESSION_CURRENCY)),
|
||||||
'activities' => $activities,
|
'activities' => $activities,
|
||||||
'pastDue' => $pastDue,
|
'pastDue' => $pastDue,
|
||||||
'upcoming' => $upcoming
|
'upcoming' => $upcoming
|
||||||
|
@ -16,22 +16,22 @@ class HomeController extends BaseController {
|
|||||||
|
|
||||||
public function showWelcome()
|
public function showWelcome()
|
||||||
{
|
{
|
||||||
return View::make('splash');
|
return View::make('public.splash');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function showAboutUs()
|
public function showAboutUs()
|
||||||
{
|
{
|
||||||
return View::make('about_us');
|
return View::make('public.about_us');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function showContactUs()
|
public function showContactUs()
|
||||||
{
|
{
|
||||||
return View::make('contact_us');
|
return View::make('public.contact_us');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function showTerms()
|
public function showTerms()
|
||||||
{
|
{
|
||||||
return View::make('terms');
|
return View::make('public.terms');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function doContactUs()
|
public function doContactUs()
|
||||||
@ -46,7 +46,7 @@ class HomeController extends BaseController {
|
|||||||
'text' => $message
|
'text' => $message
|
||||||
];
|
];
|
||||||
|
|
||||||
$this->mailer->sendTo('contact@invoiceninja.com', 'contact@invoiceninja.com', 'Invoice Ninja Feedback', 'contact', $data);
|
$this->mailer->sendTo(CONTACT_EMAIL, CONTACT_EMAIL, CONTACT_NAME, 'Invoice Ninja Feedback', 'contact', $data);
|
||||||
|
|
||||||
Session::flash('message', 'Successfully sent message');
|
Session::flash('message', 'Successfully sent message');
|
||||||
return Redirect::to('/contact');
|
return Redirect::to('/contact');
|
||||||
|
@ -27,13 +27,13 @@ class InvoiceController extends \BaseController {
|
|||||||
$data = [
|
$data = [
|
||||||
'title' => '- Invoices',
|
'title' => '- Invoices',
|
||||||
'entityType'=>ENTITY_INVOICE,
|
'entityType'=>ENTITY_INVOICE,
|
||||||
'columns'=>['checkbox', 'Invoice Number', 'Client', 'Invoice Date', 'Invoice Total', 'Balance Due', 'Due Date', 'Status', 'Action']
|
'columns'=>Utils::trans(['checkbox', 'invoice_number', 'client', 'invoice_date', 'invoice_total', 'balance_due', 'due_date', 'status', 'action'])
|
||||||
];
|
];
|
||||||
|
|
||||||
if (Invoice::scope()->where('is_recurring', '=', true)->count() > 0)
|
if (Invoice::scope()->where('is_recurring', '=', true)->count() > 0)
|
||||||
{
|
{
|
||||||
$data['secEntityType'] = ENTITY_RECURRING_INVOICE;
|
$data['secEntityType'] = ENTITY_RECURRING_INVOICE;
|
||||||
$data['secColumns'] = ['checkbox', 'Frequency', 'Client', 'Start Date', 'End Date', 'Invoice Total', 'Action'];
|
$data['secColumns'] = Utils::trans(['checkbox', 'frequency', 'client', 'start_date', 'end_date', 'invoice_total', 'action']);
|
||||||
}
|
}
|
||||||
|
|
||||||
return View::make('list', $data);
|
return View::make('list', $data);
|
||||||
@ -63,14 +63,14 @@ class InvoiceController extends \BaseController {
|
|||||||
{
|
{
|
||||||
return '<div class="btn-group tr-action" style="visibility:hidden;">
|
return '<div class="btn-group tr-action" style="visibility:hidden;">
|
||||||
<button type="button" class="btn btn-xs btn-default dropdown-toggle" data-toggle="dropdown">
|
<button type="button" class="btn btn-xs btn-default dropdown-toggle" data-toggle="dropdown">
|
||||||
Select <span class="caret"></span>
|
'.trans('texts.select').' <span class="caret"></span>
|
||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu" role="menu">
|
<ul class="dropdown-menu" role="menu">
|
||||||
<li><a href="' . URL::to('invoices/'.$model->public_id.'/edit') . '">Edit Invoice</a></li>
|
<li><a href="' . URL::to('invoices/'.$model->public_id.'/edit') . '">'.trans('texts.edit_invoice').'</a></li>
|
||||||
<li><a href="' . URL::to('payments/create/' . $model->client_public_id . '/' . $model->public_id ) . '">Enter Payment</a></li>
|
<li><a href="' . URL::to('payments/create/' . $model->client_public_id . '/' . $model->public_id ) . '">'.trans('texts.enter_payment').'</a></li>
|
||||||
<li class="divider"></li>
|
<li class="divider"></li>
|
||||||
<li><a href="javascript:archiveEntity(' . $model->public_id . ')">Archive Invoice</a></li>
|
<li><a href="javascript:archiveEntity(' . $model->public_id . ')">'.trans('texts.archive_invoice').'</a></li>
|
||||||
<li><a href="javascript:deleteEntity(' . $model->public_id . ')">Delete Invoice</a></li>
|
<li><a href="javascript:deleteEntity(' . $model->public_id . ')">'.trans('texts.delete_invoice').'</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>';
|
</div>';
|
||||||
})
|
})
|
||||||
@ -89,7 +89,7 @@ class InvoiceController extends \BaseController {
|
|||||||
$table->addColumn('frequency', function($model) { return link_to('invoices/' . $model->public_id, $model->frequency); });
|
$table->addColumn('frequency', function($model) { return link_to('invoices/' . $model->public_id, $model->frequency); });
|
||||||
|
|
||||||
if (!$clientPublicId) {
|
if (!$clientPublicId) {
|
||||||
$table->addColumn('client', function($model) { return link_to('clients/' . $model->client_public_id, Utils::getClientDisplayName($model)); });
|
$table->addColumn('client_name', function($model) { return link_to('clients/' . $model->client_public_id, Utils::getClientDisplayName($model)); });
|
||||||
}
|
}
|
||||||
|
|
||||||
return $table->addColumn('start_date', function($model) { return Utils::fromSqlDate($model->start_date); })
|
return $table->addColumn('start_date', function($model) { return Utils::fromSqlDate($model->start_date); })
|
||||||
@ -99,13 +99,13 @@ class InvoiceController extends \BaseController {
|
|||||||
{
|
{
|
||||||
return '<div class="btn-group tr-action" style="visibility:hidden;">
|
return '<div class="btn-group tr-action" style="visibility:hidden;">
|
||||||
<button type="button" class="btn btn-xs btn-default dropdown-toggle" data-toggle="dropdown">
|
<button type="button" class="btn btn-xs btn-default dropdown-toggle" data-toggle="dropdown">
|
||||||
Select <span class="caret"></span>
|
'.trans('texts.select').' <span class="caret"></span>
|
||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu" role="menu">
|
<ul class="dropdown-menu" role="menu">
|
||||||
<li><a href="' . URL::to('invoices/'.$model->public_id.'/edit') . '">Edit Invoice</a></li>
|
<li><a href="' . URL::to('invoices/'.$model->public_id.'/edit') . '">'.trans('texts.edit_invoice').'</a></li>
|
||||||
<li class="divider"></li>
|
<li class="divider"></li>
|
||||||
<li><a href="javascript:archiveEntity(' . $model->public_id . ')">Archive Invoice</a></li>
|
<li><a href="javascript:archiveEntity(' . $model->public_id . ')">'.trans('texts.archive_invoice').'</a></li>
|
||||||
<li><a href="javascript:deleteEntity(' . $model->public_id . ')">Delete Invoice</a></li>
|
<li><a href="javascript:deleteEntity(' . $model->public_id . ')">'.trans('texts.delete_invoice').'</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>';
|
</div>';
|
||||||
})
|
})
|
||||||
@ -143,7 +143,8 @@ class InvoiceController extends \BaseController {
|
|||||||
$data = array(
|
$data = array(
|
||||||
'showBreadcrumbs' => false,
|
'showBreadcrumbs' => false,
|
||||||
'invoice' => $invoice->hidePrivateFields(),
|
'invoice' => $invoice->hidePrivateFields(),
|
||||||
'invitation' => $invitation
|
'invitation' => $invitation,
|
||||||
|
'invoiceLabels' => $client->account->getInvoiceLabels(),
|
||||||
);
|
);
|
||||||
|
|
||||||
return View::make('invoices.view', $data);
|
return View::make('invoices.view', $data);
|
||||||
@ -206,6 +207,12 @@ class InvoiceController extends \BaseController {
|
|||||||
|
|
||||||
public static function getViewModel()
|
public static function getViewModel()
|
||||||
{
|
{
|
||||||
|
// Temporary fix to let users know to re-upload their logos for higher res
|
||||||
|
if (Auth::user()->account->getLogoHeight() == 80)
|
||||||
|
{
|
||||||
|
Session::flash('warning', "We've increased the logo resolution in the PDF. Please re-upload your logo to take advantage of it.");
|
||||||
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'account' => Auth::user()->account,
|
'account' => Auth::user()->account,
|
||||||
'products' => Product::scope()->orderBy('id')->get(array('product_key','notes','cost','qty')),
|
'products' => Product::scope()->orderBy('id')->get(array('product_key','notes','cost','qty')),
|
||||||
@ -217,6 +224,7 @@ class InvoiceController extends \BaseController {
|
|||||||
'paymentTerms' => PaymentTerm::remember(DEFAULT_QUERY_CACHE)->orderBy('num_days')->get(['name', 'num_days']),
|
'paymentTerms' => PaymentTerm::remember(DEFAULT_QUERY_CACHE)->orderBy('num_days')->get(['name', 'num_days']),
|
||||||
'industries' => Industry::remember(DEFAULT_QUERY_CACHE)->orderBy('id')->get(),
|
'industries' => Industry::remember(DEFAULT_QUERY_CACHE)->orderBy('id')->get(),
|
||||||
'invoiceDesigns' => InvoiceDesign::remember(DEFAULT_QUERY_CACHE)->orderBy('id')->get(),
|
'invoiceDesigns' => InvoiceDesign::remember(DEFAULT_QUERY_CACHE)->orderBy('id')->get(),
|
||||||
|
'invoiceLabels' => Auth::user()->account->getInvoiceLabels(),
|
||||||
'frequencies' => array(
|
'frequencies' => array(
|
||||||
1 => 'Weekly',
|
1 => 'Weekly',
|
||||||
2 => 'Two weeks',
|
2 => 'Two weeks',
|
||||||
@ -329,7 +337,15 @@ class InvoiceController extends \BaseController {
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
Session::flash('message', 'Successfully saved invoice'.$message);
|
Session::flash('message', 'Successfully saved invoice'.$message);
|
||||||
Session::flash('error', 'Please sign up to email an invoice');
|
|
||||||
|
if (Auth::user()->registered)
|
||||||
|
{
|
||||||
|
Session::flash('error', 'Please confirm your email address');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Session::flash('error', 'Please sign up to email an invoice');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -18,7 +18,7 @@ class PaymentController extends \BaseController
|
|||||||
return View::make('list', array(
|
return View::make('list', array(
|
||||||
'entityType'=>ENTITY_PAYMENT,
|
'entityType'=>ENTITY_PAYMENT,
|
||||||
'title' => '- Payments',
|
'title' => '- Payments',
|
||||||
'columns'=>['checkbox', 'Invoice', 'Client', 'Transaction Reference', 'Method', 'Payment Amount', 'Payment Date', 'Action']
|
'columns'=>Utils::trans(['checkbox', 'invoice', 'client', 'transaction_reference', 'method', 'payment_amount', 'payment_date', 'action'])
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,11 +46,11 @@ class PaymentController extends \BaseController
|
|||||||
{
|
{
|
||||||
return '<div class="btn-group tr-action" style="visibility:hidden;">
|
return '<div class="btn-group tr-action" style="visibility:hidden;">
|
||||||
<button type="button" class="btn btn-xs btn-default dropdown-toggle" data-toggle="dropdown">
|
<button type="button" class="btn btn-xs btn-default dropdown-toggle" data-toggle="dropdown">
|
||||||
Select <span class="caret"></span>
|
'.trans('texts.select').' <span class="caret"></span>
|
||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu" role="menu">
|
<ul class="dropdown-menu" role="menu">
|
||||||
<li><a href="javascript:archiveEntity(' . $model->public_id. ')">Archive Payment</a></li>
|
<li><a href="javascript:archiveEntity(' . $model->public_id. ')">'.trans('texts.archive_payment').'</a></li>
|
||||||
<li><a href="javascript:deleteEntity(' . $model->public_id. ')">Delete Payment</a></li>
|
<li><a href="javascript:deleteEntity(' . $model->public_id. ')">'.trans('texts.delete_payment').'</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>';
|
</div>';
|
||||||
})
|
})
|
||||||
@ -115,12 +115,21 @@ class PaymentController extends \BaseController
|
|||||||
$function = "set" . ucfirst($key);
|
$function = "set" . ucfirst($key);
|
||||||
$gateway->$function($val);
|
$gateway->$function($val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (!Utils::isProd())
|
||||||
|
{
|
||||||
|
$gateway->setTestMode(true);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
return $gateway;
|
return $gateway;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getPaymentDetails($invoice, $input = null)
|
private function getPaymentDetails($invoice, $input = null)
|
||||||
{
|
{
|
||||||
|
$key = $invoice->invoice_number . '_details';
|
||||||
|
|
||||||
if ($input)
|
if ($input)
|
||||||
{
|
{
|
||||||
$data = [
|
$data = [
|
||||||
@ -142,11 +151,15 @@ class PaymentController extends \BaseController
|
|||||||
'shippingPostcode' => $input['postal_code'],
|
'shippingPostcode' => $input['postal_code'],
|
||||||
];
|
];
|
||||||
|
|
||||||
Session::put($invoice->invoice_number . '_details', $data);
|
Session::put($key, $data);
|
||||||
|
}
|
||||||
|
else if (Session::get($key))
|
||||||
|
{
|
||||||
|
$data = Session::get($key);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$data = Session::get($invoice->invoice_number . '_details');
|
$data = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
$card = new CreditCard($data);
|
$card = new CreditCard($data);
|
||||||
@ -162,6 +175,22 @@ class PaymentController extends \BaseController
|
|||||||
|
|
||||||
public function show_payment($invitationKey)
|
public function show_payment($invitationKey)
|
||||||
{
|
{
|
||||||
|
// For PayPal Express we redirect straight to their site
|
||||||
|
$invitation = Invitation::with('invoice.client.account')->where('invitation_key', '=', $invitationKey)->firstOrFail();
|
||||||
|
$account = $invitation->invoice->client->account;
|
||||||
|
if ($account->isGatewayConfigured(GATEWAY_PAYPAL_EXPRESS))
|
||||||
|
{
|
||||||
|
if (Session::has('error'))
|
||||||
|
{
|
||||||
|
Session::reflash();
|
||||||
|
return Redirect::to('view/' . $invitationKey);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return self::do_payment($invitationKey, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$invitation = Invitation::with('contact', 'invoice.client')->where('invitation_key', '=', $invitationKey)->firstOrFail();
|
$invitation = Invitation::with('contact', 'invoice.client')->where('invitation_key', '=', $invitationKey)->firstOrFail();
|
||||||
$invoice = $invitation->invoice;
|
$invoice = $invitation->invoice;
|
||||||
$client = $invoice->client;
|
$client = $invoice->client;
|
||||||
@ -177,7 +206,7 @@ class PaymentController extends \BaseController
|
|||||||
return View::make('payments.payment', $data);
|
return View::make('payments.payment', $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function do_payment($invitationKey)
|
public function do_payment($invitationKey, $onSite = true)
|
||||||
{
|
{
|
||||||
$rules = array(
|
$rules = array(
|
||||||
'first_name' => 'required',
|
'first_name' => 'required',
|
||||||
@ -192,20 +221,24 @@ class PaymentController extends \BaseController
|
|||||||
'postal_code' => 'required',
|
'postal_code' => 'required',
|
||||||
);
|
);
|
||||||
|
|
||||||
$validator = Validator::make(Input::all(), $rules);
|
if ($onSite)
|
||||||
|
|
||||||
if ($validator->fails())
|
|
||||||
{
|
{
|
||||||
return Redirect::to('payment/' . $invitationKey)
|
$validator = Validator::make(Input::all(), $rules);
|
||||||
->withErrors($validator);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$invitation = Invitation::with('invoice.invoice_items', 'invoice.client.currency', 'invoice.client.account.account_gateways.gateway')->where('invitation_key', '=', $invitationKey)->firstOrFail();
|
|
||||||
$invoice = $invitation->invoice;
|
|
||||||
$accountGateway = $invoice->client->account->account_gateways[0];
|
|
||||||
$gateway = self::createGateway($accountGateway);
|
|
||||||
|
|
||||||
|
if ($validator->fails())
|
||||||
|
{
|
||||||
|
return Redirect::to('payment/' . $invitationKey)
|
||||||
|
->withErrors($validator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$invitation = Invitation::with('invoice.invoice_items', 'invoice.client.currency', 'invoice.client.account.account_gateways.gateway')->where('invitation_key', '=', $invitationKey)->firstOrFail();
|
||||||
|
$invoice = $invitation->invoice;
|
||||||
|
$accountGateway = $invoice->client->account->account_gateways[0];
|
||||||
|
$gateway = self::createGateway($accountGateway);
|
||||||
|
|
||||||
|
if ($onSite)
|
||||||
|
{
|
||||||
$client = $invoice->client;
|
$client = $invoice->client;
|
||||||
$client->address1 = trim(Input::get('address1'));
|
$client->address1 = trim(Input::get('address1'));
|
||||||
$client->address2 = trim(Input::get('address2'));
|
$client->address2 = trim(Input::get('address2'));
|
||||||
@ -213,51 +246,51 @@ class PaymentController extends \BaseController
|
|||||||
$client->state = trim(Input::get('state'));
|
$client->state = trim(Input::get('state'));
|
||||||
$client->postal_code = trim(Input::get('postal_code'));
|
$client->postal_code = trim(Input::get('postal_code'));
|
||||||
$client->save();
|
$client->save();
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
|
{
|
||||||
|
$details = self::getPaymentDetails($invoice, Input::all());
|
||||||
|
$response = $gateway->purchase($details)->send();
|
||||||
|
$ref = $response->getTransactionReference();
|
||||||
|
|
||||||
|
if (!$ref)
|
||||||
{
|
{
|
||||||
$details = self::getPaymentDetails($invoice, Input::all());
|
Session::flash('error', $response->getMessage());
|
||||||
$response = $gateway->purchase($details)->send();
|
|
||||||
$ref = $response->getTransactionReference();
|
|
||||||
|
|
||||||
if (!$ref)
|
|
||||||
{
|
|
||||||
Session::flash('error', $response->getMessage());
|
|
||||||
return Redirect::to('payment/' . $invitationKey)
|
|
||||||
->withInput();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($response->isSuccessful())
|
|
||||||
{
|
|
||||||
$payment = self::createPayment($invitation, $ref);
|
|
||||||
|
|
||||||
$invoice->invoice_status_id = INVOICE_STATUS_PAID;
|
|
||||||
$invoice->save();
|
|
||||||
|
|
||||||
Event::fire('invoice.paid', $payment);
|
|
||||||
|
|
||||||
Session::flash('message', 'Successfully applied payment');
|
|
||||||
return Redirect::to('view/' . $payment->invitation->invitation_key);
|
|
||||||
}
|
|
||||||
else if ($response->isRedirect())
|
|
||||||
{
|
|
||||||
$invitation->transaction_reference = $ref;
|
|
||||||
$invitation->save();
|
|
||||||
|
|
||||||
$response->redirect();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Session::flash('error', $response->getMessage());
|
|
||||||
return Utils::fatalError('Sorry, there was an error processing your payment. Please try again later.<p>', $response->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (\Exception $e)
|
|
||||||
{
|
|
||||||
Session::flash('error', $e->getMessage());
|
|
||||||
return Redirect::to('payment/' . $invitationKey)
|
return Redirect::to('payment/' . $invitationKey)
|
||||||
->withInput();
|
->withInput();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($response->isSuccessful())
|
||||||
|
{
|
||||||
|
$payment = self::createPayment($invitation, $ref);
|
||||||
|
|
||||||
|
$invoice->invoice_status_id = INVOICE_STATUS_PAID;
|
||||||
|
$invoice->save();
|
||||||
|
|
||||||
|
Event::fire('invoice.paid', $payment);
|
||||||
|
|
||||||
|
Session::flash('message', 'Successfully applied payment');
|
||||||
|
return Redirect::to('view/' . $payment->invitation->invitation_key);
|
||||||
|
}
|
||||||
|
else if ($response->isRedirect())
|
||||||
|
{
|
||||||
|
$invitation->transaction_reference = $ref;
|
||||||
|
$invitation->save();
|
||||||
|
|
||||||
|
$response->redirect();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Session::flash('error', $response->getMessage());
|
||||||
|
return Utils::fatalError('Sorry, there was an error processing your payment. Please try again later.<p>', $response->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (\Exception $e)
|
||||||
|
{
|
||||||
|
Session::flash('error', $e->getMessage());
|
||||||
|
return Redirect::to('payment/' . $invitationKey)
|
||||||
|
->withInput();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,7 +299,7 @@ class PaymentController extends \BaseController
|
|||||||
$invoice = $invitation->invoice;
|
$invoice = $invitation->invoice;
|
||||||
$accountGateway = $invoice->client->account->account_gateways[0];
|
$accountGateway = $invoice->client->account->account_gateways[0];
|
||||||
|
|
||||||
$payment = Payment::createNew();
|
$payment = Payment::createNew($invitation);
|
||||||
$payment->invitation_id = $invitation->id;
|
$payment->invitation_id = $invitation->id;
|
||||||
$payment->account_gateway_id = $accountGateway->id;
|
$payment->account_gateway_id = $accountGateway->id;
|
||||||
$payment->invoice_id = $invoice->id;
|
$payment->invoice_id = $invoice->id;
|
||||||
@ -309,7 +342,7 @@ class PaymentController extends \BaseController
|
|||||||
|
|
||||||
$invoice->invoice_status_id = INVOICE_STATUS_PAID;
|
$invoice->invoice_status_id = INVOICE_STATUS_PAID;
|
||||||
$invoice->save();
|
$invoice->save();
|
||||||
|
|
||||||
Event::fire('invoice.paid', $payment);
|
Event::fire('invoice.paid', $payment);
|
||||||
|
|
||||||
Session::flash('message', 'Successfully applied payment');
|
Session::flash('message', 'Successfully applied payment');
|
||||||
|
@ -20,6 +20,17 @@ class UserController extends BaseController {
|
|||||||
return Redirect::to(Input::get('path'));
|
return Redirect::to(Input::get('path'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function forcePDFJS()
|
||||||
|
{
|
||||||
|
$user = Auth::user();
|
||||||
|
$user->force_pdfjs = true;
|
||||||
|
$user->save();
|
||||||
|
|
||||||
|
Session::flash('message', 'Successfully updated PDF settings');
|
||||||
|
|
||||||
|
return Redirect::to('/invoices/create');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Displays the form for account creation
|
* Displays the form for account creation
|
||||||
*
|
*
|
||||||
@ -110,18 +121,18 @@ class UserController extends BaseController {
|
|||||||
// with the second parameter as true.
|
// with the second parameter as true.
|
||||||
// logAttempt will check if the 'email' perhaps is the username.
|
// logAttempt will check if the 'email' perhaps is the username.
|
||||||
// Get the value from the config file instead of changing the controller
|
// Get the value from the config file instead of changing the controller
|
||||||
if ( Confide::logAttempt( $input, false ) )
|
if ( Input::get( 'login_email' ) && Confide::logAttempt( $input, false ) )
|
||||||
{
|
{
|
||||||
Event::fire('user.login');
|
Event::fire('user.login');
|
||||||
// Redirect the user to the URL they were trying to access before
|
// Redirect the user to the URL they were trying to access before
|
||||||
// caught by the authentication filter IE Redirect::guest('user/login').
|
// caught by the authentication filter IE Redirect::guest('user/login').
|
||||||
// Otherwise fallback to '/'
|
// Otherwise fallback to '/'
|
||||||
// Fix pull #145
|
// Fix pull #145
|
||||||
return Redirect::intended('/clients'); // change it to '/admin', '/dashboard' or something
|
return Redirect::intended('/dashboard'); // change it to '/admin', '/dashboard' or something
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$user = new User;
|
//$user = new User;
|
||||||
|
|
||||||
// Check if there was too many login attempts
|
// Check if there was too many login attempts
|
||||||
if( Confide::isThrottled( $input ) )
|
if( Confide::isThrottled( $input ) )
|
||||||
@ -249,10 +260,13 @@ class UserController extends BaseController {
|
|||||||
*/
|
*/
|
||||||
public function logout()
|
public function logout()
|
||||||
{
|
{
|
||||||
if (!Auth::user()->registered)
|
if (Auth::check())
|
||||||
{
|
{
|
||||||
$account = Auth::user()->account;
|
if (!Auth::user()->registered)
|
||||||
$account->forceDelete();
|
{
|
||||||
|
$account = Auth::user()->account;
|
||||||
|
$account->forceDelete();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Confide::logout();
|
Confide::logout();
|
||||||
|
@ -0,0 +1,57 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
class AddLanguageSupport extends Migration {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('languages', function($table)
|
||||||
|
{
|
||||||
|
$table->increments('id');
|
||||||
|
$table->string('name');
|
||||||
|
$table->string('locale');
|
||||||
|
});
|
||||||
|
|
||||||
|
DB::table('languages')->insert(['name' => 'English', 'locale' => 'en']);
|
||||||
|
DB::table('languages')->insert(['name' => 'Italian', 'locale' => 'it']);
|
||||||
|
DB::table('languages')->insert(['name' => 'German', 'locale' => 'de']);
|
||||||
|
DB::table('languages')->insert(['name' => 'French', 'locale' => 'fr']);
|
||||||
|
DB::table('languages')->insert(['name' => 'Brazilian Portuguese', 'locale' => 'pt_BR']);
|
||||||
|
|
||||||
|
Schema::table('accounts', function($table)
|
||||||
|
{
|
||||||
|
$table->unsignedInteger('language_id')->default(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
DB::table('accounts')->update(['language_id' => 1]);
|
||||||
|
|
||||||
|
Schema::table('accounts', function($table)
|
||||||
|
{
|
||||||
|
$table->foreign('language_id')->references('id')->on('languages');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::table('accounts', function($table)
|
||||||
|
{
|
||||||
|
$table->dropForeign('accounts_language_id_foreign');
|
||||||
|
$table->dropColumn('language_id');
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::drop('languages');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
class EnableForcingJspdf extends Migration {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('users', function($table)
|
||||||
|
{
|
||||||
|
$table->boolean('force_pdfjs')->default(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::table('users', function($table)
|
||||||
|
{
|
||||||
|
$table->dropColumn('force_pdfjs');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -5,21 +5,7 @@ class UserTableSeeder extends Seeder
|
|||||||
|
|
||||||
public function run()
|
public function run()
|
||||||
{
|
{
|
||||||
//DB::table('users')->delete();
|
|
||||||
|
|
||||||
/*
|
|
||||||
$account = Account::create(array(
|
|
||||||
'name' => 'Acme Inc',
|
|
||||||
));
|
|
||||||
|
|
||||||
$user = User::create(array(
|
|
||||||
'account_id' => $account->id,
|
|
||||||
'first_name' => 'Hillel',
|
|
||||||
'last_name' => 'Coren',
|
|
||||||
'email' => 'hillelcoren@gmail.com',
|
|
||||||
'password' => Hash::make('1234'),
|
|
||||||
));
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -20,6 +20,11 @@ App::before(function($request)
|
|||||||
return Redirect::secure(Request::getRequestUri());
|
return Redirect::secure(Request::getRequestUri());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Auth::check())
|
||||||
|
{
|
||||||
|
App::setLocale(Auth::user()->getLocale());
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,11 +17,11 @@ class UserEventHandler
|
|||||||
|
|
||||||
public function onLogin()
|
public function onLogin()
|
||||||
{
|
{
|
||||||
$account = Auth::user()->account;
|
$account = Auth::user()->account;
|
||||||
$account->last_login = Carbon::now()->toDateTimeString();
|
$account->last_login = Carbon::now()->toDateTimeString();
|
||||||
$account->save();
|
$account->save();
|
||||||
|
|
||||||
Event::fire('user.refresh');
|
Event::fire('user.refresh');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onRefresh()
|
public function onRefresh()
|
||||||
|
54
app/lang/de/fields.php
Normal file
54
app/lang/de/fields.php
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return array(
|
||||||
|
|
||||||
|
// client
|
||||||
|
'organization' => 'Organisation',
|
||||||
|
'name' => 'Name',
|
||||||
|
'website' => 'Webseite',
|
||||||
|
'work_phone' => 'Telefon',
|
||||||
|
'address' => 'Adresse',
|
||||||
|
'address1' => 'Straße',
|
||||||
|
'address2' => 'Adresszusatz',
|
||||||
|
'city' => 'Stadt',
|
||||||
|
'state' => 'Bundesland',
|
||||||
|
'postal_code' => 'Postleitzahl',
|
||||||
|
'country_id' => 'Land',
|
||||||
|
'contacts' => 'Kontakte',
|
||||||
|
'first_name' => 'Vorname',
|
||||||
|
'last_name' => 'Nachname',
|
||||||
|
'phone' => 'Telefon',
|
||||||
|
'email' => 'Email',
|
||||||
|
'additional_info' => 'Zusätzliche Info',
|
||||||
|
'payment_terms' => 'Zahlungsbedingungen',
|
||||||
|
'currency_id' => 'Währung',
|
||||||
|
'size_id' => 'Größe',
|
||||||
|
'industry_id' => 'Kategorie',
|
||||||
|
'private_notes' => 'Notizen',
|
||||||
|
|
||||||
|
// invoice
|
||||||
|
'invoice' => 'Rechnung',
|
||||||
|
'client' => 'Kunde',
|
||||||
|
'invoice_date' => 'Rechnungsdatum',
|
||||||
|
'due_date' => 'Fällig am',
|
||||||
|
'invoice_number' => 'Rechungsnummer',
|
||||||
|
'invoice_number_short' => 'Rechnung #',
|
||||||
|
'po_number' => 'Bestell Nummer',
|
||||||
|
'po_number_short' => 'BN #',
|
||||||
|
'frequency_id' => 'Wie oft',
|
||||||
|
'dicount' => 'Rabatt',
|
||||||
|
'taxes' => 'Steuern',
|
||||||
|
'tax' => 'Steuer',
|
||||||
|
'item' => 'Artikel',
|
||||||
|
'description' => 'Beschreibung',
|
||||||
|
'unit_cost' => 'Kosten pro Einheit',
|
||||||
|
'quantity' => 'Menge',
|
||||||
|
'line_total' => 'Summe',
|
||||||
|
'subtotal' => 'Zwischensumme',
|
||||||
|
'paid_to_date' => 'Zahlungsdatum',
|
||||||
|
'balance_due' => 'Rechnungsbetrag',
|
||||||
|
'invoice_design_id' => 'Design',
|
||||||
|
'terms' => 'Bedingungen',
|
||||||
|
'your_invoice' => 'Ihre Rechnung',
|
||||||
|
|
||||||
|
);
|
20
app/lang/de/pagination.php
Normal file
20
app/lang/de/pagination.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return array(
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Pagination Language Lines
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| The following language lines are used by the paginator library to build
|
||||||
|
| the simple pagination links. You are free to change them to anything
|
||||||
|
| you want to customize your views to better match your application.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'previous' => '« zurück',
|
||||||
|
|
||||||
|
'next' => 'weiter »',
|
||||||
|
|
||||||
|
);
|
24
app/lang/de/reminders.php
Normal file
24
app/lang/de/reminders.php
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return array(
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Password Reminder Language Lines
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| The following language lines are the default lines which match reasons
|
||||||
|
| that are given by the password broker for a password update attempt
|
||||||
|
| has failed, such as for an invalid token or invalid new password.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
"password" => "Passwörter müssen 6 Zeichen lang sein und korrekt bestätigt werden.",
|
||||||
|
|
||||||
|
"user" => "Wir konnten leider keinen Nutzer mit dieser E-Mail Adresse finden.",
|
||||||
|
|
||||||
|
"token" => "Der Passwort-Wiederherstellungs-Schlüssel ist ungültig.",
|
||||||
|
|
||||||
|
"sent" => "Passworterinnerung wurde gesendet!",
|
||||||
|
|
||||||
|
);
|
54
app/lang/de/texts.php
Normal file
54
app/lang/de/texts.php
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return array(
|
||||||
|
|
||||||
|
// client
|
||||||
|
'organization' => 'Organisation',
|
||||||
|
'name' => 'Name',
|
||||||
|
'website' => 'Webseite',
|
||||||
|
'work_phone' => 'Telefon',
|
||||||
|
'address' => 'Adresse',
|
||||||
|
'address1' => 'Straße',
|
||||||
|
'address2' => 'Adresszusatz',
|
||||||
|
'city' => 'Stadt',
|
||||||
|
'state' => 'Bundesland',
|
||||||
|
'postal_code' => 'Postleitzahl',
|
||||||
|
'country_id' => 'Land',
|
||||||
|
'contacts' => 'Kontakte',
|
||||||
|
'first_name' => 'Vorname',
|
||||||
|
'last_name' => 'Nachname',
|
||||||
|
'phone' => 'Telefon',
|
||||||
|
'email' => 'Email',
|
||||||
|
'additional_info' => 'Zusätzliche Info',
|
||||||
|
'payment_terms' => 'Payment Terms',
|
||||||
|
'currency_id' => 'Währung',
|
||||||
|
'size_id' => 'Größe',
|
||||||
|
'industry_id' => 'Kategorie',
|
||||||
|
'private_notes' => 'Notizen',
|
||||||
|
|
||||||
|
// invoice
|
||||||
|
'invoice' => 'Rechnung',
|
||||||
|
'client' => 'Kunde',
|
||||||
|
'invoice_date' => 'Rechnungsdatum',
|
||||||
|
'due_date' => 'Fällig am',
|
||||||
|
'invoice_number' => 'Rechungsnummer',
|
||||||
|
'invoice_number_short' => 'Rechnung #',
|
||||||
|
'po_number' => 'Bestell Nummer',
|
||||||
|
'po_number_short' => 'BN #',
|
||||||
|
'frequency_id' => 'Wie oft',
|
||||||
|
'dicount' => 'Rabatt',
|
||||||
|
'taxes' => 'Steuern',
|
||||||
|
'tax' => 'Steuer',
|
||||||
|
'item' => 'Artikel',
|
||||||
|
'description' => 'Beschreibung',
|
||||||
|
'unit_cost' => 'Kosten pro Einheit',
|
||||||
|
'quantity' => 'Menge',
|
||||||
|
'line_total' => 'Summe',
|
||||||
|
'subtotal' => 'Zwischensumme',
|
||||||
|
'paid_to_date' => 'Zahlungsdatum',
|
||||||
|
'balance_due' => 'Rechnungsbetrag',
|
||||||
|
'invoice_design_id' => 'Design',
|
||||||
|
'terms' => 'Bedingungen',
|
||||||
|
'your_invoice' => 'Ihre Rechnung',
|
||||||
|
|
||||||
|
);
|
104
app/lang/de/validation.php
Normal file
104
app/lang/de/validation.php
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return array(
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Validation Language Lines
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| The following language lines contain the default error messages used by
|
||||||
|
| the validator class. Some of these rules have multiple versions such
|
||||||
|
| such as the size rules. Feel free to tweak each of these messages.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
"accepted" => ":attribute muss akzeptiert werden.",
|
||||||
|
"active_url" => ":attribute ist keine gültige Internet-Adresse.",
|
||||||
|
"after" => ":attribute muss ein Datum nach dem :date sein.",
|
||||||
|
"alpha" => ":attribute darf nur aus Buchstaben bestehen.",
|
||||||
|
"alpha_dash" => ":attribute darf nur aus Buchstaben, Zahlen, Binde- und Unterstrichen bestehen. Umlaute (ä, ö, ü) und Eszett (ß) sind nicht erlaubt.",
|
||||||
|
"alpha_num" => ":attribute darf nur aus Buchstaben und Zahlen bestehen.",
|
||||||
|
"array" => ":attribute muss ein Array sein.",
|
||||||
|
"before" => ":attribute muss ein Datum vor dem :date sein.",
|
||||||
|
"between" => array(
|
||||||
|
"numeric" => ":attribute muss zwischen :min & :max liegen.",
|
||||||
|
"file" => ":attribute muss zwischen :min & :max Kilobytes groß sein.",
|
||||||
|
"string" => ":attribute muss zwischen :min & :max Zeichen lang sein.",
|
||||||
|
"array" => ":attribute muss zwischen :min & :max Elemente haben."
|
||||||
|
),
|
||||||
|
"confirmed" => ":attribute stimmt nicht mit der Bestätigung überein.",
|
||||||
|
"date" => ":attribute muss ein gültiges Datum sein.",
|
||||||
|
"date_format" => ":attribute entspricht nicht dem gültigen Format für :format.",
|
||||||
|
"different" => ":attribute und :other müssen sich unterscheiden.",
|
||||||
|
"digits" => ":attribute muss :digits Stellen haben.",
|
||||||
|
"digits_between" => ":attribute muss zwischen :min und :max Stellen haben.",
|
||||||
|
"email" => ":attribute Format ist ungültig.",
|
||||||
|
"exists" => "Der gewählte Wert für :attribute ist ungültig.",
|
||||||
|
"image" => ":attribute muss ein Bild sein.",
|
||||||
|
"in" => "Der gewählte Wert für :attribute ist ungültig.",
|
||||||
|
"integer" => ":attribute muss eine ganze Zahl sein.",
|
||||||
|
"ip" => ":attribute muss eine gültige IP-Adresse sein.",
|
||||||
|
"max" => array(
|
||||||
|
"numeric" => ":attribute darf maximal :max sein.",
|
||||||
|
"file" => ":attribute darf maximal :max Kilobytes groß sein.",
|
||||||
|
"string" => ":attribute darf maximal :max Zeichen haben.",
|
||||||
|
"array" => ":attribute darf nicht mehr als :max Elemente haben."
|
||||||
|
),
|
||||||
|
"mimes" => ":attribute muss den Dateityp :values haben.",
|
||||||
|
"min" => array(
|
||||||
|
"numeric" => ":attribute muss mindestens :min sein.",
|
||||||
|
"file" => ":attribute muss mindestens :min Kilobytes groß sein.",
|
||||||
|
"string" => ":attribute muss mindestens :min Zeichen lang sein.",
|
||||||
|
"array" => ":attribute muss mindestens :min Elemente haben."
|
||||||
|
),
|
||||||
|
"not_in" => "Der gewählte Wert für :attribute ist ungültig.",
|
||||||
|
"numeric" => ":attribute muss eine Zahl sein.",
|
||||||
|
"regex" => ":attribute Format ist ungültig.",
|
||||||
|
"required" => ":attribute muss ausgefüllt sein.",
|
||||||
|
"required_if" => ":attribute muss ausgefüllt sein wenn :other :value ist.",
|
||||||
|
"required_with" => ":attribute muss angegeben werden wenn :values ausgefüllt wurde.",
|
||||||
|
"required_with_all" => "The :attribute field is required when :values is present.",
|
||||||
|
"required_without" => ":attribute muss angegeben werden wenn :values nicht ausgefüllt wurde.",
|
||||||
|
"required_without_all" => ":attribute muss angegeben werden wenn keines der Felder :values ausgefüllt wurde.",
|
||||||
|
"same" => ":attribute und :other müssen übereinstimmen.",
|
||||||
|
"size" => array(
|
||||||
|
"numeric" => ":attribute muss gleich :size sein.",
|
||||||
|
"file" => ":attribute muss :size Kilobyte groß sein.",
|
||||||
|
"string" => ":attribute muss :size Zeichen lang sein.",
|
||||||
|
"array" => ":attribute muss genau :size Elemente haben."
|
||||||
|
),
|
||||||
|
"unique" => ":attribute ist schon vergeben.",
|
||||||
|
"url" => "Das Format von :attribute ist ungültig.",
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Custom Validation Language Lines
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Here you may specify custom validation messages for attributes using the
|
||||||
|
| convention "attribute.rule" to name the lines. This makes it quick to
|
||||||
|
| specify a specific custom language line for a given attribute rule.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'custom' => array(
|
||||||
|
'attribute-name' => array(
|
||||||
|
'rule-name' => 'custom-message',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Custom Validation Attributes
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| The following language lines are used to swap attribute place-holders
|
||||||
|
| with something more reader friendly such as E-Mail Address instead
|
||||||
|
| of "email". This simply helps us make messages a little cleaner.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'attributes' => array(),
|
||||||
|
|
||||||
|
);
|
154
app/lang/en/texts.php
Normal file
154
app/lang/en/texts.php
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return array(
|
||||||
|
|
||||||
|
// client
|
||||||
|
'organization' => 'Organization',
|
||||||
|
'name' => 'Name',
|
||||||
|
'website' => 'Website',
|
||||||
|
'work_phone' => 'Phone',
|
||||||
|
'address' => 'Address',
|
||||||
|
'address1' => 'Street',
|
||||||
|
'address2' => 'Apt/Suite',
|
||||||
|
'city' => 'City',
|
||||||
|
'state' => 'State/Province',
|
||||||
|
'postal_code' => 'Postal Code',
|
||||||
|
'country_id' => 'Country',
|
||||||
|
'contacts' => 'Contacts',
|
||||||
|
'first_name' => 'First Name',
|
||||||
|
'last_name' => 'Last Name',
|
||||||
|
'phone' => 'Phone',
|
||||||
|
'email' => 'Email',
|
||||||
|
'additional_info' => 'Additional Info',
|
||||||
|
'payment_terms' => 'Payment Terms',
|
||||||
|
'currency_id' => 'Currency',
|
||||||
|
'size_id' => 'Size',
|
||||||
|
'industry_id' => 'Industry',
|
||||||
|
'private_notes' => 'Private Notes',
|
||||||
|
|
||||||
|
// invoice
|
||||||
|
'invoice' => 'Invoice',
|
||||||
|
'client' => 'Client',
|
||||||
|
'invoice_date' => 'Invoice Date',
|
||||||
|
'due_date' => 'Due Date',
|
||||||
|
'invoice_number' => 'Invoice Number',
|
||||||
|
'invoice_number_short' => 'Invoice #',
|
||||||
|
'po_number' => 'PO Number',
|
||||||
|
'po_number_short' => 'PO #',
|
||||||
|
'frequency_id' => 'How often',
|
||||||
|
'discount' => 'Discount',
|
||||||
|
'taxes' => 'Taxes',
|
||||||
|
'tax' => 'Tax',
|
||||||
|
'item' => 'Item',
|
||||||
|
'description' => 'Description',
|
||||||
|
'unit_cost' => 'Unit Cost',
|
||||||
|
'quantity' => 'Quantity',
|
||||||
|
'line_total' => 'Line Total',
|
||||||
|
'subtotal' => 'Subtotal',
|
||||||
|
'paid_to_date' => 'Paid to Date',
|
||||||
|
'balance_due' => 'Balance Due',
|
||||||
|
'invoice_design_id' => 'Design',
|
||||||
|
'terms' => 'Terms',
|
||||||
|
'your_invoice' => 'Your Invoice',
|
||||||
|
|
||||||
|
'remove_contact' => 'Remove contact',
|
||||||
|
'add_contact' => 'Add contact',
|
||||||
|
'create_new_client' => 'Create new client',
|
||||||
|
'edit_client_details' => 'Edit client details',
|
||||||
|
'enable' => 'Enable',
|
||||||
|
'learn_more' => 'Learn more',
|
||||||
|
'manage_rates' => 'Manage rates',
|
||||||
|
'note_to_client' => 'Note to client',
|
||||||
|
'invoice_terms' => 'Invoice terms',
|
||||||
|
'save_as_default_terms' => 'Save as default terms',
|
||||||
|
'download_pdf' => 'Download PDF',
|
||||||
|
'save_invoice' => 'Save Invoice',
|
||||||
|
'clone_invoice' => 'Clone Invoice',
|
||||||
|
'archive_invoice' => 'Archive Invoice',
|
||||||
|
'delete_invoice' => 'Delete Invoice',
|
||||||
|
'email_invoice' => 'Email Invoice',
|
||||||
|
'enter_payment' => 'Enter Payment',
|
||||||
|
'tax_rates' => 'Tax Rates',
|
||||||
|
'rate' => 'Rate',
|
||||||
|
'settings' => 'Settings',
|
||||||
|
'enable_invoice_tax' => 'Enable specifying an <b>invoice tax</b>',
|
||||||
|
'enable_line_item_tax' => 'Enable specifying <b>line item taxes</b>',
|
||||||
|
|
||||||
|
// navigation
|
||||||
|
'dashboard' => 'Dashboard',
|
||||||
|
'clients' => 'Clients',
|
||||||
|
'invoices' => 'Invoices',
|
||||||
|
'payments' => 'Payments',
|
||||||
|
'credits' => 'Credits',
|
||||||
|
'history' => 'History',
|
||||||
|
'search' => 'Search',
|
||||||
|
'sign_up' => 'Sign Up',
|
||||||
|
'guest' => 'Guest',
|
||||||
|
'company_details' => 'Company Details',
|
||||||
|
'online_payments' => 'Online Payments',
|
||||||
|
'notifications' => 'Notifications',
|
||||||
|
'import_export' => 'Import/Export',
|
||||||
|
'done' => 'Done',
|
||||||
|
'cancel' => 'Cancel',
|
||||||
|
'provide_email' => 'Please provide a valid email address',
|
||||||
|
'powered_by' => 'Powered by',
|
||||||
|
'no_items' => 'No items',
|
||||||
|
|
||||||
|
// recurring invoices
|
||||||
|
'recurring_invoices' => 'Recurring Invoices',
|
||||||
|
'recurring_help' => '<p>Automatically send clients the same invoices weekly, bi-monthly, monthly, quarterly or annually. </p>
|
||||||
|
<p>Use :MONTH, :QUARTER or :YEAR for dynamic dates. Basic math works as well, for example :MONTH-1.</p>
|
||||||
|
<p>Examples of dynamic invoice variables:</p>
|
||||||
|
<ul>
|
||||||
|
<li>"Gym membership for the month of :MONTH" => "Gym membership for the month of July"</li>
|
||||||
|
<li>":YEAR+1 yearly subscription" => "2015 Yearly Subscription"</li>
|
||||||
|
<li>"Retainer payment for :QUARTER+1" => "Retainer payment for Q2"</li>
|
||||||
|
</ul>',
|
||||||
|
|
||||||
|
// dashboard
|
||||||
|
'in_total_revenue' => 'in total revenue',
|
||||||
|
'billed_client' => 'billed client',
|
||||||
|
'billed_clients' => 'billed clients',
|
||||||
|
'active_client' => 'active client',
|
||||||
|
'active_clients' => 'active clients',
|
||||||
|
'invoices_past_due' => 'Invoices Past Due',
|
||||||
|
'upcoming_invoices' => 'Upcoming invoices',
|
||||||
|
'average_invoice' => 'Average invoice',
|
||||||
|
|
||||||
|
// list pages
|
||||||
|
'archive' => 'Archive',
|
||||||
|
'delete' => 'Delete',
|
||||||
|
'archive_client' => 'Archive client',
|
||||||
|
'delete_client' => 'Delete client',
|
||||||
|
'archive_payment' => 'Archive payment',
|
||||||
|
'delete_payment' => 'Delete payment',
|
||||||
|
'archive_credit' => 'Archive credit',
|
||||||
|
'delete_credit' => 'Delete credit',
|
||||||
|
'show_archived_deleted' => 'Show archived/deleted',
|
||||||
|
'filter' => 'Filter',
|
||||||
|
'new_client' => 'New Client',
|
||||||
|
'new_invoice' => 'New Invoice',
|
||||||
|
'new_payment' => 'New Payment',
|
||||||
|
'new_credit' => 'New Credit',
|
||||||
|
'contact' => 'Contact',
|
||||||
|
'date_created' => 'Date Created',
|
||||||
|
'last_login' => 'Last Login',
|
||||||
|
'balance' => 'Balance',
|
||||||
|
'action' => 'Action',
|
||||||
|
'status' => 'Status',
|
||||||
|
'invoice_total' => 'Invoice Total',
|
||||||
|
'frequency' => 'Frequency',
|
||||||
|
'start_date' => 'Start Date',
|
||||||
|
'end_date' => 'End Date',
|
||||||
|
'transaction_reference' => 'Transaction Reference',
|
||||||
|
'method' => 'Method',
|
||||||
|
'payment_amount' => 'Payment Amount',
|
||||||
|
'payment_date' => 'Payment Date',
|
||||||
|
'credit_amount' => 'Credit Amount',
|
||||||
|
'credit_balance' => 'Credit Balance',
|
||||||
|
'credit_date' => 'Credit Date',
|
||||||
|
'empty_table' => 'No data available in table',
|
||||||
|
'select' => 'Select',
|
||||||
|
'edit_client' => 'Edit Client',
|
||||||
|
'edit_invoice' => 'Edit Invoice',
|
||||||
|
);
|
52
app/lang/es/fields.php
Normal file
52
app/lang/es/fields.php
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return array(
|
||||||
|
// client
|
||||||
|
'organization' => 'Organización',
|
||||||
|
'name' => 'Nombre',
|
||||||
|
'website' => 'Página Web',
|
||||||
|
'work_phone' => 'Teléfono',
|
||||||
|
'address' => 'Dirección',
|
||||||
|
'address1' => 'Calle',
|
||||||
|
'address2' => 'Bloq/Pta',
|
||||||
|
'city' => 'Ciudad',
|
||||||
|
'state' => 'Región/Provincia',
|
||||||
|
'postal_code' => 'Código Postal',
|
||||||
|
'country_id' => 'País',
|
||||||
|
'contacts' => 'Contactos',
|
||||||
|
'first_name' => 'Nombre',
|
||||||
|
'last_name' => 'Apellidos',
|
||||||
|
'phone' => 'Teléfono',
|
||||||
|
'email' => 'Email',
|
||||||
|
'additional_info' => 'Información extra',
|
||||||
|
'payment_terms' => 'Términos de pago',
|
||||||
|
'currency_id' => 'Divisa',
|
||||||
|
'size_id' => 'Tamaño',
|
||||||
|
'industry_id' => 'Industria',
|
||||||
|
'private_notes' => 'Notas Privadas',
|
||||||
|
|
||||||
|
// invoice
|
||||||
|
'invoice' => 'Factura',
|
||||||
|
'client' => 'Clienta',
|
||||||
|
'invoice_date' => 'Fecha de factura',
|
||||||
|
'due_date' => 'Fecha de pago',
|
||||||
|
'invoice_number' => 'Número de Factura',
|
||||||
|
'invoice_number_short' => 'Nº de Factura',
|
||||||
|
'po_number' => 'Apartado de correos',
|
||||||
|
'po_number_short' => 'Apdo.',
|
||||||
|
'frequency_id' => 'Fracuencia',
|
||||||
|
'discount' => 'Descuento',
|
||||||
|
'taxes' => 'Impuestos',
|
||||||
|
'tax' => 'Impuesto',
|
||||||
|
'item' => 'Elemento',
|
||||||
|
'description' => 'Descripción',
|
||||||
|
'unit_cost' => 'Coste unitario',
|
||||||
|
'quantity' => 'Cantidad',
|
||||||
|
'line_total' => 'Total línea',
|
||||||
|
'subtotal' => 'Subtotal',
|
||||||
|
'paid_to_date' => 'Pagado',
|
||||||
|
'balance_due' => 'Pendiente',
|
||||||
|
'invoice_design_id' => 'Diseño',
|
||||||
|
'terms' => 'Términos',
|
||||||
|
'your_invoice' => 'Tu factura',
|
||||||
|
);
|
0
app/lang/es/messages.php
Normal file
0
app/lang/es/messages.php
Normal file
20
app/lang/es/pagination.php
Executable file
20
app/lang/es/pagination.php
Executable file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return array(
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Pagination Language Lines
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| The following language lines are used by the paginator library to build
|
||||||
|
| the simple pagination links. You are free to change them to anything
|
||||||
|
| you want to customize your views to better match your application.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'previous' => '« Anterior',
|
||||||
|
|
||||||
|
'next' => 'Siguiente »',
|
||||||
|
|
||||||
|
);
|
24
app/lang/es/reminders.php
Executable file
24
app/lang/es/reminders.php
Executable file
@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return array(
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Password Reminder Language Lines
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| The following language lines are the default lines which match reasons
|
||||||
|
| that are given by the password broker for a password update attempt
|
||||||
|
| has failed, such as for an invalid token or invalid new password.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
"password" => "Las contraseñas deben contener al menos 6 caracteres y coincidir.",
|
||||||
|
|
||||||
|
"user" => "No podemos encontrar a un usuario con ese correo electrónico.",
|
||||||
|
|
||||||
|
"token" => "Este token de recuperación de contraseña es inválido.",
|
||||||
|
|
||||||
|
"sent" => "¡Recordatorio de contraseña enviado!",
|
||||||
|
|
||||||
|
);
|
107
app/lang/es/validation.php
Executable file
107
app/lang/es/validation.php
Executable file
@ -0,0 +1,107 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return array(
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Validation Language Lines
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| The following language lines contain the default error messages used by
|
||||||
|
| the validator class. Some of these rules have multiple versions such
|
||||||
|
| such as the size rules. Feel free to tweak each of these messages.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
"accepted" => ":attribute debe ser aceptado.",
|
||||||
|
"active_url" => ":attribute no es una URL válida.",
|
||||||
|
"after" => ":attribute debe ser una fecha posterior a :date.",
|
||||||
|
"alpha" => ":attribute solo debe contener letras.",
|
||||||
|
"alpha_dash" => ":attribute solo debe contener letras, números y guiones.",
|
||||||
|
"alpha_num" => ":attribute solo debe contener letras y números.",
|
||||||
|
"array" => ":attribute debe ser un conjunto.",
|
||||||
|
"before" => ":attribute debe ser una fecha anterior a :date.",
|
||||||
|
"between" => array(
|
||||||
|
"numeric" => ":attribute tiene que estar entre :min - :max.",
|
||||||
|
"file" => ":attribute debe pesar entre :min - :max kilobytes.",
|
||||||
|
"string" => ":attribute tiene que tener entre :min - :max caracteres.",
|
||||||
|
"array" => ":attribute tiene que tener entre :min - :max ítems.",
|
||||||
|
),
|
||||||
|
"confirmed" => "La confirmación de :attribute no coincide.",
|
||||||
|
"date" => ":attribute no es una fecha válida.",
|
||||||
|
"date_format" => ":attribute no corresponde al formato :format.",
|
||||||
|
"different" => ":attribute y :other deben ser diferentes.",
|
||||||
|
"digits" => ":attribute debe tener :digits dígitos.",
|
||||||
|
"digits_between" => ":attribute debe tener entre :min y :max dígitos.",
|
||||||
|
"email" => ":attribute no es un correo válido",
|
||||||
|
"exists" => ":attribute es inválido.",
|
||||||
|
"image" => ":attribute debe ser una imagen.",
|
||||||
|
"in" => ":attribute es inválido.",
|
||||||
|
"integer" => ":attribute debe ser un número entero.",
|
||||||
|
"ip" => ":attribute debe ser una dirección IP válida.",
|
||||||
|
"max" => array(
|
||||||
|
"numeric" => ":attribute no debe ser mayor a :max.",
|
||||||
|
"file" => ":attribute no debe ser mayor que :max kilobytes.",
|
||||||
|
"string" => ":attribute no debe ser mayor que :max caracteres.",
|
||||||
|
"array" => ":attribute no debe tener más de :max elementos.",
|
||||||
|
),
|
||||||
|
"mimes" => ":attribute debe ser un archivo con formato: :values.",
|
||||||
|
"min" => array(
|
||||||
|
"numeric" => "El tamaño de :attribute debe ser de al menos :min.",
|
||||||
|
"file" => "El tamaño de :attribute debe ser de al menos :min kilobytes.",
|
||||||
|
"string" => ":attribute debe contener al menos :min caracteres.",
|
||||||
|
"array" => ":attribute debe tener al menos :min elementos.",
|
||||||
|
),
|
||||||
|
"not_in" => ":attribute es inválido.",
|
||||||
|
"numeric" => ":attribute debe ser numérico.",
|
||||||
|
"regex" => "El formato de :attribute es inválido.",
|
||||||
|
"required" => "El campo :attribute es obligatorio.",
|
||||||
|
"required_if" => "El campo :attribute es obligatorio cuando :other es :value.",
|
||||||
|
"required_with" => "El campo :attribute es obligatorio cuando :values está presente.",
|
||||||
|
"required_with_all" => "The :attribute field is required when :values is present.",
|
||||||
|
"required_without" => "El campo :attribute es obligatorio cuando :values no está presente.",
|
||||||
|
"required_without_all" => "The :attribute field is required when none of :values are present.",
|
||||||
|
"same" => ":attribute y :other deben coincidir.",
|
||||||
|
"size" => array(
|
||||||
|
"numeric" => "El tamaño de :attribute debe ser :size.",
|
||||||
|
"file" => "El tamaño de :attribute debe ser :size kilobytes.",
|
||||||
|
"string" => ":attribute debe contener :size caracteres.",
|
||||||
|
"array" => ":attribute debe contener :size elementos.",
|
||||||
|
),
|
||||||
|
"unique" => ":attribute ya ha sido registrado.",
|
||||||
|
"url" => "El formato :attribute es inválido.",
|
||||||
|
"positive" => ":attribute debe ser mayor que cero.",
|
||||||
|
"has_credit" => "el cliente no tiene crédito suficiente.",
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Custom Validation Language Lines
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Here you may specify custom validation messages for attributes using the
|
||||||
|
| convention "attribute.rule" to name the lines. This makes it quick to
|
||||||
|
| specify a specific custom language line for a given attribute rule.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'custom' => array(
|
||||||
|
'attribute-name' => array(
|
||||||
|
'rule-name' => 'custom-message',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Custom Validation Attributes
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| The following language lines are used to swap attribute place-holders
|
||||||
|
| with something more reader friendly such as E-Mail Address instead
|
||||||
|
| of "email". This simply helps us make messages a little cleaner.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'attributes' => array(),
|
||||||
|
|
||||||
|
);
|
20
app/lang/fr/pagination.php
Normal file
20
app/lang/fr/pagination.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return array(
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Pagination Language Lines
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| The following language lines are used by the paginator library to build
|
||||||
|
| the simple pagination links. You are free to change them to anything
|
||||||
|
| you want to customize your views to better match your application.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'previous' => '« Précédent',
|
||||||
|
|
||||||
|
'next' => 'Suivant »',
|
||||||
|
|
||||||
|
);
|
24
app/lang/fr/reminders.php
Normal file
24
app/lang/fr/reminders.php
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return array(
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Password Reminder Language Lines
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| The following language lines are the default lines which match reasons
|
||||||
|
| that are given by the password broker for a password update attempt
|
||||||
|
| has failed, such as for an invalid token or invalid new password.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
"password" => "Les mots de passe doivent avoir au moins six caractères et doivent être identiques.",
|
||||||
|
|
||||||
|
"user" => "Nous ne pouvons trouver cet utilisateur avec cette adresse e-mail.",
|
||||||
|
|
||||||
|
"token" => "Ce jeton de réinitialisation du mot de passe n'est pas valide.",
|
||||||
|
|
||||||
|
"sent" => "Rappel du mot de passe envoyé !",
|
||||||
|
|
||||||
|
);
|
54
app/lang/fr/texts.php
Normal file
54
app/lang/fr/texts.php
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return array(
|
||||||
|
|
||||||
|
// client
|
||||||
|
'organization' => 'Entreprise',
|
||||||
|
'name' => 'Nom',
|
||||||
|
'website' => 'Site web',
|
||||||
|
'work_phone' => 'Téléphone',
|
||||||
|
'address' => 'Adresse',
|
||||||
|
'address1' => 'Rue',
|
||||||
|
'address2' => 'Appt/Batîment',
|
||||||
|
'city' => 'Ville',
|
||||||
|
'state' => 'Région/Département',
|
||||||
|
'postal_code' => 'Code Postal',
|
||||||
|
'country_id' => 'Pays',
|
||||||
|
'contacts' => 'Informations de contact', //if you speak about contact details
|
||||||
|
'first_name' => 'Prénom',
|
||||||
|
'last_name' => 'Nom',
|
||||||
|
'phone' => 'Téléphone',
|
||||||
|
'email' => 'Email',
|
||||||
|
'additional_info' => 'Informations complémentaires',
|
||||||
|
'payment_terms' => 'Conditions de paiement',
|
||||||
|
'currency_id' => 'Devise',
|
||||||
|
'size_id' => 'Taille',
|
||||||
|
'industry_id' => 'Secteur', // literal translation : Industrie
|
||||||
|
'private_notes' => 'Note personnelle',
|
||||||
|
|
||||||
|
// invoice
|
||||||
|
'invoice' => 'Facture',
|
||||||
|
'client' => 'Client',
|
||||||
|
'invoice_date' => 'Date de la facture',
|
||||||
|
'due_date' => 'Date d\'échéance',
|
||||||
|
'invoice_number' => 'Numéro de facture',
|
||||||
|
'invoice_number_short' => 'Facture #',
|
||||||
|
'po_number' => 'Numéro du bon de commande',
|
||||||
|
'po_number_short' => 'Bon de commande #',
|
||||||
|
'frequency_id' => 'Fréquence', //litteral translation : Combien de fois
|
||||||
|
'discount' => 'Remise', //can be "rabais" or "réduction"
|
||||||
|
'taxes' => 'Taxes',
|
||||||
|
'tax' => 'Taxe',
|
||||||
|
'item' => 'Ligne', //I'm not sure, I need the context : screenshot ?
|
||||||
|
'description' => 'Description',
|
||||||
|
'unit_cost' => 'Coût à l\'unité',
|
||||||
|
'quantity' => 'Quantité',
|
||||||
|
'line_total' => 'Total',
|
||||||
|
'subtotal' => 'Total',
|
||||||
|
'paid_to_date' => 'Versé à ce jour',//this one is not very used in France
|
||||||
|
'balance_due' => 'Montant total',//can be "Montant à verser" or "Somme totale"
|
||||||
|
'invoice_design_id' => 'Design', //if you speak about invoice's design -> "Modèle"
|
||||||
|
'terms' => 'Conditions',
|
||||||
|
'your_invoice' => 'Votre Facture',
|
||||||
|
|
||||||
|
);
|
134
app/lang/fr/validation.php
Normal file
134
app/lang/fr/validation.php
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return array(
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Validation Language Lines
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| The following language lines contain the default error messages used by
|
||||||
|
| the validator class. Some of these rules have multiple versions such
|
||||||
|
| such as the size rules. Feel free to tweak each of these messages.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
"accepted" => "Le champ :attribute doit être accepté.",
|
||||||
|
"active_url" => "Le champ :attribute n'est pas une URL valide.",
|
||||||
|
"after" => "Le champ :attribute doit être une date postérieure au :date.",
|
||||||
|
"alpha" => "Le champ :attribute doit seulement contenir des lettres.",
|
||||||
|
"alpha_dash" => "Le champ :attribute doit seulement contenir des lettres, des chiffres et des tirets.",
|
||||||
|
"alpha_num" => "Le champ :attribute doit seulement contenir des chiffres et des lettres.",
|
||||||
|
"array" => "Le champ :attribute doit être un tableau.",
|
||||||
|
"before" => "Le champ :attribute doit être une date antérieure au :date.",
|
||||||
|
"between" => array(
|
||||||
|
"numeric" => "La valeur de :attribute doit être comprise entre :min et :max.",
|
||||||
|
"file" => "Le fichier :attribute doit avoir une taille entre :min et :max kilobytes.",
|
||||||
|
"string" => "Le texte :attribute doit avoir entre :min et :max caractères.",
|
||||||
|
"array" => "Le champ :attribute doit avoir entre :min et :max éléments."
|
||||||
|
),
|
||||||
|
"confirmed" => "Le champ de confirmation :attribute ne correspond pas.",
|
||||||
|
"date" => "Le champ :attribute n'est pas une date valide.",
|
||||||
|
"date_format" => "Le champ :attribute ne correspond pas au format :format.",
|
||||||
|
"different" => "Les champs :attribute et :other doivent être différents.",
|
||||||
|
"digits" => "Le champ :attribute doit avoir :digits chiffres.",
|
||||||
|
"digits_between" => "Le champ :attribute doit avoir entre :min and :max chiffres.",
|
||||||
|
"email" => "Le champ :attribute doit être une adresse email valide.",
|
||||||
|
"exists" => "Le champ :attribute sélectionné est invalide.",
|
||||||
|
"image" => "Le champ :attribute doit être une image.",
|
||||||
|
"in" => "Le champ :attribute est invalide.",
|
||||||
|
"integer" => "Le champ :attribute doit être un entier.",
|
||||||
|
"ip" => "Le champ :attribute doit être une adresse IP valide.",
|
||||||
|
"max" => array(
|
||||||
|
"numeric" => "La valeur de :attribute ne peut être supérieure à :max.",
|
||||||
|
"file" => "Le fichier :attribute ne peut être plus gros que :max kilobytes.",
|
||||||
|
"string" => "Le texte de :attribute ne peut contenir plus de :max caractères.",
|
||||||
|
"array" => "Le champ :attribute ne peut avoir plus de :max éléments.",
|
||||||
|
),
|
||||||
|
"mimes" => "Le champ :attribute doit être un fichier de type : :values.",
|
||||||
|
"min" => array(
|
||||||
|
"numeric" => "La valeur de :attribute doit être supérieure à :min.",
|
||||||
|
"file" => "Le fichier :attribute doit être plus que gros que :min kilobytes.",
|
||||||
|
"string" => "Le texte :attribute doit contenir au moins :min caractères.",
|
||||||
|
"array" => "Le champ :attribute doit avoir au moins :min éléments."
|
||||||
|
),
|
||||||
|
"not_in" => "Le champ :attribute sélectionné n'est pas valide.",
|
||||||
|
"numeric" => "Le champ :attribute doit contenir un nombre.",
|
||||||
|
"regex" => "Le format du champ :attribute est invalide.",
|
||||||
|
"required" => "Le champ :attribute est obligatoire.",
|
||||||
|
"required_if" => "Le champ :attribute est obligatoire quand la valeur de :other est :value.",
|
||||||
|
"required_with" => "Le champ :attribute est obligatoire quand :values est présent.",
|
||||||
|
"required_with_all" => "Le champ :attribute est obligatoire quand :values est présent.",
|
||||||
|
"required_without" => "Le champ :attribute est obligatoire quand :values n'est pas présent.",
|
||||||
|
"required_without_all" => "Le champ :attribute est requis quand aucun de :values n'est présent.",
|
||||||
|
"same" => "Les champs :attribute et :other doivent être identiques.",
|
||||||
|
"size" => array(
|
||||||
|
"numeric" => "La valeur de :attribute doit être :size.",
|
||||||
|
"file" => "La taille du fichier de :attribute doit être de :size kilobytes.",
|
||||||
|
"string" => "Le texte de :attribute doit contenir :size caractères.",
|
||||||
|
"array" => "Le champ :attribute doit contenir :size éléments."
|
||||||
|
),
|
||||||
|
"unique" => "La valeur du champ :attribute est déjà utilisée.",
|
||||||
|
"url" => "Le format de l'URL de :attribute n'est pas valide.",
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Custom Validation Language Lines
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Here you may specify custom validation messages for attributes using the
|
||||||
|
| convention "attribute.rule" to name the lines. This makes it quick to
|
||||||
|
| specify a specific custom language line for a given attribute rule.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'custom' => array(
|
||||||
|
'attribute-name' => array(
|
||||||
|
'rule-name' => 'custom-message',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Custom Validation Attributes
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| The following language lines are used to swap attribute place-holders
|
||||||
|
| with something more reader friendly such as E-Mail Address instead
|
||||||
|
| of "email". This simply helps us make messages a little cleaner.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'attributes' => array(
|
||||||
|
"name" => "Nom",
|
||||||
|
"username" => "Pseudo",
|
||||||
|
"email" => "E-mail",
|
||||||
|
"first_name" => "Prénom",
|
||||||
|
"last_name" => "Nom",
|
||||||
|
"password" => "Mot de passe",
|
||||||
|
"password_confirmation" => "Confirmation du mot de passe",
|
||||||
|
"city" => "Ville",
|
||||||
|
"country" => "Pays",
|
||||||
|
"address" => "Adresse",
|
||||||
|
"phone" => "Téléphone",
|
||||||
|
"mobile" => "Portable",
|
||||||
|
"age" => "Age",
|
||||||
|
"sex" => "Sexe",
|
||||||
|
"gender" => "Genre",
|
||||||
|
"day" => "Jour",
|
||||||
|
"month" => "Mois",
|
||||||
|
"year" => "Année",
|
||||||
|
"hour" => "Heure",
|
||||||
|
"minute" => "Minute",
|
||||||
|
"second" => "Seconde",
|
||||||
|
"title" => "Titre",
|
||||||
|
"content" => "Contenu",
|
||||||
|
"description" => "Description",
|
||||||
|
"excerpt" => "Extrait",
|
||||||
|
"date" => "Date",
|
||||||
|
"time" => "Heure",
|
||||||
|
"available" => "Disponible",
|
||||||
|
"size" => "Taille"
|
||||||
|
),
|
||||||
|
|
||||||
|
);
|
20
app/lang/it/pagination.php
Normal file
20
app/lang/it/pagination.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return array(
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Pagination Language Lines
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| The following language lines are used by the paginator library to build
|
||||||
|
| the simple pagination links. You are free to change them to anything
|
||||||
|
| you want to customize your views to better match your application.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'previous' => '« Precedente',
|
||||||
|
|
||||||
|
'next' => 'Successivo »',
|
||||||
|
|
||||||
|
);
|
24
app/lang/it/reminders.php
Normal file
24
app/lang/it/reminders.php
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return array(
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Password Reminder Language Lines
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| The following language lines are the default lines which match reasons
|
||||||
|
| that are given by the password broker for a password update attempt
|
||||||
|
| has failed, such as for an invalid token or invalid new password.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
"password" => "Le password devono essere di almeno 6 caratteri e devono coincidere.",
|
||||||
|
|
||||||
|
"user" => "Non esiste un utente associato a questo indirizzo e-mail.",
|
||||||
|
|
||||||
|
"token" => "Questo token per la reimpostazione della password non è valido.",
|
||||||
|
|
||||||
|
"sent" => "Promemoria della password inviato!",
|
||||||
|
|
||||||
|
);
|
54
app/lang/it/texts.php
Normal file
54
app/lang/it/texts.php
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return array(
|
||||||
|
|
||||||
|
// client
|
||||||
|
'organization' => 'Organization',
|
||||||
|
'name' => 'Name',
|
||||||
|
'website' => 'Website',
|
||||||
|
'work_phone' => 'Phone',
|
||||||
|
'address' => 'Address',
|
||||||
|
'address1' => 'Street',
|
||||||
|
'address2' => 'Apt/Suite',
|
||||||
|
'city' => 'City',
|
||||||
|
'state' => 'State/Province',
|
||||||
|
'postal_code' => 'Postal Code',
|
||||||
|
'country_id' => 'Country',
|
||||||
|
'contacts' => 'Contacts',
|
||||||
|
'first_name' => 'First Name',
|
||||||
|
'last_name' => 'Last Name',
|
||||||
|
'phone' => 'Phone',
|
||||||
|
'email' => 'Email',
|
||||||
|
'additional_info' => 'Additional Info',
|
||||||
|
'payment_terms' => 'Payment Terms',
|
||||||
|
'currency_id' => 'Currency',
|
||||||
|
'size_id' => 'Size',
|
||||||
|
'industry_id' => 'Industry',
|
||||||
|
'private_notes' => 'Private Notes',
|
||||||
|
|
||||||
|
// invoice
|
||||||
|
'invoice' => 'Invoice',
|
||||||
|
'client' => 'Client',
|
||||||
|
'invoice_date' => 'Invoice Date',
|
||||||
|
'due_date' => 'Due Date',
|
||||||
|
'invoice_number' => 'Invoice Number',
|
||||||
|
'invoice_number_short' => 'Invoice #',
|
||||||
|
'po_number' => 'PO Number',
|
||||||
|
'po_number_short' => 'PO #',
|
||||||
|
'frequency_id' => 'How often',
|
||||||
|
'dicount' => 'Discount',
|
||||||
|
'taxes' => 'Taxes',
|
||||||
|
'tax' => 'Tax',
|
||||||
|
'item' => 'Item',
|
||||||
|
'description' => 'Description',
|
||||||
|
'unit_cost' => 'Unit Cost',
|
||||||
|
'quantity' => 'Quantity',
|
||||||
|
'line_total' => 'Line Total',
|
||||||
|
'subtotal' => 'Subtotal',
|
||||||
|
'paid_to_date' => 'Paid to Date',
|
||||||
|
'balance_due' => 'Balance Due',
|
||||||
|
'invoice_design_id' => 'Design',
|
||||||
|
'terms' => 'Terms',
|
||||||
|
'your_invoice' => 'Your Invoice',
|
||||||
|
|
||||||
|
);
|
103
app/lang/it/validation.php
Normal file
103
app/lang/it/validation.php
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return array(
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Validation Language Lines
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| The following language lines contain the default error messages used by
|
||||||
|
| the validator class. Some of these rules have multiple versions such
|
||||||
|
| such as the size rules. Feel free to tweak each of these messages.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
"accepted" => ":attribute deve essere accettato.",
|
||||||
|
"active_url" => ":attribute non è un URL valido.",
|
||||||
|
"after" => ":attribute deve essere una data successiva al :date.",
|
||||||
|
"alpha" => ":attribute può contenere solo lettere.",
|
||||||
|
"alpha_dash" => ":attribute può contenere solo lettere, numeri e trattini.",
|
||||||
|
"alpha_num" => ":attribute può contenere solo lettere e numeri.",
|
||||||
|
"array" => ":attribute deve essere un array.",
|
||||||
|
"before" => ":attribute deve essere una data precedente al :date.",
|
||||||
|
"between" => array(
|
||||||
|
"numeric" => ":attribute deve trovarsi tra :min - :max.",
|
||||||
|
"file" => ":attribute deve trovarsi tra :min - :max kilobytes.",
|
||||||
|
"string" => ":attribute deve trovarsi tra :min - :max caratteri.",
|
||||||
|
"array" => ":attribute deve avere tra :min - :max elementi."
|
||||||
|
),
|
||||||
|
"confirmed" => "Il campo di conferma per :attribute non coincide.",
|
||||||
|
"date" => ":attribute non è una data valida.",
|
||||||
|
"date_format" => ":attribute non coincide con il formato :format.",
|
||||||
|
"different" => ":attribute e :other devono essere differenti.",
|
||||||
|
"digits" => ":attribute deve essere di :digits cifre.",
|
||||||
|
"digits_between" => ":attribute deve essere tra :min e :max cifre.",
|
||||||
|
"email" => ":attribute non è valido.",
|
||||||
|
"exists" => ":attribute selezionato/a non è valido.",
|
||||||
|
"image" => ":attribute deve essere un'immagine.",
|
||||||
|
"in" => ":attribute selezionato non è valido.",
|
||||||
|
"integer" => ":attribute deve essere intero.",
|
||||||
|
"ip" => ":attribute deve essere un indirizzo IP valido.",
|
||||||
|
"max" => array(
|
||||||
|
"numeric" => ":attribute deve essere minore di :max.",
|
||||||
|
"file" => ":attribute non deve essere più grande di :max kilobytes.",
|
||||||
|
"string" => ":attribute non può contenere più di :max caratteri.",
|
||||||
|
"array" => ":attribute non può avere più di :max elementi."
|
||||||
|
),
|
||||||
|
"mimes" => ":attribute deve essere del tipo: :values.",
|
||||||
|
"min" => array(
|
||||||
|
"numeric" => ":attribute deve valere almeno :min.",
|
||||||
|
"file" => ":attribute deve essere più grande di :min kilobytes.",
|
||||||
|
"string" => ":attribute deve contenere almeno :min caratteri.",
|
||||||
|
"array" => ":attribute deve avere almeno :min elementi."
|
||||||
|
),
|
||||||
|
"not_in" => "Il valore selezionato per :attribute non è valido.",
|
||||||
|
"numeric" => ":attribute deve essere un numero.",
|
||||||
|
"regex" => "Il formato del campo :attribute non è valido.",
|
||||||
|
"required" => ":attribute è richiesto.",
|
||||||
|
"required_if" => "Il campo :attribute è richiesto quando :other è :value.",
|
||||||
|
"required_with" => "Il campo :attribute è richiesto quando :values è presente.",
|
||||||
|
"required_with_all" => "The :attribute field is required when :values is present.",
|
||||||
|
"required_without" => "Il campo :attribute è richiesto quando :values non è presente.",
|
||||||
|
"required_without_all" => "The :attribute field is required when none of :values are present.",
|
||||||
|
"same" => ":attribute e :other devono coincidere.",
|
||||||
|
"size" => array(
|
||||||
|
"numeric" => ":attribute deve valere :size.",
|
||||||
|
"file" => ":attribute deve essere grande :size kilobytes.",
|
||||||
|
"string" => ":attribute deve contenere :size caratteri.",
|
||||||
|
"array" => ":attribute deve contenere :size elementi."
|
||||||
|
),
|
||||||
|
"unique" => ":attribute è stato già utilizzato.",
|
||||||
|
"url" => ":attribute deve essere un URL.",
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Custom Validation Language Lines
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Here you may specify custom validation messages for attributes using the
|
||||||
|
| convention "attribute.rule" to name the lines. This makes it quick to
|
||||||
|
| specify a specific custom language line for a given attribute rule.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'custom' => array(
|
||||||
|
'attribute-name' => array(
|
||||||
|
'rule-name' => 'custom-message',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Custom Validation Attributes
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| The following language lines are used to swap attribute place-holders
|
||||||
|
| with something more reader friendly such as E-Mail Address instead
|
||||||
|
| of "email". This simply helps us make messages a little cleaner.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'attributes' => array(),
|
||||||
|
|
||||||
|
);
|
20
app/lang/pt_BR/pagination.php
Normal file
20
app/lang/pt_BR/pagination.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return array(
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Pagination Language Lines
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| The following language lines are used by the paginator library to build
|
||||||
|
| the simple pagination links. You are free to change them to anything
|
||||||
|
| you want to customize your views to better match your application.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'previous' => '« Anterior',
|
||||||
|
|
||||||
|
'next' => 'Próximo »',
|
||||||
|
|
||||||
|
);
|
24
app/lang/pt_BR/reminders.php
Normal file
24
app/lang/pt_BR/reminders.php
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return array(
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Password Reminder Language Lines
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| The following language lines are the default lines which match reasons
|
||||||
|
| that are given by the password broker for a password update attempt
|
||||||
|
| has failed, such as for an invalid token or invalid new password.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
"password" => "Senhas devem possuir no mínimo seis caracteres e devem ser iguais.",
|
||||||
|
|
||||||
|
"user" => "Não achamos um usuário com o endereço de e-mail informado.",
|
||||||
|
|
||||||
|
"token" => "Este token de redefinição de senha é inválido.",
|
||||||
|
|
||||||
|
"sent" => "Lmebrete de senha enviado!",
|
||||||
|
|
||||||
|
);
|
53
app/lang/pt_BR/texts.php
Normal file
53
app/lang/pt_BR/texts.php
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return array(
|
||||||
|
|
||||||
|
'organization' => 'Organização',
|
||||||
|
'name' => 'Nome',
|
||||||
|
'website' => 'Website',
|
||||||
|
'work_phone' => 'Telefone',
|
||||||
|
'address' => 'Endereço',
|
||||||
|
'address1' => 'Rua',
|
||||||
|
'address2' => 'Bloco/apto',
|
||||||
|
'city' => 'Cidade',
|
||||||
|
'state' => 'Estado',
|
||||||
|
'postal_code' => 'CEP',
|
||||||
|
'country_id' => 'País',
|
||||||
|
'contacts' => 'Contatos',
|
||||||
|
'first_name' => 'Primeiro Nome',
|
||||||
|
'last_name' => 'Último Nome',
|
||||||
|
'phone' => 'Telefone',
|
||||||
|
'email' => 'Email',
|
||||||
|
'additional_info' => 'Informações Adicionais',
|
||||||
|
'payment_terms' => 'Termos de Pagamento',
|
||||||
|
'currency_id' => 'Moeda',
|
||||||
|
'size_id' => 'Tamanho',
|
||||||
|
'industry_id' => 'Empresa',
|
||||||
|
'private_notes' => 'Notas Privadas',
|
||||||
|
|
||||||
|
// invoice
|
||||||
|
'invoice' => 'Invoice',
|
||||||
|
'client' => 'Client',
|
||||||
|
'invoice_date' => 'Invoice Date',
|
||||||
|
'due_date' => 'Due Date',
|
||||||
|
'invoice_number' => 'Invoice Number',
|
||||||
|
'invoice_number_short' => 'Invoice #',
|
||||||
|
'po_number' => 'PO Number',
|
||||||
|
'po_number_short' => 'PO #',
|
||||||
|
'frequency_id' => 'How often',
|
||||||
|
'discount' => 'Discount',
|
||||||
|
'taxes' => 'Taxes',
|
||||||
|
'tax' => 'Tax',
|
||||||
|
'item' => 'Item',
|
||||||
|
'description' => 'Description',
|
||||||
|
'unit_cost' => 'Unit Cost',
|
||||||
|
'quantity' => 'Quantity',
|
||||||
|
'line_total' => 'Line Total',
|
||||||
|
'subtotal' => 'Subtotal',
|
||||||
|
'paid_to_date' => 'Paid to Date',
|
||||||
|
'balance_due' => 'Balance Due',
|
||||||
|
'invoice_design_id' => 'Design',
|
||||||
|
'terms' => 'Terms',
|
||||||
|
'your_invoice' => 'Your Invoice',
|
||||||
|
|
||||||
|
);
|
102
app/lang/pt_BR/validation.php
Normal file
102
app/lang/pt_BR/validation.php
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return array(
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Validation Language Lines
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| The following language lines contain the default error messages used by
|
||||||
|
| the validator class. Some of these rules have multiple versions such
|
||||||
|
| such as the size rules. Feel free to tweak each of these messages.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
"accepted" => ":attribute deve ser aceito.",
|
||||||
|
"active_url" => ":attribute não é uma URL válida.",
|
||||||
|
"after" => ":attribute deve ser uma data maior que :date.",
|
||||||
|
"alpha" => ":attribute deve conter apenas letras.",
|
||||||
|
"alpha_dash" => ":attribute pode conter apenas letras, número e traços",
|
||||||
|
"alpha_num" => ":attribute pode conter apenas letras e números.",
|
||||||
|
"array" => ":attribute deve ser um array.",
|
||||||
|
"before" => ":attribute deve ser uma data anterior a :date.",
|
||||||
|
"between" => array(
|
||||||
|
"numeric" => ":attribute deve ser entre :min - :max.",
|
||||||
|
"file" => ":attribute deve ser entre :min - :max kilobytes.",
|
||||||
|
"string" => ":attribute deve ser entre :min - :max caracteres.",
|
||||||
|
"array" => ":attribute deve conter entre :min - :max itens.",
|
||||||
|
),
|
||||||
|
"confirmed" => ":attribute confirmação não correponde.",
|
||||||
|
"date" => ":attribute não é uma data válida.",
|
||||||
|
"date_format" => ":attribute não satisfaz o formato :format.",
|
||||||
|
"different" => ":attribute e :other devem ser diferentes.",
|
||||||
|
"digits" => ":attribute deve conter :digits dígitos.",
|
||||||
|
"digits_between" => ":attribute deve conter entre :min e :max dígitos.",
|
||||||
|
"email" => ":attribute está em um formato inválido.",
|
||||||
|
"exists" => "A opção selecionada :attribute é inválida.",
|
||||||
|
"image" => ":attribute deve ser uma imagem.",
|
||||||
|
"in" => "A opção selecionada :attribute é inválida.",
|
||||||
|
"integer" => ":attribute deve ser um número inteiro.",
|
||||||
|
"ip" => ":attribute deve ser um endereço IP válido.",
|
||||||
|
"max" => array(
|
||||||
|
"numeric" => ":attribute não pode ser maior que :max.",
|
||||||
|
"file" => ":attribute não pode ser maior que :max kilobytes.",
|
||||||
|
"string" => ":attribute não pode ser maior que :max caracteres.",
|
||||||
|
"array" => ":attribute não pode conter mais que :max itens.",
|
||||||
|
),
|
||||||
|
"mimes" => ":attribute deve ser um arquivo do tipo: :values.",
|
||||||
|
"min" => array(
|
||||||
|
"numeric" => ":attribute não deve ser menor que :min.",
|
||||||
|
"file" => ":attribute deve ter no mínimo :min kilobytes.",
|
||||||
|
"string" => ":attribute deve conter no mínimo :min caracteres.",
|
||||||
|
"array" => ":attribute deve conter ao menos :min itens.",
|
||||||
|
),
|
||||||
|
"not_in" => "A opção selecionada :attribute é inválida.",
|
||||||
|
"numeric" => ":attribute deve ser um número.",
|
||||||
|
"regex" => ":attribute está em um formato inválido.",
|
||||||
|
"required" => ":attribute é um campo obrigatório.",
|
||||||
|
"required_if" => ":attribute é necessário quando :other é :value.",
|
||||||
|
"required_with" => ":attribute é obrigatório quando :values está presente.",
|
||||||
|
"required_without" => ":attribute é obrigatório quando :values não está presente.",
|
||||||
|
"same" => ":attribute e :other devem corresponder.",
|
||||||
|
"size" => array(
|
||||||
|
"numeric" => ":attribute deve ter :size.",
|
||||||
|
"file" => ":attribute deve ter :size kilobytes.",
|
||||||
|
"string" => ":attribute deve conter :size caracteres.",
|
||||||
|
"array" => ":attribute deve conter :size itens.",
|
||||||
|
),
|
||||||
|
"unique" => ":attribute já está sendo utilizado.",
|
||||||
|
"url" => ":attribute está num formato inválido.",
|
||||||
|
|
||||||
|
"positive" => ":attribute deve ser maior que zero.",
|
||||||
|
"has_credit" => "O cliente não possui crédito suficiente.",
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Custom Validation Language Lines
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Here you may specify custom validation messages for attributes using the
|
||||||
|
| convention "attribute.rule" to name the lines. This makes it quick to
|
||||||
|
| specify a specific custom language line for a given attribute rule.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'custom' => array(),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Custom Validation Attributes
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| The following language lines are used to swap attribute place-holders
|
||||||
|
| with something more reader friendly such as E-Mail Address instead
|
||||||
|
| of "email". This simply helps us make messages a little cleaner.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'attributes' => array(),
|
||||||
|
|
||||||
|
);
|
@ -2,6 +2,35 @@
|
|||||||
|
|
||||||
class Utils
|
class Utils
|
||||||
{
|
{
|
||||||
|
public static function isProd()
|
||||||
|
{
|
||||||
|
return App::environment() == ENV_PRODUCTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function basePath()
|
||||||
|
{
|
||||||
|
return substr($_SERVER['SCRIPT_NAME'], 0, strrpos($_SERVER['SCRIPT_NAME'], '/') + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function trans($input)
|
||||||
|
{
|
||||||
|
$data = [];
|
||||||
|
|
||||||
|
foreach ($input as $field)
|
||||||
|
{
|
||||||
|
if ($field == "checkbox")
|
||||||
|
{
|
||||||
|
$data[] = $field;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$data[] = trans("texts.$field");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
public static function fatalError($message = false, $exception = false)
|
public static function fatalError($message = false, $exception = false)
|
||||||
{
|
{
|
||||||
if (!$message)
|
if (!$message)
|
||||||
@ -27,11 +56,10 @@ class Utils
|
|||||||
'url' => Input::get('url', Request::url()),
|
'url' => Input::get('url', Request::url()),
|
||||||
'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '',
|
'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '',
|
||||||
'ip' => Request::getClientIp(),
|
'ip' => Request::getClientIp(),
|
||||||
'count' => Session::get('error_count', 0),
|
'count' => Session::get('error_count', 0)
|
||||||
'input' => Input::all()
|
|
||||||
];
|
];
|
||||||
|
|
||||||
Log::error('\n'.$error, $data);
|
Log::error($error."\n", $data);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Mail::queue('emails.error', ['message'=>$error.' '.json_encode($data)], function($message)
|
Mail::queue('emails.error', ['message'=>$error.' '.json_encode($data)], function($message)
|
||||||
@ -95,7 +123,8 @@ class Utils
|
|||||||
public static function pluralize($string, $count)
|
public static function pluralize($string, $count)
|
||||||
{
|
{
|
||||||
$string = str_replace('?', $count, $string);
|
$string = str_replace('?', $count, $string);
|
||||||
return $count == 1 ? $string : $string . 's';
|
$field = $count == 1 ? $string : $string . 's';
|
||||||
|
return trans("texts.$field");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function toArray($data)
|
public static function toArray($data)
|
||||||
|
@ -118,14 +118,22 @@ class Account extends Eloquent
|
|||||||
|
|
||||||
public function getLogoWidth()
|
public function getLogoWidth()
|
||||||
{
|
{
|
||||||
list($width, $height) = getimagesize($this->getLogoPath());
|
$path = $this->getLogoPath();
|
||||||
|
if (!file_exists($path)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
list($width, $height) = getimagesize($path);
|
||||||
return $width;
|
return $width;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getLogoHeight()
|
public function getLogoHeight()
|
||||||
{
|
{
|
||||||
list($width, $height) = getimagesize($this->getLogoPath());
|
$path = $this->getLogoPath();
|
||||||
return $height;
|
if (!file_exists($path)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
list($width, $height) = getimagesize($path);
|
||||||
|
return $height;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getNextInvoiceNumber()
|
public function getNextInvoiceNumber()
|
||||||
@ -158,6 +166,39 @@ class Account extends Eloquent
|
|||||||
Session::put(SESSION_DATE_FORMAT, $this->date_format ? $this->date_format->format : DEFAULT_DATE_FORMAT);
|
Session::put(SESSION_DATE_FORMAT, $this->date_format ? $this->date_format->format : DEFAULT_DATE_FORMAT);
|
||||||
Session::put(SESSION_DATE_PICKER_FORMAT, $this->date_format ? $this->date_format->picker_format : DEFAULT_DATE_PICKER_FORMAT);
|
Session::put(SESSION_DATE_PICKER_FORMAT, $this->date_format ? $this->date_format->picker_format : DEFAULT_DATE_PICKER_FORMAT);
|
||||||
Session::put(SESSION_DATETIME_FORMAT, $this->datetime_format ? $this->datetime_format->format : DEFAULT_DATETIME_FORMAT);
|
Session::put(SESSION_DATETIME_FORMAT, $this->datetime_format ? $this->datetime_format->format : DEFAULT_DATETIME_FORMAT);
|
||||||
Session::put(SESSION_CURRENCY, $this->currency_id ? $this->currency_id : DEFAULT_CURRENCY);
|
Session::put(SESSION_CURRENCY, $this->currency_id ? $this->currency_id : DEFAULT_CURRENCY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getInvoiceLabels()
|
||||||
|
{
|
||||||
|
$data = [];
|
||||||
|
$fields = [
|
||||||
|
'invoice',
|
||||||
|
'invoice_date',
|
||||||
|
'due_date',
|
||||||
|
'invoice_number',
|
||||||
|
'po_number',
|
||||||
|
'discount',
|
||||||
|
'taxes',
|
||||||
|
'tax',
|
||||||
|
'item',
|
||||||
|
'description',
|
||||||
|
'unit_cost',
|
||||||
|
'quantity',
|
||||||
|
'line_total',
|
||||||
|
'subtotal',
|
||||||
|
'paid_to_date',
|
||||||
|
'balance_due',
|
||||||
|
'terms',
|
||||||
|
'your_invoice',
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($fields as $field)
|
||||||
|
{
|
||||||
|
$data[$field] = trans("texts.$field");
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -96,13 +96,13 @@ class Activity extends Eloquent
|
|||||||
|
|
||||||
public static function createInvoice($invoice)
|
public static function createInvoice($invoice)
|
||||||
{
|
{
|
||||||
if ($invoice->is_recurring)
|
if (Auth::check())
|
||||||
{
|
{
|
||||||
$message = Utils::encodeActivity(null, 'created recurring', $invoice);
|
$message = Utils::encodeActivity(Auth::user(), 'created', $invoice);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$message = Utils::encodeActivity(Auth::user(), 'created', $invoice);
|
$message = Utils::encodeActivity(null, 'created', $invoice);
|
||||||
}
|
}
|
||||||
|
|
||||||
$client = $invoice->client;
|
$client = $invoice->client;
|
||||||
@ -235,9 +235,7 @@ class Activity extends Eloquent
|
|||||||
$client->last_login = $now;
|
$client->last_login = $now;
|
||||||
$client->save();
|
$client->save();
|
||||||
|
|
||||||
$activity = new Activity;
|
$activity = Activity::getBlank($invitation);
|
||||||
$activity->user_id = $invitation->user_id;
|
|
||||||
$activity->account_id = $invitation->user->account_id;
|
|
||||||
$activity->client_id = $invitation->invoice->client_id;
|
$activity->client_id = $invitation->invoice->client_id;
|
||||||
$activity->invitation_id = $invitation->id;
|
$activity->invitation_id = $invitation->id;
|
||||||
$activity->contact_id = $invitation->contact_id;
|
$activity->contact_id = $invitation->contact_id;
|
||||||
@ -259,7 +257,7 @@ class Activity extends Eloquent
|
|||||||
|
|
||||||
if ($payment->contact_id)
|
if ($payment->contact_id)
|
||||||
{
|
{
|
||||||
$activity = new Activity;
|
$activity = Activity::getBlank($client);
|
||||||
$activity->contact_id = $payment->contact_id;
|
$activity->contact_id = $payment->contact_id;
|
||||||
$activity->message = Utils::encodeActivity($payment->invitation->contact, 'entered payment');
|
$activity->message = Utils::encodeActivity($payment->invitation->contact, 'entered payment');
|
||||||
}
|
}
|
||||||
|
7
app/models/Language.php
Executable file
7
app/models/Language.php
Executable file
@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Language extends Eloquent
|
||||||
|
{
|
||||||
|
public $timestamps = false;
|
||||||
|
protected $softDelete = false;
|
||||||
|
}
|
@ -104,11 +104,25 @@ class User extends ConfideUser implements UserInterface, RemindableInterface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getLocale()
|
||||||
|
{
|
||||||
|
$language = Language::remember(DEFAULT_QUERY_CACHE)->where('id', '=', $this->account->language_id)->first();
|
||||||
|
return $language->locale;
|
||||||
|
}
|
||||||
|
|
||||||
public function showGreyBackground()
|
public function showGreyBackground()
|
||||||
{
|
{
|
||||||
return !$this->theme_id || in_array($this->theme_id, [2, 3, 5, 6, 7, 8, 10, 11, 12]);
|
return !$this->theme_id || in_array($this->theme_id, [2, 3, 5, 6, 7, 8, 10, 11, 12]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function showSignUpPopOver()
|
||||||
|
{
|
||||||
|
$count = Session::get(SESSION_COUNTER, 0);
|
||||||
|
Session::put(SESSION_COUNTER, ++$count);
|
||||||
|
|
||||||
|
return $count == 1 || $count % 7 == 0;
|
||||||
|
}
|
||||||
|
|
||||||
public function afterSave($success=true, $forced = false)
|
public function afterSave($success=true, $forced = false)
|
||||||
{
|
{
|
||||||
if ($this->email)
|
if ($this->email)
|
||||||
|
@ -37,7 +37,10 @@ class ContactMailer extends Mailer {
|
|||||||
'emailFooter' => $invoice->account->email_footer
|
'emailFooter' => $invoice->account->email_footer
|
||||||
];
|
];
|
||||||
|
|
||||||
$this->sendTo($invitation->contact->email, $invitation->user->email, $subject, $view, $data);
|
$fromEmail = $invitation->user->email;
|
||||||
|
$fromName = $invitation->user->getDisplayName();
|
||||||
|
|
||||||
|
$this->sendTo($invitation->contact->email, $fromEmail, $fromName, $subject, $view, $data);
|
||||||
|
|
||||||
Activity::emailInvoice($invitation);
|
Activity::emailInvoice($invitation);
|
||||||
}
|
}
|
||||||
@ -63,6 +66,7 @@ class ContactMailer extends Mailer {
|
|||||||
'paymentAmount' => Utils::formatMoney($payment->amount, $payment->client->currency_id)
|
'paymentAmount' => Utils::formatMoney($payment->amount, $payment->client->currency_id)
|
||||||
];
|
];
|
||||||
|
|
||||||
$this->sendTo($payment->contact->email, $payment->invitation->user->email, $subject, $view, $data);
|
$user = $payment->invitation->user;
|
||||||
|
$this->sendTo($payment->contact->email, $user->email, $user->getDisplayName(), $subject, $view, $data);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -4,7 +4,7 @@ use Mail;
|
|||||||
|
|
||||||
class Mailer {
|
class Mailer {
|
||||||
|
|
||||||
public function sendTo($toEmail, $fromEmail, $subject, $view, $data = [])
|
public function sendTo($toEmail, $fromEmail, $fromName, $subject, $view, $data = [])
|
||||||
{
|
{
|
||||||
$views = [
|
$views = [
|
||||||
'emails.'.$view.'_html',
|
'emails.'.$view.'_html',
|
||||||
@ -13,9 +13,10 @@ class Mailer {
|
|||||||
|
|
||||||
//$view = 'emails.' . $view;
|
//$view = 'emails.' . $view;
|
||||||
|
|
||||||
Mail::queue($views, $data, function($message) use ($toEmail, $fromEmail, $subject)
|
Mail::queue($views, $data, function($message) use ($toEmail, $fromEmail, $fromName, $subject)
|
||||||
{
|
{
|
||||||
$message->to($toEmail)->replyTo($fromEmail)->subject($subject);
|
$message->to($toEmail)->from($fromEmail, $fromName)->sender($fromEmail, $fromName)
|
||||||
|
->replyTo($fromEmail, $fromName)->returnPath($fromEmail)->subject($subject);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -22,7 +22,7 @@ class UserMailer extends Mailer {
|
|||||||
'user' => $user
|
'user' => $user
|
||||||
];
|
];
|
||||||
|
|
||||||
$this->sendTo($user->email, CONTACT_EMAIL, $subject, $view, $data);
|
$this->sendTo($user->email, CONTACT_EMAIL, CONTACT_NAME, $subject, $view, $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function sendNotification(User $user, Invoice $invoice, $type, Payment $payment = null)
|
public function sendNotification(User $user, Invoice $invoice, $type, Payment $payment = null)
|
||||||
@ -63,6 +63,6 @@ class UserMailer extends Mailer {
|
|||||||
|
|
||||||
$subject = "Invoice {$invoice->invoice_number} was $action {$invoice->client->getDisplayName()}";
|
$subject = "Invoice {$invoice->invoice_number} was $action {$invoice->client->getDisplayName()}";
|
||||||
|
|
||||||
$this->sendTo($user->email, CONTACT_EMAIL, $subject, $view, $data);
|
$this->sendTo($user->email, CONTACT_EMAIL, CONTACT_NAME, $subject, $view, $data);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -50,13 +50,13 @@ class InvoiceRepository
|
|||||||
{
|
{
|
||||||
$query = \DB::table('invoices')
|
$query = \DB::table('invoices')
|
||||||
->join('clients', 'clients.id', '=','invoices.client_id')
|
->join('clients', 'clients.id', '=','invoices.client_id')
|
||||||
->join('frequencies', 'frequencies.id', '=', 'invoices.frequency_id')
|
->join('frequencies', 'frequencies.id', '=', 'invoices.frequency_id')
|
||||||
->join('contacts', 'contacts.client_id', '=', 'clients.id')
|
->join('contacts', 'contacts.client_id', '=', 'clients.id')
|
||||||
->where('invoices.account_id', '=', $accountId)
|
->where('invoices.account_id', '=', $accountId)
|
||||||
->where('clients.deleted_at', '=', null)
|
->where('clients.deleted_at', '=', null)
|
||||||
->where('invoices.is_recurring', '=', true)
|
->where('invoices.is_recurring', '=', true)
|
||||||
->where('contacts.is_primary', '=', true)
|
->where('contacts.is_primary', '=', true)
|
||||||
->select('clients.public_id as client_public_id', 'clients.name as client_name', 'invoices.public_id', 'amount', 'frequencies.name as frequency', 'start_date', 'end_date', 'clients.currency_id', 'contacts.first_name', 'contacts.last_name', 'contacts.email');
|
->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');
|
||||||
|
|
||||||
if ($clientPublicId)
|
if ($clientPublicId)
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Application Routes
|
| Application Routes
|
||||||
@ -22,38 +23,6 @@
|
|||||||
//dd(gethostname());
|
//dd(gethostname());
|
||||||
//Log::error('test');
|
//Log::error('test');
|
||||||
|
|
||||||
/*
|
|
||||||
Event::listen('illuminate.query', function($query, $bindings, $time, $name)
|
|
||||||
{
|
|
||||||
$data = compact('bindings', 'time', 'name');
|
|
||||||
|
|
||||||
// Format binding data for sql insertion
|
|
||||||
foreach ($bindings as $i => $binding)
|
|
||||||
{
|
|
||||||
if ($binding instanceof \DateTime)
|
|
||||||
{
|
|
||||||
$bindings[$i] = $binding->format('\'Y-m-d H:i:s\'');
|
|
||||||
}
|
|
||||||
else if (is_string($binding))
|
|
||||||
{
|
|
||||||
$bindings[$i] = "'$binding'";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Insert bindings into query
|
|
||||||
$query = str_replace(array('%', '?'), array('%%', '%s'), $query);
|
|
||||||
$query = vsprintf($query, $bindings);
|
|
||||||
|
|
||||||
Log::info($query, $data);
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
Route::get('/send_emails', function() {
|
|
||||||
Artisan::call('ninja:send-invoices');
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
|
|
||||||
Route::get('/', 'HomeController@showWelcome');
|
Route::get('/', 'HomeController@showWelcome');
|
||||||
Route::get('/rocksteady', 'HomeController@showWelcome');
|
Route::get('/rocksteady', 'HomeController@showWelcome');
|
||||||
Route::get('/about', 'HomeController@showAboutUs');
|
Route::get('/about', 'HomeController@showAboutUs');
|
||||||
@ -87,11 +56,13 @@ Route::group(array('before' => 'auth'), function()
|
|||||||
{
|
{
|
||||||
Route::get('dashboard', 'DashboardController@index');
|
Route::get('dashboard', 'DashboardController@index');
|
||||||
Route::get('view_archive/{entity_type}/{visible}', 'AccountController@setTrashVisible');
|
Route::get('view_archive/{entity_type}/{visible}', 'AccountController@setTrashVisible');
|
||||||
|
Route::get('force_inline_pdf', 'UserController@forcePDFJS');
|
||||||
|
|
||||||
Route::get('account/getSearchData', array('as' => 'getSearchData', 'uses' => 'AccountController@getSearchData'));
|
Route::get('account/getSearchData', array('as' => 'getSearchData', 'uses' => 'AccountController@getSearchData'));
|
||||||
Route::get('company/{section?}', 'AccountController@showSection');
|
Route::get('company/{section?}', 'AccountController@showSection');
|
||||||
Route::post('company/{section?}', 'AccountController@doSection');
|
Route::post('company/{section?}', 'AccountController@doSection');
|
||||||
Route::post('user/setTheme', 'UserController@setTheme');
|
Route::post('user/setTheme', 'UserController@setTheme');
|
||||||
|
Route::post('remove_logo', 'AccountController@removeLogo');
|
||||||
|
|
||||||
Route::resource('clients', 'ClientController');
|
Route::resource('clients', 'ClientController');
|
||||||
Route::get('api/clients', array('as'=>'api.clients', 'uses'=>'ClientController@getDatatable'));
|
Route::get('api/clients', array('as'=>'api.clients', 'uses'=>'ClientController@getDatatable'));
|
||||||
@ -127,7 +98,7 @@ Route::group(array('before' => 'auth'), function()
|
|||||||
|
|
||||||
HTML::macro('nav_link', function($url, $text, $url2 = '', $extra = '') {
|
HTML::macro('nav_link', function($url, $text, $url2 = '', $extra = '') {
|
||||||
$class = ( Request::is($url) || Request::is($url.'/*') || Request::is($url2) ) ? ' class="active"' : '';
|
$class = ( Request::is($url) || Request::is($url.'/*') || Request::is($url2) ) ? ' class="active"' : '';
|
||||||
return '<li'.$class.'><a href="'.URL::to($url).'" '.$extra.'>'.$text.'</a></li>';
|
return '<li'.$class.'><a href="'.URL::to($url).'" '.$extra.'>'.trans("texts.$text").'</a></li>';
|
||||||
});
|
});
|
||||||
|
|
||||||
HTML::macro('tab_link', function($url, $text, $active = false) {
|
HTML::macro('tab_link', function($url, $text, $active = false) {
|
||||||
@ -163,7 +134,17 @@ HTML::macro('image_data', function($imagePath) {
|
|||||||
|
|
||||||
HTML::macro('breadcrumbs', function() {
|
HTML::macro('breadcrumbs', function() {
|
||||||
$str = '<ol class="breadcrumb">';
|
$str = '<ol class="breadcrumb">';
|
||||||
$crumbs = explode('/', $_SERVER['REQUEST_URI']);
|
|
||||||
|
// Get the breadcrumbs by exploding the current path.
|
||||||
|
$basePath = Utils::basePath();
|
||||||
|
$parts = explode('?', $_SERVER['REQUEST_URI']);
|
||||||
|
$path = $parts[0];
|
||||||
|
|
||||||
|
if ($basePath != '/')
|
||||||
|
{
|
||||||
|
$path = str_replace($basePath, '', $path);
|
||||||
|
}
|
||||||
|
$crumbs = explode('/', $path);
|
||||||
|
|
||||||
foreach ($crumbs as $key => $val)
|
foreach ($crumbs as $key => $val)
|
||||||
{
|
{
|
||||||
@ -172,6 +153,7 @@ HTML::macro('breadcrumbs', function() {
|
|||||||
unset($crumbs[$key]);
|
unset($crumbs[$key]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$crumbs = array_values($crumbs);
|
$crumbs = array_values($crumbs);
|
||||||
for ($i=0; $i<count($crumbs); $i++) {
|
for ($i=0; $i<count($crumbs); $i++) {
|
||||||
$crumb = trim($crumbs[$i]);
|
$crumb = trim($crumbs[$i]);
|
||||||
@ -190,7 +172,10 @@ HTML::macro('breadcrumbs', function() {
|
|||||||
return $str . '</ol>';
|
return $str . '</ol>';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
define('CONTACT_EMAIL', 'contact@invoiceninja.com');
|
define('CONTACT_EMAIL', 'contact@invoiceninja.com');
|
||||||
|
define('CONTACT_NAME', 'Invoice Ninja');
|
||||||
|
|
||||||
|
|
||||||
define('ENV_DEVELOPMENT', 'local');
|
define('ENV_DEVELOPMENT', 'local');
|
||||||
define('ENV_STAGING', 'staging');
|
define('ENV_STAGING', 'staging');
|
||||||
@ -240,13 +225,16 @@ define('SESSION_CURRENCY', 'currency');
|
|||||||
define('SESSION_DATE_FORMAT', 'dateFormat');
|
define('SESSION_DATE_FORMAT', 'dateFormat');
|
||||||
define('SESSION_DATE_PICKER_FORMAT', 'datePickerFormat');
|
define('SESSION_DATE_PICKER_FORMAT', 'datePickerFormat');
|
||||||
define('SESSION_DATETIME_FORMAT', 'datetimeFormat');
|
define('SESSION_DATETIME_FORMAT', 'datetimeFormat');
|
||||||
|
define('SESSION_COUNTER', 'sessionCounter');
|
||||||
|
|
||||||
define('DEFAULT_TIMEZONE', 'US/Eastern');
|
define('DEFAULT_TIMEZONE', 'US/Eastern');
|
||||||
define('DEFAULT_CURRENCY', 1); // US Dollar
|
define('DEFAULT_CURRENCY', 1); // US Dollar
|
||||||
define('DEFAULT_DATE_FORMAT', 'M j, Y');
|
define('DEFAULT_DATE_FORMAT', 'M j, Y');
|
||||||
define('DEFAULT_DATE_PICKER_FORMAT', 'M d, yyyy');
|
define('DEFAULT_DATE_PICKER_FORMAT', 'M d, yyyy');
|
||||||
define('DEFAULT_DATETIME_FORMAT', 'F j, Y, g:i a');
|
define('DEFAULT_DATETIME_FORMAT', 'F j, Y, g:i a');
|
||||||
define('DEFAULT_QUERY_CACHE', 120);
|
define('DEFAULT_QUERY_CACHE', 120); // minutes
|
||||||
|
|
||||||
|
define('GATEWAY_PAYPAL_EXPRESS', 17);
|
||||||
|
|
||||||
|
|
||||||
if (Auth::check() && !Session::has(SESSION_TIMEZONE))
|
if (Auth::check() && !Session::has(SESSION_TIMEZONE))
|
||||||
@ -254,7 +242,6 @@ if (Auth::check() && !Session::has(SESSION_TIMEZONE))
|
|||||||
Event::fire('user.refresh');
|
Event::fire('user.refresh');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Validator::extend('positive', function($attribute, $value, $parameters)
|
Validator::extend('positive', function($attribute, $value, $parameters)
|
||||||
{
|
{
|
||||||
return Utils::parseFloat($value) > 0;
|
return Utils::parseFloat($value) > 0;
|
||||||
@ -269,4 +256,38 @@ Validator::extend('has_credit', function($attribute, $value, $parameters)
|
|||||||
$credit = $client->getTotalCredit();
|
$credit = $client->getTotalCredit();
|
||||||
|
|
||||||
return $credit >= $amount;
|
return $credit >= $amount;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Event::listen('illuminate.query', function($query, $bindings, $time, $name)
|
||||||
|
{
|
||||||
|
$data = compact('bindings', 'time', 'name');
|
||||||
|
|
||||||
|
// Format binding data for sql insertion
|
||||||
|
foreach ($bindings as $i => $binding)
|
||||||
|
{
|
||||||
|
if ($binding instanceof \DateTime)
|
||||||
|
{
|
||||||
|
$bindings[$i] = $binding->format('\'Y-m-d H:i:s\'');
|
||||||
|
}
|
||||||
|
else if (is_string($binding))
|
||||||
|
{
|
||||||
|
$bindings[$i] = "'$binding'";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert bindings into query
|
||||||
|
$query = str_replace(array('%', '?'), array('%%', '%s'), $query);
|
||||||
|
$query = vsprintf($query, $bindings);
|
||||||
|
|
||||||
|
Log::info($query, $data);
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (Auth::check() && Auth::user()->id === 1)
|
||||||
|
{
|
||||||
|
Auth::loginUsingId(1);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
@ -1,170 +0,0 @@
|
|||||||
@extends('master')
|
|
||||||
|
|
||||||
@section('head')
|
|
||||||
<link href="{{ asset('css/bootstrap.splash.css') }}" rel="stylesheet" type="text/css"/>
|
|
||||||
<link href="{{ asset('css/splash.css') }}" rel="stylesheet" type="text/css"/>
|
|
||||||
<link href="{{ asset('images/apple-touch-icon-114x114-precomposed.png') }}" rel="apple-touch-icon-precomposed" sizes="114x114">
|
|
||||||
<link href="{{ asset('images/apple-touch-icon-72x72-precomposed.png') }}" rel="apple-touch-icon-precomposed" sizes="72x72">
|
|
||||||
<link href="{{ asset('images/apple-touch-icon-57x57-precomposed.png') }}" rel="apple-touch-icon-precomposed">
|
|
||||||
@stop
|
|
||||||
|
|
||||||
@section('body')
|
|
||||||
|
|
||||||
{{ Form::open(array('url' => 'get_started', 'id' => 'startForm')) }}
|
|
||||||
{{ Form::hidden('guest_key') }}
|
|
||||||
{{ Form::close() }}
|
|
||||||
|
|
||||||
<script>
|
|
||||||
|
|
||||||
$(document).ready(function () {
|
|
||||||
if (isStorageSupported()) {
|
|
||||||
$('[name="guest_key"]').val(localStorage.getItem('guest_key'));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
function isStorageSupported() {
|
|
||||||
try {
|
|
||||||
return 'localStorage' in window && window['localStorage'] !== null;
|
|
||||||
} catch (e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getStarted() {
|
|
||||||
$('#startForm').submit();
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
<div class="navbar" style="margin-bottom:0px">
|
|
||||||
<div class="container">
|
|
||||||
<div class="navbar-inner">
|
|
||||||
<a class="brand" href="/"><img src=
|
|
||||||
"images/invoiceninja-logo.png"></a>
|
|
||||||
<ul class="navbar-list">
|
|
||||||
<li>{{ link_to('about', 'About Us' ) }}</li>
|
|
||||||
<li>{{ link_to('contact', 'Contact Us' ) }}</li>
|
|
||||||
<li>{{ link_to('login', Auth::check() ? 'My Account' : 'Login' ) }}</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<section class="hero3" data-speed="2" data-type="background">
|
|
||||||
<div class="container">
|
|
||||||
<div class="caption">
|
|
||||||
<h1>WHY INVOICE NINJA?
|
|
||||||
</h1>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="about center">
|
|
||||||
<div class="container">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-8 col-md-offset-2">
|
|
||||||
<h2>Open Source Platform</h2>
|
|
||||||
<p>Free yourself from online invoicing platforms with high monthly fees and limited functionality. Being <a href="https://github.com/hillelcoren/invoice-ninja" target="_blank">open source</a> allows us fast app development, security audits by the open-course community, and we can keep it <strong>FREE!</strong></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="about white-bg">
|
|
||||||
<div class="container">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-5">
|
|
||||||
<div class="screendump">
|
|
||||||
<img src="images/about1.jpg">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-7">
|
|
||||||
<h2>Live PDF Creation</h2>
|
|
||||||
<p><strong>Look professional from day #1.</strong> Select one of our beautiful invoice templates to suit your company identity, switch between designs in real time to preview invoices & email them to clients with one click. The live preview PDF function was designed for an efficient and hassle-free experience, and it’s awesome!
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<section class="about">
|
|
||||||
<div class="container">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-7">
|
|
||||||
<h2>Online Payments</h2>
|
|
||||||
<p><strong>Authorize.net, Beanstream, PayPal?</strong> InvoiceNinja supports the most popular online payment gateways! If you need help integrating a third party gateway we don’t yet support, please contact us! We’re happy to help! If you need assistance of want to learn more about online payment solutions, contact us!</p>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-5">
|
|
||||||
<div class="screendump">
|
|
||||||
<img src="images/about2.jpg">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<!--
|
|
||||||
<section class="about center white-bg">
|
|
||||||
<div class="container">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-8 col-md-offset-2">
|
|
||||||
<h2>Info about the company/story</h2>
|
|
||||||
<p>Donec id elit non mi porta gravida at eget metus.
|
|
||||||
Fusce dapibus, tellus ac cursus commodo, tortor mauris
|
|
||||||
condimentum nibh, ut fermentum massa justo sit amet
|
|
||||||
risus. Etiam porta sem malesuada magna mollis euismod.
|
|
||||||
Donec sed odio dui.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
-->
|
|
||||||
<section class="upper-footer">
|
|
||||||
<div class="container">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-3 center-block">
|
|
||||||
<a href="#">
|
|
||||||
<div class="cta">
|
|
||||||
<h2 onclick="getStarted()">Invoice Now <span>+</span></h2>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<footer>
|
|
||||||
<div class="navbar" style="margin-bottom:0px">
|
|
||||||
<div class="container">
|
|
||||||
<div class="social">
|
|
||||||
<!--
|
|
||||||
<a href="http://twitter.com/eas_id"><span class=
|
|
||||||
"socicon">c</span></a>
|
|
||||||
-->
|
|
||||||
<a href=
|
|
||||||
"http://facebook.com/invoiceninja" target="_blank"><span class=
|
|
||||||
"socicon">b</span></a> <a href=
|
|
||||||
"http://twitter.com/invoiceninja" target="_blank"><span class=
|
|
||||||
"socicon">a</span></a>
|
|
||||||
<p>Copyright © 2014 InvoiceNinja. All rights reserved.</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="navbar-inner">
|
|
||||||
<ul class="navbar-list">
|
|
||||||
<li>{{ link_to('about', 'About Us' ) }}</li>
|
|
||||||
<li>{{ link_to('contact', 'Contact Us' ) }}</li>
|
|
||||||
<li>{{ link_to('login', Auth::check() ? 'My Account' : 'Login' ) }}</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
<ul class="navbar-list">
|
|
||||||
<li><a href="#">For developers</a></li>
|
|
||||||
<li><a href="#">Jobs</a></li>
|
|
||||||
<li><a href="#">Terms & Conditions</a></li>
|
|
||||||
<li><a href="#">Our Blog</a></li>
|
|
||||||
</ul>
|
|
||||||
-->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</footer><script src="{{ asset('/js/retina-1.1.0.min.js') }}" type="text/javascript"></script>
|
|
||||||
|
|
||||||
@stop
|
|
@ -29,11 +29,12 @@
|
|||||||
{{ Former::text('name') }}
|
{{ Former::text('name') }}
|
||||||
{{ Former::text('work_email')->label('Email') }}
|
{{ Former::text('work_email')->label('Email') }}
|
||||||
{{ Former::text('work_phone')->label('Phone') }}
|
{{ Former::text('work_phone')->label('Phone') }}
|
||||||
{{ Former::file('logo')->max(2, 'MB')->accept('image')->inlineHelp('Supported: JPEG, GIF and PNG. Recommnded size: 120px width, 80px height') }}
|
{{ Former::file('logo')->max(2, 'MB')->accept('image')->inlineHelp('Supported: JPEG, GIF and PNG. Recommended height: 120px') }}
|
||||||
|
|
||||||
@if (file_exists($account->getLogoPath()))
|
@if (file_exists($account->getLogoPath()))
|
||||||
<center>
|
<center>
|
||||||
{{ HTML::image($account->getLogoPath(), "Logo") }}
|
{{ HTML::image($account->getLogoPath(), "Logo") }}
|
||||||
|
<a href="#" onclick="deleteLogo()">Remove logo</a>
|
||||||
</center><br/>
|
</center><br/>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@ -61,8 +62,9 @@
|
|||||||
{{ Former::text('email') }}
|
{{ Former::text('email') }}
|
||||||
{{ Former::text('phone') }}
|
{{ Former::text('phone') }}
|
||||||
|
|
||||||
|
|
||||||
{{ Former::legend('Localization') }}
|
{{ Former::legend('Localization') }}
|
||||||
|
{{ Former::select('language_id')->addOption('','')->label('Language')
|
||||||
|
->fromQuery($languages, 'name', 'id') }}
|
||||||
{{ Former::select('currency_id')->addOption('','')->label('Currency')
|
{{ Former::select('currency_id')->addOption('','')->label('Currency')
|
||||||
->fromQuery($currencies, 'name', 'id') }}
|
->fromQuery($currencies, 'name', 'id') }}
|
||||||
{{ Former::select('timezone_id')->addOption('','')->label('Timezone')
|
{{ Former::select('timezone_id')->addOption('','')->label('Timezone')
|
||||||
@ -82,12 +84,22 @@
|
|||||||
|
|
||||||
{{ Former::close() }}
|
{{ Former::close() }}
|
||||||
|
|
||||||
|
{{ Form::open(['url' => 'remove_logo', 'class' => 'removeLogoForm']) }}
|
||||||
|
{{ Form::close() }}
|
||||||
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
|
||||||
$(function() {
|
$(function() {
|
||||||
$('#country_id').combobox();
|
$('#country_id').combobox();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function deleteLogo() {
|
||||||
|
if (confirm('Are you sure?')) {
|
||||||
|
$('.removeLogoForm').submit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@stop
|
@stop
|
@ -3,10 +3,10 @@
|
|||||||
@section('content')
|
@section('content')
|
||||||
|
|
||||||
<ul class="nav nav-tabs nav nav-justified">
|
<ul class="nav nav-tabs nav nav-justified">
|
||||||
{{ HTML::nav_link('company/details', 'Company Details') }}
|
{{ HTML::nav_link('company/details', 'company_details') }}
|
||||||
{{ HTML::nav_link('company/payments', 'Online Payments') }}
|
{{ HTML::nav_link('company/payments', 'online_payments') }}
|
||||||
{{ HTML::nav_link('company/notifications', 'Notifications') }}
|
{{ HTML::nav_link('company/notifications', 'notifications') }}
|
||||||
{{ HTML::nav_link('company/import_export', 'Import/Export', 'company/import_map') }}
|
{{ HTML::nav_link('company/import_export', 'import_export', 'company/import_map') }}
|
||||||
</ul>
|
</ul>
|
||||||
<p> </p>
|
<p> </p>
|
||||||
|
|
||||||
|
@ -14,6 +14,28 @@
|
|||||||
{{ Former::checkbox('notify_viewed')->label(' ')->text('Email me when an invoice is <b>viewed</b>') }}
|
{{ Former::checkbox('notify_viewed')->label(' ')->text('Email me when an invoice is <b>viewed</b>') }}
|
||||||
{{ Former::checkbox('notify_paid')->label(' ')->text('Email me when an invoice is <b>paid</b>') }}
|
{{ Former::checkbox('notify_paid')->label(' ')->text('Email me when an invoice is <b>paid</b>') }}
|
||||||
|
|
||||||
|
{{ Former::legend('Site Updates') }}
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="invoice_terms" class="control-label col-lg-4 col-sm-4"></label>
|
||||||
|
<div class="col-lg-8 col-sm-8">
|
||||||
|
|
||||||
|
<div id="fb-root"></div>
|
||||||
|
<script>(function(d, s, id) {
|
||||||
|
var js, fjs = d.getElementsByTagName(s)[0];
|
||||||
|
if (d.getElementById(id)) return;
|
||||||
|
js = d.createElement(s); js.id = id;
|
||||||
|
js.src = "//connect.facebook.net/en_US/all.js#xfbml=1&appId=635126583203143";
|
||||||
|
fjs.parentNode.insertBefore(js, fjs);
|
||||||
|
}(document, 'script', 'facebook-jssdk'));</script>
|
||||||
|
|
||||||
|
<div class="fb-follow" data-href="https://www.facebook.com/invoiceninja" data-colorscheme="light" data-layout="button" data-show-faces="false"></div>
|
||||||
|
|
||||||
|
<a href="https://twitter.com/invoiceninja" class="twitter-follow-button" data-show-count="false" data-related="hillelcoren" data-size="medium">Follow @invoiceninja</a>
|
||||||
|
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
|
||||||
|
|
||||||
|
</div></div>
|
||||||
|
|
||||||
{{ Former::legend('Custom Messages') }}
|
{{ Former::legend('Custom Messages') }}
|
||||||
{{ Former::textarea('invoice_terms')->label('Set default invoice terms') }}
|
{{ Former::textarea('invoice_terms')->label('Set default invoice terms') }}
|
||||||
{{ Former::textarea('email_footer')->label('Set default email signature') }}
|
{{ Former::textarea('email_footer')->label('Set default email signature') }}
|
||||||
|
@ -14,10 +14,8 @@
|
|||||||
@if ($accountGateway)
|
@if ($accountGateway)
|
||||||
{{ Former::populateField('gateway_id', $accountGateway->gateway_id) }}
|
{{ Former::populateField('gateway_id', $accountGateway->gateway_id) }}
|
||||||
@foreach ($accountGateway->fields as $field => $junk)
|
@foreach ($accountGateway->fields as $field => $junk)
|
||||||
@if ($field == 'testMode' || $field == 'developerMode')
|
@if (in_array($field, ['solutionType', 'landingPage', 'headerImageUrl', 'brandName']))
|
||||||
@if ($config->$field)
|
{{-- do nothing --}}
|
||||||
{{-- Former::populateField($accountGateway->gateway_id.'_'.$field, true ) --}}
|
|
||||||
@endif
|
|
||||||
@else
|
@else
|
||||||
{{ Former::populateField($accountGateway->gateway_id.'_'.$field, $config->$field) }}
|
{{ Former::populateField($accountGateway->gateway_id.'_'.$field, $config->$field) }}
|
||||||
@endif
|
@endif
|
||||||
@ -32,7 +30,7 @@
|
|||||||
<div id="gateway_{{ $gateway->id }}_div" style="display: none">
|
<div id="gateway_{{ $gateway->id }}_div" style="display: none">
|
||||||
@foreach ($gateway->fields as $field => $details)
|
@foreach ($gateway->fields as $field => $details)
|
||||||
|
|
||||||
@if ($field == 'solutionType' || $field == 'landingPage')
|
@if (in_array($field, ['solutionType', 'landingPage', 'headerImageUrl', 'brandName']))
|
||||||
{{-- do nothing --}}
|
{{-- do nothing --}}
|
||||||
@elseif ($field == 'testMode' || $field == 'developerMode')
|
@elseif ($field == 'testMode' || $field == 'developerMode')
|
||||||
{{-- Former::checkbox($gateway->id.'_'.$field)->label(Utils::toSpaceCase($field))->text('Enable') --}}
|
{{-- Former::checkbox($gateway->id.'_'.$field)->label(Utils::toSpaceCase($field))->text('Enable') --}}
|
||||||
|
@ -1,216 +0,0 @@
|
|||||||
@extends('master')
|
|
||||||
|
|
||||||
@section('head')
|
|
||||||
<link href="{{ asset('vendor/bootstrap/dist/css/bootstrap.min.css') }}" rel="stylesheet" type="text/css"/>
|
|
||||||
<link href="{{ asset('css/bootstrap.splash.css') }}" rel="stylesheet" type="text/css"/>
|
|
||||||
<link href="{{ asset('css/splash.css') }}" rel="stylesheet" type="text/css"/>
|
|
||||||
<link href="{{ asset('images/apple-touch-icon-114x114-precomposed.png') }}" rel="apple-touch-icon-precomposed" sizes="114x114">
|
|
||||||
<link href="{{ asset('images/apple-touch-icon-72x72-precomposed.png') }}" rel="apple-touch-icon-precomposed" sizes="72x72">
|
|
||||||
<link href="{{ asset('images/apple-touch-icon-57x57-precomposed.png') }}" rel="apple-touch-icon-precomposed">
|
|
||||||
@stop
|
|
||||||
|
|
||||||
@section('body')
|
|
||||||
|
|
||||||
{{ Form::open(array('url' => 'get_started', 'id' => 'startForm')) }}
|
|
||||||
{{ Form::hidden('guest_key') }}
|
|
||||||
{{ Form::close() }}
|
|
||||||
|
|
||||||
<script>
|
|
||||||
$(document).ready(function () {
|
|
||||||
|
|
||||||
if (isStorageSupported()) {
|
|
||||||
$('[name="guest_key"]').val(localStorage.getItem('guest_key'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$("#feedbackSubmit").click(function() {
|
|
||||||
//clear any errors
|
|
||||||
contactForm.clearErrors();
|
|
||||||
|
|
||||||
//do a little client-side validation -- check that each field has a value and e-mail field is in proper format
|
|
||||||
var hasErrors = false;
|
|
||||||
$('.feedbackForm input,textarea').each(function() {
|
|
||||||
if (!$(this).val()) {
|
|
||||||
hasErrors = true;
|
|
||||||
contactForm.addError($(this));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
var $email = $('#email');
|
|
||||||
if (!contactForm.isValidEmail($email.val())) {
|
|
||||||
hasErrors = true;
|
|
||||||
contactForm.addError($email);
|
|
||||||
}
|
|
||||||
|
|
||||||
//if there are any errors return without sending e-mail
|
|
||||||
if (hasErrors) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
//namespace as not to pollute global namespace
|
|
||||||
var contactForm = {
|
|
||||||
isValidEmail: function (email) {
|
|
||||||
var regex = /^([a-zA-Z0-9_.+-])+\@(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9]{2,4})+$/;
|
|
||||||
return regex.test(email);
|
|
||||||
},
|
|
||||||
clearErrors: function () {
|
|
||||||
$('#emailAlert').remove();
|
|
||||||
$('.feedbackForm .help-block').hide();
|
|
||||||
$('.feedbackForm .form-group').removeClass('has-error');
|
|
||||||
},
|
|
||||||
addError: function ($input) {
|
|
||||||
$input.siblings('.help-block').show();
|
|
||||||
$input.parent('.form-group').addClass('has-error');
|
|
||||||
},
|
|
||||||
addAjaxMessage: function(msg, isError) {
|
|
||||||
$("#feedbackSubmit").after('<div id="emailAlert" class="alert alert-' + (isError ? 'danger' : 'success') + '" style="margin-top: 5px;">' + $('<div/>').text(msg).html() + '</div>');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function isStorageSupported() {
|
|
||||||
try {
|
|
||||||
return 'localStorage' in window && window['localStorage'] !== null;
|
|
||||||
} catch (e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getStarted() {
|
|
||||||
$('#startForm').submit();
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
<div class="navbar" style="margin-bottom:0px">
|
|
||||||
<div class="container">
|
|
||||||
<div class="navbar-inner">
|
|
||||||
<a class="brand" href="/"><img src=
|
|
||||||
"images/invoiceninja-logo.png"></a>
|
|
||||||
<ul class="navbar-list">
|
|
||||||
<li>{{ link_to('about', 'About Us' ) }}</li>
|
|
||||||
<li>{{ link_to('contact', 'Contact Us' ) }}</li>
|
|
||||||
<li>{{ link_to('login', Auth::check() ? 'My Account' : 'Login' ) }}</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<section class="hero4" data-speed="2" data-type="background">
|
|
||||||
<div class="container">
|
|
||||||
<div class="caption">
|
|
||||||
<h1>Contact us
|
|
||||||
</h1>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="about contact">
|
|
||||||
<div class="container">
|
|
||||||
<div id="contact_form" class="row">
|
|
||||||
|
|
||||||
|
|
||||||
@if (Session::has('message'))
|
|
||||||
<div class="alert alert-info">{{ Session::get('message') }}</div>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
@if (Session::has('error'))
|
|
||||||
<div class="alert alert-danger">{{ Session::get('error') }}</div>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-7">
|
|
||||||
<h2>Questions, special requests, or just want to say hi?</h2>
|
|
||||||
<p>Fill in the form below and we'll get back to you as soon as possible. Hope to hear from you!</p>
|
|
||||||
|
|
||||||
{{ Former::open('contact')->addClass('feedbackForm') }}
|
|
||||||
<div class="form-group">
|
|
||||||
<input type="text" class="form-control" id="name" name="name" placeholder="Name">
|
|
||||||
<span class="help-block" style="display: none;">Please enter your name.</span>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<input type="email" class="form-control" id="email" name="email" placeholder="Email Address">
|
|
||||||
<span class="help-block" style="display: none;">Please enter a valid e-mail address.</span>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<textarea rows="10" cols="100" class="form-control" id="message" name="message" placeholder="Message"></textarea>
|
|
||||||
<span class="help-block" style="display: none;">Please enter a message.</span>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-5">
|
|
||||||
<button type="submit" id="feedbackSubmit" class="btn btn-primary btn-lg">Send Message <span class="glyphicon glyphicon-send"></span></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{{ Former::close() }}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="col-md-4 col-md-offset-1 address">
|
|
||||||
<h2>Other ways to reach us</h2>
|
|
||||||
<p><span class="glyphicon glyphicon-send"></span><a href="mailto:contact@invoiceninja.com">contact@invoiceninja.com</a></p>
|
|
||||||
<p><span class="glyphicon glyphicon-earphone"></span>+1-800-763-1948</p>
|
|
||||||
<p><span class="github"></span><div style="padding-top:10px"> <a href="https://github.com/hillelcoren/invoice-ninja" target="_blank">GitHub Project</a></div></p>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<section class="upper-footer white-bg">
|
|
||||||
<div class="container">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-3 center-block">
|
|
||||||
<a href="#">
|
|
||||||
<div class="cta">
|
|
||||||
<h2 onclick="getStarted()">Invoice Now <span>+</span></h2>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<footer>
|
|
||||||
<div class="navbar" style="margin-bottom:0px">
|
|
||||||
<div class="container">
|
|
||||||
<div class="social">
|
|
||||||
<!--
|
|
||||||
<a href="http://twitter.com/eas_id"><span class=
|
|
||||||
"socicon">c</span></a>
|
|
||||||
-->
|
|
||||||
<a href=
|
|
||||||
"http://facebook.com/invoiceninja" target="_blank"><span class=
|
|
||||||
"socicon">b</span></a> <a href=
|
|
||||||
"http://twitter.com/invoiceninja" target="_blank"><span class=
|
|
||||||
"socicon">a</span></a>
|
|
||||||
<p>Copyright © 2014 InvoiceNinja. All rights reserved.</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="navbar-inner">
|
|
||||||
<ul class="navbar-list">
|
|
||||||
<li>{{ link_to('about', 'About Us' ) }}</li>
|
|
||||||
<li>{{ link_to('contact', 'Contact Us' ) }}</li>
|
|
||||||
<li>{{ link_to('login', Auth::check() ? 'My Account' : 'Login' ) }}</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
<ul class="navbar-list">
|
|
||||||
<li><a href="#">For developers</a></li>
|
|
||||||
<li><a href="#">Jobs</a></li>
|
|
||||||
<li><a href="#">Terms & Conditions</a></li>
|
|
||||||
<li><a href="#">Our Blog</a></li>
|
|
||||||
</ul>
|
|
||||||
-->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</footer><script src="{{ asset('/js/retina-1.1.0.min.js') }}" type="text/javascript"></script>
|
|
||||||
|
|
||||||
@stop
|
|
@ -11,7 +11,7 @@
|
|||||||
{{ $totalIncome }}
|
{{ $totalIncome }}
|
||||||
</div>
|
</div>
|
||||||
<div class="in-thin">
|
<div class="in-thin">
|
||||||
in total revenue
|
{{ trans('texts.in_total_revenue') }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -24,7 +24,7 @@
|
|||||||
{{ $billedClients }}
|
{{ $billedClients }}
|
||||||
</div>
|
</div>
|
||||||
<div class="in-thin">
|
<div class="in-thin">
|
||||||
{{ Utils::pluralize('billed client', $billedClients) }}
|
{{ Utils::pluralize('billed_client', $billedClients) }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -52,7 +52,7 @@
|
|||||||
<div class="panel panel-default dashboard" style="min-height:320px">
|
<div class="panel panel-default dashboard" style="min-height:320px">
|
||||||
<div class="panel-heading" style="background-color:#0b4d78">
|
<div class="panel-heading" style="background-color:#0b4d78">
|
||||||
<h3 class="panel-title in-bold-white">
|
<h3 class="panel-title in-bold-white">
|
||||||
<i class="glyphicon glyphicon-exclamation-sign"></i> Notifications
|
<i class="glyphicon glyphicon-exclamation-sign"></i> {{ trans('texts.notifications') }}
|
||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
<ul class="panel-body list-group">
|
<ul class="panel-body list-group">
|
||||||
@ -69,16 +69,16 @@
|
|||||||
<div class="panel panel-default dashboard" style="min-height:320px">
|
<div class="panel panel-default dashboard" style="min-height:320px">
|
||||||
<div class="panel-heading" style="background-color:#e37329">
|
<div class="panel-heading" style="background-color:#e37329">
|
||||||
<h3 class="panel-title in-bold-white">
|
<h3 class="panel-title in-bold-white">
|
||||||
<i class="glyphicon glyphicon-time"></i> Invoices Past Due
|
<i class="glyphicon glyphicon-time"></i> {{ trans('texts.invoices_past_due') }}
|
||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<table class="table table-striped">
|
<table class="table table-striped">
|
||||||
<thead>
|
<thead>
|
||||||
<th>Invoice #</th>
|
<th>{{ trans('texts.invoice_number_short') }}</th>
|
||||||
<th>Client</th>
|
<th>{{ trans('texts.client') }}</th>
|
||||||
<th>Due date</th>
|
<th>{{ trans('texts.due_date') }}</th>
|
||||||
<th>Balance due</th>
|
<th>{{ trans('texts.balance_due') }}</th>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@foreach ($pastDue as $invoice)
|
@foreach ($pastDue as $invoice)
|
||||||
@ -101,16 +101,16 @@
|
|||||||
<div class="panel panel-default dashboard" style="min-height:320px;">
|
<div class="panel panel-default dashboard" style="min-height:320px;">
|
||||||
<div class="panel-heading" style="margin:0;">
|
<div class="panel-heading" style="margin:0;">
|
||||||
<h3 class="panel-title">
|
<h3 class="panel-title">
|
||||||
<i class="glyphicon glyphicon-time"></i> Upcoming invoices
|
<i class="glyphicon glyphicon-time"></i> {{ trans('texts.upcoming_invoices') }}
|
||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<table class="table table-striped">
|
<table class="table table-striped">
|
||||||
<thead>
|
<thead>
|
||||||
<th>Invoice #</th>
|
<th>{{ trans('texts.invoice_number_short') }}</th>
|
||||||
<th>Client</th>
|
<th>{{ trans('texts.client') }}</th>
|
||||||
<th>Due date</th>
|
<th>{{ trans('texts.due_date') }}</th>
|
||||||
<th>Balance due</th>
|
<th>{{ trans('texts.balance_due') }}</th>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@foreach ($upcoming as $invoice)
|
@foreach ($upcoming as $invoice)
|
||||||
@ -129,12 +129,12 @@
|
|||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
<div class="active-clients">
|
<div class="active-clients">
|
||||||
<div class="in-bold in-white" style="font-size:42px">{{ $activeClients }}</div>
|
<div class="in-bold in-white" style="font-size:42px">{{ $activeClients }}</div>
|
||||||
<div class="in-thin in-white">{{ Utils::pluralize('active client', $activeClients) }}</div>
|
<div class="in-thin in-white">{{ Utils::pluralize('active_client', $activeClients) }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
<div class="average-invoice">
|
<div class="average-invoice">
|
||||||
<div><b>Average invoice</b></div>
|
<div><b>{{ trans('texts.average_invoice') }}</b></div>
|
||||||
<div class="in-bold in-white" style="font-size:42px">{{ $invoiceAvg }}</div>
|
<div class="in-bold in-white" style="font-size:42px">{{ $invoiceAvg }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -18,8 +18,8 @@
|
|||||||
<script src="{{ asset('vendor/accounting/accounting.min.js') }}" type="text/javascript"></script>
|
<script src="{{ asset('vendor/accounting/accounting.min.js') }}" type="text/javascript"></script>
|
||||||
<script src="{{ asset('js/bootstrap-combobox.js') }}" type="text/javascript"></script>
|
<script src="{{ asset('js/bootstrap-combobox.js') }}" type="text/javascript"></script>
|
||||||
<script src="{{ asset('js/jspdf.source.js') }}" type="text/javascript"></script>
|
<script src="{{ asset('js/jspdf.source.js') }}" type="text/javascript"></script>
|
||||||
<script src="{{ asset('js/jspdf.plugin.split_text_to_size.js') }}" type="text/javascript"></script>
|
<script src="{{ asset('js/jspdf.plugin.split_text_to_size.js') }}" type="text/javascript"></script>
|
||||||
<script src="{{ asset('js/script.js') }}" type="text/javascript"></script>
|
<script src="{{ asset('js/script.js') }}" type="text/javascript"></script>
|
||||||
|
|
||||||
<link href="{{ asset('vendor/bootstrap/dist/css/bootstrap.min.css') }}" rel="stylesheet" type="text/css"/>
|
<link href="{{ asset('vendor/bootstrap/dist/css/bootstrap.min.css') }}" rel="stylesheet" type="text/css"/>
|
||||||
<link href="{{ asset('vendor/datatables/media/css/jquery.dataTables.css') }}" rel="stylesheet" type="text/css">
|
<link href="{{ asset('vendor/datatables/media/css/jquery.dataTables.css') }}" rel="stylesheet" type="text/css">
|
||||||
@ -60,6 +60,19 @@
|
|||||||
var currency = currencyMap[currency_id];
|
var currency = currencyMap[currency_id];
|
||||||
return accounting.formatMoney(value, hide_symbol ? '' : currency.symbol, currency.precision, currency.thousand_separator, currency.decimal_separator);
|
return accounting.formatMoney(value, hide_symbol ? '' : currency.symbol, currency.precision, currency.thousand_separator, currency.decimal_separator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set the defaults for DataTables initialisation */
|
||||||
|
$.extend( true, $.fn.dataTable.defaults, {
|
||||||
|
"sDom": "t<'row-fluid'<'span6'i><'span6'p>>",
|
||||||
|
"sPaginationType": "bootstrap",
|
||||||
|
"bInfo": true,
|
||||||
|
"oLanguage": {
|
||||||
|
'sEmptyTable': "{{ trans('texts.empty_table') }}",
|
||||||
|
'sLengthMenu': '_MENU_',
|
||||||
|
'sSearch': ''
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
@stop
|
@stop
|
||||||
|
|
||||||
@ -84,7 +97,7 @@
|
|||||||
|
|
||||||
<div class="collapse navbar-collapse" id="navbar-collapse-1">
|
<div class="collapse navbar-collapse" id="navbar-collapse-1">
|
||||||
<ul class="nav navbar-nav" style="font-weight: bold">
|
<ul class="nav navbar-nav" style="font-weight: bold">
|
||||||
{{ HTML::nav_link('dashboard', 'Dashboard') }}
|
{{ HTML::nav_link('dashboard', 'dashboard') }}
|
||||||
{{ HTML::menu_link('client') }}
|
{{ HTML::menu_link('client') }}
|
||||||
{{ HTML::menu_link('invoice') }}
|
{{ HTML::menu_link('invoice') }}
|
||||||
{{ HTML::menu_link('payment') }}
|
{{ HTML::menu_link('payment') }}
|
||||||
@ -94,6 +107,22 @@
|
|||||||
<div class="navbar-form navbar-right">
|
<div class="navbar-form navbar-right">
|
||||||
@if (Auth::check() && !Auth::user()->registered)
|
@if (Auth::check() && !Auth::user()->registered)
|
||||||
{{ Button::sm_success_primary('Sign up', array('id' => 'signUpButton', 'data-toggle'=>'modal', 'data-target'=>'#signUpModal')) }}
|
{{ Button::sm_success_primary('Sign up', array('id' => 'signUpButton', 'data-toggle'=>'modal', 'data-target'=>'#signUpModal')) }}
|
||||||
|
|
||||||
|
@if (Auth::check() && Auth::user()->showSignUpPopOver())
|
||||||
|
<button id="signUpPopOver" type="button" class="btn btn-default" data-toggle="popover" data-placement="bottom" data-content="Sign up to save your work" data-html="true" style="display:none">
|
||||||
|
Sign Up
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(function() {
|
||||||
|
$('#signUpPopOver').show().popover('show').hide();
|
||||||
|
$('body').click(function() {
|
||||||
|
$('#signUpPopOver').popover('hide');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@endif
|
||||||
|
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@if (Auth::check())
|
@if (Auth::check())
|
||||||
@ -103,7 +132,7 @@
|
|||||||
@if (Auth::check() && Auth::user()->registered)
|
@if (Auth::check() && Auth::user()->registered)
|
||||||
{{ Auth::user()->getFullName() }}
|
{{ Auth::user()->getFullName() }}
|
||||||
@else
|
@else
|
||||||
My Company
|
Guest
|
||||||
@endif
|
@endif
|
||||||
</span>
|
</span>
|
||||||
<span class="caret"></span>
|
<span class="caret"></span>
|
||||||
@ -124,16 +153,16 @@
|
|||||||
|
|
||||||
<form class="navbar-form navbar-right" role="search">
|
<form class="navbar-form navbar-right" role="search">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<input type="text" id="search" class="form-control" placeholder="Search">
|
<input type="text" id="search" class="form-control" placeholder="{{ trans('texts.search') }}">
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<ul class="nav navbar-nav navbar-right">
|
<ul class="nav navbar-nav navbar-right">
|
||||||
<li class="dropdown">
|
<li class="dropdown">
|
||||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">History <b class="caret"></b></a>
|
<a href="#" class="dropdown-toggle" data-toggle="dropdown">{{ trans('texts.history') }} <b class="caret"></b></a>
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
@if (count(Session::get(RECENTLY_VIEWED)) == 0)
|
@if (count(Session::get(RECENTLY_VIEWED)) == 0)
|
||||||
<li><a href="#">No items</a></li>
|
<li><a href="#">{{ trans('texts.no_items') }}</a></li>
|
||||||
@else
|
@else
|
||||||
@foreach (Session::get(RECENTLY_VIEWED) as $link)
|
@foreach (Session::get(RECENTLY_VIEWED) as $link)
|
||||||
<li><a href="{{ $link->url }}">{{ $link->name }}</a></li>
|
<li><a href="{{ $link->url }}">{{ $link->name }}</a></li>
|
||||||
@ -164,6 +193,10 @@
|
|||||||
{{ HTML::breadcrumbs() }}
|
{{ HTML::breadcrumbs() }}
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
|
@if (Session::has('warning'))
|
||||||
|
<div class="alert alert-warning">{{ Session::get('warning') }}</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
@if (Session::has('message'))
|
@if (Session::has('message'))
|
||||||
<div class="alert alert-info">{{ Session::get('message') }}</div>
|
<div class="alert alert-info">{{ Session::get('message') }}</div>
|
||||||
@endif
|
@endif
|
||||||
@ -291,7 +324,7 @@
|
|||||||
@endif
|
@endif
|
||||||
|
|
||||||
@if ($_SERVER['SERVER_NAME'] != 'www.invoiceninja.com')
|
@if ($_SERVER['SERVER_NAME'] != 'www.invoiceninja.com')
|
||||||
<div class="container">Powered by <a href="https://www.invoiceninja.com/" target="_blank">InvoiceNinja.com</a></div>
|
<div class="container">{{ trans('texts.powered_by') }} <a href="https://www.invoiceninja.com/" target="_blank">InvoiceNinja.com</a></div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
<p> </p>
|
<p> </p>
|
||||||
@ -368,10 +401,10 @@
|
|||||||
$.ajax({
|
$.ajax({
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
url: '{{ URL::to('signup/submit') }}',
|
url: '{{ URL::to('signup/submit') }}',
|
||||||
data: 'new_email=' + $('form.signUpForm #new_email').val() +
|
data: 'new_email=' + encodeURIComponent($('form.signUpForm #new_email').val()) +
|
||||||
'&new_password=' + $('form.signUpForm #new_password').val() +
|
'&new_password=' + encodeURIComponent($('form.signUpForm #new_password').val()) +
|
||||||
'&new_first_name=' + $('form.signUpForm #new_first_name').val() +
|
'&new_first_name=' + encodeURIComponent($('form.signUpForm #new_first_name').val()) +
|
||||||
'&new_last_name=' + $('form.signUpForm #new_last_name').val(),
|
'&new_last_name=' + encodeURIComponent($('form.signUpForm #new_last_name').val()),
|
||||||
success: function(result) {
|
success: function(result) {
|
||||||
if (result) {
|
if (result) {
|
||||||
localStorage.setItem('guest_key', '');
|
localStorage.setItem('guest_key', '');
|
||||||
@ -436,7 +469,7 @@
|
|||||||
if (isStorageSupported()) {
|
if (isStorageSupported()) {
|
||||||
@if (Auth::check() && !Auth::user()->registered)
|
@if (Auth::check() && !Auth::user()->registered)
|
||||||
localStorage.setItem('guest_key', '{{ Auth::user()->password }}');
|
localStorage.setItem('guest_key', '{{ Auth::user()->password }}');
|
||||||
@endif
|
@endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (!Auth::check() || !Auth::user()->registered)
|
@if (!Auth::check() || !Auth::user()->registered)
|
||||||
@ -472,4 +505,5 @@
|
|||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
@stop
|
@stop
|
@ -20,7 +20,7 @@
|
|||||||
'client' => 'required',
|
'client' => 'required',
|
||||||
'email' => 'required',
|
'email' => 'required',
|
||||||
'product_key' => 'max:20',
|
'product_key' => 'max:20',
|
||||||
)); }}
|
)) }}
|
||||||
|
|
||||||
<input type="submit" style="display:none" name="submitButton" id="submitButton">
|
<input type="submit" style="display:none" name="submitButton" id="submitButton">
|
||||||
|
|
||||||
@ -70,7 +70,7 @@
|
|||||||
->data_date_format(Session::get(SESSION_DATE_PICKER_FORMAT))->append('<i class="glyphicon glyphicon-calendar" onclick="toggleDatePicker(\'due_date\')"></i>') }}
|
->data_date_format(Session::get(SESSION_DATE_PICKER_FORMAT))->append('<i class="glyphicon glyphicon-calendar" onclick="toggleDatePicker(\'due_date\')"></i>') }}
|
||||||
</div>
|
</div>
|
||||||
<div data-bind="visible: is_recurring" style="display: none">
|
<div data-bind="visible: is_recurring" style="display: none">
|
||||||
{{ Former::select('frequency_id')->label('How often')->options($frequencies)->data_bind("value: frequency_id") }}
|
{{ Former::select('frequency_id')->options($frequencies)->data_bind("value: frequency_id") }}
|
||||||
{{ Former::text('start_date')->data_bind("datePicker: start_date, valueUpdate: 'afterkeydown'")
|
{{ Former::text('start_date')->data_bind("datePicker: start_date, valueUpdate: 'afterkeydown'")
|
||||||
->data_date_format(Session::get(SESSION_DATE_PICKER_FORMAT))->append('<i class="glyphicon glyphicon-calendar" onclick="toggleDatePicker(\'start_date\')"></i>') }}
|
->data_date_format(Session::get(SESSION_DATE_PICKER_FORMAT))->append('<i class="glyphicon glyphicon-calendar" onclick="toggleDatePicker(\'start_date\')"></i>') }}
|
||||||
{{ Former::text('end_date')->data_bind("datePicker: end_date, valueUpdate: 'afterkeydown'")
|
{{ Former::text('end_date')->data_bind("datePicker: end_date, valueUpdate: 'afterkeydown'")
|
||||||
@ -82,7 +82,7 @@
|
|||||||
</div>
|
</div>
|
||||||
@else
|
@else
|
||||||
<div data-bind="visible: invoice_status_id() < CONSTS.INVOICE_STATUS_SENT">
|
<div data-bind="visible: invoice_status_id() < CONSTS.INVOICE_STATUS_SENT">
|
||||||
{{ Former::checkbox('recurring')->text('Enable <a href="#" onclick="showLearnMore()"><i class="glyphicon glyphicon-question-sign"></i> Learn more</a>')->data_bind("checked: is_recurring")
|
{{ Former::checkbox('recurring')->text(trans('texts.enable').' <a href="#" onclick="showLearnMore()"><i class="glyphicon glyphicon-question-sign"></i> '.trans('texts.learn_more').'</a>')->data_bind("checked: is_recurring")
|
||||||
->inlineHelp($invoice && $invoice->last_sent_date ? 'Last invoice sent ' . Utils::dateToString($invoice->last_sent_date) : '') }}
|
->inlineHelp($invoice && $invoice->last_sent_date ? 'Last invoice sent ' . Utils::dateToString($invoice->last_sent_date) : '') }}
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
@ -90,15 +90,15 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-md-4" id="col_2">
|
<div class="col-md-4" id="col_2">
|
||||||
{{ Former::text('invoice_number')->label('Invoice #')->data_bind("value: invoice_number, valueUpdate: 'afterkeydown'") }}
|
{{ Former::text('invoice_number')->label(trans('texts.invoice_number_short'))->data_bind("value: invoice_number, valueUpdate: 'afterkeydown'") }}
|
||||||
{{ Former::text('po_number')->label('PO #')->data_bind("value: po_number, valueUpdate: 'afterkeydown'") }}
|
{{ Former::text('po_number')->label(trans('texts.po_number_short'))->data_bind("value: po_number, valueUpdate: 'afterkeydown'") }}
|
||||||
{{ Former::text('discount')->data_bind("value: discount, valueUpdate: 'afterkeydown'")->append('%') }}
|
{{ Former::text('discount')->data_bind("value: discount, valueUpdate: 'afterkeydown'")->append('%') }}
|
||||||
{{-- Former::select('currency_id')->label('Currency')->addOption('', '')->fromQuery($currencies, 'name', 'id')->data_bind("value: currency_id") --}}
|
{{-- Former::select('currency_id')->addOption('', '')->fromQuery($currencies, 'name', 'id')->data_bind("value: currency_id") --}}
|
||||||
|
|
||||||
<div class="form-group" style="margin-bottom: 8px">
|
<div class="form-group" style="margin-bottom: 8px">
|
||||||
<label for="recurring" class="control-label col-lg-4 col-sm-4">Taxes</label>
|
<label for="recurring" class="control-label col-lg-4 col-sm-4">{{ trans('texts.taxes') }}</label>
|
||||||
<div class="col-lg-8 col-sm-8" style="padding-top: 7px">
|
<div class="col-lg-8 col-sm-8" style="padding-top: 7px">
|
||||||
<a href="#" data-bind="click: $root.showTaxesForm"><i class="glyphicon glyphicon-list-alt"></i> Manage rates</a>
|
<a href="#" data-bind="click: $root.showTaxesForm"><i class="glyphicon glyphicon-list-alt"></i> {{ trans('texts.manage_rates') }}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -113,12 +113,12 @@
|
|||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th style="min-width:32px;" class="hide-border"></th>
|
<th style="min-width:32px;" class="hide-border"></th>
|
||||||
<th style="min-width:160px">Item</th>
|
<th style="min-width:160px">{{ trans('texts.item') }}</th>
|
||||||
<th style="width:100%">Description</th>
|
<th style="width:100%">{{ trans('texts.description') }}</th>
|
||||||
<th style="min-width:120px">Unit Cost</th>
|
<th style="min-width:120px">{{ trans('texts.unit_cost') }}</th>
|
||||||
<th style="min-width:120px">Quantity</th>
|
<th style="min-width:120px">{{ trans('texts.quantity') }}</th>
|
||||||
<th style="min-width:120px;display:none;" data-bind="visible: $root.invoice_item_taxes.show">Tax</th>
|
<th style="min-width:120px;display:none;" data-bind="visible: $root.invoice_item_taxes.show">{{ trans('texts.tax') }}</th>
|
||||||
<th style="min-width:120px;">Line Total</th>
|
<th style="min-width:120px;">{{ trans('texts.line_total') }}</th>
|
||||||
<th style="min-width:32px;" class="hide-border"></th>
|
<th style="min-width:32px;" class="hide-border"></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@ -128,7 +128,7 @@
|
|||||||
<i style="display:none" data-bind="visible: actionsVisible() && $parent.invoice_items().length > 1" class="fa fa-sort"></i>
|
<i style="display:none" data-bind="visible: actionsVisible() && $parent.invoice_items().length > 1" class="fa fa-sort"></i>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{{ Former::text('product_key')->useDatalist(Product::getProductKeys($products), 'key')->onkeyup('onItemChange()')
|
{{ Former::text('product_key')->useDatalist(Product::getProductKeys($products), 'product_key')->onkeyup('onItemChange()')
|
||||||
->raw()->data_bind("value: product_key, valueUpdate: 'afterkeydown'")->addClass('datalist') }}
|
->raw()->data_bind("value: product_key, valueUpdate: 'afterkeydown'")->addClass('datalist') }}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@ -157,41 +157,41 @@
|
|||||||
<td colspan="2" rowspan="5">
|
<td colspan="2" rowspan="5">
|
||||||
<br/>
|
<br/>
|
||||||
{{ Former::textarea('public_notes')->data_bind("value: wrapped_notes, valueUpdate: 'afterkeydown'")
|
{{ Former::textarea('public_notes')->data_bind("value: wrapped_notes, valueUpdate: 'afterkeydown'")
|
||||||
->label(false)->placeholder('Note to client')->style('width: 520px; resize: none') }}
|
->label(false)->placeholder(trans('texts.note_to_client'))->style('width: 520px; resize: none') }}
|
||||||
{{ Former::textarea('terms')->data_bind("value: wrapped_terms, valueUpdate: 'afterkeydown'")
|
{{ Former::textarea('terms')->data_bind("value: wrapped_terms, valueUpdate: 'afterkeydown'")
|
||||||
->label(false)->placeholder('Invoice terms')->style('width: 520px; resize: none')
|
->label(false)->placeholder(trans('texts.invoice_terms'))->style('width: 520px; resize: none')
|
||||||
->addGroupClass('less-space-bottom') }}
|
->addGroupClass('less-space-bottom') }}
|
||||||
<label class="checkbox" style="width: 200px">
|
<label class="checkbox" style="width: 200px">
|
||||||
<input type="checkbox" style="width: 24px" data-bind="checked: set_default_terms"/>Save as default terms
|
<input type="checkbox" style="width: 24px" data-bind="checked: set_default_terms"/>{{ trans('texts.save_as_default_terms') }}
|
||||||
</label>
|
</label>
|
||||||
</td>
|
</td>
|
||||||
<td style="display:none" data-bind="visible: $root.invoice_item_taxes.show"/>
|
<td style="display:none" data-bind="visible: $root.invoice_item_taxes.show"/>
|
||||||
<td colspan="2">Subtotal</td>
|
<td colspan="2">{{ trans('texts.subtotal') }}</td>
|
||||||
<td style="text-align: right"><span data-bind="text: totals.subtotal"/></td>
|
<td style="text-align: right"><span data-bind="text: totals.subtotal"/></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr style="display:none" data-bind="visible: discount() > 0">
|
<tr style="display:none" data-bind="visible: discount() > 0">
|
||||||
<td class="hide-border" colspan="3"/>
|
<td class="hide-border" colspan="3"/>
|
||||||
<td style="display:none" class="hide-border" data-bind="visible: $root.invoice_item_taxes.show"/>
|
<td style="display:none" class="hide-border" data-bind="visible: $root.invoice_item_taxes.show"/>
|
||||||
<td colspan="2">Discount</td>
|
<td colspan="2">{{ trans('texts.discount') }}</td>
|
||||||
<td style="text-align: right"><span data-bind="text: totals.discounted"/></td>
|
<td style="text-align: right"><span data-bind="text: totals.discounted"/></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr style="display:none" data-bind="visible: $root.invoice_taxes.show">
|
<tr style="display:none" data-bind="visible: $root.invoice_taxes.show">
|
||||||
<td class="hide-border" colspan="3"/>
|
<td class="hide-border" colspan="3"/>
|
||||||
<td style="display:none" class="hide-border" data-bind="visible: $root.invoice_item_taxes.show"/>
|
<td style="display:none" class="hide-border" data-bind="visible: $root.invoice_item_taxes.show"/>
|
||||||
<td>Tax</td>
|
<td>{{ trans('texts.tax') }}</td>
|
||||||
<td style="min-width:120px"><select class="form-control" style="width:100%" data-bind="value: tax, options: $root.tax_rates, optionsText: 'displayName'"></select></td>
|
<td style="min-width:120px"><select class="form-control" style="width:100%" data-bind="value: tax, options: $root.tax_rates, optionsText: 'displayName'"></select></td>
|
||||||
<td style="text-align: right"><span data-bind="text: totals.taxAmount"/></td>
|
<td style="text-align: right"><span data-bind="text: totals.taxAmount"/></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="hide-border" colspan="3"/>
|
<td class="hide-border" colspan="3"/>
|
||||||
<td style="display:none" class="hide-border" data-bind="visible: $root.invoice_item_taxes.show"/>
|
<td style="display:none" class="hide-border" data-bind="visible: $root.invoice_item_taxes.show"/>
|
||||||
<td colspan="2">Paid to Date</td>
|
<td colspan="2">{{ trans('texts.paid_to_date') }}</td>
|
||||||
<td style="text-align: right" data-bind="text: totals.paidToDate"></td>
|
<td style="text-align: right" data-bind="text: totals.paidToDate"></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="hide-border" colspan="3"/>
|
<td class="hide-border" colspan="3"/>
|
||||||
<td style="display:none" class="hide-border" data-bind="visible: $root.invoice_item_taxes.show"/>
|
<td style="display:none" class="hide-border" data-bind="visible: $root.invoice_item_taxes.show"/>
|
||||||
<td colspan="2"><b>Balance Due</b></td>
|
<td colspan="2"><b>{{ trans('texts.balance_due') }}</b></td>
|
||||||
<td style="text-align: right"><span data-bind="text: totals.total"/></td>
|
<td style="text-align: right"><span data-bind="text: totals.total"/></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tfoot>
|
</tfoot>
|
||||||
@ -210,30 +210,29 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
{{ Former::select('invoice_design_id')->label('Design')->style('display:inline;width:120px')->raw()
|
{{ Former::select('invoice_design_id')->style('display:inline;width:120px')->raw()
|
||||||
->fromQuery($invoiceDesigns, 'name', 'id')->data_bind("value: invoice_design_id") }}
|
->fromQuery($invoiceDesigns, 'name', 'id')->data_bind("value: invoice_design_id") }}
|
||||||
|
|
||||||
|
|
||||||
{{ Button::primary('Download PDF', array('onclick' => 'onDownloadClick()'))->append_with_icon('download-alt'); }}
|
{{ Button::primary(trans('texts.download_pdf'), array('onclick' => 'onDownloadClick()'))->append_with_icon('download-alt'); }}
|
||||||
|
|
||||||
@if (!$invoice || (!$invoice->trashed() && !$invoice->client->trashed()))
|
@if (!$invoice || (!$invoice->trashed() && !$invoice->client->trashed()))
|
||||||
@if ($invoice)
|
@if ($invoice)
|
||||||
|
|
||||||
<div id="primaryActions" style="text-align:left" class="btn-group">
|
<div id="primaryActions" style="text-align:left" class="btn-group">
|
||||||
<button class="btn-success btn" type="button">Save Invoice</button>
|
<button class="btn-success btn" type="button">{{ trans('texts.save_invoice') }}</button>
|
||||||
<button class="btn-success btn dropdown-toggle" type="button" data-toggle="dropdown">
|
<button class="btn-success btn dropdown-toggle" type="button" data-toggle="dropdown">
|
||||||
<span class="caret"></span>
|
<span class="caret"></span>
|
||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
<li><a href="javascript:onSaveClick()" id="saveButton">Save Invoice</a></li>
|
<li><a href="javascript:onSaveClick()" id="saveButton">{{ trans('texts.save_invoice') }}</a></li>
|
||||||
<li><a href="javascript:onCloneClick()">Clone Invoice</a></li>
|
<li><a href="javascript:onCloneClick()">{{ trans('texts.clone_invoice') }}</a></li>
|
||||||
<li class="divider"></li>
|
<li class="divider"></li>
|
||||||
<li><a href="javascript:onArchiveClick()">Archive Invoice</a></li>
|
<li><a href="javascript:onArchiveClick()">{{ trans('texts.archive_invoice') }}</a></li>
|
||||||
<li><a href="javascript:onDeleteClick()">Delete Invoice</a></li>
|
<li><a href="javascript:onDeleteClick()">{{ trans('texts.delete_invoice') }}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
{{-- DropdownButton::normal('Download PDF',
|
{{-- DropdownButton::normal('Download PDF',
|
||||||
Navigation::links(
|
Navigation::links(
|
||||||
array(
|
array(
|
||||||
@ -257,13 +256,13 @@
|
|||||||
)
|
)
|
||||||
, array('id'=>'primaryActions', 'style'=>'text-align:left', 'data-bind'=>'css: $root.enable.save'))->split(); --}}
|
, array('id'=>'primaryActions', 'style'=>'text-align:left', 'data-bind'=>'css: $root.enable.save'))->split(); --}}
|
||||||
@else
|
@else
|
||||||
{{ Button::success('Save Invoice', array('id' => 'saveButton', 'onclick' => 'onSaveClick()')) }}
|
{{ Button::success(trans('texts.save_invoice'), array('id' => 'saveButton', 'onclick' => 'onSaveClick()')) }}
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
{{ Button::normal('Email Invoice', array('id' => 'email_button', 'onclick' => 'onEmailClick()'))->append_with_icon('send'); }}
|
{{ Button::normal(trans('texts.email_invoice'), array('id' => 'email_button', 'onclick' => 'onEmailClick()'))->append_with_icon('send'); }}
|
||||||
|
|
||||||
@if ($invoice)
|
@if ($invoice)
|
||||||
{{ Button::primary('Enter Payment', array('onclick' => 'onPaymentClick()'))->append_with_icon('usd'); }}
|
{{ Button::primary(trans('texts.enter_payment'), array('onclick' => 'onPaymentClick()'))->append_with_icon('usd'); }}
|
||||||
@endif
|
@endif
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@ -281,33 +280,33 @@
|
|||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||||
<h4 class="modal-title" id="clientModalLabel">Client</h4>
|
<h4 class="modal-title" id="clientModalLabel">{{ trans('texts.client') }}</h4>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="container" style="width: 100%">
|
<div class="container" style="width: 100%">
|
||||||
<div style="background-color: #fff" class="row" data-bind="with: client" onkeypress="clientModalEnterClick(event)">
|
<div style="background-color: #fff" class="row" data-bind="with: client" onkeypress="clientModalEnterClick(event)">
|
||||||
<div class="col-md-6" style="margin-left:0px;margin-right:0px" >
|
<div class="col-md-6" style="margin-left:0px;margin-right:0px" >
|
||||||
|
|
||||||
{{ Former::legend('Organization') }}
|
{{ Former::legend('organization') }}
|
||||||
{{ Former::text('name')->data_bind("value: name, valueUpdate: 'afterkeydown', attr { placeholder: name.placeholder }") }}
|
{{ Former::text('name')->data_bind("value: name, valueUpdate: 'afterkeydown', attr { placeholder: name.placeholder }") }}
|
||||||
{{ Former::text('website')->data_bind("value: website, valueUpdate: 'afterkeydown'") }}
|
{{ Former::text('website')->data_bind("value: website, valueUpdate: 'afterkeydown'") }}
|
||||||
{{ Former::text('work_phone')->data_bind("value: work_phone, valueUpdate: 'afterkeydown'")->label('Phone') }}
|
{{ Former::text('work_phone')->data_bind("value: work_phone, valueUpdate: 'afterkeydown'") }}
|
||||||
|
|
||||||
|
|
||||||
{{ Former::legend('Address') }}
|
{{ Former::legend('address') }}
|
||||||
{{ Former::text('address1')->label('Street')->data_bind("value: address1, valueUpdate: 'afterkeydown'") }}
|
{{ Former::text('address1')->data_bind("value: address1, valueUpdate: 'afterkeydown'") }}
|
||||||
{{ Former::text('address2')->label('Apt/Suite')->data_bind("value: address2, valueUpdate: 'afterkeydown'") }}
|
{{ Former::text('address2')->data_bind("value: address2, valueUpdate: 'afterkeydown'") }}
|
||||||
{{ Former::text('city')->data_bind("value: city, valueUpdate: 'afterkeydown'") }}
|
{{ Former::text('city')->data_bind("value: city, valueUpdate: 'afterkeydown'") }}
|
||||||
{{ Former::text('state')->label('State/Province')->data_bind("value: state, valueUpdate: 'afterkeydown'") }}
|
{{ Former::text('state')->data_bind("value: state, valueUpdate: 'afterkeydown'") }}
|
||||||
{{ Former::text('postal_code')->data_bind("value: postal_code, valueUpdate: 'afterkeydown'") }}
|
{{ Former::text('postal_code')->data_bind("value: postal_code, valueUpdate: 'afterkeydown'") }}
|
||||||
{{ Former::select('country_id')->addOption('','')->label('Country')->addGroupClass('country_select')
|
{{ Former::select('country_id')->addOption('','')->addGroupClass('country_select')
|
||||||
->fromQuery($countries, 'name', 'id')->data_bind("dropdown: country_id") }}
|
->fromQuery($countries, 'name', 'id')->data_bind("dropdown: country_id") }}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6" style="margin-left:0px;margin-right:0px" >
|
<div class="col-md-6" style="margin-left:0px;margin-right:0px" >
|
||||||
|
|
||||||
|
|
||||||
{{ Former::legend('Contacts') }}
|
{{ Former::legend('contacts') }}
|
||||||
<div data-bind='template: { foreach: contacts,
|
<div data-bind='template: { foreach: contacts,
|
||||||
beforeRemove: hideContact,
|
beforeRemove: hideContact,
|
||||||
afterAdd: showContact }'>
|
afterAdd: showContact }'>
|
||||||
@ -320,23 +319,23 @@
|
|||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="col-lg-8 col-lg-offset-4">
|
<div class="col-lg-8 col-lg-offset-4">
|
||||||
<span class="redlink bold" data-bind="visible: $parent.contacts().length > 1">
|
<span class="redlink bold" data-bind="visible: $parent.contacts().length > 1">
|
||||||
{{ link_to('#', 'Remove contact -', array('data-bind'=>'click: $parent.removeContact')) }}
|
{{ link_to('#', trans('texts.remove_contact').' -', array('data-bind'=>'click: $parent.removeContact')) }}
|
||||||
</span>
|
</span>
|
||||||
<span data-bind="visible: $index() === ($parent.contacts().length - 1)" class="pull-right greenlink bold">
|
<span data-bind="visible: $index() === ($parent.contacts().length - 1)" class="pull-right greenlink bold">
|
||||||
{{ link_to('#', 'Add contact +', array('data-bind'=>'click: $parent.addContact')) }}
|
{{ link_to('#', trans('texts.add_contact').' +', array('data-bind'=>'click: $parent.addContact')) }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{ Former::legend('Additional Info') }}
|
{{ Former::legend('additional_info') }}
|
||||||
{{ Former::select('payment_terms')->addOption('','0')->data_bind('value: payment_terms')
|
{{ Former::select('payment_terms')->addOption('','0')->data_bind('value: payment_terms')
|
||||||
->fromQuery($paymentTerms, 'name', 'num_days') }}
|
->fromQuery($paymentTerms, 'name', 'num_days') }}
|
||||||
{{ Former::select('currency_id')->addOption('','')->label('Currency')->data_bind('value: currency_id')
|
{{ Former::select('currency_id')->addOption('','')->data_bind('value: currency_id')
|
||||||
->fromQuery($currencies, 'name', 'id') }}
|
->fromQuery($currencies, 'name', 'id') }}
|
||||||
{{ Former::select('size_id')->addOption('','')->label('Size')->data_bind('value: size_id')
|
{{ Former::select('size_id')->addOption('','')->data_bind('value: size_id')
|
||||||
->fromQuery($sizes, 'name', 'id') }}
|
->fromQuery($sizes, 'name', 'id') }}
|
||||||
{{ Former::select('industry_id')->addOption('','')->label('Industry')->data_bind('value: industry_id')
|
{{ Former::select('industry_id')->addOption('','')->data_bind('value: industry_id')
|
||||||
->fromQuery($industries, 'name', 'id') }}
|
->fromQuery($industries, 'name', 'id') }}
|
||||||
{{ Former::textarea('private_notes')->data_bind('value: private_notes') }}
|
{{ Former::textarea('private_notes')->data_bind('value: private_notes') }}
|
||||||
|
|
||||||
@ -346,9 +345,9 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="modal-footer" style="margin-top: 0px">
|
<div class="modal-footer" style="margin-top: 0px">
|
||||||
<span class="error-block" id="emailError" style="display:none;float:left;font-weight:bold">Please provide a valid email address.</span><span> </span>
|
<span class="error-block" id="emailError" style="display:none;float:left;font-weight:bold">{{ trans('texts.provide_email') }}</span><span> </span>
|
||||||
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
|
<button type="button" class="btn btn-default" data-dismiss="modal">{{ trans('texts.cancel') }}</button>
|
||||||
<button id="clientDoneButton" type="button" class="btn btn-primary" data-bind="click: $root.clientFormComplete">Done</button>
|
<button id="clientDoneButton" type="button" class="btn btn-primary" data-bind="click: $root.clientFormComplete">{{ trans('texts.done') }}</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@ -360,7 +359,7 @@
|
|||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||||
<h4 class="modal-title" id="taxModalLabel">Tax Rates</h4>
|
<h4 class="modal-title" id="taxModalLabel">{{ trans('texts.tax_rates') }}</h4>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="background-color: #fff" onkeypress="taxModalEnterClick(event)">
|
<div style="background-color: #fff" onkeypress="taxModalEnterClick(event)">
|
||||||
@ -368,8 +367,8 @@
|
|||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="hide-border"></th>
|
<th class="hide-border"></th>
|
||||||
<th class="hide-border">Name</th>
|
<th class="hide-border">{{ trans('texts.name') }}</th>
|
||||||
<th class="hide-border">Rate</th>
|
<th class="hide-border">{{ trans('texts.rate') }}</th>
|
||||||
<th class="hide-border"></th>
|
<th class="hide-border"></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@ -390,9 +389,9 @@
|
|||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
||||||
{{ Former::checkbox('invoice_taxes')->text('Enable specifying an <b>invoice tax</b>')
|
{{ Former::checkbox('invoice_taxes')->text(trans('texts.enable_invoice_tax'))
|
||||||
->label('Settings')->data_bind('checked: $root.invoice_taxes, enable: $root.tax_rates().length > 1') }}
|
->label(trans('texts.settings'))->data_bind('checked: $root.invoice_taxes, enable: $root.tax_rates().length > 1') }}
|
||||||
{{ Former::checkbox('invoice_item_taxes')->text('Enable specifying <b>line item taxes</b>')
|
{{ 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') }}
|
->label(' ')->data_bind('checked: $root.invoice_item_taxes, enable: $root.tax_rates().length > 1') }}
|
||||||
|
|
||||||
<br/>
|
<br/>
|
||||||
@ -401,7 +400,7 @@
|
|||||||
|
|
||||||
<div class="modal-footer" style="margin-top: 0px">
|
<div class="modal-footer" style="margin-top: 0px">
|
||||||
<!-- <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button> -->
|
<!-- <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button> -->
|
||||||
<button type="button" class="btn btn-primary" data-bind="click: $root.taxFormComplete">Done</button>
|
<button type="button" class="btn btn-primary" data-bind="click: $root.taxFormComplete">{{ trans('texts.done') }}</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@ -413,22 +412,11 @@
|
|||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||||
<h4 class="modal-title" id="recurringModalLabel">Recurring Invoices</h4>
|
<h4 class="modal-title" id="recurringModalLabel">{{ trans('texts.recurring_invoices') }}</h4>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="background-color: #fff; padding-left: 16px; padding-right: 16px">
|
<div style="background-color: #fff; padding-left: 16px; padding-right: 16px">
|
||||||
|
{{ trans('texts.recurring_help') }}
|
||||||
<p>Automatically send clients the same invoices weekly, bi-monthly, monthly, quarterly or annually. </p>
|
|
||||||
|
|
||||||
<p>Use :MONTH, :QUARTER or :YEAR for dynamic dates. Basic math works as well, for example :MONTH-1.</p>
|
|
||||||
|
|
||||||
<p>Examples of dynamic invoice variables:</p>
|
|
||||||
<ul>
|
|
||||||
<li>"Gym membership for the month of :MONTH" => "Gym membership for the month of July"</li>
|
|
||||||
<li>":YEAR+1 yearly subscription" => "2015 Yearly Subscription"</li>
|
|
||||||
<li>"Retainer payment for :QUARTER+1" => "Retainer payment for Q2"</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="modal-footer" style="margin-top: 0px">
|
<div class="modal-footer" style="margin-top: 0px">
|
||||||
@ -616,14 +604,15 @@
|
|||||||
|
|
||||||
var isRefreshing = false;
|
var isRefreshing = false;
|
||||||
var needsRefresh = false;
|
var needsRefresh = false;
|
||||||
|
|
||||||
function getPDFString() {
|
function getPDFString() {
|
||||||
var invoice = createInvoiceModel();
|
var invoice = createInvoiceModel();
|
||||||
var doc = generatePDF(invoice);
|
var doc = generatePDF(invoice, invoiceLabels);
|
||||||
if (!doc) return;
|
if (!doc) return;
|
||||||
return doc.output('datauristring');
|
return doc.output('datauristring');
|
||||||
}
|
}
|
||||||
function refreshPDF() {
|
function refreshPDF() {
|
||||||
if (isFirefox || (isChrome && !isChromium)) {
|
if ({{ Auth::user()->force_pdfjs ? 'false' : 'true' }} && (isFirefox || (isChrome && !isChromium))) {
|
||||||
var string = getPDFString();
|
var string = getPDFString();
|
||||||
$('#theFrame').attr('src', string).show();
|
$('#theFrame').attr('src', string).show();
|
||||||
} else {
|
} else {
|
||||||
@ -956,7 +945,7 @@
|
|||||||
self.clientLinkText = ko.computed(function() {
|
self.clientLinkText = ko.computed(function() {
|
||||||
if (self.invoice().client().public_id())
|
if (self.invoice().client().public_id())
|
||||||
{
|
{
|
||||||
return 'Edit client details';
|
return "{{ trans('texts.edit_client_details') }}";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -966,7 +955,7 @@
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return 'Create new client';
|
return "{{ trans('texts.create_new_client') }}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -980,7 +969,7 @@
|
|||||||
self.discount = ko.observable('');
|
self.discount = ko.observable('');
|
||||||
self.frequency_id = ko.observable('');
|
self.frequency_id = ko.observable('');
|
||||||
//self.currency_id = ko.observable({{ $client && $client->currency_id ? $client->currency_id : Session::get(SESSION_CURRENCY) }});
|
//self.currency_id = ko.observable({{ $client && $client->currency_id ? $client->currency_id : Session::get(SESSION_CURRENCY) }});
|
||||||
self.terms = ko.observable(wordWrapText('{{ str_replace(["\r\n","\r","\n"], '\n', $account->invoice_terms) }}', 300));
|
self.terms = ko.observable(wordWrapText('{{ str_replace(["\r\n","\r","\n"], '\n', addslashes($account->invoice_terms)) }}', 300));
|
||||||
self.set_default_terms = ko.observable(false);
|
self.set_default_terms = ko.observable(false);
|
||||||
self.public_notes = ko.observable('');
|
self.public_notes = ko.observable('');
|
||||||
self.po_number = ko.observable('');
|
self.po_number = ko.observable('');
|
||||||
@ -1445,10 +1434,10 @@
|
|||||||
|
|
||||||
var products = {{ $products }};
|
var products = {{ $products }};
|
||||||
var clients = {{ $clients }};
|
var clients = {{ $clients }};
|
||||||
|
var invoiceLabels = {{ json_encode($invoiceLabels) }};
|
||||||
var clientMap = {};
|
var clientMap = {};
|
||||||
var $clientSelect = $('select#client');
|
var $clientSelect = $('select#client');
|
||||||
|
|
||||||
|
|
||||||
for (var i=0; i<clients.length; i++) {
|
for (var i=0; i<clients.length; i++) {
|
||||||
var client = clients[i];
|
var client = clients[i];
|
||||||
for (var j=0; j<client.contacts.length; j++) {
|
for (var j=0; j<client.contacts.length; j++) {
|
||||||
|
@ -29,6 +29,19 @@
|
|||||||
|
|
||||||
$(function() {
|
$(function() {
|
||||||
window.invoice = {{ $invoice->toJson() }};
|
window.invoice = {{ $invoice->toJson() }};
|
||||||
|
|
||||||
|
invoice.imageLogo1 = "{{ HTML::image_data('images/report_logo1.jpg') }}";
|
||||||
|
invoice.imageLogoWidth1 =120;
|
||||||
|
invoice.imageLogoHeight1 = 40
|
||||||
|
|
||||||
|
invoice.imageLogo2 = "{{ HTML::image_data('images/report_logo2.jpg') }}";
|
||||||
|
invoice.imageLogoWidth2 =325/2;
|
||||||
|
invoice.imageLogoHeight2 = 81/2;
|
||||||
|
|
||||||
|
invoice.imageLogo3 = "{{ HTML::image_data('images/report_logo3.jpg') }}";
|
||||||
|
invoice.imageLogoWidth3 =325/2;
|
||||||
|
invoice.imageLogoHeight3 = 81/2;
|
||||||
|
|
||||||
@if (file_exists($invoice->client->account->getLogoPath()))
|
@if (file_exists($invoice->client->account->getLogoPath()))
|
||||||
invoice.image = "{{ HTML::image_data($invoice->client->account->getLogoPath()) }}";
|
invoice.image = "{{ HTML::image_data($invoice->client->account->getLogoPath()) }}";
|
||||||
invoice.imageWidth = {{ $invoice->client->account->getLogoWidth() }};
|
invoice.imageWidth = {{ $invoice->client->account->getLogoWidth() }};
|
||||||
@ -59,6 +72,8 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var invoiceLabels = {{ json_encode($invoiceLabels) }};
|
||||||
|
|
||||||
function onDownloadClick() {
|
function onDownloadClick() {
|
||||||
var doc = generatePDF(invoice);
|
var doc = generatePDF(invoice);
|
||||||
|
@ -8,23 +8,23 @@
|
|||||||
{{ Former::text('id') }}
|
{{ Former::text('id') }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{ DropdownButton::normal('Archive',
|
{{ DropdownButton::normal(trans('texts.archive'),
|
||||||
Navigation::links(
|
Navigation::links(
|
||||||
array(
|
array(
|
||||||
array('Archive '.ucwords($entityType), "javascript:submitForm('archive')"),
|
array(trans('texts.archive_'.$entityType), "javascript:submitForm('archive')"),
|
||||||
array('Delete '.ucwords($entityType), "javascript:submitForm('delete')"),
|
array(trans('texts.delete_'.$entityType), "javascript:submitForm('delete')"),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
, array('id'=>'archive'))->split(); }}
|
, array('id'=>'archive'))->split(); }}
|
||||||
|
|
||||||
<label for="trashed" style="font-weight:normal; margin-left: 10px;">
|
<label for="trashed" style="font-weight:normal; margin-left: 10px;">
|
||||||
<input id="trashed" type="checkbox" onclick="setTrashVisible()"
|
<input id="trashed" type="checkbox" onclick="setTrashVisible()"
|
||||||
{{ Session::get('show_trash') ? 'checked' : ''}}/> Show archived/deleted {{ $entityType }}s
|
{{ Session::get('show_trash') ? 'checked' : ''}}/> {{ trans('texts.show_archived_deleted')}} {{ strtolower(trans('texts.'.$entityType.'s')) }}
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<div id="top_right_buttons" class="pull-right">
|
<div id="top_right_buttons" class="pull-right">
|
||||||
<input id="tableFilter" type="text" style="width:140px;margin-right:17px" class="form-control pull-left" placeholder="Filter"/>
|
<input id="tableFilter" type="text" style="width:140px;margin-right:17px" class="form-control pull-left" placeholder="{{ trans('texts.filter') }}"/>
|
||||||
{{ Button::success_link(URL::to($entityType . 's/create'), 'New ' . Utils::getEntityName($entityType), array('class' => 'pull-right'))->append_with_icon('plus-sign'); }}
|
{{ Button::success_link(URL::to($entityType . 's/create'), trans("texts.new_$entityType"), array('class' => 'pull-right'))->append_with_icon('plus-sign'); }}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
|
|
||||||
<title>Invoice Ninja {{ isset($title) ? $title : '' }}</title>
|
<title>Invoice Ninja {{ isset($title) ? $title : ' - Free Online Invoicing' }}</title>
|
||||||
<link rel="canonical" href="https://www.invoiceninja.com"></link>
|
<link rel="canonical" href="https://www.invoiceninja.com"></link>
|
||||||
<link href="{{ asset('favicon.ico') }}" rel="icon" type="image/x-icon">
|
<link href="{{ asset('favicon.ico') }}" rel="icon" type="image/x-icon">
|
||||||
|
|
||||||
@ -15,18 +15,19 @@
|
|||||||
<meta property="og:site_name" content="Invoice Ninja"></meta>
|
<meta property="og:site_name" content="Invoice Ninja"></meta>
|
||||||
<meta property="og:url" content="https://www.invoiceninja.com"></meta>
|
<meta property="og:url" content="https://www.invoiceninja.com"></meta>
|
||||||
<meta property="og:title" content="Invoice Ninja"></meta>
|
<meta property="og:title" content="Invoice Ninja"></meta>
|
||||||
<meta property="og:image" content="https://www.invoiceninja.com/images/facebook.jpg"></meta>
|
<meta property="og:image" content="https://www.invoiceninja.com/images/social.jpg"></meta>
|
||||||
<meta property="og:description" content="Simple, Intuitive Invoicing."></meta>
|
<meta property="og:description" content="Simple, Intuitive Invoicing."></meta>
|
||||||
<meta name="keywords" content="Invoice Ninja"></meta>
|
<meta name="keywords" content="Invoice Ninja"></meta>
|
||||||
|
|
||||||
<script src="{{ asset('vendor/jquery/jquery.min.js') }}" type="text/javascript"></script>
|
<script src="{{ asset('vendor/jquery/jquery.min.js') }}" type="text/javascript"></script>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
window.onerror = function(e) {
|
window.onerror = function(e) {
|
||||||
try {
|
try {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: 'GET',
|
type: 'GET',
|
||||||
url: '{{ URL::to('log_error') }}',
|
url: '{{ URL::to('log_error') }}',
|
||||||
data: 'error='+e+'&url='+window.location
|
data: 'error='+encodeURIComponent(e)+'&url='+encodeURIComponent(window.location)
|
||||||
});
|
});
|
||||||
} catch(err) {}
|
} catch(err) {}
|
||||||
return false;
|
return false;
|
||||||
@ -45,22 +46,16 @@
|
|||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
@if (App::environment() == ENV_PRODUCTION)
|
@if (App::environment() == ENV_PRODUCTION && isset($_ENV['ANALYTICS_KEY']) && $_ENV['ANALYTICS_KEY'])
|
||||||
<script>
|
<script>
|
||||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||||
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
||||||
|
|
||||||
ga('create', 'UA-46031341-1');
|
ga('create', '{{ $_ENV['ANALYTICS_KEY'] }}');
|
||||||
ga('send', 'pageview');
|
ga('send', 'pageview');
|
||||||
</script>
|
</script>
|
||||||
@else
|
|
||||||
<style>
|
|
||||||
.navbar {
|
|
||||||
background-color: #006600 !important;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@yield('body')
|
@yield('body')
|
||||||
|
86
app/views/public/about_us.blade.php
Normal file
86
app/views/public/about_us.blade.php
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
@extends('public.header')
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<section class="hero3" data-speed="2" data-type="background">
|
||||||
|
<div class="container">
|
||||||
|
<div class="caption">
|
||||||
|
<h1>WHY INVOICE NINJA?
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="about center">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-8 col-md-offset-2">
|
||||||
|
<h2>Open Source Platform</h2>
|
||||||
|
<p>Free yourself from online invoicing platforms with high monthly fees and limited functionality. Being <a href="https://github.com/hillelcoren/invoice-ninja" target="_blank">open source</a> allows us fast app development, security audits by the open-course community, and we can keep it <strong>FREE!</strong></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="about white-bg">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-5">
|
||||||
|
<div class="screendump">
|
||||||
|
<img src="images/about1.jpg">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-7">
|
||||||
|
<h2>Live PDF Creation</h2>
|
||||||
|
<p><strong>Look professional from day #1.</strong> Select one of our beautiful invoice templates to suit your company identity, switch between designs in real time to preview invoices & email them to clients with one click. The live preview PDF function was designed for an efficient and hassle-free experience, and it’s awesome!
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section class="about">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-7">
|
||||||
|
<h2>Online Payments</h2>
|
||||||
|
<p><strong>Authorize.net, Beanstream, PayPal?</strong> InvoiceNinja supports the most popular online payment gateways! If you need help integrating a third party gateway we don’t yet support, please contact us! We’re happy to help! If you need assistance of want to learn more about online payment solutions, contact us!</p>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-5">
|
||||||
|
<div class="screendump">
|
||||||
|
<img src="images/about2.jpg">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<!--
|
||||||
|
<section class="about center white-bg">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-8 col-md-offset-2">
|
||||||
|
<h2>Info about the company/story</h2>
|
||||||
|
<p>Donec id elit non mi porta gravida at eget metus.
|
||||||
|
Fusce dapibus, tellus ac cursus commodo, tortor mauris
|
||||||
|
condimentum nibh, ut fermentum massa justo sit amet
|
||||||
|
risus. Etiam porta sem malesuada magna mollis euismod.
|
||||||
|
Donec sed odio dui.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
-->
|
||||||
|
<section class="upper-footer">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-3 center-block">
|
||||||
|
<a href="#">
|
||||||
|
<div class="cta">
|
||||||
|
<h2 onclick="return getStarted()">Invoice Now <span>+</span></h2>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
|
||||||
|
@stop
|
138
app/views/public/contact_us.blade.php
Normal file
138
app/views/public/contact_us.blade.php
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
@extends('public.header')
|
||||||
|
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(document).ready(function () {
|
||||||
|
|
||||||
|
$("#feedbackSubmit").click(function() {
|
||||||
|
//clear any errors
|
||||||
|
contactForm.clearErrors();
|
||||||
|
|
||||||
|
//do a little client-side validation -- check that each field has a value and e-mail field is in proper format
|
||||||
|
var hasErrors = false;
|
||||||
|
$('.feedbackForm input,textarea').each(function() {
|
||||||
|
if (!$(this).val()) {
|
||||||
|
hasErrors = true;
|
||||||
|
contactForm.addError($(this));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var $email = $('#email');
|
||||||
|
if (!contactForm.isValidEmail($email.val())) {
|
||||||
|
hasErrors = true;
|
||||||
|
contactForm.addError($email);
|
||||||
|
}
|
||||||
|
|
||||||
|
//if there are any errors return without sending e-mail
|
||||||
|
if (hasErrors) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
//namespace as not to pollute global namespace
|
||||||
|
var contactForm = {
|
||||||
|
isValidEmail: function (email) {
|
||||||
|
var regex = /^([a-zA-Z0-9_.+-])+\@(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9]{2,4})+$/;
|
||||||
|
return regex.test(email);
|
||||||
|
},
|
||||||
|
clearErrors: function () {
|
||||||
|
$('#emailAlert').remove();
|
||||||
|
$('.feedbackForm .help-block').hide();
|
||||||
|
$('.feedbackForm .form-group').removeClass('has-error');
|
||||||
|
},
|
||||||
|
addError: function ($input) {
|
||||||
|
$input.siblings('.help-block').show();
|
||||||
|
$input.parent('.form-group').addClass('has-error');
|
||||||
|
},
|
||||||
|
addAjaxMessage: function(msg, isError) {
|
||||||
|
$("#feedbackSubmit").after('<div id="emailAlert" class="alert alert-' + (isError ? 'danger' : 'success') + '" style="margin-top: 5px;">' + $('<div/>').text(msg).html() + '</div>');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<section class="hero4" data-speed="2" data-type="background">
|
||||||
|
<div class="container">
|
||||||
|
<div class="caption">
|
||||||
|
<h1>Contact us
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="about contact">
|
||||||
|
<div class="container">
|
||||||
|
<div id="contact_form" class="row">
|
||||||
|
|
||||||
|
|
||||||
|
@if (Session::has('message'))
|
||||||
|
<div class="alert alert-info">{{ Session::get('message') }}</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
@if (Session::has('error'))
|
||||||
|
<div class="alert alert-danger">{{ Session::get('error') }}</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-7">
|
||||||
|
<h2>Questions, special requests, or just want to say hi?</h2>
|
||||||
|
<p>Fill in the form below and we'll get back to you as soon as possible. Hope to hear from you!</p>
|
||||||
|
|
||||||
|
{{ Form::open(['url' => 'contact', 'class' => 'feedbackForm']) }}
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="text" class="form-control" id="name" name="name" placeholder="Name">
|
||||||
|
<span class="help-block" style="display: none;">Please enter your name.</span>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="email" class="form-control" id="email" name="email" placeholder="Email Address">
|
||||||
|
<span class="help-block" style="display: none;">Please enter a valid e-mail address.</span>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<textarea rows="10" cols="100" class="form-control" id="message" name="message" placeholder="Message"></textarea>
|
||||||
|
<span class="help-block" style="display: none;">Please enter a message.</span>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-5">
|
||||||
|
<button type="submit" id="feedbackSubmit" class="btn btn-primary btn-lg">Send Message <span class="glyphicon glyphicon-send"></span></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{ Form::close() }}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4 col-md-offset-1 address">
|
||||||
|
<h2>Other ways to reach us</h2>
|
||||||
|
<p><span class="glyphicon glyphicon-send"></span><a href="mailto:contact@invoiceninja.com">contact@invoiceninja.com</a></p>
|
||||||
|
<p><span class="glyphicon glyphicon-earphone"></span>+1-800-763-1948</p>
|
||||||
|
<p><span class="github"></span><div style="padding-top:10px"> <a href="https://github.com/hillelcoren/invoice-ninja" target="_blank">GitHub Project</a></div></p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<section class="upper-footer white-bg">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-3 center-block">
|
||||||
|
<a href="#">
|
||||||
|
<div class="cta">
|
||||||
|
<h2 onclick="return getStarted()">Invoice Now <span>+</span></h2>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
@stop
|
141
app/views/public/header.blade.php
Normal file
141
app/views/public/header.blade.php
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
@extends('master')
|
||||||
|
|
||||||
|
@section('head')
|
||||||
|
<link href="{{ asset('vendor/bootstrap/dist/css/bootstrap.min.css') }}" rel="stylesheet" type="text/css"/>
|
||||||
|
<link href="{{ asset('css/bootstrap.splash.css') }}" rel="stylesheet" type="text/css"/>
|
||||||
|
<link href="{{ asset('css/splash.css') }}" rel="stylesheet" type="text/css"/>
|
||||||
|
<link href="{{ asset('images/apple-touch-icon-114x114-precomposed.png') }}" rel="apple-touch-icon-precomposed" sizes="114x114">
|
||||||
|
<link href="{{ asset('images/apple-touch-icon-72x72-precomposed.png') }}" rel="apple-touch-icon-precomposed" sizes="72x72">
|
||||||
|
<link href="{{ asset('images/apple-touch-icon-57x57-precomposed.png') }}" rel="apple-touch-icon-precomposed">
|
||||||
|
@stop
|
||||||
|
|
||||||
|
@section('body')
|
||||||
|
|
||||||
|
<div id="fb-root"></div>
|
||||||
|
<script>(function(d, s, id) {
|
||||||
|
var js, fjs = d.getElementsByTagName(s)[0];
|
||||||
|
if (d.getElementById(id)) return;
|
||||||
|
js = d.createElement(s); js.id = id;
|
||||||
|
js.src = "//connect.facebook.net/en_US/all.js#xfbml=1&appId=635126583203143";
|
||||||
|
fjs.parentNode.insertBefore(js, fjs);
|
||||||
|
}(document, 'script', 'facebook-jssdk'));</script>
|
||||||
|
|
||||||
|
|
||||||
|
{{ Form::open(array('url' => 'get_started', 'id' => 'startForm')) }}
|
||||||
|
{{ Form::hidden('guest_key') }}
|
||||||
|
{{ Form::close() }}
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(document).ready(function () {
|
||||||
|
if (isStorageSupported()) {
|
||||||
|
$('[name="guest_key"]').val(localStorage.getItem('guest_key'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function isStorageSupported() {
|
||||||
|
if ('localStorage' in window && window['localStorage'] !== null) {
|
||||||
|
var storage = window.localStorage;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var testKey = 'test';
|
||||||
|
try {
|
||||||
|
storage.setItem(testKey, '1');
|
||||||
|
storage.removeItem(testKey);
|
||||||
|
return true;
|
||||||
|
} catch (error) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getStarted() {
|
||||||
|
$('#startForm').submit();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="navbar" style="margin-bottom:0px">
|
||||||
|
<div class="container">
|
||||||
|
<div class="navbar-inner">
|
||||||
|
<a class="brand" href="/"><img src=
|
||||||
|
"images/invoiceninja-logo.png"></a>
|
||||||
|
<ul class="navbar-list">
|
||||||
|
<li>{{ link_to('about', 'About Us' ) }}</li>
|
||||||
|
<li>{{ link_to('contact', 'Contact Us' ) }}</li>
|
||||||
|
<li>{{ link_to('login', Auth::check() ? 'My Account' : 'Login' ) }}</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
@yield('content')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<footer>
|
||||||
|
<div class="navbar" style="margin-bottom:0px">
|
||||||
|
<div class="container">
|
||||||
|
<div class="social">
|
||||||
|
<!--<div class="fb-follow" data-href="https://www.facebook.com/invoiceninja" data-colorscheme="light" data-layout="button" data-show-faces="false"></div>-->
|
||||||
|
|
||||||
|
<!--<a href="https://twitter.com/invoiceninja" class="twitter-follow-button" data-show-count="false" data-size="large">Follow @invoiceninja</a>
|
||||||
|
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>-->
|
||||||
|
<!--<div class="fb-like" data-href="https://www.invoiceninja.com" data-layout="button" data-action="like" data-show-faces="false" data-share="false"></div> -->
|
||||||
|
<div class="fb-share-button" data-href="https://www.invoiceninja.com/" data-type="button"></div>
|
||||||
|
|
||||||
|
|
||||||
|
<a href="https://twitter.com/share" class="twitter-share-button" data-url="https://www.invoiceninja.com/" data-via="invoiceninja" data-related="hillelcoren" data-count="none" data-text="Free online invoicing">Tweet</a>
|
||||||
|
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
|
||||||
|
|
||||||
|
<!-- Place this tag where you want the +1 button to render. -->
|
||||||
|
<div class="g-plusone" data-size="medium" data-width="300" data-href="https://www.invoiceninja.com/" data-annotation="none" data-count="false" data-recommendations="false"></div>
|
||||||
|
|
||||||
|
<!-- Place this tag after the last +1 button tag. -->
|
||||||
|
<script type="text/javascript">
|
||||||
|
(function() {
|
||||||
|
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
|
||||||
|
po.src = 'https://apis.google.com/js/platform.js';
|
||||||
|
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<script src="//platform.linkedin.com/in.js" type="text/javascript">
|
||||||
|
lang: en_US
|
||||||
|
</script>
|
||||||
|
<script type="IN/Share" data-url="https://www.invoiceninja.com/"></script>
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!--<iframe src="http://ghbtns.com/github-btn.html?user=hillelcoren&repo=invoice-ninja&type=watch" allowtransparency="true" frameborder="0" scrolling="0" width="62" height="20"></iframe>-->
|
||||||
|
|
||||||
|
<p> </p>
|
||||||
|
<p>Copyright © 2014 InvoiceNinja. All rights reserved.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="navbar-inner">
|
||||||
|
<ul class="navbar-list">
|
||||||
|
<li>{{ link_to('about', 'About Us' ) }}</li>
|
||||||
|
<li>{{ link_to('contact', 'Contact Us' ) }}</li>
|
||||||
|
<li>{{ link_to('login', Auth::check() ? 'My Account' : 'Login' ) }}</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<ul class="navbar-list">
|
||||||
|
<li><a href="#">For developers</a></li>
|
||||||
|
<li><a href="#">Jobs</a></li>
|
||||||
|
<li><a href="#">Terms & Conditions</a></li>
|
||||||
|
<li><a href="#">Our Blog</a></li>
|
||||||
|
</ul>
|
||||||
|
-->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer><script src="{{ asset('/js/retina-1.1.0.min.js') }}" type="text/javascript"></script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@stop
|
111
app/views/public/splash.blade.php
Executable file
111
app/views/public/splash.blade.php
Executable file
@ -0,0 +1,111 @@
|
|||||||
|
@extends('public.header')
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
|
||||||
|
|
||||||
|
<section class="hero background" data-speed="2" data-type="background">
|
||||||
|
<div class="caption-side"></div>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="row" style="margin:0;">
|
||||||
|
<div class="caption-wrap">
|
||||||
|
<div class="caption">
|
||||||
|
<h1>THE <span style="color:#2299c0">SIMPLE</span> &
|
||||||
|
<span style="color:#edd71e">FREE</span> WAY TO INVOICE
|
||||||
|
CLIENTS</h1>
|
||||||
|
<p>It's that easy. Stop spending time on
|
||||||
|
complicated and expensive invoicing.<br>
|
||||||
|
No fuss, just get started and <span style=
|
||||||
|
"color:#2299c0">get paid.</span></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-3 center-block">
|
||||||
|
<a href="#">
|
||||||
|
<div class="cta">
|
||||||
|
<h2 id="startButton" onclick="return getStarted()">Invoice Now <span>+</span></h2>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="features">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-3 one">
|
||||||
|
<div class="box">
|
||||||
|
<div class="icon"><img src="{{ asset('images/icon-free.png') }}"></div>
|
||||||
|
<h2>100% FREE, ALWAYS</h2>
|
||||||
|
<p>Invoicing with no monthly fee, because you have enough bills already! Free, now and forever! Quality invoicing to build your business and get paid.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-3 two">
|
||||||
|
<div class="box">
|
||||||
|
<div class="icon"><img src="{{ asset('images/icon-opensource.png') }}"></div>
|
||||||
|
<h2>OPEN-SOURCE</h2>
|
||||||
|
<p>Cloud-based, super secure, and user-developed. Open source platforms are a better way to do business (and save the world). Need we say more?</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-3 three">
|
||||||
|
<div class="box">
|
||||||
|
<div class="icon"><img src="{{ asset('images/icon-pdf.png') }}"></div>
|
||||||
|
<h2>LIVE .PDF VIEW</h2>
|
||||||
|
<p>Create beautiful email-ready .PDF invoices created instantly as you type. Our ‘Save & send’ feature saves you time and impresses clients.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-3 four">
|
||||||
|
<div class="box">
|
||||||
|
<div class="icon"><img src="{{ asset('images/icon-payment.png') }}"></div>
|
||||||
|
<h2>ONLINE PAYMENTS</h2>
|
||||||
|
<p>PayPal? Authorize.Net? Stripe? We support many payment technologies and if you need help or advice we’ll lend a hand (we’re pretty friendly).</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="blue">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<!--<h1>2.500 <span>sent invoices</span></h1>-->
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<!--<h1>$350.456 <span>billed</span></h1>-->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="hero2">
|
||||||
|
<div class="container">
|
||||||
|
<div class="caption">
|
||||||
|
<h1>SIMPLE, INTUITIVE INVOICING.</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="upper-footer">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-3 center-block">
|
||||||
|
<a href="#">
|
||||||
|
<div class="cta">
|
||||||
|
<h2 onclick="return getStarted()">Invoice Now <span>+</span></h2>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
@stop
|
@ -1,29 +1,6 @@
|
|||||||
@extends('master')
|
@extends('public.header')
|
||||||
|
|
||||||
@section('head')
|
@section('content')
|
||||||
<link href="{{ asset('css/bootstrap.splash.css') }}" rel="stylesheet" type="text/css"/>
|
|
||||||
<link href="{{ asset('css/splash.css') }}" rel="stylesheet" type="text/css"/>
|
|
||||||
<link href="{{ asset('images/apple-touch-icon-114x114-precomposed.png') }}" rel="apple-touch-icon-precomposed" sizes="114x114">
|
|
||||||
<link href="{{ asset('images/apple-touch-icon-72x72-precomposed.png') }}" rel="apple-touch-icon-precomposed" sizes="72x72">
|
|
||||||
<link href="{{ asset('images/apple-touch-icon-57x57-precomposed.png') }}" rel="apple-touch-icon-precomposed">
|
|
||||||
@stop
|
|
||||||
|
|
||||||
@section('body')
|
|
||||||
|
|
||||||
<div class="navbar" style="margin-bottom:0px">
|
|
||||||
<div class="container">
|
|
||||||
<div class="navbar-inner">
|
|
||||||
<a class="brand" href="#"><img src=
|
|
||||||
"images/invoiceninja-logo.png"></a>
|
|
||||||
<ul class="navbar-list">
|
|
||||||
<li>{{ link_to('about', 'About Us' ) }}</li>
|
|
||||||
<li>{{ link_to('contact', 'Contact Us' ) }}</li>
|
|
||||||
<li>{{ link_to('login', Auth::check() ? 'My Account' : 'Login' ) }}</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<section class="hero3" data-speed="2" data-type="background">
|
<section class="hero3" data-speed="2" data-type="background">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
@ -170,41 +147,4 @@
|
|||||||
<p> </p>
|
<p> </p>
|
||||||
<p> </p>
|
<p> </p>
|
||||||
|
|
||||||
|
@stop
|
||||||
<footer>
|
|
||||||
<div class="navbar" style="margin-bottom:0px">
|
|
||||||
<div class="container">
|
|
||||||
<div class="social">
|
|
||||||
<!--
|
|
||||||
<a href="http://twitter.com/eas_id"><span class=
|
|
||||||
"socicon">c</span></a>
|
|
||||||
-->
|
|
||||||
<a href=
|
|
||||||
"http://facebook.com/invoiceninja" target="_blank"><span class=
|
|
||||||
"socicon">b</span></a> <a href=
|
|
||||||
"http://twitter.com/invoiceninja" target="_blank"><span class=
|
|
||||||
"socicon">a</span></a>
|
|
||||||
<p>Copyright © 2014 InvoiceNinja. All rights reserved.</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="navbar-inner">
|
|
||||||
<ul class="navbar-list">
|
|
||||||
<li>{{ link_to('about', 'About Us' ) }}</li>
|
|
||||||
<li>{{ link_to('contact', 'Contact Us' ) }}</li>
|
|
||||||
<li>{{ link_to('login', Auth::check() ? 'My Account' : 'Login' ) }}</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
<ul class="navbar-list">
|
|
||||||
<li><a href="#">For developers</a></li>
|
|
||||||
<li><a href="#">Jobs</a></li>
|
|
||||||
<li><a href="#">Terms & Conditions</a></li>
|
|
||||||
<li><a href="#">Our Blog</a></li>
|
|
||||||
</ul>
|
|
||||||
-->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</footer><script src="{{ asset('/js/retina-1.1.0.min.js') }}" type="text/javascript"></script>
|
|
||||||
|
|
||||||
@stop
|
|
@ -1,196 +0,0 @@
|
|||||||
@extends('master')
|
|
||||||
|
|
||||||
@section('head')
|
|
||||||
<link href="{{ asset('css/bootstrap.splash.css') }}" rel="stylesheet" type="text/css"/>
|
|
||||||
<link href="{{ asset('css/splash.css') }}" rel="stylesheet" type="text/css"/>
|
|
||||||
<link href="{{ asset('images/apple-touch-icon-114x114-precomposed.png') }}" rel="apple-touch-icon-precomposed" sizes="114x114">
|
|
||||||
<link href="{{ asset('images/apple-touch-icon-72x72-precomposed.png') }}" rel="apple-touch-icon-precomposed" sizes="72x72">
|
|
||||||
<link href="{{ asset('images/apple-touch-icon-57x57-precomposed.png') }}" rel="apple-touch-icon-precomposed">
|
|
||||||
@stop
|
|
||||||
|
|
||||||
@section('body')
|
|
||||||
|
|
||||||
{{ Form::open(array('url' => 'get_started', 'id' => 'startForm')) }}
|
|
||||||
{{ Form::hidden('guest_key') }}
|
|
||||||
{{ Form::close() }}
|
|
||||||
|
|
||||||
<script>
|
|
||||||
$(document).ready(function () {
|
|
||||||
if (isStorageSupported()) {
|
|
||||||
$('[name="guest_key"]').val(localStorage.getItem('guest_key'));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
function isStorageSupported() {
|
|
||||||
try {
|
|
||||||
return 'localStorage' in window && window['localStorage'] !== null;
|
|
||||||
} catch (e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getStarted() {
|
|
||||||
$('#startForm').submit();
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div class="navbar" style="margin-bottom:0px">
|
|
||||||
<div class="container">
|
|
||||||
<div class="navbar-inner">
|
|
||||||
<a class="brand" href="/"><img src=
|
|
||||||
"images/invoiceninja-logo.png"></a>
|
|
||||||
<ul class="navbar-list">
|
|
||||||
<li>{{ link_to('about', 'About Us' ) }}</li>
|
|
||||||
<li>{{ link_to('contact', 'Contact Us' ) }}</li>
|
|
||||||
<li>{{ link_to('login', Auth::check() ? 'My Account' : 'Login' ) }}</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<section class="hero background" data-speed="2" data-type="background">
|
|
||||||
<div class="caption-side"></div>
|
|
||||||
|
|
||||||
<div class="container">
|
|
||||||
<div class="row" style="margin:0;">
|
|
||||||
<div class="caption-wrap">
|
|
||||||
<div class="caption">
|
|
||||||
<h1>THE <span style="color:#2299c0">SIMPLE</span> &
|
|
||||||
<span style="color:#edd71e">FREE</span> WAY TO INVOICE
|
|
||||||
CLIENTS</h1>
|
|
||||||
<p>It's that easy. Stop spending time on
|
|
||||||
complicated and expensive invoicing.<br>
|
|
||||||
No fuss, just get started and <span style=
|
|
||||||
"color:#2299c0">get paid.</span></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="container">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-3 center-block">
|
|
||||||
<a href="#">
|
|
||||||
<div class="cta">
|
|
||||||
<h2 id="startButton" onclick="getStarted()">Invoice Now <span>+</span></h2>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="features">
|
|
||||||
<div class="container">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-3 one">
|
|
||||||
<div class="box">
|
|
||||||
<div class="icon"><img src="images/icon-free.png"></div>
|
|
||||||
<h2>100% FREE, ALWAYS</h2>
|
|
||||||
<p>Invoicing with no monthly fee, because you have enough bills already! Free, now and forever! Quality invoicing to build your business and get paid.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-3 two">
|
|
||||||
<div class="box">
|
|
||||||
<div class="icon"><img src=
|
|
||||||
"images/icon-opensource.png"></div>
|
|
||||||
<h2>OPEN-SOURCE</h2>
|
|
||||||
<p>Cloud-based, super secure, and user-developed. Open source platforms are a better way to do business (and save the world). Need we say more?</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-3 three">
|
|
||||||
<div class="box">
|
|
||||||
<div class="icon"><img src="images/icon-pdf.png"></div>
|
|
||||||
<h2>LIVE .PDF VIEW</h2>
|
|
||||||
<p>Create beautiful email-ready .PDF invoices created instantly as you type. Our ‘Save & send’ feature saves you time and impresses clients.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-3 four">
|
|
||||||
<div class="box">
|
|
||||||
<div class="icon"><img src=
|
|
||||||
"images/icon-payment.png"></div>
|
|
||||||
<h2>ONLINE PAYMENTS</h2>
|
|
||||||
<p>PayPal? Authorize.Net? Stripe? We support many payment technologies and if you need help or advice we’ll lend a hand (we’re pretty friendly).</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="blue">
|
|
||||||
<div class="container">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-6">
|
|
||||||
<!--<h1>2.500 <span>sent invoices</span></h1>-->
|
|
||||||
</div>
|
|
||||||
<div class="col-md-6">
|
|
||||||
<!--<h1>$350.456 <span>billed</span></h1>-->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="hero2">
|
|
||||||
<div class="container">
|
|
||||||
<div class="caption">
|
|
||||||
<h1>SIMPLE, INTUITIVE INVOICING.</h1>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="upper-footer">
|
|
||||||
<div class="container">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-3 center-block">
|
|
||||||
<a href="#">
|
|
||||||
<div class="cta">
|
|
||||||
<h2 onclick="getStarted()">Invoice Now <span>+</span></h2>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<footer>
|
|
||||||
<div class="navbar" style="margin-bottom:0px">
|
|
||||||
<div class="container">
|
|
||||||
<div class="social">
|
|
||||||
<!--
|
|
||||||
<a href="http://twitter.com/eas_id"><span class=
|
|
||||||
"socicon">c</span></a>
|
|
||||||
-->
|
|
||||||
<a href=
|
|
||||||
"http://facebook.com/invoiceninja" target="_blank"><span class=
|
|
||||||
"socicon">b</span></a> <a href=
|
|
||||||
"http://twitter.com/invoiceninja" target="_blank"><span class=
|
|
||||||
"socicon">a</span></a>
|
|
||||||
<p>Copyright © 2014 InvoiceNinja. All rights reserved.</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="navbar-inner">
|
|
||||||
<ul class="navbar-list">
|
|
||||||
<li>{{ link_to('about', 'About Us' ) }}</li>
|
|
||||||
<li>{{ link_to('contact', 'Contact Us' ) }}</li>
|
|
||||||
<li>{{ link_to('login', Auth::check() ? 'My Account' : 'Login' ) }}</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
<ul class="navbar-list">
|
|
||||||
<li><a href="#">For developers</a></li>
|
|
||||||
<li><a href="#">Jobs</a></li>
|
|
||||||
<li><a href="#">Terms & Conditions</a></li>
|
|
||||||
<li><a href="#">Our Blog</a></li>
|
|
||||||
</ul>
|
|
||||||
-->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</footer><script src="{{ asset('/js/retina-1.1.0.min.js') }}" type="text/javascript"></script>
|
|
||||||
|
|
||||||
|
|
||||||
@stop
|
|
@ -13,8 +13,9 @@
|
|||||||
"chumper/datatable": "2.x",
|
"chumper/datatable": "2.x",
|
||||||
"omnipay/omnipay": "2.x",
|
"omnipay/omnipay": "2.x",
|
||||||
"intervention/image": "dev-master",
|
"intervention/image": "dev-master",
|
||||||
"webpatser/laravel-countries": "dev-master",
|
"webpatser/laravel-countries": "dev-master"
|
||||||
"anahkiasen/rocketeer": "dev-develop",
|
},
|
||||||
|
"require-dev": {
|
||||||
"codeception/codeception": "dev-master"
|
"codeception/codeception": "dev-master"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
|
5171
composer.lock
generated
5171
composer.lock
generated
File diff suppressed because it is too large
Load Diff
BIN
public/apple-touch-icon.png
Executable file
BIN
public/apple-touch-icon.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 2.2 KiB |
@ -528,6 +528,15 @@ footer .social .socicon {
|
|||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div.fb_iframe_widget {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
div.fb_iframe_widget > span {
|
||||||
|
vertical-align: top !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'socicon';
|
font-family: 'socicon';
|
||||||
|
@ -616,6 +616,16 @@ color: #fff;
|
|||||||
background-color: #08273c;
|
background-color: #08273c;
|
||||||
border-color: #08273c;
|
border-color: #08273c;
|
||||||
}
|
}
|
||||||
|
#signUpPopOver {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
div.fb_iframe_widget {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
div.fb_iframe_widget > span {
|
||||||
|
vertical-align: top !important;
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 767px) {
|
@media (max-width: 767px) {
|
||||||
.navbar-default .navbar-nav .open .dropdown-menu > li > a {
|
.navbar-default .navbar-nav .open .dropdown-menu > li > a {
|
||||||
color: #ecf0f1;
|
color: #ecf0f1;
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 150 KiB After Width: | Height: | Size: 15 KiB |
BIN
public/images/social.jpg
Normal file
BIN
public/images/social.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
280
public/js/jspdf.min.js
vendored
280
public/js/jspdf.min.js
vendored
File diff suppressed because one or more lines are too long
@ -39,7 +39,6 @@ cell ocupied by the width of the char in that position.
|
|||||||
@returns {Array}
|
@returns {Array}
|
||||||
*/
|
*/
|
||||||
var getCharWidthsArray = API.getCharWidthsArray = function(text, options){
|
var getCharWidthsArray = API.getCharWidthsArray = function(text, options){
|
||||||
|
|
||||||
if (!options) {
|
if (!options) {
|
||||||
options = {}
|
options = {}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ function GetReportTemplate4(doc, invoice, layout, checkMath) {
|
|||||||
if (invoice.image)
|
if (invoice.image)
|
||||||
{
|
{
|
||||||
var left = layout.headerRight - invoice.imageWidth;
|
var left = layout.headerRight - invoice.imageWidth;
|
||||||
doc.addImage(invoice.image, 'JPEG', left, 30, invoice.imageWidth, invoice.imageHeight);
|
doc.addImage(invoice.image, 'JPEG', left, 30);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* table header */
|
/* table header */
|
||||||
@ -69,6 +69,7 @@ function GetReportTemplate4(doc, invoice, layout, checkMath) {
|
|||||||
|
|
||||||
y += displaySubtotals(doc, layout, invoice, y+20, 480) + 20;
|
y += displaySubtotals(doc, layout, invoice, y+20, 480) + 20;
|
||||||
|
|
||||||
|
/*
|
||||||
if (checkMath && NINJA.parseFloat(total).toFixed(4) != NINJA.parseFloat(invoice.amount).toFixed(4))
|
if (checkMath && NINJA.parseFloat(total).toFixed(4) != NINJA.parseFloat(invoice.amount).toFixed(4))
|
||||||
{
|
{
|
||||||
var doc = new jsPDF('p', 'pt');
|
var doc = new jsPDF('p', 'pt');
|
||||||
@ -78,7 +79,7 @@ function GetReportTemplate4(doc, invoice, layout, checkMath) {
|
|||||||
onerror('Failed to generate PDF ' + total + ', ' + invoice.amount );
|
onerror('Failed to generate PDF ' + total + ', ' + invoice.amount );
|
||||||
return doc;
|
return doc;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
doc.setDrawColor(200,200,200);
|
doc.setDrawColor(200,200,200);
|
||||||
doc.setFillColor(230,230,230);
|
doc.setFillColor(230,230,230);
|
||||||
@ -91,8 +92,8 @@ function GetReportTemplate4(doc, invoice, layout, checkMath) {
|
|||||||
|
|
||||||
doc.setFontType("bold");
|
doc.setFontType("bold");
|
||||||
doc.text(layout.footerLeft, y, 'Balance Due');
|
doc.text(layout.footerLeft, y, 'Balance Due');
|
||||||
|
|
||||||
total = formatMoney(total - (invoice.amount - invoice.balance), currencyId);
|
total = formatMoney(invoice.balance_amount, currencyId)
|
||||||
var totalX = layout.headerRight - (doc.getStringUnitWidth(total) * doc.internal.getFontSize());
|
var totalX = layout.headerRight - (doc.getStringUnitWidth(total) * doc.internal.getFontSize());
|
||||||
doc.text(totalX, y, total);
|
doc.text(totalX, y, total);
|
||||||
|
|
||||||
@ -182,22 +183,6 @@ function getQuarter(offset) {
|
|||||||
return 'Q' + quarter;
|
return 'Q' + quarter;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the defaults for DataTables initialisation */
|
|
||||||
$.extend( true, $.fn.dataTable.defaults, {
|
|
||||||
"sDom": "t<'row-fluid'<'span6'i><'span6'p>>",
|
|
||||||
//"sDom": "<'row'<'span6'l><'span6'f>r>t<'row'<'span6'i><'span6'p>>",
|
|
||||||
"sPaginationType": "bootstrap",
|
|
||||||
//"bProcessing": true,
|
|
||||||
//"iDisplayLength": 50,
|
|
||||||
"bInfo": true,
|
|
||||||
"oLanguage": {
|
|
||||||
//"sLengthMenu": "_MENU_ records per page"
|
|
||||||
"sLengthMenu": "_MENU_",
|
|
||||||
"sSearch": ""
|
|
||||||
}
|
|
||||||
//"sScrollY": "500px",
|
|
||||||
} );
|
|
||||||
|
|
||||||
|
|
||||||
/* Default class modification */
|
/* Default class modification */
|
||||||
$.extend( $.fn.dataTableExt.oStdClasses, {
|
$.extend( $.fn.dataTableExt.oStdClasses, {
|
||||||
@ -626,17 +611,17 @@ $.fn.datepicker.defaults.todayHighlight = true;
|
|||||||
|
|
||||||
function GetPdf(invoice,checkMath,report_id){
|
function GetPdf(invoice,checkMath,report_id){
|
||||||
var layout = {
|
var layout = {
|
||||||
accountTop: 30,
|
accountTop: 40,
|
||||||
marginLeft: 50,
|
marginLeft: 50,
|
||||||
marginRight: 550,
|
marginRight: 550,
|
||||||
headerTop: 140,
|
headerTop: 150,
|
||||||
headerLeft: 360,
|
headerLeft: 360,
|
||||||
headerRight: 550,
|
headerRight: 550,
|
||||||
rowHeight: 15,
|
rowHeight: 15,
|
||||||
tableRowHeight: 10,
|
tableRowHeight: 10,
|
||||||
footerLeft: 420,
|
footerLeft: 420,
|
||||||
tablePadding: 12,
|
tablePadding: 12,
|
||||||
tableTop: 250,
|
tableTop: 260,
|
||||||
descriptionLeft: 162,
|
descriptionLeft: 162,
|
||||||
unitCostRight: 410,
|
unitCostRight: 410,
|
||||||
qtyRight: 480,
|
qtyRight: 480,
|
||||||
@ -691,7 +676,6 @@ function GetReportTemplate1(doc, invoice, layout, checkMath)
|
|||||||
var account = invoice.account;
|
var account = invoice.account;
|
||||||
var currencyId = client.currency_id;
|
var currencyId = client.currency_id;
|
||||||
|
|
||||||
layout.headerTop = 140;
|
|
||||||
layout.headerRight = 550;
|
layout.headerRight = 550;
|
||||||
layout.rowHeight = 15;
|
layout.rowHeight = 15;
|
||||||
|
|
||||||
@ -700,7 +684,7 @@ function GetReportTemplate1(doc, invoice, layout, checkMath)
|
|||||||
if (invoice.image)
|
if (invoice.image)
|
||||||
{
|
{
|
||||||
var left = layout.headerRight - invoice.imageWidth;
|
var left = layout.headerRight - invoice.imageWidth;
|
||||||
doc.addImage(invoice.image, 'JPEG', layout.marginLeft, layout.accountTop, invoice.imageWidth, invoice.imageHeight);
|
doc.addImage(invoice.image, 'JPEG', layout.marginLeft, 30);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (invoice.imageLogo1)
|
if (invoice.imageLogo1)
|
||||||
@ -717,7 +701,7 @@ function GetReportTemplate1(doc, invoice, layout, checkMath)
|
|||||||
|
|
||||||
SetPdfColor('LightBlue',doc);
|
SetPdfColor('LightBlue',doc);
|
||||||
doc.setFontSize('11');
|
doc.setFontSize('11');
|
||||||
doc.text(50, layout.headerTop, 'INVOICE');
|
doc.text(50, layout.headerTop, invoiceLabels.invoice.toUpperCase());
|
||||||
|
|
||||||
//doc.setDrawColor(220,220,220);
|
//doc.setDrawColor(220,220,220);
|
||||||
//doc.line(30, y, 560, y); // horizontal line
|
//doc.line(30, y, 560, y); // horizontal line
|
||||||
@ -726,8 +710,8 @@ function GetReportTemplate1(doc, invoice, layout, checkMath)
|
|||||||
SetPdfColor('Black',doc); //set black color
|
SetPdfColor('Black',doc); //set black color
|
||||||
doc.setFontSize(9);
|
doc.setFontSize(9);
|
||||||
|
|
||||||
displayInvoice(doc, invoice, 50, 160, layout);
|
displayInvoice(doc, invoice, 50, 170, layout);
|
||||||
displayClient(doc, invoice, 220, 160, layout);
|
displayClient(doc, invoice, 220, 170, layout);
|
||||||
|
|
||||||
doc.setLineWidth(0.3);
|
doc.setLineWidth(0.3);
|
||||||
doc.setDrawColor(200,200,200);
|
doc.setDrawColor(200,200,200);
|
||||||
@ -793,8 +777,6 @@ function GetReportTemplate1(doc, invoice, layout, checkMath)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function GetReportTemplate2(doc, invoice, layout, checkMath)
|
function GetReportTemplate2(doc, invoice, layout, checkMath)
|
||||||
{
|
{
|
||||||
var GlobalY=0;//Y position of line at current page
|
var GlobalY=0;//Y position of line at current page
|
||||||
@ -822,7 +804,7 @@ function GetReportTemplate2(doc, invoice, layout, checkMath)
|
|||||||
if (invoice.image)
|
if (invoice.image)
|
||||||
{
|
{
|
||||||
var left = layout.headerRight - invoice.imageWidth;
|
var left = layout.headerRight - invoice.imageWidth;
|
||||||
doc.addImage(invoice.image, 'JPEG', layout.marginLeft, 30, invoice.imageWidth, invoice.imageHeight);
|
doc.addImage(invoice.image, 'JPEG', layout.marginLeft, 30);
|
||||||
}
|
}
|
||||||
|
|
||||||
Report2AddFooter (invoice,doc);
|
Report2AddFooter (invoice,doc);
|
||||||
@ -897,7 +879,7 @@ function GetReportTemplate2(doc, invoice, layout, checkMath)
|
|||||||
SetPdfColor('SomeGreen',doc);
|
SetPdfColor('SomeGreen',doc);
|
||||||
doc.setFontSize('14');
|
doc.setFontSize('14');
|
||||||
doc.setFontType("bold");
|
doc.setFontType("bold");
|
||||||
doc.text(50, GlobalY, 'YOUR INVOICE');
|
doc.text(50, GlobalY, invoiceLabels.your_invoice.toUpperCase());
|
||||||
|
|
||||||
|
|
||||||
var z=GlobalY;
|
var z=GlobalY;
|
||||||
@ -1140,7 +1122,7 @@ function GetReportTemplate3(doc, invoice, layout, checkMath)
|
|||||||
{
|
{
|
||||||
y=130;
|
y=130;
|
||||||
var left = layout.headerRight - invoice.imageWidth;
|
var left = layout.headerRight - invoice.imageWidth;
|
||||||
doc.addImage(invoice.image, 'JPEG', layout.marginLeft, y, invoice.imageWidth, invoice.imageHeight);
|
doc.addImage(invoice.image, 'JPEG', layout.marginLeft, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
Report3AddFooter (invoice, account, doc, layout);
|
Report3AddFooter (invoice, account, doc, layout);
|
||||||
@ -1307,11 +1289,11 @@ function displayInvoice(doc, invoice, x, y, layout, rightAlignX) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var data = [
|
var data = [
|
||||||
{'Invoice Number': invoice.invoice_number},
|
{'invoice_number': invoice.invoice_number},
|
||||||
{'PO Number': invoice.po_number},
|
{'po_number': invoice.po_number},
|
||||||
{'Invoice Date': invoice.invoice_date},
|
{'invoice_date': invoice.invoice_date},
|
||||||
{'Due Date': invoice.due_date},
|
{'due_date': invoice.due_date},
|
||||||
{'Balance Due': formatMoney(invoice.balance_amount, invoice.client.currency_id)}
|
{'balance_due': formatMoney(invoice.balance_amount, invoice.client.currency_id)}
|
||||||
];
|
];
|
||||||
|
|
||||||
displayGrid(doc, invoice, data, x, y, layout, true, rightAlignX);
|
displayGrid(doc, invoice, data, x, y, layout, true, rightAlignX);
|
||||||
@ -1325,10 +1307,10 @@ function displaySubtotals(doc, layout, invoice, y, rightAlignTitleX)
|
|||||||
|
|
||||||
//var taxTitle = 'Tax ' + getInvoiceTaxRate(invoice) + '%';
|
//var taxTitle = 'Tax ' + getInvoiceTaxRate(invoice) + '%';
|
||||||
var data = [
|
var data = [
|
||||||
{'Subtotal': formatMoney(invoice.subtotal_amount, invoice.client.currency_id)},
|
{'subtotal': formatMoney(invoice.subtotal_amount, invoice.client.currency_id)},
|
||||||
{'Discount': invoice.discount_amount > 0 ? formatMoney(invoice.discount_amount, invoice.client.currency_id) : false},
|
{'discount': invoice.discount_amount > 0 ? formatMoney(invoice.discount_amount, invoice.client.currency_id) : false},
|
||||||
{'Tax': invoice.tax_amount > 0 ? formatMoney(invoice.tax_amount, invoice.client.currency_id) : false},
|
{'tax': invoice.tax_amount > 0 ? formatMoney(invoice.tax_amount, invoice.client.currency_id) : false},
|
||||||
{'Paid to Date': formatMoney(invoice.amount - invoice.balance, invoice.client.currency_id)}
|
{'paid_to_date': formatMoney(invoice.amount - invoice.balance, invoice.client.currency_id)}
|
||||||
];
|
];
|
||||||
|
|
||||||
return displayGrid(doc, invoice, data, 300, y, layout, true, 550, rightAlignTitleX) + 10;
|
return displayGrid(doc, invoice, data, 300, y, layout, true, 550, rightAlignTitleX) + 10;
|
||||||
@ -1357,9 +1339,10 @@ function concatStrings() {
|
|||||||
function displayGrid(doc, invoice, data, x, y, layout, hasheader, rightAlignX, rightAlignTitleX) {
|
function displayGrid(doc, invoice, data, x, y, layout, hasheader, rightAlignX, rightAlignTitleX) {
|
||||||
var numLines = 0;
|
var numLines = 0;
|
||||||
var origY = y;
|
var origY = y;
|
||||||
|
|
||||||
for (var i=0; i<data.length; i++) {
|
for (var i=0; i<data.length; i++) {
|
||||||
doc.setFontType('normal');
|
doc.setFontType('normal');
|
||||||
|
|
||||||
if (invoice.invoice_design_id == 1 && i > 0 && origY === layout.accountTop) {
|
if (invoice.invoice_design_id == 1 && i > 0 && origY === layout.accountTop) {
|
||||||
SetPdfColor('GrayText',doc);
|
SetPdfColor('GrayText',doc);
|
||||||
}
|
}
|
||||||
@ -1391,11 +1374,16 @@ function displayGrid(doc, invoice, data, x, y, layout, hasheader, rightAlignX, r
|
|||||||
}
|
}
|
||||||
doc.text(marginLeft, y, value);
|
doc.text(marginLeft, y, value);
|
||||||
|
|
||||||
|
/*
|
||||||
if (rightAlignTitleX && i === 0) {
|
if (rightAlignTitleX && i === 0) {
|
||||||
doc.setFontType('bold');
|
doc.setFontType('bold');
|
||||||
} else {
|
} else {
|
||||||
doc.setFontType('normal');
|
doc.setFontType('normal');
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
doc.setFontType('normal');
|
||||||
|
key = invoiceLabels[key];
|
||||||
|
|
||||||
if (rightAlignTitleX) {
|
if (rightAlignTitleX) {
|
||||||
marginLeft = rightAlignTitleX - (doc.getStringUnitWidth(key) * doc.internal.getFontSize());
|
marginLeft = rightAlignTitleX - (doc.getStringUnitWidth(key) * doc.internal.getFontSize());
|
||||||
@ -1427,7 +1415,7 @@ function displayNotesAndTerms(doc, layout, invoice, y)
|
|||||||
|
|
||||||
if (invoice.terms) {
|
if (invoice.terms) {
|
||||||
doc.setFontType("bold");
|
doc.setFontType("bold");
|
||||||
doc.text(layout.marginLeft, y, "Terms");
|
doc.text(layout.marginLeft, y, invoiceLabels.terms);
|
||||||
y += 16;
|
y += 16;
|
||||||
doc.setFontType("normal");
|
doc.setFontType("normal");
|
||||||
doc.text(layout.marginLeft, y, invoice.terms);
|
doc.text(layout.marginLeft, y, invoice.terms);
|
||||||
@ -1503,26 +1491,25 @@ function getInvoiceTaxRate(invoice) {
|
|||||||
|
|
||||||
function displayInvoiceHeader(doc, invoice, layout) {
|
function displayInvoiceHeader(doc, invoice, layout) {
|
||||||
|
|
||||||
var costX = layout.unitCostRight - (doc.getStringUnitWidth('Unit Cost') * doc.internal.getFontSize());
|
var costX = layout.unitCostRight - (doc.getStringUnitWidth(invoiceLabels.unit_cost) * doc.internal.getFontSize());
|
||||||
var qtyX = layout.qtyRight - (doc.getStringUnitWidth('Quantity') * doc.internal.getFontSize());
|
var qtyX = layout.qtyRight - (doc.getStringUnitWidth(invoiceLabels.quantity) * doc.internal.getFontSize());
|
||||||
var taxX = layout.taxRight - (doc.getStringUnitWidth('Tax') * doc.internal.getFontSize());
|
var taxX = layout.taxRight - (doc.getStringUnitWidth(invoiceLabels.tax) * doc.internal.getFontSize());
|
||||||
var totalX = layout.lineTotalRight - (doc.getStringUnitWidth('Line Total') * doc.internal.getFontSize());
|
var totalX = layout.lineTotalRight - (doc.getStringUnitWidth(invoiceLabels.line_total) * doc.internal.getFontSize());
|
||||||
|
|
||||||
doc.text(layout.marginLeft, layout.tableTop, 'Item');
|
doc.text(layout.marginLeft, layout.tableTop, invoiceLabels.item);
|
||||||
doc.text(layout.descriptionLeft, layout.tableTop, 'Description');
|
doc.text(layout.descriptionLeft, layout.tableTop, invoiceLabels.description);
|
||||||
doc.text(costX, layout.tableTop, 'Unit Cost');
|
doc.text(costX, layout.tableTop, invoiceLabels.unit_cost);
|
||||||
doc.text(qtyX, layout.tableTop, 'Quantity');
|
doc.text(qtyX, layout.tableTop, invoiceLabels.quantity);
|
||||||
doc.text(totalX, layout.tableTop, 'Line Total');
|
doc.text(totalX, layout.tableTop, invoiceLabels.line_total);
|
||||||
|
|
||||||
if (invoice.has_taxes)
|
if (invoice.has_taxes)
|
||||||
{
|
{
|
||||||
doc.text(taxX, layout.tableTop, 'Tax');
|
doc.text(taxX, layout.tableTop, invoiceLabels.tax);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function displayInvoiceItems(doc, invoice, layout) {
|
function displayInvoiceItems(doc, invoice, layout) {
|
||||||
|
|
||||||
doc.setFontType("normal");
|
doc.setFontType("normal");
|
||||||
|
|
||||||
var line = 1;
|
var line = 1;
|
||||||
|
485
public/js/stacktrace.js
Normal file
485
public/js/stacktrace.js
Normal file
@ -0,0 +1,485 @@
|
|||||||
|
// Domain Public by Eric Wendelin http://eriwen.com/ (2008)
|
||||||
|
// Luke Smith http://lucassmith.name/ (2008)
|
||||||
|
// Loic Dachary <loic@dachary.org> (2008)
|
||||||
|
// Johan Euphrosine <proppy@aminche.com> (2008)
|
||||||
|
// Oyvind Sean Kinsey http://kinsey.no/blog (2010)
|
||||||
|
// Victor Homyakov <victor-homyakov@users.sourceforge.net> (2010)
|
||||||
|
/*global module, exports, define, ActiveXObject*/
|
||||||
|
(function(global, factory) {
|
||||||
|
if (typeof exports === 'object') {
|
||||||
|
// Node
|
||||||
|
module.exports = factory();
|
||||||
|
} else if (typeof define === 'function' && define.amd) {
|
||||||
|
// AMD
|
||||||
|
define(factory);
|
||||||
|
} else {
|
||||||
|
// Browser globals
|
||||||
|
global.printStackTrace = factory();
|
||||||
|
}
|
||||||
|
}(this, function() {
|
||||||
|
/**
|
||||||
|
* Main function giving a function stack trace with a forced or passed in Error
|
||||||
|
*
|
||||||
|
* @cfg {Error} e The error to create a stacktrace from (optional)
|
||||||
|
* @cfg {Boolean} guess If we should try to resolve the names of anonymous functions
|
||||||
|
* @return {Array} of Strings with functions, lines, files, and arguments where possible
|
||||||
|
*/
|
||||||
|
function printStackTrace(options) {
|
||||||
|
options = options || {guess: true};
|
||||||
|
var ex = options.e || null, guess = !!options.guess;
|
||||||
|
var p = new printStackTrace.implementation(), result = p.run(ex);
|
||||||
|
return (guess) ? p.guessAnonymousFunctions(result) : result;
|
||||||
|
}
|
||||||
|
|
||||||
|
printStackTrace.implementation = function() {
|
||||||
|
};
|
||||||
|
|
||||||
|
printStackTrace.implementation.prototype = {
|
||||||
|
/**
|
||||||
|
* @param {Error} [ex] The error to create a stacktrace from (optional)
|
||||||
|
* @param {String} [mode] Forced mode (optional, mostly for unit tests)
|
||||||
|
*/
|
||||||
|
run: function(ex, mode) {
|
||||||
|
ex = ex || this.createException();
|
||||||
|
mode = mode || this.mode(ex);
|
||||||
|
if (mode === 'other') {
|
||||||
|
return this.other(arguments.callee);
|
||||||
|
} else {
|
||||||
|
return this[mode](ex);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
createException: function() {
|
||||||
|
try {
|
||||||
|
this.undef();
|
||||||
|
} catch (e) {
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mode could differ for different exception, e.g.
|
||||||
|
* exceptions in Chrome may or may not have arguments or stack.
|
||||||
|
*
|
||||||
|
* @return {String} mode of operation for the exception
|
||||||
|
*/
|
||||||
|
mode: function(e) {
|
||||||
|
if (e['arguments'] && e.stack) {
|
||||||
|
return 'chrome';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.stack && e.sourceURL) {
|
||||||
|
return 'safari';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.stack && e.number) {
|
||||||
|
return 'ie';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.stack && e.fileName) {
|
||||||
|
return 'firefox';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.message && e['opera#sourceloc']) {
|
||||||
|
// e.message.indexOf("Backtrace:") > -1 -> opera9
|
||||||
|
// 'opera#sourceloc' in e -> opera9, opera10a
|
||||||
|
// !e.stacktrace -> opera9
|
||||||
|
if (!e.stacktrace) {
|
||||||
|
return 'opera9'; // use e.message
|
||||||
|
}
|
||||||
|
if (e.message.indexOf('\n') > -1 && e.message.split('\n').length > e.stacktrace.split('\n').length) {
|
||||||
|
// e.message may have more stack entries than e.stacktrace
|
||||||
|
return 'opera9'; // use e.message
|
||||||
|
}
|
||||||
|
return 'opera10a'; // use e.stacktrace
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.message && e.stack && e.stacktrace) {
|
||||||
|
// e.stacktrace && e.stack -> opera10b
|
||||||
|
if (e.stacktrace.indexOf("called from line") < 0) {
|
||||||
|
return 'opera10b'; // use e.stacktrace, format differs from 'opera10a'
|
||||||
|
}
|
||||||
|
// e.stacktrace && e.stack -> opera11
|
||||||
|
return 'opera11'; // use e.stacktrace, format differs from 'opera10a', 'opera10b'
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.stack && !e.fileName) {
|
||||||
|
// Chrome 27 does not have e.arguments as earlier versions,
|
||||||
|
// but still does not have e.fileName as Firefox
|
||||||
|
return 'chrome';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'other';
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a context, function name, and callback function, overwrite it so that it calls
|
||||||
|
* printStackTrace() first with a callback and then runs the rest of the body.
|
||||||
|
*
|
||||||
|
* @param {Object} context of execution (e.g. window)
|
||||||
|
* @param {String} functionName to instrument
|
||||||
|
* @param {Function} callback function to call with a stack trace on invocation
|
||||||
|
*/
|
||||||
|
instrumentFunction: function(context, functionName, callback) {
|
||||||
|
context = context || window;
|
||||||
|
var original = context[functionName];
|
||||||
|
context[functionName] = function instrumented() {
|
||||||
|
callback.call(this, printStackTrace().slice(4));
|
||||||
|
return context[functionName]._instrumented.apply(this, arguments);
|
||||||
|
};
|
||||||
|
context[functionName]._instrumented = original;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a context and function name of a function that has been
|
||||||
|
* instrumented, revert the function to it's original (non-instrumented)
|
||||||
|
* state.
|
||||||
|
*
|
||||||
|
* @param {Object} context of execution (e.g. window)
|
||||||
|
* @param {String} functionName to de-instrument
|
||||||
|
*/
|
||||||
|
deinstrumentFunction: function(context, functionName) {
|
||||||
|
if (context[functionName].constructor === Function &&
|
||||||
|
context[functionName]._instrumented &&
|
||||||
|
context[functionName]._instrumented.constructor === Function) {
|
||||||
|
context[functionName] = context[functionName]._instrumented;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given an Error object, return a formatted Array based on Chrome's stack string.
|
||||||
|
*
|
||||||
|
* @param e - Error object to inspect
|
||||||
|
* @return Array<String> of function calls, files and line numbers
|
||||||
|
*/
|
||||||
|
chrome: function(e) {
|
||||||
|
return (e.stack + '\n')
|
||||||
|
.replace(/^[\s\S]+?\s+at\s+/, ' at ') // remove message
|
||||||
|
.replace(/^\s+(at eval )?at\s+/gm, '') // remove 'at' and indentation
|
||||||
|
.replace(/^([^\(]+?)([\n$])/gm, '{anonymous}() ($1)$2')
|
||||||
|
.replace(/^Object.<anonymous>\s*\(([^\)]+)\)/gm, '{anonymous}() ($1)')
|
||||||
|
.replace(/^(.+) \((.+)\)$/gm, '$1@$2')
|
||||||
|
.split('\n')
|
||||||
|
.slice(0, -1);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given an Error object, return a formatted Array based on Safari's stack string.
|
||||||
|
*
|
||||||
|
* @param e - Error object to inspect
|
||||||
|
* @return Array<String> of function calls, files and line numbers
|
||||||
|
*/
|
||||||
|
safari: function(e) {
|
||||||
|
return e.stack.replace(/\[native code\]\n/m, '')
|
||||||
|
.replace(/^(?=\w+Error\:).*$\n/m, '')
|
||||||
|
.replace(/^@/gm, '{anonymous}()@')
|
||||||
|
.split('\n');
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given an Error object, return a formatted Array based on IE's stack string.
|
||||||
|
*
|
||||||
|
* @param e - Error object to inspect
|
||||||
|
* @return Array<String> of function calls, files and line numbers
|
||||||
|
*/
|
||||||
|
ie: function(e) {
|
||||||
|
return e.stack
|
||||||
|
.replace(/^\s*at\s+(.*)$/gm, '$1')
|
||||||
|
.replace(/^Anonymous function\s+/gm, '{anonymous}() ')
|
||||||
|
.replace(/^(.+)\s+\((.+)\)$/gm, '$1@$2')
|
||||||
|
.split('\n')
|
||||||
|
.slice(1);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given an Error object, return a formatted Array based on Firefox's stack string.
|
||||||
|
*
|
||||||
|
* @param e - Error object to inspect
|
||||||
|
* @return Array<String> of function calls, files and line numbers
|
||||||
|
*/
|
||||||
|
firefox: function(e) {
|
||||||
|
return e.stack.replace(/(?:\n@:0)?\s+$/m, '')
|
||||||
|
.replace(/^(?:\((\S*)\))?@/gm, '{anonymous}($1)@')
|
||||||
|
.split('\n');
|
||||||
|
},
|
||||||
|
|
||||||
|
opera11: function(e) {
|
||||||
|
var ANON = '{anonymous}', lineRE = /^.*line (\d+), column (\d+)(?: in (.+))? in (\S+):$/;
|
||||||
|
var lines = e.stacktrace.split('\n'), result = [];
|
||||||
|
|
||||||
|
for (var i = 0, len = lines.length; i < len; i += 2) {
|
||||||
|
var match = lineRE.exec(lines[i]);
|
||||||
|
if (match) {
|
||||||
|
var location = match[4] + ':' + match[1] + ':' + match[2];
|
||||||
|
var fnName = match[3] || "global code";
|
||||||
|
fnName = fnName.replace(/<anonymous function: (\S+)>/, "$1").replace(/<anonymous function>/, ANON);
|
||||||
|
result.push(fnName + '@' + location + ' -- ' + lines[i + 1].replace(/^\s+/, ''));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
opera10b: function(e) {
|
||||||
|
// "<anonymous function: run>([arguments not available])@file://localhost/G:/js/stacktrace.js:27\n" +
|
||||||
|
// "printStackTrace([arguments not available])@file://localhost/G:/js/stacktrace.js:18\n" +
|
||||||
|
// "@file://localhost/G:/js/test/functional/testcase1.html:15"
|
||||||
|
var lineRE = /^(.*)@(.+):(\d+)$/;
|
||||||
|
var lines = e.stacktrace.split('\n'), result = [];
|
||||||
|
|
||||||
|
for (var i = 0, len = lines.length; i < len; i++) {
|
||||||
|
var match = lineRE.exec(lines[i]);
|
||||||
|
if (match) {
|
||||||
|
var fnName = match[1] ? (match[1] + '()') : "global code";
|
||||||
|
result.push(fnName + '@' + match[2] + ':' + match[3]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given an Error object, return a formatted Array based on Opera 10's stacktrace string.
|
||||||
|
*
|
||||||
|
* @param e - Error object to inspect
|
||||||
|
* @return Array<String> of function calls, files and line numbers
|
||||||
|
*/
|
||||||
|
opera10a: function(e) {
|
||||||
|
// " Line 27 of linked script file://localhost/G:/js/stacktrace.js\n"
|
||||||
|
// " Line 11 of inline#1 script in file://localhost/G:/js/test/functional/testcase1.html: In function foo\n"
|
||||||
|
var ANON = '{anonymous}', lineRE = /Line (\d+).*script (?:in )?(\S+)(?:: In function (\S+))?$/i;
|
||||||
|
var lines = e.stacktrace.split('\n'), result = [];
|
||||||
|
|
||||||
|
for (var i = 0, len = lines.length; i < len; i += 2) {
|
||||||
|
var match = lineRE.exec(lines[i]);
|
||||||
|
if (match) {
|
||||||
|
var fnName = match[3] || ANON;
|
||||||
|
result.push(fnName + '()@' + match[2] + ':' + match[1] + ' -- ' + lines[i + 1].replace(/^\s+/, ''));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
// Opera 7.x-9.2x only!
|
||||||
|
opera9: function(e) {
|
||||||
|
// " Line 43 of linked script file://localhost/G:/js/stacktrace.js\n"
|
||||||
|
// " Line 7 of inline#1 script in file://localhost/G:/js/test/functional/testcase1.html\n"
|
||||||
|
var ANON = '{anonymous}', lineRE = /Line (\d+).*script (?:in )?(\S+)/i;
|
||||||
|
var lines = e.message.split('\n'), result = [];
|
||||||
|
|
||||||
|
for (var i = 2, len = lines.length; i < len; i += 2) {
|
||||||
|
var match = lineRE.exec(lines[i]);
|
||||||
|
if (match) {
|
||||||
|
result.push(ANON + '()@' + match[2] + ':' + match[1] + ' -- ' + lines[i + 1].replace(/^\s+/, ''));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
// Safari 5-, IE 9-, and others
|
||||||
|
other: function(curr) {
|
||||||
|
var ANON = '{anonymous}', fnRE = /function\s*([\w\-$]+)?\s*\(/i, stack = [], fn, args, maxStackSize = 10;
|
||||||
|
var slice = Array.prototype.slice;
|
||||||
|
while (curr && curr['arguments'] && stack.length < maxStackSize) {
|
||||||
|
fn = fnRE.test(curr.toString()) ? RegExp.$1 || ANON : ANON;
|
||||||
|
args = slice.call(curr['arguments'] || []);
|
||||||
|
stack[stack.length] = fn + '(' + this.stringifyArguments(args) + ')';
|
||||||
|
try {
|
||||||
|
curr = curr.caller;
|
||||||
|
} catch (e) {
|
||||||
|
stack[stack.length] = '' + e;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return stack;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given arguments array as a String, substituting type names for non-string types.
|
||||||
|
*
|
||||||
|
* @param {Arguments,Array} args
|
||||||
|
* @return {String} stringified arguments
|
||||||
|
*/
|
||||||
|
stringifyArguments: function(args) {
|
||||||
|
var result = [];
|
||||||
|
var slice = Array.prototype.slice;
|
||||||
|
for (var i = 0; i < args.length; ++i) {
|
||||||
|
var arg = args[i];
|
||||||
|
if (arg === undefined) {
|
||||||
|
result[i] = 'undefined';
|
||||||
|
} else if (arg === null) {
|
||||||
|
result[i] = 'null';
|
||||||
|
} else if (arg.constructor) {
|
||||||
|
// TODO constructor comparison does not work for iframes
|
||||||
|
if (arg.constructor === Array) {
|
||||||
|
if (arg.length < 3) {
|
||||||
|
result[i] = '[' + this.stringifyArguments(arg) + ']';
|
||||||
|
} else {
|
||||||
|
result[i] = '[' + this.stringifyArguments(slice.call(arg, 0, 1)) + '...' + this.stringifyArguments(slice.call(arg, -1)) + ']';
|
||||||
|
}
|
||||||
|
} else if (arg.constructor === Object) {
|
||||||
|
result[i] = '#object';
|
||||||
|
} else if (arg.constructor === Function) {
|
||||||
|
result[i] = '#function';
|
||||||
|
} else if (arg.constructor === String) {
|
||||||
|
result[i] = '"' + arg + '"';
|
||||||
|
} else if (arg.constructor === Number) {
|
||||||
|
result[i] = arg;
|
||||||
|
} else {
|
||||||
|
result[i] = '?';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.join(',');
|
||||||
|
},
|
||||||
|
|
||||||
|
sourceCache: {},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the text from a given URL
|
||||||
|
*/
|
||||||
|
ajax: function(url) {
|
||||||
|
var req = this.createXMLHTTPObject();
|
||||||
|
if (req) {
|
||||||
|
try {
|
||||||
|
req.open('GET', url, false);
|
||||||
|
//req.overrideMimeType('text/plain');
|
||||||
|
//req.overrideMimeType('text/javascript');
|
||||||
|
req.send(null);
|
||||||
|
//return req.status == 200 ? req.responseText : '';
|
||||||
|
return req.responseText;
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try XHR methods in order and store XHR factory.
|
||||||
|
*
|
||||||
|
* @return <Function> XHR function or equivalent
|
||||||
|
*/
|
||||||
|
createXMLHTTPObject: function() {
|
||||||
|
var xmlhttp, XMLHttpFactories = [
|
||||||
|
function() {
|
||||||
|
return new XMLHttpRequest();
|
||||||
|
}, function() {
|
||||||
|
return new ActiveXObject('Msxml2.XMLHTTP');
|
||||||
|
}, function() {
|
||||||
|
return new ActiveXObject('Msxml3.XMLHTTP');
|
||||||
|
}, function() {
|
||||||
|
return new ActiveXObject('Microsoft.XMLHTTP');
|
||||||
|
}
|
||||||
|
];
|
||||||
|
for (var i = 0; i < XMLHttpFactories.length; i++) {
|
||||||
|
try {
|
||||||
|
xmlhttp = XMLHttpFactories[i]();
|
||||||
|
// Use memoization to cache the factory
|
||||||
|
this.createXMLHTTPObject = XMLHttpFactories[i];
|
||||||
|
return xmlhttp;
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a URL, check if it is in the same domain (so we can get the source
|
||||||
|
* via Ajax).
|
||||||
|
*
|
||||||
|
* @param url <String> source url
|
||||||
|
* @return <Boolean> False if we need a cross-domain request
|
||||||
|
*/
|
||||||
|
isSameDomain: function(url) {
|
||||||
|
return typeof location !== "undefined" && url.indexOf(location.hostname) !== -1; // location may not be defined, e.g. when running from nodejs.
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get source code from given URL if in the same domain.
|
||||||
|
*
|
||||||
|
* @param url <String> JS source URL
|
||||||
|
* @return <Array> Array of source code lines
|
||||||
|
*/
|
||||||
|
getSource: function(url) {
|
||||||
|
// TODO reuse source from script tags?
|
||||||
|
if (!(url in this.sourceCache)) {
|
||||||
|
this.sourceCache[url] = this.ajax(url).split('\n');
|
||||||
|
}
|
||||||
|
return this.sourceCache[url];
|
||||||
|
},
|
||||||
|
|
||||||
|
guessAnonymousFunctions: function(stack) {
|
||||||
|
for (var i = 0; i < stack.length; ++i) {
|
||||||
|
var reStack = /\{anonymous\}\(.*\)@(.*)/,
|
||||||
|
reRef = /^(.*?)(?::(\d+))(?::(\d+))?(?: -- .+)?$/,
|
||||||
|
frame = stack[i], ref = reStack.exec(frame);
|
||||||
|
|
||||||
|
if (ref) {
|
||||||
|
var m = reRef.exec(ref[1]);
|
||||||
|
if (m) { // If falsey, we did not get any file/line information
|
||||||
|
var file = m[1], lineno = m[2], charno = m[3] || 0;
|
||||||
|
if (file && this.isSameDomain(file) && lineno) {
|
||||||
|
var functionName = this.guessAnonymousFunction(file, lineno, charno);
|
||||||
|
stack[i] = frame.replace('{anonymous}', functionName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return stack;
|
||||||
|
},
|
||||||
|
|
||||||
|
guessAnonymousFunction: function(url, lineNo, charNo) {
|
||||||
|
var ret;
|
||||||
|
try {
|
||||||
|
ret = this.findFunctionName(this.getSource(url), lineNo);
|
||||||
|
} catch (e) {
|
||||||
|
ret = 'getSource failed with url: ' + url + ', exception: ' + e.toString();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
},
|
||||||
|
|
||||||
|
findFunctionName: function(source, lineNo) {
|
||||||
|
// FIXME findFunctionName fails for compressed source
|
||||||
|
// (more than one function on the same line)
|
||||||
|
// function {name}({args}) m[1]=name m[2]=args
|
||||||
|
var reFunctionDeclaration = /function\s+([^(]*?)\s*\(([^)]*)\)/;
|
||||||
|
// {name} = function ({args}) TODO args capture
|
||||||
|
// /['"]?([0-9A-Za-z_]+)['"]?\s*[:=]\s*function(?:[^(]*)/
|
||||||
|
var reFunctionExpression = /['"]?([$_A-Za-z][$_A-Za-z0-9]*)['"]?\s*[:=]\s*function\b/;
|
||||||
|
// {name} = eval()
|
||||||
|
var reFunctionEvaluation = /['"]?([$_A-Za-z][$_A-Za-z0-9]*)['"]?\s*[:=]\s*(?:eval|new Function)\b/;
|
||||||
|
// Walk backwards in the source lines until we find
|
||||||
|
// the line which matches one of the patterns above
|
||||||
|
var code = "", line, maxLines = Math.min(lineNo, 20), m, commentPos;
|
||||||
|
for (var i = 0; i < maxLines; ++i) {
|
||||||
|
// lineNo is 1-based, source[] is 0-based
|
||||||
|
line = source[lineNo - i - 1];
|
||||||
|
commentPos = line.indexOf('//');
|
||||||
|
if (commentPos >= 0) {
|
||||||
|
line = line.substr(0, commentPos);
|
||||||
|
}
|
||||||
|
// TODO check other types of comments? Commented code may lead to false positive
|
||||||
|
if (line) {
|
||||||
|
code = line + code;
|
||||||
|
m = reFunctionExpression.exec(code);
|
||||||
|
if (m && m[1]) {
|
||||||
|
return m[1];
|
||||||
|
}
|
||||||
|
m = reFunctionDeclaration.exec(code);
|
||||||
|
if (m && m[1]) {
|
||||||
|
//return m[1] + "(" + (m[2] || "") + ")";
|
||||||
|
return m[1];
|
||||||
|
}
|
||||||
|
m = reFunctionEvaluation.exec(code);
|
||||||
|
if (m && m[1]) {
|
||||||
|
return m[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return '(?)';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return printStackTrace;
|
||||||
|
}));
|
Loading…
x
Reference in New Issue
Block a user