This commit is contained in:
David Bomba 2016-03-17 07:54:09 +11:00
commit e6d7b5e233
33 changed files with 327 additions and 169 deletions

View File

@ -123,7 +123,8 @@ class AccountController extends BaseController
public function getSearchData() public function getSearchData()
{ {
$data = $this->accountRepo->getSearchData(); $account = Auth::user()->account;
$data = $this->accountRepo->getSearchData($account);
return Response::json($data); return Response::json($data);
} }

View File

@ -231,7 +231,8 @@ class AppController extends BaseController
} }
Artisan::call('optimize', array('--force' => true)); Artisan::call('optimize', array('--force' => true));
} catch (Exception $e) { } catch (Exception $e) {
Response::make($e->getMessage(), 500); Utils::logError($e);
return Response::make($e->getMessage(), 500);
} }
} }
@ -262,7 +263,8 @@ class AppController extends BaseController
Event::fire(new UserSettingsChanged()); Event::fire(new UserSettingsChanged());
Session::flash('message', trans('texts.processed_updates')); Session::flash('message', trans('texts.processed_updates'));
} catch (Exception $e) { } catch (Exception $e) {
Response::make($e->getMessage(), 500); Utils::logError($e);
return Response::make($e->getMessage(), 500);
} }
} }

View File

@ -50,7 +50,8 @@ class PublicClientController extends BaseController
]); ]);
} }
if (!Input::has('phantomjs') && !Session::has($invitationKey) && (!Auth::check() || Auth::user()->account_id != $invoice->account_id)) { if (!Input::has('phantomjs') && !Input::has('silent') && !Session::has($invitationKey)
&& (!Auth::check() || Auth::user()->account_id != $invoice->account_id)) {
if ($invoice->is_quote) { if ($invoice->is_quote) {
event(new QuoteInvitationWasViewed($invoice, $invitation)); event(new QuoteInvitationWasViewed($invoice, $invitation));
} else { } else {

View File

@ -70,7 +70,7 @@ class Authenticate {
} }
protected function getInvitation($key){ protected function getInvitation($key){
$invitation = Invitation::where('invitation_key', '=', $key)->first(); $invitation = Invitation::withTrashed()->where('invitation_key', '=', $key)->first();
if ($invitation && !$invitation->is_deleted) { if ($invitation && !$invitation->is_deleted) {
return $invitation; return $invitation;
} }

View File

@ -25,45 +25,45 @@ class SubscriptionListener
public function createdClient(ClientWasCreated $event) public function createdClient(ClientWasCreated $event)
{ {
$transformer = new ClientTransformer($event->client->account); $transformer = new ClientTransformer($event->client->account);
$this->checkSubscriptions(ACTIVITY_TYPE_CREATE_CLIENT, $event->client, $transformer); $this->checkSubscriptions(EVENT_CREATE_CLIENT, $event->client, $transformer);
} }
public function createdQuote(QuoteWasCreated $event) public function createdQuote(QuoteWasCreated $event)
{ {
$transformer = new InvoiceTransformer($event->quote->account); $transformer = new InvoiceTransformer($event->quote->account);
$this->checkSubscriptions(ACTIVITY_TYPE_CREATE_QUOTE, $event->quote, $transformer, ENTITY_CLIENT); $this->checkSubscriptions(EVENT_CREATE_QUOTE, $event->quote, $transformer, ENTITY_CLIENT);
} }
public function createdPayment(PaymentWasCreated $event) public function createdPayment(PaymentWasCreated $event)
{ {
$transformer = new PaymentTransformer($event->payment->account); $transformer = new PaymentTransformer($event->payment->account);
$this->checkSubscriptions(ACTIVITY_TYPE_CREATE_PAYMENT, $event->payment, $transformer, [ENTITY_CLIENT, ENTITY_INVOICE]); $this->checkSubscriptions(EVENT_CREATE_PAYMENT, $event->payment, $transformer, [ENTITY_CLIENT, ENTITY_INVOICE]);
} }
public function createdInvoice(InvoiceWasCreated $event) public function createdInvoice(InvoiceWasCreated $event)
{ {
$transformer = new InvoiceTransformer($event->invoice->account); $transformer = new InvoiceTransformer($event->invoice->account);
$this->checkSubscriptions(ACTIVITY_TYPE_CREATE_INVOICE, $event->invoice, $transformer, ENTITY_CLIENT); $this->checkSubscriptions(EVENT_CREATE_INVOICE, $event->invoice, $transformer, ENTITY_CLIENT);
} }
public function createdCredit(CreditWasCreated $event) public function createdCredit(CreditWasCreated $event)
{ {
//$this->checkSubscriptions(ACTIVITY_TYPE_CREATE_CREDIT, $event->credit);
} }
public function createdVendor(VendorWasCreated $event) public function createdVendor(VendorWasCreated $event)
{ {
//$this->checkSubscriptions(ACTIVITY_TYPE_CREATE_VENDOR, $event->vendor);
} }
public function createdExpense(ExpenseWasCreated $event) public function createdExpense(ExpenseWasCreated $event)
{ {
//$this->checkSubscriptions(ACTIVITY_TYPE_CREATE_EXPENSE, $event->expense);
} }
private function checkSubscriptions($activityTypeId, $entity, $transformer, $include = '') private function checkSubscriptions($eventId, $entity, $transformer, $include = '')
{ {
$subscription = $entity->account->getSubscription($activityTypeId); $subscription = $entity->account->getSubscription($eventId);
if ($subscription) { if ($subscription) {
$manager = new Manager(); $manager = new Manager();

View File

@ -1023,7 +1023,7 @@ class Account extends Eloquent
return true; return true;
} }
public function showCustomField($field, $entity) public function showCustomField($field, $entity = false)
{ {
if ($this->isPro()) { if ($this->isPro()) {
return $this->$field ? true : false; return $this->$field ? true : false;

View File

@ -70,16 +70,16 @@ class AccountRepository
return $account; return $account;
} }
public function getSearchData() public function getSearchData($account)
{ {
$data = $this->getAccountSearchData(); $data = $this->getAccountSearchData($account);
$data['navigation'] = $this->getNavigationSearchData(); $data['navigation'] = $this->getNavigationSearchData();
return $data; return $data;
} }
private function getAccountSearchData() private function getAccountSearchData($account)
{ {
$data = [ $data = [
'clients' => [], 'clients' => [],
@ -88,6 +88,14 @@ class AccountRepository
'quotes' => [], 'quotes' => [],
]; ];
// include custom client fields in search
if ($account->custom_client_label1) {
$data[$account->custom_client_label1] = [];
}
if ($account->custom_client_label2) {
$data[$account->custom_client_label2] = [];
}
$clients = Client::scope() $clients = Client::scope()
->with('contacts', 'invoices') ->with('contacts', 'invoices')
->get(); ->get();
@ -96,20 +104,38 @@ class AccountRepository
if ($client->name) { if ($client->name) {
$data['clients'][] = [ $data['clients'][] = [
'value' => $client->name, 'value' => $client->name,
'tokens' => $client->name,
'url' => $client->present()->url, 'url' => $client->present()->url,
]; ];
}
if ($client->custom_value1) {
$data[$account->custom_client_label1][] = [
'value' => "{$client->custom_value1}: " . $client->getDisplayName(),
'tokens' => $client->custom_value1,
'url' => $client->present()->url,
];
}
if ($client->custom_value2) {
$data[$account->custom_client_label2][] = [
'value' => "{$client->custom_value2}: " . $client->getDisplayName(),
'tokens' => $client->custom_value2,
'url' => $client->present()->url,
];
} }
foreach ($client->contacts as $contact) { foreach ($client->contacts as $contact) {
if ($contact->getFullName()) { if ($contact->getFullName()) {
$data['contacts'][] = [ $data['contacts'][] = [
'value' => $contact->getDisplayName(), 'value' => $contact->getDisplayName(),
'tokens' => $contact->getDisplayName(),
'url' => $client->present()->url, 'url' => $client->present()->url,
]; ];
} }
if ($contact->email) { if ($contact->email) {
$data[trans('texts.contacts')][] = [ $data['contacts'][] = [
'value' => $contact->email, 'value' => $contact->email,
'tokens' => $contact->email,
'url' => $client->present()->url, 'url' => $client->present()->url,
]; ];
} }
@ -119,6 +145,7 @@ class AccountRepository
$entityType = $invoice->getEntityType(); $entityType = $invoice->getEntityType();
$data["{$entityType}s"][] = [ $data["{$entityType}s"][] = [
'value' => $invoice->getDisplayName() . ': ' . $client->getDisplayName(), 'value' => $invoice->getDisplayName() . ': ' . $client->getDisplayName(),
'tokens' => $invoice->getDisplayName() . ': ' . $client->getDisplayName(),
'url' => $invoice->present()->url, 'url' => $invoice->present()->url,
]; ];
} }
@ -156,6 +183,7 @@ class AccountRepository
$features[] = ['new_tax_rate', '/tax_rates/create']; $features[] = ['new_tax_rate', '/tax_rates/create'];
$features[] = ['new_product', '/products/create']; $features[] = ['new_product', '/products/create'];
$features[] = ['new_user', '/users/create']; $features[] = ['new_user', '/users/create'];
$features[] = ['custom_fields', '/settings/invoice_settings'];
$settings = array_merge(Account::$basicSettings, Account::$advancedSettings); $settings = array_merge(Account::$basicSettings, Account::$advancedSettings);
@ -169,6 +197,7 @@ class AccountRepository
foreach ($features as $feature) { foreach ($features as $feature) {
$data[] = [ $data[] = [
'value' => trans('texts.' . $feature[0]), 'value' => trans('texts.' . $feature[0]),
'tokens' => trans('texts.' . $feature[0]),
'url' => URL::to($feature[1]) 'url' => URL::to($feature[1])
]; ];
} }

View File

@ -160,8 +160,8 @@ class InvoiceService extends BaseService
], ],
[ [
'invoice_status_name', 'invoice_status_name',
function ($model) { function ($model) use ($entityType) {
return $model->quote_invoice_id ? link_to("invoices/{$model->quote_invoice_id}/edit", trans('texts.converted'))->toHtml() : self::getStatusLabel($model); return $model->quote_invoice_id ? link_to("invoices/{$model->quote_invoice_id}/edit", trans('texts.converted'))->toHtml() : self::getStatusLabel($entityType, $model);
} }
] ]
]; ];
@ -237,12 +237,13 @@ class InvoiceService extends BaseService
]; ];
} }
private function getStatusLabel($model) private function getStatusLabel($entityType, $model)
{ {
// check if invoice is overdue // check if invoice is overdue
if (Utils::parseFloat($model->balance) && $model->due_date && $model->due_date != '0000-00-00') { if (Utils::parseFloat($model->balance) && $model->due_date && $model->due_date != '0000-00-00') {
if (\DateTime::createFromFormat('Y-m-d', $model->due_date) < new \DateTime("now")) { if (\DateTime::createFromFormat('Y-m-d', $model->due_date) < new \DateTime("now")) {
return "<h4><div class=\"label label-danger\">".trans('texts.overdue')."</div></h4>"; $label = $entityType == ENTITY_INVOICE ? trans('texts.overdue') : trans('texts.expired');
return "<h4><div class=\"label label-danger\">" . $label . "</div></h4>";
} }
} }

View File

@ -15,7 +15,7 @@
"omnipay/2checkout": "dev-master#e9c079c2dde0d7ba461903b3b7bd5caf6dee1248", "omnipay/2checkout": "dev-master#e9c079c2dde0d7ba461903b3b7bd5caf6dee1248",
"omnipay/gocardless": "dev-master", "omnipay/gocardless": "dev-master",
"omnipay/stripe": "2.3.0", "omnipay/stripe": "2.3.0",
"laravel/framework": "5.2.*", "laravel/framework": "5.2.22",
"laravelcollective/html": "5.2.*", "laravelcollective/html": "5.2.*",
"laravelcollective/bus": "5.2.*", "laravelcollective/bus": "5.2.*",
"symfony/css-selector": "~3.0", "symfony/css-selector": "~3.0",

163
composer.lock generated
View File

@ -4,8 +4,8 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"hash": "e5e8524886bd38794a15e406acc3745a", "hash": "a33dce96f4ded3fb269a6d9dcbf24b27",
"content-hash": "6b3f343959ba3f330c425325574dfe28", "content-hash": "f73a83c64422ef3560da4adb988850ae",
"packages": [ "packages": [
{ {
"name": "agmscode/omnipay-agms", "name": "agmscode/omnipay-agms",
@ -123,12 +123,12 @@
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/formers/former.git", "url": "https://github.com/formers/former.git",
"reference": "795f7b9b200a4ff4a33b37a96eaaab0229e36325" "reference": "e196c4336db77be97131f6a3b3c3b69b3a22b683"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/formers/former/zipball/795f7b9b200a4ff4a33b37a96eaaab0229e36325", "url": "https://api.github.com/repos/formers/former/zipball/e196c4336db77be97131f6a3b3c3b69b3a22b683",
"reference": "795f7b9b200a4ff4a33b37a96eaaab0229e36325", "reference": "e196c4336db77be97131f6a3b3c3b69b3a22b683",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -174,7 +174,7 @@
"foundation", "foundation",
"laravel" "laravel"
], ],
"time": "2015-11-05 15:53:52" "time": "2016-03-02 17:21:21"
}, },
{ {
"name": "anahkiasen/html-object", "name": "anahkiasen/html-object",
@ -381,12 +381,12 @@
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/barryvdh/laravel-ide-helper.git", "url": "https://github.com/barryvdh/laravel-ide-helper.git",
"reference": "19553f63e4635480363ff2254350075f285fbbc5" "reference": "e97ed532f09e290b91ff7713b785ed7ab11d0812"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/19553f63e4635480363ff2254350075f285fbbc5", "url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/e97ed532f09e290b91ff7713b785ed7ab11d0812",
"reference": "19553f63e4635480363ff2254350075f285fbbc5", "reference": "e97ed532f09e290b91ff7713b785ed7ab11d0812",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -436,7 +436,7 @@
"phpstorm", "phpstorm",
"sublime" "sublime"
], ],
"time": "2016-03-02 10:03:09" "time": "2016-03-03 14:38:04"
}, },
{ {
"name": "cardgate/omnipay-cardgate", "name": "cardgate/omnipay-cardgate",
@ -579,7 +579,7 @@
"laravel" "laravel"
], ],
"abandoned": "OpenSkill/Datatable", "abandoned": "OpenSkill/Datatable",
"time": "2015-11-23 21:33:41" "time": "2015-04-29 07:00:36"
}, },
{ {
"name": "classpreloader/classpreloader", "name": "classpreloader/classpreloader",
@ -2000,16 +2000,16 @@
}, },
{ {
"name": "guzzlehttp/promises", "name": "guzzlehttp/promises",
"version": "1.0.3", "version": "1.1.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/guzzle/promises.git", "url": "https://github.com/guzzle/promises.git",
"reference": "b1e1c0d55f8083c71eda2c28c12a228d708294ea" "reference": "bb9024c526b22f3fe6ae55a561fd70653d470aa8"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/guzzle/promises/zipball/b1e1c0d55f8083c71eda2c28c12a228d708294ea", "url": "https://api.github.com/repos/guzzle/promises/zipball/bb9024c526b22f3fe6ae55a561fd70653d470aa8",
"reference": "b1e1c0d55f8083c71eda2c28c12a228d708294ea", "reference": "bb9024c526b22f3fe6ae55a561fd70653d470aa8",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -2047,7 +2047,7 @@
"keywords": [ "keywords": [
"promise" "promise"
], ],
"time": "2015-10-15 22:28:00" "time": "2016-03-08 01:15:46"
}, },
{ {
"name": "guzzlehttp/psr7", "name": "guzzlehttp/psr7",
@ -2975,16 +2975,16 @@
}, },
{ {
"name": "league/flysystem", "name": "league/flysystem",
"version": "1.0.17", "version": "1.0.20",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/thephpleague/flysystem.git", "url": "https://github.com/thephpleague/flysystem.git",
"reference": "02f5b6c9a8b9278c8381e3361e7bd9d641c740ca" "reference": "e87a786e3ae12a25cf78a71bb07b4b384bfaa83a"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/02f5b6c9a8b9278c8381e3361e7bd9d641c740ca", "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/e87a786e3ae12a25cf78a71bb07b4b384bfaa83a",
"reference": "02f5b6c9a8b9278c8381e3361e7bd9d641c740ca", "reference": "e87a786e3ae12a25cf78a71bb07b4b384bfaa83a",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -3054,7 +3054,7 @@
"sftp", "sftp",
"storage" "storage"
], ],
"time": "2016-02-19 15:35:38" "time": "2016-03-14 21:54:11"
}, },
{ {
"name": "league/fractal", "name": "league/fractal",
@ -3587,16 +3587,16 @@
}, },
{ {
"name": "monolog/monolog", "name": "monolog/monolog",
"version": "1.18.0", "version": "1.18.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/Seldaek/monolog.git", "url": "https://github.com/Seldaek/monolog.git",
"reference": "e19b764b5c855580e8ffa7e615f72c10fd2f99cc" "reference": "a5f2734e8c16f3aa21b3da09715d10e15b4d2d45"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/e19b764b5c855580e8ffa7e615f72c10fd2f99cc", "url": "https://api.github.com/repos/Seldaek/monolog/zipball/a5f2734e8c16f3aa21b3da09715d10e15b4d2d45",
"reference": "e19b764b5c855580e8ffa7e615f72c10fd2f99cc", "reference": "a5f2734e8c16f3aa21b3da09715d10e15b4d2d45",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -3661,7 +3661,7 @@
"logging", "logging",
"psr-3" "psr-3"
], ],
"time": "2016-03-01 18:00:40" "time": "2016-03-13 16:08:35"
}, },
{ {
"name": "mtdowling/cron-expression", "name": "mtdowling/cron-expression",
@ -3866,16 +3866,16 @@
}, },
{ {
"name": "omnipay/authorizenet", "name": "omnipay/authorizenet",
"version": "v2.3.0", "version": "2.3.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/thephpleague/omnipay-authorizenet.git", "url": "https://github.com/thephpleague/omnipay-authorizenet.git",
"reference": "142a95f550a5320db09e66019ecf5c8b8c3885b9" "reference": "e2e813b0b6306ef97b8763037f05476456546b3e"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/thephpleague/omnipay-authorizenet/zipball/142a95f550a5320db09e66019ecf5c8b8c3885b9", "url": "https://api.github.com/repos/thephpleague/omnipay-authorizenet/zipball/e2e813b0b6306ef97b8763037f05476456546b3e",
"reference": "142a95f550a5320db09e66019ecf5c8b8c3885b9", "reference": "e2e813b0b6306ef97b8763037f05476456546b3e",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -3921,7 +3921,7 @@
"pay", "pay",
"payment" "payment"
], ],
"time": "2015-07-15 18:11:17" "time": "2016-03-10 11:35:24"
}, },
{ {
"name": "omnipay/bitpay", "name": "omnipay/bitpay",
@ -3929,12 +3929,12 @@
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/thephpleague/omnipay-bitpay.git", "url": "https://github.com/thephpleague/omnipay-bitpay.git",
"reference": "e659f0e993c586cb36acafaf50835570b4a16eb2" "reference": "cf813f1d5436a1d2f942d3df6666695d1e2b5280"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/thephpleague/omnipay-bitpay/zipball/e659f0e993c586cb36acafaf50835570b4a16eb2", "url": "https://api.github.com/repos/thephpleague/omnipay-bitpay/zipball/cf813f1d5436a1d2f942d3df6666695d1e2b5280",
"reference": "e659f0e993c586cb36acafaf50835570b4a16eb2", "reference": "cf813f1d5436a1d2f942d3df6666695d1e2b5280",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -3979,7 +3979,7 @@
"pay", "pay",
"payment" "payment"
], ],
"time": "2015-03-23 14:18:26" "time": "2016-03-10 03:16:04"
}, },
{ {
"name": "omnipay/buckaroo", "name": "omnipay/buckaroo",
@ -5536,16 +5536,16 @@
}, },
{ {
"name": "paragonie/random_compat", "name": "paragonie/random_compat",
"version": "v1.2.1", "version": "v1.2.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/paragonie/random_compat.git", "url": "https://github.com/paragonie/random_compat.git",
"reference": "f078eba3bcf140fd69b5fcc3ea5ac809abf729dc" "reference": "b3313b618f4edd76523572531d5d7e22fe747430"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/f078eba3bcf140fd69b5fcc3ea5ac809abf729dc", "url": "https://api.github.com/repos/paragonie/random_compat/zipball/b3313b618f4edd76523572531d5d7e22fe747430",
"reference": "f078eba3bcf140fd69b5fcc3ea5ac809abf729dc", "reference": "b3313b618f4edd76523572531d5d7e22fe747430",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -5580,7 +5580,7 @@
"pseudorandom", "pseudorandom",
"random" "random"
], ],
"time": "2016-02-29 17:25:04" "time": "2016-03-11 19:54:08"
}, },
{ {
"name": "patricktalmadge/bootstrapper", "name": "patricktalmadge/bootstrapper",
@ -5836,16 +5836,16 @@
}, },
{ {
"name": "psy/psysh", "name": "psy/psysh",
"version": "v0.7.1", "version": "v0.7.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/bobthecow/psysh.git", "url": "https://github.com/bobthecow/psysh.git",
"reference": "5e8cedbe0a3681f18782594eefc78423f8401fc8" "reference": "e64e10b20f8d229cac76399e1f3edddb57a0f280"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/bobthecow/psysh/zipball/5e8cedbe0a3681f18782594eefc78423f8401fc8", "url": "https://api.github.com/repos/bobthecow/psysh/zipball/e64e10b20f8d229cac76399e1f3edddb57a0f280",
"reference": "5e8cedbe0a3681f18782594eefc78423f8401fc8", "reference": "e64e10b20f8d229cac76399e1f3edddb57a0f280",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -5904,20 +5904,20 @@
"interactive", "interactive",
"shell" "shell"
], ],
"time": "2016-02-27 18:59:18" "time": "2016-03-09 05:03:14"
}, },
{ {
"name": "samvaughton/omnipay-barclays-epdq", "name": "samvaughton/omnipay-barclays-epdq",
"version": "2.1.1", "version": "2.2.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/samvaughton/omnipay-barclays-epdq.git", "url": "https://github.com/samvaughton/omnipay-barclays-epdq.git",
"reference": "f971de37aa40c72cc58f02d05f540a93b2c5958e" "reference": "b7f9263afa73b8e6c3c5e8bb2bf04a82548a41da"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/samvaughton/omnipay-barclays-epdq/zipball/f971de37aa40c72cc58f02d05f540a93b2c5958e", "url": "https://api.github.com/repos/samvaughton/omnipay-barclays-epdq/zipball/b7f9263afa73b8e6c3c5e8bb2bf04a82548a41da",
"reference": "f971de37aa40c72cc58f02d05f540a93b2c5958e", "reference": "b7f9263afa73b8e6c3c5e8bb2bf04a82548a41da",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -5966,7 +5966,7 @@
"pay", "pay",
"payment" "payment"
], ],
"time": "2015-05-07 14:45:43" "time": "2016-03-03 14:40:27"
}, },
{ {
"name": "simshaun/recurr", "name": "simshaun/recurr",
@ -6716,7 +6716,7 @@
}, },
{ {
"name": "symfony/polyfill-mbstring", "name": "symfony/polyfill-mbstring",
"version": "v1.1.0", "version": "v1.1.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git", "url": "https://github.com/symfony/polyfill-mbstring.git",
@ -6775,16 +6775,16 @@
}, },
{ {
"name": "symfony/polyfill-php54", "name": "symfony/polyfill-php54",
"version": "v1.1.0", "version": "v1.1.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-php54.git", "url": "https://github.com/symfony/polyfill-php54.git",
"reference": "74663d5a2ff3c530c1bc0571500e0feec9094054" "reference": "9ba741ca01c77282ecf5796c2c1d667f03454ffb"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php54/zipball/74663d5a2ff3c530c1bc0571500e0feec9094054", "url": "https://api.github.com/repos/symfony/polyfill-php54/zipball/9ba741ca01c77282ecf5796c2c1d667f03454ffb",
"reference": "74663d5a2ff3c530c1bc0571500e0feec9094054", "reference": "9ba741ca01c77282ecf5796c2c1d667f03454ffb",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -6829,11 +6829,11 @@
"portable", "portable",
"shim" "shim"
], ],
"time": "2016-01-20 09:13:37" "time": "2016-01-25 19:13:00"
}, },
{ {
"name": "symfony/polyfill-php55", "name": "symfony/polyfill-php55",
"version": "v1.1.0", "version": "v1.1.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-php55.git", "url": "https://github.com/symfony/polyfill-php55.git",
@ -6889,7 +6889,7 @@
}, },
{ {
"name": "symfony/polyfill-php56", "name": "symfony/polyfill-php56",
"version": "v1.1.0", "version": "v1.1.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-php56.git", "url": "https://github.com/symfony/polyfill-php56.git",
@ -6945,7 +6945,7 @@
}, },
{ {
"name": "symfony/polyfill-util", "name": "symfony/polyfill-util",
"version": "v1.1.0", "version": "v1.1.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-util.git", "url": "https://github.com/symfony/polyfill-util.git",
@ -8211,41 +8211,42 @@
}, },
{ {
"name": "codeception/codeception", "name": "codeception/codeception",
"version": "2.1.6", "version": "2.1.7",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/Codeception/Codeception.git", "url": "https://github.com/Codeception/Codeception.git",
"reference": "b199941f5e59d1e7fd32d78296c8ab98db873d89" "reference": "65971b0dee4972710365b6102154cd412a9bf7b1"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/Codeception/Codeception/zipball/b199941f5e59d1e7fd32d78296c8ab98db873d89", "url": "https://api.github.com/repos/Codeception/Codeception/zipball/65971b0dee4972710365b6102154cd412a9bf7b1",
"reference": "b199941f5e59d1e7fd32d78296c8ab98db873d89", "reference": "65971b0dee4972710365b6102154cd412a9bf7b1",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"ext-json": "*", "ext-json": "*",
"ext-mbstring": "*", "ext-mbstring": "*",
"facebook/webdriver": ">=1.0.1", "facebook/webdriver": ">=1.0.1 <2.0",
"guzzlehttp/guzzle": ">=4.1.4 <7.0", "guzzlehttp/guzzle": ">=4.1.4 <7.0",
"guzzlehttp/psr7": "~1.0", "guzzlehttp/psr7": "~1.0",
"php": ">=5.4.0", "php": ">=5.4.0 <8.0",
"phpunit/phpunit": "~4.8.0", "phpunit/php-code-coverage": ">=2.1.3",
"symfony/browser-kit": ">=2.4|<3.1", "phpunit/phpunit": ">4.8.20 <6.0",
"symfony/console": ">=2.4|<3.1", "symfony/browser-kit": ">=2.5 <3.1",
"symfony/css-selector": ">=2.4|<3.1", "symfony/console": ">=2.5 <3.1",
"symfony/dom-crawler": ">=2.4|<3.1", "symfony/css-selector": ">=2.5 <3.1",
"symfony/event-dispatcher": ">=2.4|<3.1", "symfony/dom-crawler": ">=2.5 <3.1",
"symfony/finder": ">=2.4|<3.1", "symfony/event-dispatcher": ">=2.5 <3.1",
"symfony/yaml": ">=2.4|<3.1" "symfony/finder": ">=2.5 <3.1",
"symfony/yaml": ">=2.5 <3.1"
}, },
"require-dev": { "require-dev": {
"codeception/specify": "~0.3", "codeception/specify": "~0.3",
"facebook/php-sdk-v4": "~4.0", "facebook/php-sdk-v4": "~5.0",
"flow/jsonpath": "~0.2", "flow/jsonpath": "~0.2",
"monolog/monolog": "~1.8", "monolog/monolog": "~1.8",
"pda/pheanstalk": "~2.0", "pda/pheanstalk": "~2.0",
"videlalvaro/php-amqplib": "~2.4" "php-amqplib/php-amqplib": "~2.4"
}, },
"suggest": { "suggest": {
"codeception/phpbuiltinserver": "Extension to start and stop PHP built-in web server for your tests", "codeception/phpbuiltinserver": "Extension to start and stop PHP built-in web server for your tests",
@ -8287,7 +8288,7 @@
"functional testing", "functional testing",
"unit testing" "unit testing"
], ],
"time": "2016-02-09 22:27:48" "time": "2016-03-12 01:15:25"
}, },
{ {
"name": "doctrine/instantiator", "name": "doctrine/instantiator",
@ -8854,16 +8855,16 @@
}, },
{ {
"name": "phpunit/phpunit", "name": "phpunit/phpunit",
"version": "4.8.23", "version": "4.8.24",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git", "url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "6e351261f9cd33daf205a131a1ba61c6d33bd483" "reference": "a1066c562c52900a142a0e2bbf0582994671385e"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/6e351261f9cd33daf205a131a1ba61c6d33bd483", "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a1066c562c52900a142a0e2bbf0582994671385e",
"reference": "6e351261f9cd33daf205a131a1ba61c6d33bd483", "reference": "a1066c562c52900a142a0e2bbf0582994671385e",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -8922,7 +8923,7 @@
"testing", "testing",
"xunit" "xunit"
], ],
"time": "2016-02-11 14:56:33" "time": "2016-03-14 06:16:08"
}, },
{ {
"name": "phpunit/phpunit-mock-objects", "name": "phpunit/phpunit-mock-objects",

View File

@ -0,0 +1,28 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddSupportThreeDecimalTaxes extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('tax_rates', function($table) {
$table->decimal('rate', 13, 3)->change();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('tax_rates', function($table) {
$table->decimal('rate', 13, 2)->change();
});
}
}

View File

@ -31259,10 +31259,10 @@ NINJA.invoiceColumns = function(invoice)
columns.push("*") columns.push("*")
if (account.custom_invoice_item_label1) { if (invoice.is_pro && account.custom_invoice_item_label1) {
columns.push("10%"); columns.push("10%");
} }
if (account.custom_invoice_item_label2) { if (invoice.is_pro && account.custom_invoice_item_label2) {
columns.push("10%"); columns.push("10%");
} }
@ -31314,10 +31314,10 @@ NINJA.invoiceLines = function(invoice) {
grid[0].push({text: invoiceLabels.description, style: ['tableHeader', 'descriptionTableHeader']}); grid[0].push({text: invoiceLabels.description, style: ['tableHeader', 'descriptionTableHeader']});
if (account.custom_invoice_item_label1) { if (invoice.is_pro && account.custom_invoice_item_label1) {
grid[0].push({text: account.custom_invoice_item_label1, style: ['tableHeader', 'custom1TableHeader']}); grid[0].push({text: account.custom_invoice_item_label1, style: ['tableHeader', 'custom1TableHeader']});
} }
if (account.custom_invoice_item_label2) { if (invoice.is_pro && account.custom_invoice_item_label2) {
grid[0].push({text: account.custom_invoice_item_label2, style: ['tableHeader', 'custom2TableHeader']}); grid[0].push({text: account.custom_invoice_item_label2, style: ['tableHeader', 'custom2TableHeader']});
} }
@ -31372,10 +31372,10 @@ NINJA.invoiceLines = function(invoice) {
row.push({style:["productKey", rowStyle], text:productKey || ' '}); // product key can be blank when selecting from a datalist row.push({style:["productKey", rowStyle], text:productKey || ' '}); // product key can be blank when selecting from a datalist
} }
row.push({style:["notes", rowStyle], stack:[{text:notes || ' '}]}); row.push({style:["notes", rowStyle], stack:[{text:notes || ' '}]});
if (account.custom_invoice_item_label1) { if (invoice.is_pro && account.custom_invoice_item_label1) {
row.push({style:["customValue1", rowStyle], text:item.custom_value1 || ' '}); row.push({style:["customValue1", rowStyle], text:item.custom_value1 || ' '});
} }
if (account.custom_invoice_item_label2) { if (invoice.is_pro && account.custom_invoice_item_label2) {
row.push({style:["customValue2", rowStyle], text:item.custom_value2 || ' '}); row.push({style:["customValue2", rowStyle], text:item.custom_value2 || ' '});
} }
row.push({style:["cost", rowStyle], text:cost}); row.push({style:["cost", rowStyle], text:cost});

23
public/css/built.css vendored
View File

@ -2216,7 +2216,8 @@ th:last-child {
} }
tr {border: none;} tr {border: none;}
th {border-left: 1px solid #d26b26; } thead th {border-left: 1px solid #d26b26;}
tbody td {border-left: 1px solid #FFFFFF;}
.table>thead>tr>th, .table>tbody>tr>th, .table>tfoot>tr>th, .table>thead>tr>td, .table>tbody>tr>td, .table>tfoot>tr>td { .table>thead>tr>th, .table>tbody>tr>th, .table>tfoot>tr>th, .table>thead>tr>td, .table>tbody>tr>td, .table>tfoot>tr>td {
vertical-align: middle; vertical-align: middle;
border-top: none; border-top: none;
@ -2910,8 +2911,24 @@ box-shadow: 0px 0px 15px 0px rgba(0, 5, 5, 0.2);
.large-dialog { .large-dialog {
width: 960px; width: 960px;
} }
.hide-desktop .hide-desktop {
{ display: none;
}
}
/* Style to fix navigation by show icon instead of name */
@media only screen and (min-width : 1200px) {
.nav-account-icon {
display: none;
}
}
@media only screen and (max-width : 992px) {
.nav-account-icon {
display: none;
}
}
@media only screen and (max-width : 1200px) and (min-width: 992px) {
.nav-account-name {
display: none; display: none;
} }
} }

23
public/css/style.css vendored
View File

@ -89,7 +89,8 @@ th:last-child {
} }
tr {border: none;} tr {border: none;}
th {border-left: 1px solid #d26b26; } thead th {border-left: 1px solid #d26b26;}
tbody td {border-left: 1px solid #FFFFFF;}
.table>thead>tr>th, .table>tbody>tr>th, .table>tfoot>tr>th, .table>thead>tr>td, .table>tbody>tr>td, .table>tfoot>tr>td { .table>thead>tr>th, .table>tbody>tr>th, .table>tfoot>tr>th, .table>thead>tr>td, .table>tbody>tr>td, .table>tfoot>tr>td {
vertical-align: middle; vertical-align: middle;
border-top: none; border-top: none;
@ -783,8 +784,24 @@ box-shadow: 0px 0px 15px 0px rgba(0, 5, 5, 0.2);
.large-dialog { .large-dialog {
width: 960px; width: 960px;
} }
.hide-desktop .hide-desktop {
{ display: none;
}
}
/* Style to fix navigation by show icon instead of name */
@media only screen and (min-width : 1200px) {
.nav-account-icon {
display: none;
}
}
@media only screen and (max-width : 992px) {
.nav-account-icon {
display: none;
}
}
@media only screen and (max-width : 1200px) and (min-width: 992px) {
.nav-account-name {
display: none; display: none;
} }
} }

View File

@ -267,10 +267,10 @@ NINJA.invoiceColumns = function(invoice)
columns.push("*") columns.push("*")
if (account.custom_invoice_item_label1) { if (invoice.is_pro && account.custom_invoice_item_label1) {
columns.push("10%"); columns.push("10%");
} }
if (account.custom_invoice_item_label2) { if (invoice.is_pro && account.custom_invoice_item_label2) {
columns.push("10%"); columns.push("10%");
} }
@ -322,10 +322,10 @@ NINJA.invoiceLines = function(invoice) {
grid[0].push({text: invoiceLabels.description, style: ['tableHeader', 'descriptionTableHeader']}); grid[0].push({text: invoiceLabels.description, style: ['tableHeader', 'descriptionTableHeader']});
if (account.custom_invoice_item_label1) { if (invoice.is_pro && account.custom_invoice_item_label1) {
grid[0].push({text: account.custom_invoice_item_label1, style: ['tableHeader', 'custom1TableHeader']}); grid[0].push({text: account.custom_invoice_item_label1, style: ['tableHeader', 'custom1TableHeader']});
} }
if (account.custom_invoice_item_label2) { if (invoice.is_pro && account.custom_invoice_item_label2) {
grid[0].push({text: account.custom_invoice_item_label2, style: ['tableHeader', 'custom2TableHeader']}); grid[0].push({text: account.custom_invoice_item_label2, style: ['tableHeader', 'custom2TableHeader']});
} }
@ -380,10 +380,10 @@ NINJA.invoiceLines = function(invoice) {
row.push({style:["productKey", rowStyle], text:productKey || ' '}); // product key can be blank when selecting from a datalist row.push({style:["productKey", rowStyle], text:productKey || ' '}); // product key can be blank when selecting from a datalist
} }
row.push({style:["notes", rowStyle], stack:[{text:notes || ' '}]}); row.push({style:["notes", rowStyle], stack:[{text:notes || ' '}]});
if (account.custom_invoice_item_label1) { if (invoice.is_pro && account.custom_invoice_item_label1) {
row.push({style:["customValue1", rowStyle], text:item.custom_value1 || ' '}); row.push({style:["customValue1", rowStyle], text:item.custom_value1 || ' '});
} }
if (account.custom_invoice_item_label2) { if (invoice.is_pro && account.custom_invoice_item_label2) {
row.push({style:["customValue2", rowStyle], text:item.custom_value2 || ' '}); row.push({style:["customValue2", rowStyle], text:item.custom_value2 || ' '});
} }
row.push({style:["cost", rowStyle], text:cost}); row.push({style:["cost", rowStyle], text:cost});

View File

@ -942,7 +942,7 @@ return array(
'notes' => 'Notes', 'notes' => 'Notes',
'invoice_will_create' => 'client will be created', 'invoice_will_create' => 'client will be created',
'invoices_will_create' => 'invoices will be created', 'invoices_will_create' => 'invoices will be created',
'failed_to_import' => 'The following records failed to import', 'failed_to_import' => 'The following records failed to import, they either already exist or are missing required fields.',
'publishable_key' => 'Publishable Key', 'publishable_key' => 'Publishable Key',
'secret_key' => 'Secret Key', 'secret_key' => 'Secret Key',

View File

@ -943,7 +943,7 @@ return array(
'notes' => 'Notes', 'notes' => 'Notes',
'invoice_will_create' => 'client will be created', 'invoice_will_create' => 'client will be created',
'invoices_will_create' => 'invoices will be created', 'invoices_will_create' => 'invoices will be created',
'failed_to_import' => 'The following records failed to import', 'failed_to_import' => 'The following records failed to import, they either already exist or are missing required fields.',
'publishable_key' => 'Publishable Key', 'publishable_key' => 'Publishable Key',
'secret_key' => 'Secret Key', 'secret_key' => 'Secret Key',

View File

@ -161,7 +161,7 @@ $LANG = array(
'work_email' => 'Email', 'work_email' => 'Email',
'language_id' => 'Language', 'language_id' => 'Language',
'timezone_id' => 'Timezone', 'timezone_id' => 'Timezone',
'date_format_id' => 'Date format', 'date_format_id' => 'Date Format',
'datetime_format_id' => 'Date/Time Format', 'datetime_format_id' => 'Date/Time Format',
'users' => 'Users', 'users' => 'Users',
'localization' => 'Localization', 'localization' => 'Localization',
@ -826,7 +826,7 @@ $LANG = array(
'notes' => 'Notes', 'notes' => 'Notes',
'invoice_will_create' => 'client will be created', 'invoice_will_create' => 'client will be created',
'invoices_will_create' => 'invoices will be created', 'invoices_will_create' => 'invoices will be created',
'failed_to_import' => 'The following records failed to import', 'failed_to_import' => 'The following records failed to import, they either already exist or are missing required fields.',
'publishable_key' => 'Publishable Key', 'publishable_key' => 'Publishable Key',
'secret_key' => 'Secret Key', 'secret_key' => 'Secret Key',
'missing_publishable_key' => 'Set your Stripe publishable key for an improved checkout process', 'missing_publishable_key' => 'Set your Stripe publishable key for an improved checkout process',
@ -950,7 +950,7 @@ $LANG = array(
'add_bank_account' => 'Add Bank Account', 'add_bank_account' => 'Add Bank Account',
'setup_account' => 'Setup Account', 'setup_account' => 'Setup Account',
'import_expenses' => 'Import Expenses', 'import_expenses' => 'Import Expenses',
'bank_id' => 'bank', 'bank_id' => 'Bank',
'integration_type' => 'Integration Type', 'integration_type' => 'Integration Type',
'updated_bank_account' => 'Successfully updated bank account', 'updated_bank_account' => 'Successfully updated bank account',
'edit_bank_account' => 'Edit Bank Account', 'edit_bank_account' => 'Edit Bank Account',
@ -1057,6 +1057,14 @@ $LANG = array(
'enable_portal_password_help'=>'Allows you to set a password for each contact. If a password is set, the contact will be required to enter a password before viewing invoices.', 'enable_portal_password_help'=>'Allows you to set a password for each contact. If a password is set, the contact will be required to enter a password before viewing invoices.',
'send_portal_password'=>'Generate password automatically', 'send_portal_password'=>'Generate password automatically',
'send_portal_password_help'=>'If no password is set, one will be generated and sent with the first invoice.', 'send_portal_password_help'=>'If no password is set, one will be generated and sent with the first invoice.',
'expired' => 'Expired',
'invalid_card_number' => 'The credit card number is not valid.',
'invalid_expiry' => 'The expiration date is not valid.',
'invalid_cvv' => 'The CVV is not valid.',
'cost' => 'Cost',
'create_invoice_for_sample' => 'Note: create your first invoice to see a preview here.',
); );
return $LANG; return $LANG;

View File

@ -920,7 +920,7 @@ return array(
'notes' => 'Notes', 'notes' => 'Notes',
'invoice_will_create' => 'client will be created', 'invoice_will_create' => 'client will be created',
'invoices_will_create' => 'invoices will be created', 'invoices_will_create' => 'invoices will be created',
'failed_to_import' => 'The following records failed to import', 'failed_to_import' => 'The following records failed to import, they either already exist or are missing required fields.',
'publishable_key' => 'Publishable Key', 'publishable_key' => 'Publishable Key',
'secret_key' => 'Secret Key', 'secret_key' => 'Secret Key',

View File

@ -934,7 +934,7 @@ return array(
'notes' => 'Notes', 'notes' => 'Notes',
'invoice_will_create' => 'client will be created', 'invoice_will_create' => 'client will be created',
'invoices_will_create' => 'invoices will be created', 'invoices_will_create' => 'invoices will be created',
'failed_to_import' => 'The following records failed to import', 'failed_to_import' => 'The following records failed to import, they either already exist or are missing required fields.',
'publishable_key' => 'Publishable Key', 'publishable_key' => 'Publishable Key',
'secret_key' => 'Secret Key', 'secret_key' => 'Secret Key',

View File

@ -937,7 +937,7 @@ return array(
'notes' => 'Notes', 'notes' => 'Notes',
'invoice_will_create' => 'client will be created', 'invoice_will_create' => 'client will be created',
'invoices_will_create' => 'invoices will be created', 'invoices_will_create' => 'invoices will be created',
'failed_to_import' => 'The following records failed to import', 'failed_to_import' => 'The following records failed to import, they either already exist or are missing required fields.',
'publishable_key' => 'Publishable Key', 'publishable_key' => 'Publishable Key',
'secret_key' => 'Secret Key', 'secret_key' => 'Secret Key',

View File

@ -944,7 +944,7 @@ return array(
'notes' => 'Notes', 'notes' => 'Notes',
'invoice_will_create' => 'client will be created', 'invoice_will_create' => 'client will be created',
'invoices_will_create' => 'invoices will be created', 'invoices_will_create' => 'invoices will be created',
'failed_to_import' => 'The following records failed to import', 'failed_to_import' => 'The following records failed to import, they either already exist or are missing required fields.',
'publishable_key' => 'Publishable Key', 'publishable_key' => 'Publishable Key',
'secret_key' => 'Secret Key', 'secret_key' => 'Secret Key',

View File

@ -942,7 +942,7 @@ return array(
'notes' => 'Notes', 'notes' => 'Notes',
'invoice_will_create' => 'client will be created', 'invoice_will_create' => 'client will be created',
'invoices_will_create' => 'invoices will be created', 'invoices_will_create' => 'invoices will be created',
'failed_to_import' => 'The following records failed to import', 'failed_to_import' => 'The following records failed to import, they either already exist or are missing required fields.',
'publishable_key' => 'Publishable Key', 'publishable_key' => 'Publishable Key',
'secret_key' => 'Secret Key', 'secret_key' => 'Secret Key',

View File

@ -937,7 +937,7 @@ return array(
'notes' => 'Notities', 'notes' => 'Notities',
'invoice_will_create' => 'klant zal worden aangemaakt', 'invoice_will_create' => 'klant zal worden aangemaakt',
'invoices_will_create' => 'factuur zal worden aangemaakt', 'invoices_will_create' => 'factuur zal worden aangemaakt',
'failed_to_import' => 'The following records failed to import', 'failed_to_import' => 'The following records failed to import, they either already exist or are missing required fields.',
'publishable_key' => 'Publishable Key', 'publishable_key' => 'Publishable Key',
'secret_key' => 'Secret Key', 'secret_key' => 'Secret Key',

View File

@ -939,7 +939,7 @@ return array(
'notes' => 'Notes', 'notes' => 'Notes',
'invoice_will_create' => 'client will be created', 'invoice_will_create' => 'client will be created',
'invoices_will_create' => 'invoices will be created', 'invoices_will_create' => 'invoices will be created',
'failed_to_import' => 'The following records failed to import', 'failed_to_import' => 'The following records failed to import, they either already exist or are missing required fields.',
'publishable_key' => 'Publishable Key', 'publishable_key' => 'Publishable Key',
'secret_key' => 'Secret Key', 'secret_key' => 'Secret Key',

View File

@ -64,11 +64,11 @@
&& isset($_ENV['DWOLLA_KEY']) && isset($_ENV['DWOLLA_SECRET'])) && isset($_ENV['DWOLLA_KEY']) && isset($_ENV['DWOLLA_SECRET']))
{{-- do nothing --}} {{-- do nothing --}}
@elseif ($field == 'testMode' || $field == 'developerMode' || $field == 'sandbox') @elseif ($field == 'testMode' || $field == 'developerMode' || $field == 'sandbox')
{!! Former::checkbox($gateway->id.'_'.$field)->label(Utils::toSpaceCase($field))->text('Enable')->value('true') !!} {!! Former::checkbox($gateway->id.'_'.$field)->label(ucwords(Utils::toSpaceCase($field)))->text('Enable')->value('true') !!}
@elseif ($field == 'username' || $field == 'password') @elseif ($field == 'username' || $field == 'password')
{!! Former::text($gateway->id.'_'.$field)->label('API '. ucfirst(Utils::toSpaceCase($field))) !!} {!! Former::text($gateway->id.'_'.$field)->label('API '. ucfirst(Utils::toSpaceCase($field))) !!}
@else @else
{!! Former::text($gateway->id.'_'.$field)->label($gateway->id == GATEWAY_STRIPE ? trans('texts.secret_key') : Utils::toSpaceCase($field)) !!} {!! Former::text($gateway->id.'_'.$field)->label($gateway->id == GATEWAY_STRIPE ? trans('texts.secret_key') : ucwords(Utils::toSpaceCase($field))) !!}
@endif @endif
@endforeach @endforeach

View File

@ -153,7 +153,6 @@
@if (isset($sampleInvoice) && $sampleInvoice) @if (isset($sampleInvoice) && $sampleInvoice)
var sample = {!! $sampleInvoice->toJSON() !!} var sample = {!! $sampleInvoice->toJSON() !!}
console.log(sample);
$('#sampleData').show().html(prettyJson(sample)); $('#sampleData').show().html(prettyJson(sample));
@endif @endif
}); });
@ -222,6 +221,9 @@
{!! trans('texts.customize_help') !!} {!! trans('texts.customize_help') !!}
<pre id="sampleData" style="display:none;height:200px;padding-top:16px;"></pre> <pre id="sampleData" style="display:none;height:200px;padding-top:16px;"></pre>
@if (empty($sampleInvoice))
<div class="help-block">{{ trans('texts.create_invoice_for_sample') }}</div>
@endif
</div> </div>
<div class="modal-footer" style="margin-top: 0px"> <div class="modal-footer" style="margin-top: 0px">

View File

@ -258,27 +258,45 @@
localStorage.setItem('auth_provider', provider); localStorage.setItem('auth_provider', provider);
} }
window.loadedSearchData = false;
function showSearch() { function showSearch() {
$('#search').typeahead('val', ''); $('#search').typeahead('val', '');
$('#navbar-options').hide(); $('#navbar-options').hide();
$('#search-form').show(); $('#search-form').show();
$('#search').focus();
if (window.hasOwnProperty('loadedSearchData')) {
$('#search').focus(); if (!window.loadedSearchData) {
} else {
trackEvent('/activity', '/search'); trackEvent('/activity', '/search');
$.get('{{ URL::route('getSearchData') }}', function(data) { $.get('{{ URL::route('getSearchData') }}', function(data) {
window.loadedSearchData = true;
$('#search').typeahead({ $('#search').typeahead({
hint: true, hint: true,
highlight: true, highlight: true,
} }
@if (Auth::check() && Auth::user()->account->custom_client_label1)
,{
name: 'data',
display: 'value',
source: searchData(data['{{ Auth::user()->account->custom_client_label1 }}'], 'tokens'),
templates: {
header: '&nbsp;<span style="font-weight:600;font-size:16px">{{ Auth::user()->account->custom_client_label1 }}</span>'
}
}
@endif
@if (Auth::check() && Auth::user()->account->custom_client_label2)
,{
name: 'data',
display: 'value',
source: searchData(data['{{ Auth::user()->account->custom_client_label2 }}'], 'tokens'),
templates: {
header: '&nbsp;<span style="font-weight:600;font-size:16px">{{ Auth::user()->account->custom_client_label2 }}</span>'
}
}
@endif
@foreach (['clients', 'contacts', 'invoices', 'quotes', 'navigation'] as $type) @foreach (['clients', 'contacts', 'invoices', 'quotes', 'navigation'] as $type)
,{ ,{
name: 'data', name: 'data',
display: 'value', display: 'value',
source: searchData(data['{{ $type }}'], 'value', true), source: searchData(data['{{ $type }}'], 'tokens', true),
templates: { templates: {
header: '&nbsp;<span style="font-weight:600;font-size:16px">{{ trans("texts.{$type}") }}</span>' header: '&nbsp;<span style="font-weight:600;font-size:16px">{{ trans("texts.{$type}") }}</span>'
} }
@ -287,6 +305,7 @@
).on('typeahead:selected', function(element, datum, name) { ).on('typeahead:selected', function(element, datum, name) {
window.location = datum.url; window.location = datum.url;
}).focus(); }).focus();
window.loadedSearchData = true;
}); });
} }
} }
@ -302,7 +321,9 @@
}, 3000); }, 3000);
$('#search').blur(function(event){ $('#search').blur(function(event){
hideSearch(); if (window.loadedSearchData) {
hideSearch();
}
}); });
if (isStorageSupported()) { if (isStorageSupported()) {
@ -406,14 +427,16 @@
<div class="btn-group user-dropdown"> <div class="btn-group user-dropdown">
<button type="button" class="btn btn-default btn-sm dropdown-toggle" data-toggle="dropdown"> <button type="button" class="btn btn-default btn-sm dropdown-toggle" data-toggle="dropdown">
<div id="myAccountButton" class="ellipsis" style="max-width:{{ Utils::isPro() && ! Utils::isTrial() ? '130' : '100' }}px"> <div id="myAccountButton" class="ellipsis nav-account-name" style="max-width:{{ Utils::isPro() && ! Utils::isTrial() ? '130' : '100' }}px;">
@if (session(SESSION_USER_ACCOUNTS) && count(session(SESSION_USER_ACCOUNTS))) @if (session(SESSION_USER_ACCOUNTS) && count(session(SESSION_USER_ACCOUNTS)))
{{ Auth::user()->account->getDisplayName() }} {{ Auth::user()->account->getDisplayName() }}
@else @else
{{ Auth::user()->getDisplayName() }} {{ Auth::user()->getDisplayName() }}
@endif @endif
<span class="caret"></span> <span class="caret"></span>
</div> </div>
<span class="glyphicon glyphicon-user nav-account-icon" style="padding-left:0px"
title="{{ Auth::user()->account->getDisplayName() }}"/>
</button> </button>
<ul class="dropdown-menu user-accounts"> <ul class="dropdown-menu user-accounts">
@if (session(SESSION_USER_ACCOUNTS)) @if (session(SESSION_USER_ACCOUNTS))

View File

@ -87,7 +87,7 @@
<div data-bind="with: client" class="invoice-contact"> <div data-bind="with: client" class="invoice-contact">
<div style="display:none" class="form-group" data-bind="visible: contacts().length > 0 &amp;&amp; (contacts()[0].email() || contacts()[0].first_name()), foreach: contacts"> <div style="display:none" class="form-group" data-bind="visible: contacts().length > 0 &amp;&amp; (contacts()[0].email() || contacts()[0].first_name()), foreach: contacts">
<div class="col-lg-8 col-lg-offset-4"> <div class="col-lg-8 col-lg-offset-4 col-sm-offset-4">
<label class="checkbox" data-bind="attr: {for: $index() + '_check'}" onclick="refreshPDF(true)"> <label class="checkbox" data-bind="attr: {for: $index() + '_check'}" onclick="refreshPDF(true)">
<input type="hidden" value="0" data-bind="attr: {name: 'client[contacts][' + $index() + '][send_invoice]'}"> <input type="hidden" value="0" data-bind="attr: {name: 'client[contacts][' + $index() + '][send_invoice]'}">
<input type="checkbox" value="1" data-bind="checked: send_invoice, attr: {id: $index() + '_check', name: 'client[contacts][' + $index() + '][send_invoice]'}"> <input type="checkbox" value="1" data-bind="checked: send_invoice, attr: {id: $index() + '_check', name: 'client[contacts][' + $index() + '][send_invoice]'}">
@ -191,10 +191,10 @@
<th style="min-width:32px;" class="hide-border"></th> <th style="min-width:32px;" class="hide-border"></th>
<th style="min-width:160px">{{ $invoiceLabels['item'] }}</th> <th style="min-width:160px">{{ $invoiceLabels['item'] }}</th>
<th style="width:100%">{{ $invoiceLabels['description'] }}</th> <th style="width:100%">{{ $invoiceLabels['description'] }}</th>
@if ($account->custom_invoice_item_label1) @if ($account->showCustomField('custom_invoice_item_label1'))
<th style="min-width:120px">{{ $account->custom_invoice_item_label1 }}</th> <th style="min-width:120px">{{ $account->custom_invoice_item_label1 }}</th>
@endif @endif
@if ($account->custom_invoice_item_label2) @if ($account->showCustomField('custom_invoice_item_label2'))
<th style="min-width:120px">{{ $account->custom_invoice_item_label2 }}</th> <th style="min-width:120px">{{ $account->custom_invoice_item_label2 }}</th>
@endif @endif
<th style="min-width:120px" data-bind="text: costLabel">{{ $invoiceLabels['unit_cost'] }}</th> <th style="min-width:120px" data-bind="text: costLabel">{{ $invoiceLabels['unit_cost'] }}</th>
@ -219,12 +219,12 @@
<input type="text" data-bind="value: task_public_id, attr: {name: 'invoice_items[' + $index() + '][task_public_id]'}" style="display: none"/> <input type="text" data-bind="value: task_public_id, attr: {name: 'invoice_items[' + $index() + '][task_public_id]'}" style="display: none"/>
<input type="text" data-bind="value: expense_public_id, attr: {name: 'invoice_items[' + $index() + '][expense_public_id]'}" style="display: none"/> <input type="text" data-bind="value: expense_public_id, attr: {name: 'invoice_items[' + $index() + '][expense_public_id]'}" style="display: none"/>
</td> </td>
@if ($account->custom_invoice_item_label1) @if ($account->showCustomField('custom_invoice_item_label1'))
<td> <td>
<input data-bind="value: custom_value1, valueUpdate: 'afterkeydown', attr: {name: 'invoice_items[' + $index() + '][custom_value1]'}" class="form-control invoice-item"/> <input data-bind="value: custom_value1, valueUpdate: 'afterkeydown', attr: {name: 'invoice_items[' + $index() + '][custom_value1]'}" class="form-control invoice-item"/>
</td> </td>
@endif @endif
@if ($account->custom_invoice_item_label2) @if ($account->showCustomField('custom_invoice_item_label2'))
<td> <td>
<input data-bind="value: custom_value2, valueUpdate: 'afterkeydown', attr: {name: 'invoice_items[' + $index() + '][custom_value2]'}" class="form-control invoice-item"/> <input data-bind="value: custom_value2, valueUpdate: 'afterkeydown', attr: {name: 'invoice_items[' + $index() + '][custom_value2]'}" class="form-control invoice-item"/>
</td> </td>
@ -257,7 +257,7 @@
<tfoot> <tfoot>
<tr> <tr>
<td class="hide-border"/> <td class="hide-border"/>
<td class="hide-border" colspan="{{ 2 + ($account->custom_invoice_item_label1 ? 1 : 0) + ($account->custom_invoice_item_label2 ? 1 : 0) }}" rowspan="6" style="vertical-align:top"> <td class="hide-border" colspan="{{ 2 + ($account->showCustomField('custom_invoice_item_label1') ? 1 : 0) + ($account->showCustomField('custom_invoice_item_label2') ? 1 : 0) }}" rowspan="6" style="vertical-align:top">
<br/> <br/>
<div role="tabpanel"> <div role="tabpanel">

View File

@ -11,9 +11,6 @@
$('.payment-form').submit(function(event) { $('.payment-form').submit(function(event) {
var $form = $(this); var $form = $(this);
// Disable the submit button to prevent repeated clicks
$form.find('button').prop('disabled', true);
var data = { var data = {
name: $('#first_name').val() + ' ' + $('#last_name').val(), name: $('#first_name').val() + ' ' + $('#last_name').val(),
address_line1: $('#address1').val(), address_line1: $('#address1').val(),
@ -28,6 +25,24 @@
exp_year: $('#expiration_year').val() exp_year: $('#expiration_year').val()
}; };
// Validate the card details
if (!Stripe.card.validateCardNumber(data.number)) {
$('#js-error-message').html('{{ trans('texts.invalid_card_number') }}').fadeIn();
return false;
}
if (!Stripe.card.validateExpiry(data.exp_month, data.exp_year)) {
$('#js-error-message').html('{{ trans('texts.invalid_expiry') }}').fadeIn();
return false;
}
if (!Stripe.card.validateCVC(data.cvc)) {
$('#js-error-message').html('{{ trans('texts.invalid_cvv') }}').fadeIn();
return false;
}
// Disable the submit button to prevent repeated clicks
$form.find('button').prop('disabled', true);
$('#js-error-message').hide();
Stripe.card.createToken(data, stripeResponseHandler); Stripe.card.createToken(data, stripeResponseHandler);
// Prevent the form from submitting with the default action // Prevent the form from submitting with the default action
@ -102,11 +117,20 @@
@endif @endif
@endif @endif
@if (Utils::isNinjaDev())
{{ Former::populateField('first_name', 'Test') }}
{{ Former::populateField('last_name', 'Test') }}
{{ Former::populateField('address1', '350 5th Ave') }}
{{ Former::populateField('city', 'New York') }}
{{ Former::populateField('state', 'NY') }}
{{ Former::populateField('postal_code', '10118') }}
{{ Former::populateField('country_id', 840) }}
@endif
<div class="container"> <div class="container">
<p>&nbsp;</p> <p>&nbsp;</p>
<div id="js-error-message" style="display:none" class="alert alert-danger"></div>
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-body"> <div class="panel-body">
@ -290,14 +314,15 @@
</div> </div>
<p>&nbsp;<br/>&nbsp;</p> <p>&nbsp;</p>
<center> <center>
{!! Button::success(strtoupper(trans('texts.pay_now') . ' - ' . $account->formatMoney($amount, $client, true) )) {!! Button::success(strtoupper(trans('texts.pay_now') . ' - ' . $account->formatMoney($amount, $client, true) ))
->submit() ->submit()
->large() !!} ->large() !!}
</center> </center>
<p>&nbsp;</p>
<div id="js-error-message" style="display:none" class="alert alert-danger"></div>
</div> </div>
</div> </div>

View File

@ -80,9 +80,9 @@ $I->amOnPage('/settings/user_management');
$I->see('Add User'); $I->see('Add User');
//try to logout //try to logout
$I->click('#myAccountButton'); //$I->click('#myAccountButton');
$I->see('Log Out'); //$I->see('Log Out');
$I->click('Log Out'); //$I->click('Log Out');
// Miscellaneous pages // Miscellaneous pages
$I->amOnPage('/terms'); $I->amOnPage('/terms');

View File

@ -67,6 +67,7 @@ class OnlinePaymentCest
$I->amOnPage('/view/' . $invitationKey); $I->amOnPage('/view/' . $invitationKey);
$I->click('Pay Now'); $I->click('Pay Now');
/*
$I->fillField(['name' => 'first_name'], $this->faker->firstName); $I->fillField(['name' => 'first_name'], $this->faker->firstName);
$I->fillField(['name' => 'last_name'], $this->faker->lastName); $I->fillField(['name' => 'last_name'], $this->faker->lastName);
$I->fillField(['name' => 'address1'], $this->faker->streetAddress); $I->fillField(['name' => 'address1'], $this->faker->streetAddress);
@ -75,6 +76,8 @@ class OnlinePaymentCest
$I->fillField(['name' => 'state'], $this->faker->state); $I->fillField(['name' => 'state'], $this->faker->state);
$I->fillField(['name' => 'postal_code'], $this->faker->postcode); $I->fillField(['name' => 'postal_code'], $this->faker->postcode);
$I->selectDropdown($I, 'United States', '.country-select .dropdown-toggle'); $I->selectDropdown($I, 'United States', '.country-select .dropdown-toggle');
*/
$I->fillField('#card_number', '4242424242424242'); $I->fillField('#card_number', '4242424242424242');
$I->fillField('#cvv', '1234'); $I->fillField('#cvv', '1234');
$I->selectOption('#expiration_month', 12); $I->selectOption('#expiration_month', 12);

View File

@ -30,8 +30,8 @@ class TaxRatesCest
$total += round($itemCost * $itemTaxRate / 100, 2); $total += round($itemCost * $itemTaxRate / 100, 2);
$total += round($itemCost * $invoiceTaxRate / 100, 2); $total += round($itemCost * $invoiceTaxRate / 100, 2);
$itemTaxRate = number_format($itemTaxRate, 2); $itemTaxRate = number_format($itemTaxRate, 3);
$invoiceTaxRate = number_format($invoiceTaxRate, 2); $invoiceTaxRate = number_format($invoiceTaxRate, 3);
// create tax rates // create tax rates
$I->amOnPage('/tax_rates/create'); $I->amOnPage('/tax_rates/create');
@ -72,7 +72,7 @@ class TaxRatesCest
$I->selectDropdown($I, $clientEmail, '.client_select .dropdown-toggle'); $I->selectDropdown($I, $clientEmail, '.client_select .dropdown-toggle');
$I->fillField('table.invoice-table tbody tr:nth-child(1) #product_key', $productKey); $I->fillField('table.invoice-table tbody tr:nth-child(1) #product_key', $productKey);
$I->click('table.invoice-table tbody tr:nth-child(1) .tt-selectable'); $I->click('table.invoice-table tbody tr:nth-child(1) .tt-selectable');
$I->selectOption('#taxRateSelect', $invoiceTaxName . ' ' . $invoiceTaxRate . '%'); $I->selectOption('#taxRateSelect', $invoiceTaxName . ' ' . floatval($invoiceTaxRate) . '%');
$I->wait(2); $I->wait(2);
// check total is right before saving // check total is right before saving