diff --git a/app/Http/Controllers/AccountController.php b/app/Http/Controllers/AccountController.php index a0fb51b74654..abefe0b5f745 100644 --- a/app/Http/Controllers/AccountController.php +++ b/app/Http/Controllers/AccountController.php @@ -123,7 +123,8 @@ class AccountController extends BaseController public function getSearchData() { - $data = $this->accountRepo->getSearchData(); + $account = Auth::user()->account; + $data = $this->accountRepo->getSearchData($account); return Response::json($data); } diff --git a/app/Http/Controllers/AppController.php b/app/Http/Controllers/AppController.php index a5e787168357..394323d7420a 100644 --- a/app/Http/Controllers/AppController.php +++ b/app/Http/Controllers/AppController.php @@ -231,7 +231,8 @@ class AppController extends BaseController } Artisan::call('optimize', array('--force' => true)); } 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()); Session::flash('message', trans('texts.processed_updates')); } catch (Exception $e) { - Response::make($e->getMessage(), 500); + Utils::logError($e); + return Response::make($e->getMessage(), 500); } } diff --git a/app/Http/Controllers/PublicClientController.php b/app/Http/Controllers/PublicClientController.php index 93384037bf3b..d067ff38a740 100644 --- a/app/Http/Controllers/PublicClientController.php +++ b/app/Http/Controllers/PublicClientController.php @@ -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) { event(new QuoteInvitationWasViewed($invoice, $invitation)); } else { diff --git a/app/Http/Middleware/Authenticate.php b/app/Http/Middleware/Authenticate.php index 9d5d8549442f..a6d1363e4cdd 100644 --- a/app/Http/Middleware/Authenticate.php +++ b/app/Http/Middleware/Authenticate.php @@ -70,7 +70,7 @@ class Authenticate { } protected function getInvitation($key){ - $invitation = Invitation::where('invitation_key', '=', $key)->first(); + $invitation = Invitation::withTrashed()->where('invitation_key', '=', $key)->first(); if ($invitation && !$invitation->is_deleted) { return $invitation; } diff --git a/app/Listeners/SubscriptionListener.php b/app/Listeners/SubscriptionListener.php index cac483b4d309..fd8c39dba303 100644 --- a/app/Listeners/SubscriptionListener.php +++ b/app/Listeners/SubscriptionListener.php @@ -25,45 +25,45 @@ class SubscriptionListener public function createdClient(ClientWasCreated $event) { $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) { $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) { $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) { $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) { - //$this->checkSubscriptions(ACTIVITY_TYPE_CREATE_CREDIT, $event->credit); + } public function createdVendor(VendorWasCreated $event) { - //$this->checkSubscriptions(ACTIVITY_TYPE_CREATE_VENDOR, $event->vendor); + } 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) { $manager = new Manager(); diff --git a/app/Models/Account.php b/app/Models/Account.php index 368ecac825ab..b2d5a7d22dce 100644 --- a/app/Models/Account.php +++ b/app/Models/Account.php @@ -1023,7 +1023,7 @@ class Account extends Eloquent return true; } - public function showCustomField($field, $entity) + public function showCustomField($field, $entity = false) { if ($this->isPro()) { return $this->$field ? true : false; diff --git a/app/Ninja/Repositories/AccountRepository.php b/app/Ninja/Repositories/AccountRepository.php index ff85efb76eba..0e08fbba5d06 100644 --- a/app/Ninja/Repositories/AccountRepository.php +++ b/app/Ninja/Repositories/AccountRepository.php @@ -70,16 +70,16 @@ class AccountRepository return $account; } - public function getSearchData() + public function getSearchData($account) { - $data = $this->getAccountSearchData(); + $data = $this->getAccountSearchData($account); $data['navigation'] = $this->getNavigationSearchData(); return $data; } - private function getAccountSearchData() + private function getAccountSearchData($account) { $data = [ 'clients' => [], @@ -88,6 +88,14 @@ class AccountRepository '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() ->with('contacts', 'invoices') ->get(); @@ -96,20 +104,38 @@ class AccountRepository if ($client->name) { $data['clients'][] = [ 'value' => $client->name, + 'tokens' => $client->name, '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) { if ($contact->getFullName()) { $data['contacts'][] = [ 'value' => $contact->getDisplayName(), + 'tokens' => $contact->getDisplayName(), 'url' => $client->present()->url, ]; } if ($contact->email) { - $data[trans('texts.contacts')][] = [ + $data['contacts'][] = [ 'value' => $contact->email, + 'tokens' => $contact->email, 'url' => $client->present()->url, ]; } @@ -119,6 +145,7 @@ class AccountRepository $entityType = $invoice->getEntityType(); $data["{$entityType}s"][] = [ 'value' => $invoice->getDisplayName() . ': ' . $client->getDisplayName(), + 'tokens' => $invoice->getDisplayName() . ': ' . $client->getDisplayName(), 'url' => $invoice->present()->url, ]; } @@ -156,6 +183,7 @@ class AccountRepository $features[] = ['new_tax_rate', '/tax_rates/create']; $features[] = ['new_product', '/products/create']; $features[] = ['new_user', '/users/create']; + $features[] = ['custom_fields', '/settings/invoice_settings']; $settings = array_merge(Account::$basicSettings, Account::$advancedSettings); @@ -169,6 +197,7 @@ class AccountRepository foreach ($features as $feature) { $data[] = [ 'value' => trans('texts.' . $feature[0]), + 'tokens' => trans('texts.' . $feature[0]), 'url' => URL::to($feature[1]) ]; } diff --git a/app/Services/InvoiceService.php b/app/Services/InvoiceService.php index c5d6f258e02c..522c1a5dffc3 100644 --- a/app/Services/InvoiceService.php +++ b/app/Services/InvoiceService.php @@ -160,8 +160,8 @@ class InvoiceService extends BaseService ], [ 'invoice_status_name', - function ($model) { - return $model->quote_invoice_id ? link_to("invoices/{$model->quote_invoice_id}/edit", trans('texts.converted'))->toHtml() : self::getStatusLabel($model); + function ($model) use ($entityType) { + 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 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")) { - return "

".trans('texts.overdue')."

"; + $label = $entityType == ENTITY_INVOICE ? trans('texts.overdue') : trans('texts.expired'); + return "

" . $label . "

"; } } diff --git a/composer.json b/composer.json index 45e6e1872640..bc315ba6c285 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ "omnipay/2checkout": "dev-master#e9c079c2dde0d7ba461903b3b7bd5caf6dee1248", "omnipay/gocardless": "dev-master", "omnipay/stripe": "2.3.0", - "laravel/framework": "5.2.*", + "laravel/framework": "5.2.22", "laravelcollective/html": "5.2.*", "laravelcollective/bus": "5.2.*", "symfony/css-selector": "~3.0", diff --git a/composer.lock b/composer.lock index 61af58eb88b9..bd2369f87954 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "e5e8524886bd38794a15e406acc3745a", - "content-hash": "6b3f343959ba3f330c425325574dfe28", + "hash": "a33dce96f4ded3fb269a6d9dcbf24b27", + "content-hash": "f73a83c64422ef3560da4adb988850ae", "packages": [ { "name": "agmscode/omnipay-agms", @@ -123,12 +123,12 @@ "source": { "type": "git", "url": "https://github.com/formers/former.git", - "reference": "795f7b9b200a4ff4a33b37a96eaaab0229e36325" + "reference": "e196c4336db77be97131f6a3b3c3b69b3a22b683" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/formers/former/zipball/795f7b9b200a4ff4a33b37a96eaaab0229e36325", - "reference": "795f7b9b200a4ff4a33b37a96eaaab0229e36325", + "url": "https://api.github.com/repos/formers/former/zipball/e196c4336db77be97131f6a3b3c3b69b3a22b683", + "reference": "e196c4336db77be97131f6a3b3c3b69b3a22b683", "shasum": "" }, "require": { @@ -174,7 +174,7 @@ "foundation", "laravel" ], - "time": "2015-11-05 15:53:52" + "time": "2016-03-02 17:21:21" }, { "name": "anahkiasen/html-object", @@ -381,12 +381,12 @@ "source": { "type": "git", "url": "https://github.com/barryvdh/laravel-ide-helper.git", - "reference": "19553f63e4635480363ff2254350075f285fbbc5" + "reference": "e97ed532f09e290b91ff7713b785ed7ab11d0812" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/19553f63e4635480363ff2254350075f285fbbc5", - "reference": "19553f63e4635480363ff2254350075f285fbbc5", + "url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/e97ed532f09e290b91ff7713b785ed7ab11d0812", + "reference": "e97ed532f09e290b91ff7713b785ed7ab11d0812", "shasum": "" }, "require": { @@ -436,7 +436,7 @@ "phpstorm", "sublime" ], - "time": "2016-03-02 10:03:09" + "time": "2016-03-03 14:38:04" }, { "name": "cardgate/omnipay-cardgate", @@ -579,7 +579,7 @@ "laravel" ], "abandoned": "OpenSkill/Datatable", - "time": "2015-11-23 21:33:41" + "time": "2015-04-29 07:00:36" }, { "name": "classpreloader/classpreloader", @@ -2000,16 +2000,16 @@ }, { "name": "guzzlehttp/promises", - "version": "1.0.3", + "version": "1.1.0", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "b1e1c0d55f8083c71eda2c28c12a228d708294ea" + "reference": "bb9024c526b22f3fe6ae55a561fd70653d470aa8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/b1e1c0d55f8083c71eda2c28c12a228d708294ea", - "reference": "b1e1c0d55f8083c71eda2c28c12a228d708294ea", + "url": "https://api.github.com/repos/guzzle/promises/zipball/bb9024c526b22f3fe6ae55a561fd70653d470aa8", + "reference": "bb9024c526b22f3fe6ae55a561fd70653d470aa8", "shasum": "" }, "require": { @@ -2047,7 +2047,7 @@ "keywords": [ "promise" ], - "time": "2015-10-15 22:28:00" + "time": "2016-03-08 01:15:46" }, { "name": "guzzlehttp/psr7", @@ -2975,16 +2975,16 @@ }, { "name": "league/flysystem", - "version": "1.0.17", + "version": "1.0.20", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem.git", - "reference": "02f5b6c9a8b9278c8381e3361e7bd9d641c740ca" + "reference": "e87a786e3ae12a25cf78a71bb07b4b384bfaa83a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/02f5b6c9a8b9278c8381e3361e7bd9d641c740ca", - "reference": "02f5b6c9a8b9278c8381e3361e7bd9d641c740ca", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/e87a786e3ae12a25cf78a71bb07b4b384bfaa83a", + "reference": "e87a786e3ae12a25cf78a71bb07b4b384bfaa83a", "shasum": "" }, "require": { @@ -3054,7 +3054,7 @@ "sftp", "storage" ], - "time": "2016-02-19 15:35:38" + "time": "2016-03-14 21:54:11" }, { "name": "league/fractal", @@ -3587,16 +3587,16 @@ }, { "name": "monolog/monolog", - "version": "1.18.0", + "version": "1.18.1", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "e19b764b5c855580e8ffa7e615f72c10fd2f99cc" + "reference": "a5f2734e8c16f3aa21b3da09715d10e15b4d2d45" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/e19b764b5c855580e8ffa7e615f72c10fd2f99cc", - "reference": "e19b764b5c855580e8ffa7e615f72c10fd2f99cc", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/a5f2734e8c16f3aa21b3da09715d10e15b4d2d45", + "reference": "a5f2734e8c16f3aa21b3da09715d10e15b4d2d45", "shasum": "" }, "require": { @@ -3661,7 +3661,7 @@ "logging", "psr-3" ], - "time": "2016-03-01 18:00:40" + "time": "2016-03-13 16:08:35" }, { "name": "mtdowling/cron-expression", @@ -3866,16 +3866,16 @@ }, { "name": "omnipay/authorizenet", - "version": "v2.3.0", + "version": "2.3.1", "source": { "type": "git", "url": "https://github.com/thephpleague/omnipay-authorizenet.git", - "reference": "142a95f550a5320db09e66019ecf5c8b8c3885b9" + "reference": "e2e813b0b6306ef97b8763037f05476456546b3e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/omnipay-authorizenet/zipball/142a95f550a5320db09e66019ecf5c8b8c3885b9", - "reference": "142a95f550a5320db09e66019ecf5c8b8c3885b9", + "url": "https://api.github.com/repos/thephpleague/omnipay-authorizenet/zipball/e2e813b0b6306ef97b8763037f05476456546b3e", + "reference": "e2e813b0b6306ef97b8763037f05476456546b3e", "shasum": "" }, "require": { @@ -3921,7 +3921,7 @@ "pay", "payment" ], - "time": "2015-07-15 18:11:17" + "time": "2016-03-10 11:35:24" }, { "name": "omnipay/bitpay", @@ -3929,12 +3929,12 @@ "source": { "type": "git", "url": "https://github.com/thephpleague/omnipay-bitpay.git", - "reference": "e659f0e993c586cb36acafaf50835570b4a16eb2" + "reference": "cf813f1d5436a1d2f942d3df6666695d1e2b5280" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/omnipay-bitpay/zipball/e659f0e993c586cb36acafaf50835570b4a16eb2", - "reference": "e659f0e993c586cb36acafaf50835570b4a16eb2", + "url": "https://api.github.com/repos/thephpleague/omnipay-bitpay/zipball/cf813f1d5436a1d2f942d3df6666695d1e2b5280", + "reference": "cf813f1d5436a1d2f942d3df6666695d1e2b5280", "shasum": "" }, "require": { @@ -3979,7 +3979,7 @@ "pay", "payment" ], - "time": "2015-03-23 14:18:26" + "time": "2016-03-10 03:16:04" }, { "name": "omnipay/buckaroo", @@ -5536,16 +5536,16 @@ }, { "name": "paragonie/random_compat", - "version": "v1.2.1", + "version": "v1.2.2", "source": { "type": "git", "url": "https://github.com/paragonie/random_compat.git", - "reference": "f078eba3bcf140fd69b5fcc3ea5ac809abf729dc" + "reference": "b3313b618f4edd76523572531d5d7e22fe747430" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/paragonie/random_compat/zipball/f078eba3bcf140fd69b5fcc3ea5ac809abf729dc", - "reference": "f078eba3bcf140fd69b5fcc3ea5ac809abf729dc", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/b3313b618f4edd76523572531d5d7e22fe747430", + "reference": "b3313b618f4edd76523572531d5d7e22fe747430", "shasum": "" }, "require": { @@ -5580,7 +5580,7 @@ "pseudorandom", "random" ], - "time": "2016-02-29 17:25:04" + "time": "2016-03-11 19:54:08" }, { "name": "patricktalmadge/bootstrapper", @@ -5836,16 +5836,16 @@ }, { "name": "psy/psysh", - "version": "v0.7.1", + "version": "v0.7.2", "source": { "type": "git", "url": "https://github.com/bobthecow/psysh.git", - "reference": "5e8cedbe0a3681f18782594eefc78423f8401fc8" + "reference": "e64e10b20f8d229cac76399e1f3edddb57a0f280" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bobthecow/psysh/zipball/5e8cedbe0a3681f18782594eefc78423f8401fc8", - "reference": "5e8cedbe0a3681f18782594eefc78423f8401fc8", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/e64e10b20f8d229cac76399e1f3edddb57a0f280", + "reference": "e64e10b20f8d229cac76399e1f3edddb57a0f280", "shasum": "" }, "require": { @@ -5904,20 +5904,20 @@ "interactive", "shell" ], - "time": "2016-02-27 18:59:18" + "time": "2016-03-09 05:03:14" }, { "name": "samvaughton/omnipay-barclays-epdq", - "version": "2.1.1", + "version": "2.2.0", "source": { "type": "git", "url": "https://github.com/samvaughton/omnipay-barclays-epdq.git", - "reference": "f971de37aa40c72cc58f02d05f540a93b2c5958e" + "reference": "b7f9263afa73b8e6c3c5e8bb2bf04a82548a41da" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/samvaughton/omnipay-barclays-epdq/zipball/f971de37aa40c72cc58f02d05f540a93b2c5958e", - "reference": "f971de37aa40c72cc58f02d05f540a93b2c5958e", + "url": "https://api.github.com/repos/samvaughton/omnipay-barclays-epdq/zipball/b7f9263afa73b8e6c3c5e8bb2bf04a82548a41da", + "reference": "b7f9263afa73b8e6c3c5e8bb2bf04a82548a41da", "shasum": "" }, "require": { @@ -5966,7 +5966,7 @@ "pay", "payment" ], - "time": "2015-05-07 14:45:43" + "time": "2016-03-03 14:40:27" }, { "name": "simshaun/recurr", @@ -6716,7 +6716,7 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.1.0", + "version": "v1.1.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", @@ -6775,16 +6775,16 @@ }, { "name": "symfony/polyfill-php54", - "version": "v1.1.0", + "version": "v1.1.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php54.git", - "reference": "74663d5a2ff3c530c1bc0571500e0feec9094054" + "reference": "9ba741ca01c77282ecf5796c2c1d667f03454ffb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php54/zipball/74663d5a2ff3c530c1bc0571500e0feec9094054", - "reference": "74663d5a2ff3c530c1bc0571500e0feec9094054", + "url": "https://api.github.com/repos/symfony/polyfill-php54/zipball/9ba741ca01c77282ecf5796c2c1d667f03454ffb", + "reference": "9ba741ca01c77282ecf5796c2c1d667f03454ffb", "shasum": "" }, "require": { @@ -6829,11 +6829,11 @@ "portable", "shim" ], - "time": "2016-01-20 09:13:37" + "time": "2016-01-25 19:13:00" }, { "name": "symfony/polyfill-php55", - "version": "v1.1.0", + "version": "v1.1.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php55.git", @@ -6889,7 +6889,7 @@ }, { "name": "symfony/polyfill-php56", - "version": "v1.1.0", + "version": "v1.1.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php56.git", @@ -6945,7 +6945,7 @@ }, { "name": "symfony/polyfill-util", - "version": "v1.1.0", + "version": "v1.1.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-util.git", @@ -8211,41 +8211,42 @@ }, { "name": "codeception/codeception", - "version": "2.1.6", + "version": "2.1.7", "source": { "type": "git", "url": "https://github.com/Codeception/Codeception.git", - "reference": "b199941f5e59d1e7fd32d78296c8ab98db873d89" + "reference": "65971b0dee4972710365b6102154cd412a9bf7b1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Codeception/Codeception/zipball/b199941f5e59d1e7fd32d78296c8ab98db873d89", - "reference": "b199941f5e59d1e7fd32d78296c8ab98db873d89", + "url": "https://api.github.com/repos/Codeception/Codeception/zipball/65971b0dee4972710365b6102154cd412a9bf7b1", + "reference": "65971b0dee4972710365b6102154cd412a9bf7b1", "shasum": "" }, "require": { "ext-json": "*", "ext-mbstring": "*", - "facebook/webdriver": ">=1.0.1", + "facebook/webdriver": ">=1.0.1 <2.0", "guzzlehttp/guzzle": ">=4.1.4 <7.0", "guzzlehttp/psr7": "~1.0", - "php": ">=5.4.0", - "phpunit/phpunit": "~4.8.0", - "symfony/browser-kit": ">=2.4|<3.1", - "symfony/console": ">=2.4|<3.1", - "symfony/css-selector": ">=2.4|<3.1", - "symfony/dom-crawler": ">=2.4|<3.1", - "symfony/event-dispatcher": ">=2.4|<3.1", - "symfony/finder": ">=2.4|<3.1", - "symfony/yaml": ">=2.4|<3.1" + "php": ">=5.4.0 <8.0", + "phpunit/php-code-coverage": ">=2.1.3", + "phpunit/phpunit": ">4.8.20 <6.0", + "symfony/browser-kit": ">=2.5 <3.1", + "symfony/console": ">=2.5 <3.1", + "symfony/css-selector": ">=2.5 <3.1", + "symfony/dom-crawler": ">=2.5 <3.1", + "symfony/event-dispatcher": ">=2.5 <3.1", + "symfony/finder": ">=2.5 <3.1", + "symfony/yaml": ">=2.5 <3.1" }, "require-dev": { "codeception/specify": "~0.3", - "facebook/php-sdk-v4": "~4.0", + "facebook/php-sdk-v4": "~5.0", "flow/jsonpath": "~0.2", "monolog/monolog": "~1.8", "pda/pheanstalk": "~2.0", - "videlalvaro/php-amqplib": "~2.4" + "php-amqplib/php-amqplib": "~2.4" }, "suggest": { "codeception/phpbuiltinserver": "Extension to start and stop PHP built-in web server for your tests", @@ -8287,7 +8288,7 @@ "functional testing", "unit testing" ], - "time": "2016-02-09 22:27:48" + "time": "2016-03-12 01:15:25" }, { "name": "doctrine/instantiator", @@ -8854,16 +8855,16 @@ }, { "name": "phpunit/phpunit", - "version": "4.8.23", + "version": "4.8.24", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "6e351261f9cd33daf205a131a1ba61c6d33bd483" + "reference": "a1066c562c52900a142a0e2bbf0582994671385e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/6e351261f9cd33daf205a131a1ba61c6d33bd483", - "reference": "6e351261f9cd33daf205a131a1ba61c6d33bd483", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a1066c562c52900a142a0e2bbf0582994671385e", + "reference": "a1066c562c52900a142a0e2bbf0582994671385e", "shasum": "" }, "require": { @@ -8922,7 +8923,7 @@ "testing", "xunit" ], - "time": "2016-02-11 14:56:33" + "time": "2016-03-14 06:16:08" }, { "name": "phpunit/phpunit-mock-objects", diff --git a/database/migrations/2016_03_14_214710_add_support_three_decimal_taxes.php b/database/migrations/2016_03_14_214710_add_support_three_decimal_taxes.php new file mode 100644 index 000000000000..af35fc927564 --- /dev/null +++ b/database/migrations/2016_03_14_214710_add_support_three_decimal_taxes.php @@ -0,0 +1,28 @@ +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(); + }); + } +} diff --git a/public/built.js b/public/built.js index 5e28b8fb3f18..9d1e0d3a3ee2 100644 --- a/public/built.js +++ b/public/built.js @@ -31259,10 +31259,10 @@ NINJA.invoiceColumns = function(invoice) columns.push("*") - if (account.custom_invoice_item_label1) { + if (invoice.is_pro && account.custom_invoice_item_label1) { columns.push("10%"); } - if (account.custom_invoice_item_label2) { + if (invoice.is_pro && account.custom_invoice_item_label2) { columns.push("10%"); } @@ -31314,10 +31314,10 @@ NINJA.invoiceLines = function(invoice) { 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']}); } - 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']}); } @@ -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:["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 || ' '}); } - 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:["cost", rowStyle], text:cost}); diff --git a/public/css/built.css b/public/css/built.css index d4b3a8204e6b..c932978d3157 100644 --- a/public/css/built.css +++ b/public/css/built.css @@ -2216,7 +2216,8 @@ th:last-child { } 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 { vertical-align: middle; border-top: none; @@ -2910,8 +2911,24 @@ box-shadow: 0px 0px 15px 0px rgba(0, 5, 5, 0.2); .large-dialog { 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; } } diff --git a/public/css/style.css b/public/css/style.css index e469e9418d83..7480cbe0f2d1 100644 --- a/public/css/style.css +++ b/public/css/style.css @@ -89,7 +89,8 @@ th:last-child { } 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 { vertical-align: middle; border-top: none; @@ -783,8 +784,24 @@ box-shadow: 0px 0px 15px 0px rgba(0, 5, 5, 0.2); .large-dialog { 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; } } diff --git a/public/js/pdf.pdfmake.js b/public/js/pdf.pdfmake.js index 3a9f40280c74..d6e7906ca6d6 100644 --- a/public/js/pdf.pdfmake.js +++ b/public/js/pdf.pdfmake.js @@ -267,10 +267,10 @@ NINJA.invoiceColumns = function(invoice) columns.push("*") - if (account.custom_invoice_item_label1) { + if (invoice.is_pro && account.custom_invoice_item_label1) { columns.push("10%"); } - if (account.custom_invoice_item_label2) { + if (invoice.is_pro && account.custom_invoice_item_label2) { columns.push("10%"); } @@ -322,10 +322,10 @@ NINJA.invoiceLines = function(invoice) { 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']}); } - 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']}); } @@ -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:["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 || ' '}); } - 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:["cost", rowStyle], text:cost}); diff --git a/resources/lang/da/texts.php b/resources/lang/da/texts.php index 35a559ac6ade..e3fe7a081917 100644 --- a/resources/lang/da/texts.php +++ b/resources/lang/da/texts.php @@ -942,7 +942,7 @@ return array( 'notes' => 'Notes', 'invoice_will_create' => 'client 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', 'secret_key' => 'Secret Key', diff --git a/resources/lang/de/texts.php b/resources/lang/de/texts.php index 80289bfa29f0..a3ea1ac658f9 100644 --- a/resources/lang/de/texts.php +++ b/resources/lang/de/texts.php @@ -943,7 +943,7 @@ return array( 'notes' => 'Notes', 'invoice_will_create' => 'client 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', 'secret_key' => 'Secret Key', diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php index 1e83a7821bed..e40467673c62 100644 --- a/resources/lang/en/texts.php +++ b/resources/lang/en/texts.php @@ -161,7 +161,7 @@ $LANG = array( 'work_email' => 'Email', 'language_id' => 'Language', 'timezone_id' => 'Timezone', - 'date_format_id' => 'Date format', + 'date_format_id' => 'Date Format', 'datetime_format_id' => 'Date/Time Format', 'users' => 'Users', 'localization' => 'Localization', @@ -826,7 +826,7 @@ $LANG = array( 'notes' => 'Notes', 'invoice_will_create' => 'client 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', 'secret_key' => 'Secret Key', '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', 'setup_account' => 'Setup Account', 'import_expenses' => 'Import Expenses', - 'bank_id' => 'bank', + 'bank_id' => 'Bank', 'integration_type' => 'Integration Type', 'updated_bank_account' => 'Successfully updated 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.', '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.', + + '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; diff --git a/resources/lang/es/texts.php b/resources/lang/es/texts.php index 1b1f27947c46..56fb42534f5c 100644 --- a/resources/lang/es/texts.php +++ b/resources/lang/es/texts.php @@ -920,7 +920,7 @@ return array( 'notes' => 'Notes', 'invoice_will_create' => 'client 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', 'secret_key' => 'Secret Key', diff --git a/resources/lang/fr/texts.php b/resources/lang/fr/texts.php index 1572eb219137..2bc358e6a822 100644 --- a/resources/lang/fr/texts.php +++ b/resources/lang/fr/texts.php @@ -934,7 +934,7 @@ return array( 'notes' => 'Notes', 'invoice_will_create' => 'client 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', 'secret_key' => 'Secret Key', diff --git a/resources/lang/it/texts.php b/resources/lang/it/texts.php index 5c358ae62627..acc4cdeebab3 100644 --- a/resources/lang/it/texts.php +++ b/resources/lang/it/texts.php @@ -937,7 +937,7 @@ return array( 'notes' => 'Notes', 'invoice_will_create' => 'client 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', 'secret_key' => 'Secret Key', diff --git a/resources/lang/lt/texts.php b/resources/lang/lt/texts.php index 4dc55e9e5e4f..584f7776b435 100644 --- a/resources/lang/lt/texts.php +++ b/resources/lang/lt/texts.php @@ -944,7 +944,7 @@ return array( 'notes' => 'Notes', 'invoice_will_create' => 'client 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', 'secret_key' => 'Secret Key', diff --git a/resources/lang/nb_NO/texts.php b/resources/lang/nb_NO/texts.php index 875df81d4639..afc916a5def3 100644 --- a/resources/lang/nb_NO/texts.php +++ b/resources/lang/nb_NO/texts.php @@ -942,7 +942,7 @@ return array( 'notes' => 'Notes', 'invoice_will_create' => 'client 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', 'secret_key' => 'Secret Key', diff --git a/resources/lang/nl/texts.php b/resources/lang/nl/texts.php index 9794f7c0089b..db06a981f4f1 100644 --- a/resources/lang/nl/texts.php +++ b/resources/lang/nl/texts.php @@ -937,7 +937,7 @@ return array( 'notes' => 'Notities', 'invoice_will_create' => 'klant 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', 'secret_key' => 'Secret Key', diff --git a/resources/lang/sv/texts.php b/resources/lang/sv/texts.php index 8f72d9bb40d3..5d526092c4a8 100644 --- a/resources/lang/sv/texts.php +++ b/resources/lang/sv/texts.php @@ -939,7 +939,7 @@ return array( 'notes' => 'Notes', 'invoice_will_create' => 'client 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', 'secret_key' => 'Secret Key', diff --git a/resources/views/accounts/account_gateway.blade.php b/resources/views/accounts/account_gateway.blade.php index eda78b3c000c..f07b62f2ffb7 100644 --- a/resources/views/accounts/account_gateway.blade.php +++ b/resources/views/accounts/account_gateway.blade.php @@ -64,11 +64,11 @@ && isset($_ENV['DWOLLA_KEY']) && isset($_ENV['DWOLLA_SECRET'])) {{-- do nothing --}} @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') {!! Former::text($gateway->id.'_'.$field)->label('API '. ucfirst(Utils::toSpaceCase($field))) !!} @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 @endforeach diff --git a/resources/views/accounts/customize_design.blade.php b/resources/views/accounts/customize_design.blade.php index 2f60a9dd97e4..439ef1d4acef 100644 --- a/resources/views/accounts/customize_design.blade.php +++ b/resources/views/accounts/customize_design.blade.php @@ -153,7 +153,6 @@ @if (isset($sampleInvoice) && $sampleInvoice) var sample = {!! $sampleInvoice->toJSON() !!} - console.log(sample); $('#sampleData').show().html(prettyJson(sample)); @endif }); @@ -222,6 +221,9 @@ {!! trans('texts.customize_help') !!} + @if (empty($sampleInvoice)) +
{{ trans('texts.create_invoice_for_sample') }}
+ @endif