diff --git a/.env.development.php b/.env.development.php deleted file mode 100644 index ecc9ff2b5a4a..000000000000 --- a/.env.development.php +++ /dev/null @@ -1,9 +0,0 @@ - '', - //'ANALYTICS_KEY' => '', - 'NINJA_DEV' => true, - -); diff --git a/.gitignore b/.gitignore index 294af63cfb98..76f31224a734 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ /ninja.sublime-project /ninja.sublime-workspace /tests/_log +.env.development.php .idea .project /nbproject/private/ \ No newline at end of file diff --git a/README.md b/README.md index 4e7501b1920f..862362004e69 100644 --- a/README.md +++ b/README.md @@ -3,13 +3,13 @@ ### [https://www.invoiceninja.com](https://www.invoiceninja.com) -**If you'd like to use our code to sell your own invoicing app get in touch.** +If you'd like to use our code to sell your own invoicing app get in touch. ### Introduction Most online invoicing sites are expensive. They shouldn't be. The aim of this project is to provide a free, open-source alternative. Additionally, the hope is the codebase will serve as a sample site for Laravel as well as other JavaScript technologies. -[This guide](http://hillelcoren.com/invoice-ninja/self-hosting/) is the simplest way to setup the site. The high level instructions for setting up the site using Git are below but there's also a more detailed [setup guide](http://hillelcoren.com/invoice-ninja/laravel-ubuntu-virtualbox/). To deploy the app with [Docker](http://www.docker.com/) you can use [this project](https://github.com/rollbrettler/Dockerfiles/tree/master/invoice-ninja). +To setup the site you can either use this [zip file](http://hillelcoren.com/invoice-ninja/self-hosting/) (easier to setup) or checkout the code from GitHub following the instructions below (easier to stay up to date). There's also a more detailed setup guide [available here](http://hillelcoren.com/invoice-ninja/laravel-ubuntu-virtualbox/). To deploy the app with [Docker](http://www.docker.com/) you can use [this project](https://github.com/rollbrettler/Dockerfiles/tree/master/invoice-ninja). To connect follow [@invoiceninja](https://twitter.com/invoiceninja) or join the [Facebook Group](https://www.facebook.com/invoiceninja). For discussion of the code please use the [Google Group](https://groups.google.com/d/forum/invoiceninja). @@ -18,6 +18,7 @@ If you'd like to translate the site please use [caouecs/Laravel4-long](https://g Site design by [kantorp-wegl.in](http://kantorp-wegl.in/) ### Features + * Core application built using Laravel 4.1 * Invoice PDF generation directly in the browser * Integrates with many payment providers @@ -62,6 +63,27 @@ Configure development/config/database.php and development/config/mail.php and in Add public/ to your web server root +### Deleveloper Notes + +* If you make any changes to the JavaScript files you need to run grunt to create the built files. See Gruntfile.js for more details. +* The lookup tables are cached in memory (ie, Currencies, Timezones, Languages, etc). If you add a record to the database you need to clear the cache by uncommenting Cache::flush() in app/routes.php. +* If you run into any composer errors try running composer dump-autoload. + +### Ubuntu Notes + + # Install php-mcrypt + apt-get install php5-mcrypt + sudo php5enmod mcrypt + + # Install Composer + curl -sS https://getcomposer.org/installer | php + sudo mv composer.phar /usr/local/bin/composer + + # Install Bower + sudo apt-get install npm nodejs-legacy + sudo npm install -g bower + sudo ln -s /usr/local/lib/node_modules/bower/bin/bower /usr/local/bin/bower + ### Frameworks/Libraries * [laravel/laravel](https://github.com/laravel/laravel) - A PHP Framework For Web Artisans * [twbs/bootstrap](https://github.com/twbs/bootstrap) - Sleek, intuitive, and powerful front-end framework for faster and easier web development. @@ -86,24 +108,9 @@ Add public/ to your web server root * [briannesbitt/Carbon](https://github.com/briannesbitt/Carbon) - A simple API extension for DateTime with PHP 5.3+ * [thomaspark/bootswatch](https://github.com/thomaspark/bootswatch) - Themes for Bootstrap * [mozilla/pdf.js](https://github.com/mozilla/pdf.js) - PDF Reader in JavaScript -* [nnnick/Chart.js](https://github.com/nnnick/Chart.js) - Simple HTML5 Charts using the tag +* [nnnick/Chart.js](https://github.com/nnnick/Chart.js) - Simple HTML5 Charts using the canvas tag * [josscrowcroft/accounting.js](https://github.com/josscrowcroft/accounting.js) - A lightweight JavaScript library for number, money and currency formatting * [jashkenas/underscore](https://github.com/jashkenas/underscore) - JavaScript's utility _ belt * [caouecs/Laravel4-long](https://github.com/caouecs/Laravel4-lang) - List of languages ​​for Laravel4 * [calvinfroedge/PHP-Payments](https://github.com/calvinfroedge/PHP-Payments) - A uniform payments interface for PHP -* [bgrins/spectrum](https://github.com/bgrins/spectrum) - The No Hassle JavaScript Colorpicker - -### Ubuntu Notes - - # Install php-mcrypt - apt-get install php5-mcrypt - sudo php5enmod mcrypt - - # Install Composer - curl -sS https://getcomposer.org/installer | php - sudo mv composer.phar /usr/local/bin/composer - - # Install Bower - sudo apt-get install npm nodejs-legacy - sudo npm install -g bower - sudo ln -s /usr/local/lib/node_modules/bower/bin/bower /usr/local/bin/bower +* [bgrins/spectrum](https://github.com/bgrins/spectrum) - The No Hassle JavaScript Colorpicker \ No newline at end of file diff --git a/app/config/app.php b/app/config/app.php index 3148501412d4..601f4ed202ad 100755 --- a/app/config/app.php +++ b/app/config/app.php @@ -26,7 +26,7 @@ return array( | */ - 'url' => 'http://www.invoiceninja.com', + 'url' => 'https://www.invoiceninja.com', /* |-------------------------------------------------------------------------- diff --git a/app/controllers/AccountController.php b/app/controllers/AccountController.php index 2b7cd08e26d8..ed307aaf76b7 100755 --- a/app/controllers/AccountController.php +++ b/app/controllers/AccountController.php @@ -19,6 +19,49 @@ class AccountController extends \BaseController { $this->contactMailer = $contactMailer; } + public function install() + { + if (!Utils::isNinja() && !Schema::hasTable('accounts')) { + try { + Artisan::call('migrate'); + Artisan::call('db:seed'); + } catch (Exception $e) { + Response::make($e->getMessage(), 500); + } + } + + return Redirect::to('/'); + } + + public function update() + { + if (!Utils::isNinja()) { + try { + Artisan::call('migrate'); + } catch (Exception $e) { + Response::make($e->getMessage(), 500); + } + } + + return Redirect::to('/'); + } + + public function reset() + { + if (Utils::isNinjaDev()) { + Confide::logout(); + try { + Artisan::call('migrate:reset'); + Artisan::call('migrate'); + Artisan::call('db:seed'); + } catch (Exception $e) { + Response::make($e->getMessage(), 500); + } + } + + return Redirect::to('/'); + } + public function getStarted() { if (Auth::check()) @@ -92,6 +135,7 @@ class AccountController extends \BaseController { 'datetimeFormats' => DatetimeFormat::remember(DEFAULT_QUERY_CACHE)->get(), 'currencies' => Currency::remember(DEFAULT_QUERY_CACHE)->orderBy('name')->get(), 'languages' => Language::remember(DEFAULT_QUERY_CACHE)->orderBy('name')->get(), + 'showUser' => Auth::user()->id === Auth::user()->account->users()->first()->id, ]; return View::make('accounts.details', $data); @@ -623,12 +667,13 @@ class AccountController extends \BaseController { } else { - $account = Account::findOrFail(Auth::user()->account_id); + $account = Account::with('account_gateways')->findOrFail(Auth::user()->account_id); if ($gatewayId) { $accountGateway = AccountGateway::createNew(); $accountGateway->gateway_id = $gatewayId; + $isMasked = false; $config = new stdClass; foreach ($fields as $field => $details) @@ -637,27 +682,35 @@ class AccountController extends \BaseController { if ($value && $value === str_repeat('*', strlen($value))) { - Session::flash('error', trans('validation.notmasked')); - return Redirect::to('company/payments'); + $isMasked = true; } $config->$field = $value; } - $cardCount = 0; - if ($creditcards) - { - foreach($creditcards as $card => $value) - { - $cardCount += intval($value); - } - } - - $accountGateway->config = json_encode($config); - $accountGateway->accepted_credit_cards = $cardCount; + $cardCount = 0; + if ($creditcards) + { + foreach($creditcards as $card => $value) + { + $cardCount += intval($value); + } + } + + if ($isMasked && count($account->account_gateways)) + { + $currentGateway = $account->account_gateways[0]; + $currentGateway->accepted_credit_cards = $cardCount; + $currentGateway->save(); + } + else + { + $accountGateway->config = json_encode($config); + $accountGateway->accepted_credit_cards = $cardCount; - $account->account_gateways()->delete(); - $account->account_gateways()->save($accountGateway); + $account->account_gateways()->delete(); + $account->account_gateways()->save($accountGateway); + } Session::flash('message', trans('texts.updated_settings')); } @@ -674,9 +727,15 @@ class AccountController extends \BaseController { { $rules = array( 'name' => 'required', - 'email' => 'email|required|unique:users,email,' . Auth::user()->id . ',id' ); + $user = Auth::user()->account->users()->first(); + + if (Auth::user()->id === $user->id) + { + $rules['email'] = 'email|required|unique:users,email,' . $user->id . ',id'; + } + $validator = Validator::make(Input::all(), $rules); if ($validator->fails()) @@ -706,13 +765,15 @@ class AccountController extends \BaseController { $account->language_id = Input::get('language_id') ? Input::get('language_id') : 1; // English $account->save(); - $user = Auth::user(); - $user->first_name = trim(Input::get('first_name')); - $user->last_name = trim(Input::get('last_name')); - $user->username = trim(Input::get('email')); - $user->email = trim(strtolower(Input::get('email'))); - $user->phone = trim(Input::get('phone')); - $user->save(); + if (Auth::user()->id === $user->id) + { + $user->first_name = trim(Input::get('first_name')); + $user->last_name = trim(Input::get('last_name')); + $user->username = trim(Input::get('email')); + $user->email = trim(strtolower(Input::get('email'))); + $user->phone = trim(Input::get('phone')); + $user->save(); + } /* Logo image file */ if ($file = Input::file('logo')) @@ -797,4 +858,14 @@ class AccountController extends \BaseController { return "{$user->first_name} {$user->last_name}"; } + + public function cancelAccount() + { + $account = Auth::user()->account; + $account->forceDelete(); + + Confide::logout(); + + return Redirect::to('/')->with('clearGuestKey', true); + } } \ No newline at end of file diff --git a/app/controllers/ClientController.php b/app/controllers/ClientController.php index 6acbb50c80b4..a01c93d40e6a 100755 --- a/app/controllers/ClientController.php +++ b/app/controllers/ClientController.php @@ -207,12 +207,12 @@ class ClientController extends \BaseController { $client->city = trim(Input::get('city')); $client->state = trim(Input::get('state')); $client->postal_code = trim(Input::get('postal_code')); - $client->country_id = Input::get('country_id') ? Input::get('country_id') : null; + $client->country_id = Input::get('country_id') ? : null; $client->private_notes = trim(Input::get('private_notes')); - $client->size_id = Input::get('size_id') ? Input::get('size_id') : null; - $client->industry_id = Input::get('industry_id') ? Input::get('industry_id') : null; - $client->currency_id = Input::get('currency_id') ? Input::get('currency_id') : 1; - $client->payment_terms = Input::get('payment_terms'); + $client->size_id = Input::get('size_id') ? : null; + $client->industry_id = Input::get('industry_id') ? : null; + $client->currency_id = Input::get('currency_id') ? : 1; + $client->payment_terms = Input::get('payment_terms') ? : 0; $client->website = trim(Input::get('website')); $client->save(); diff --git a/app/controllers/DashboardController.php b/app/controllers/DashboardController.php index 4e95368da20b..a1d7a6f220fe 100644 --- a/app/controllers/DashboardController.php +++ b/app/controllers/DashboardController.php @@ -15,7 +15,7 @@ class DashboardController extends \BaseController { ->leftJoin('clients', 'accounts.id', '=', 'clients.account_id') ->leftJoin('invoices', 'clients.id', '=', 'invoices.client_id') ->where('accounts.id', '=', Auth::user()->account_id) - ->where('clients.deleted_at', '=', null) + ->where('clients.is_deleted', '=', false) ->groupBy('accounts.id') ->first(); @@ -25,7 +25,7 @@ class DashboardController extends \BaseController { ->select($select) ->leftJoin('clients', 'accounts.id', '=', 'clients.account_id') ->where('accounts.id', '=', Auth::user()->account_id) - ->where('clients.deleted_at', '=', null) + ->where('clients.is_deleted', '=', false) ->groupBy('accounts.id') ->first(); @@ -37,6 +37,7 @@ class DashboardController extends \BaseController { ->where('balance', '>', 0) ->where('is_recurring', '=', false) ->where('is_quote', '=', false) + ->where('is_deleted', '=', false) ->orderBy('due_date', 'asc')->take(6)->get(); $upcoming = Invoice::scope() @@ -44,6 +45,7 @@ class DashboardController extends \BaseController { ->where('balance', '>', 0) ->where('is_recurring', '=', false) ->where('is_quote', '=', false) + ->where('is_deleted', '=', false) ->orderBy('due_date', 'asc')->take(6)->get(); $data = [ diff --git a/app/controllers/PaymentController.php b/app/controllers/PaymentController.php index 6bbb69f679d9..da6327963b07 100755 --- a/app/controllers/PaymentController.php +++ b/app/controllers/PaymentController.php @@ -122,12 +122,10 @@ class PaymentController extends \BaseController $gateway->$function($val); } - /* - if (!Utils::isProd()) + if (Utils::isNinjaDev()) { $gateway->setTestMode(true); - } - */ + } return $gateway; } diff --git a/app/database/migrations/2013_11_05_180133_confide_setup_users_table.php b/app/database/migrations/2013_11_05_180133_confide_setup_users_table.php index 3ddc66d16b89..7412ebe74560 100755 --- a/app/database/migrations/2013_11_05_180133_confide_setup_users_table.php +++ b/app/database/migrations/2013_11_05_180133_confide_setup_users_table.php @@ -132,19 +132,19 @@ class ConfideSetupUsersTable extends Migration { $t->timestamps(); $t->softDeletes(); - $t->string('name'); + $t->string('name')->nullable(); $t->string('ip'); $t->string('account_key')->unique(); $t->timestamp('last_login'); - $t->string('address1'); - $t->string('address2'); - $t->string('city'); - $t->string('state'); - $t->string('postal_code'); + $t->string('address1')->nullable(); + $t->string('address2')->nullable(); + $t->string('city')->nullable(); + $t->string('state')->nullable(); + $t->string('postal_code')->nullable(); $t->unsignedInteger('country_id')->nullable(); - $t->text('invoice_terms'); - $t->text('email_footer'); + $t->text('invoice_terms')->nullable(); + $t->text('email_footer')->nullable(); $t->unsignedInteger('industry_id')->nullable(); $t->unsignedInteger('size_id')->nullable(); @@ -177,16 +177,16 @@ class ConfideSetupUsersTable extends Migration { $t->timestamps(); $t->softDeletes(); - $t->string('first_name'); - $t->string('last_name'); - $t->string('phone'); + $t->string('first_name')->nullable(); + $t->string('last_name')->nullable(); + $t->string('phone')->nullable(); $t->string('username')->unique(); - $t->string('email'); + $t->string('email')->nullable(); $t->string('password'); $t->string('confirmation_code'); $t->boolean('registered')->default(false); $t->boolean('confirmed')->default(false); - $t->integer('theme_id'); + $t->integer('theme_id')->nullable(); $t->boolean('notify_sent')->default(true); $t->boolean('notify_viewed')->default(false); @@ -194,7 +194,7 @@ class ConfideSetupUsersTable extends Migration { $t->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade'); - $t->unsignedInteger('public_id'); + $t->unsignedInteger('public_id')->nullable(); $t->unique( array('account_id','public_id') ); }); @@ -202,7 +202,7 @@ class ConfideSetupUsersTable extends Migration { { $t->increments('id'); $t->unsignedInteger('account_id'); - $t->unsignedInteger('user_id'); + $t->unsignedInteger('user_id'); $t->unsignedInteger('gateway_id'); $t->timestamps(); $t->softDeletes(); @@ -235,23 +235,23 @@ class ConfideSetupUsersTable extends Migration { $t->timestamps(); $t->softDeletes(); - $t->string('name'); - $t->string('address1'); - $t->string('address2'); - $t->string('city'); - $t->string('state'); - $t->string('postal_code'); + $t->string('name')->nullable(); + $t->string('address1')->nullable(); + $t->string('address2')->nullable(); + $t->string('city')->nullable(); + $t->string('state')->nullable(); + $t->string('postal_code')->nullable(); $t->unsignedInteger('country_id')->nullable(); - $t->string('work_phone'); - $t->text('private_notes'); - $t->decimal('balance', 13, 2); - $t->decimal('paid_to_date', 13, 2); + $t->string('work_phone')->nullable(); + $t->text('private_notes')->nullable(); + $t->decimal('balance', 13, 2)->nullable(); + $t->decimal('paid_to_date', 13, 2)->nullable(); $t->timestamp('last_login')->nullable(); - $t->string('website'); + $t->string('website')->nullable(); $t->unsignedInteger('industry_id')->nullable(); $t->unsignedInteger('size_id')->nullable(); - $t->boolean('is_deleted'); - $t->integer('payment_terms'); + $t->boolean('is_deleted')->default(false); + $t->integer('payment_terms')->nullable(); $t->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade'); $t->foreign('user_id')->references('id')->on('users')->onDelete('cascade'); @@ -273,18 +273,18 @@ class ConfideSetupUsersTable extends Migration { $t->timestamps(); $t->softDeletes(); - $t->boolean('is_primary'); - $t->boolean('send_invoice'); - $t->string('first_name'); - $t->string('last_name'); - $t->string('email'); - $t->string('phone'); + $t->boolean('is_primary')->default(0); + $t->boolean('send_invoice')->default(0); + $t->string('first_name')->nullable(); + $t->string('last_name')->nullable(); + $t->string('email')->nullable(); + $t->string('phone')->nullable(); $t->timestamp('last_login'); $t->foreign('client_id')->references('id')->on('clients')->onDelete('cascade'); $t->foreign('user_id')->references('id')->on('users')->onDelete('cascade');; - $t->unsignedInteger('public_id'); + $t->unsignedInteger('public_id')->nullable(); $t->unique( array('account_id','public_id') ); }); @@ -317,7 +317,7 @@ class ConfideSetupUsersTable extends Migration { $t->date('due_date')->nullable(); $t->text('terms'); $t->text('public_notes'); - $t->boolean('is_deleted'); + $t->boolean('is_deleted')->default(false); $t->boolean('is_recurring'); $t->unsignedInteger('frequency_id'); $t->date('start_date')->nullable(); @@ -331,11 +331,11 @@ class ConfideSetupUsersTable extends Migration { $t->decimal('amount', 13, 2); $t->decimal('balance', 13, 2); - $t->foreign('client_id')->references('id')->on('clients')->onDelete('cascade'); + $t->foreign('client_id')->references('id')->on('clients')->onDelete('cascade'); $t->foreign('account_id')->references('id')->on('accounts'); - $t->foreign('user_id')->references('id')->on('users')->onDelete('cascade');; + $t->foreign('user_id')->references('id')->on('users')->onDelete('cascade'); $t->foreign('invoice_status_id')->references('id')->on('invoice_statuses'); - $t->foreign('recurring_invoice_id')->references('id')->on('invoices'); + $t->foreign('recurring_invoice_id')->references('id')->on('invoices')->onDelete('cascade'); $t->unsignedInteger('public_id')->index(); $t->unique( array('account_id','public_id') ); @@ -354,7 +354,7 @@ class ConfideSetupUsersTable extends Migration { $t->timestamps(); $t->softDeletes(); - $t->string('transaction_reference'); + $t->string('transaction_reference')->nullable(); $t->timestamp('sent_date'); $t->timestamp('viewed_date'); @@ -395,7 +395,7 @@ class ConfideSetupUsersTable extends Migration { $t->string('product_key'); $t->text('notes'); $t->decimal('cost', 13, 2); - $t->decimal('qty', 13, 2); + $t->decimal('qty', 13, 2)->nullable(); $t->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade'); $t->foreign('user_id')->references('id')->on('users')->onDelete('cascade');; @@ -418,10 +418,10 @@ class ConfideSetupUsersTable extends Migration { $t->string('product_key'); $t->text('notes'); $t->decimal('cost', 13, 2); - $t->decimal('qty', 13, 2); + $t->decimal('qty', 13, 2)->nullable(); - $t->string('tax_name'); - $t->decimal('tax_rate', 13, 2); + $t->string('tax_name')->nullable(); + $t->decimal('tax_rate', 13, 2)->nullable(); $t->foreign('invoice_id')->references('id')->on('invoices')->onDelete('cascade'); $t->foreign('product_id')->references('id')->on('products'); @@ -445,11 +445,11 @@ class ConfideSetupUsersTable extends Migration { $t->timestamps(); $t->softDeletes(); - $t->boolean('is_deleted'); + $t->boolean('is_deleted')->default(false); $t->decimal('amount', 13, 2); - $t->date('payment_date'); - $t->string('transaction_reference'); - $t->string('payer_id'); + $t->date('payment_date')->nullable(); + $t->string('transaction_reference')->nullable(); + $t->string('payer_id')->nullable(); $t->foreign('invoice_id')->references('id')->on('invoices'); $t->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade'); @@ -472,11 +472,11 @@ class ConfideSetupUsersTable extends Migration { $t->timestamps(); $t->softDeletes(); - $t->boolean('is_deleted'); + $t->boolean('is_deleted')->default(false); $t->decimal('amount', 13, 2); $t->decimal('balance', 13, 2); $t->date('credit_date')->nullable(); - $t->string('credit_number'); + $t->string('credit_number')->nullable(); $t->text('private_notes'); $t->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade'); @@ -495,17 +495,17 @@ class ConfideSetupUsersTable extends Migration { $t->unsignedInteger('account_id'); $t->unsignedInteger('client_id'); $t->unsignedInteger('user_id'); - $t->unsignedInteger('contact_id'); - $t->unsignedInteger('payment_id'); - $t->unsignedInteger('invoice_id'); - $t->unsignedInteger('credit_id'); - $t->unsignedInteger('invitation_id'); + $t->unsignedInteger('contact_id')->nullable(); + $t->unsignedInteger('payment_id')->nullable(); + $t->unsignedInteger('invoice_id')->nullable(); + $t->unsignedInteger('credit_id')->nullable(); + $t->unsignedInteger('invitation_id')->nullable(); - $t->text('message'); - $t->text('json_backup'); + $t->text('message')->nullable(); + $t->text('json_backup')->nullable(); $t->integer('activity_type_id'); - $t->decimal('adjustment', 13, 2); - $t->decimal('balance', 13, 2); + $t->decimal('adjustment', 13, 2)->nullable(); + $t->decimal('balance', 13, 2)->nullable(); $t->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade'); $t->foreign('client_id')->references('id')->on('clients')->onDelete('cascade'); diff --git a/app/database/migrations/2014_03_03_155556_add_phone_to_account.php b/app/database/migrations/2014_03_03_155556_add_phone_to_account.php index 1de12fb34e3b..79e03e9d183a 100644 --- a/app/database/migrations/2014_03_03_155556_add_phone_to_account.php +++ b/app/database/migrations/2014_03_03_155556_add_phone_to_account.php @@ -14,8 +14,8 @@ class AddPhoneToAccount extends Migration { { Schema::table('accounts', function($table) { - $table->string('work_phone'); - $table->string('work_email'); + $table->string('work_phone')->nullable(); + $table->string('work_email')->nullable(); }); } diff --git a/app/database/migrations/2014_03_19_201454_add_language_support.php b/app/database/migrations/2014_03_19_201454_add_language_support.php index 6acc56e2d478..cdb092a9a498 100644 --- a/app/database/migrations/2014_03_19_201454_add_language_support.php +++ b/app/database/migrations/2014_03_19_201454_add_language_support.php @@ -26,6 +26,7 @@ class AddLanguageSupport extends Migration { DB::table('languages')->insert(['name' => 'Brazilian Portuguese', 'locale' => 'pt_BR']); DB::table('languages')->insert(['name' => 'Dutch', 'locale' => 'nl']); DB::table('languages')->insert(['name' => 'Spanish', 'locale' => 'es']); + DB::table('languages')->insert(['name' => 'Norwegian', 'locale' => 'nb_NO']); Schema::table('accounts', function($table) { diff --git a/app/database/migrations/2014_03_20_200300_create_payment_libraries.php b/app/database/migrations/2014_03_20_200300_create_payment_libraries.php index d4c7855a706e..dc8074c913bd 100644 --- a/app/database/migrations/2014_03_20_200300_create_payment_libraries.php +++ b/app/database/migrations/2014_03_20_200300_create_payment_libraries.php @@ -12,19 +12,16 @@ class CreatePaymentLibraries extends Migration { */ public function up() { - Schema::dropIfExists('payment_libraries'); + Schema::dropIfExists('payment_libraries'); - Schema::create('payment_libraries', function($t) - { - $t->increments('id'); - $t->timestamps(); + Schema::create('payment_libraries', function($t) + { + $t->increments('id'); + $t->timestamps(); - $t->string('name'); - $t->boolean('visible')->default(true); - }); - - DB::table('payment_libraries')->insert(['name' => 'Omnipay']); - DB::table('payment_libraries')->insert(['name' => 'PHP-Payments']); + $t->string('name'); + $t->boolean('visible')->default(true); + }); Schema::table('gateways', function($table) { @@ -35,7 +32,7 @@ class CreatePaymentLibraries extends Migration { Schema::table('gateways', function($table) { - $table->foreign('payment_library_id')->references('id')->on('payment_libraries')->onDelete('cascade'); + $table->foreign('payment_library_id')->references('id')->on('payment_libraries')->onDelete('cascade'); }); } diff --git a/app/database/migrations/2014_03_25_102200_add_sort_and_recommended_to_gateways.php b/app/database/migrations/2014_03_25_102200_add_sort_and_recommended_to_gateways.php index 535636f90e6a..a49fe8f855ef 100644 --- a/app/database/migrations/2014_03_25_102200_add_sort_and_recommended_to_gateways.php +++ b/app/database/migrations/2014_03_25_102200_add_sort_and_recommended_to_gateways.php @@ -15,8 +15,8 @@ class AddSortAndRecommendedToGateways extends Migration { Schema::table('gateways', function($table) { $table->unsignedInteger('sort_order')->default(10000); - $table->boolean('recommended'); - $table->string('site_url', 200); + $table->boolean('recommended')->default(0); + $table->string('site_url', 200)->nullable(); }); } diff --git a/app/database/migrations/2014_04_03_191105_add_pro_plan.php b/app/database/migrations/2014_04_03_191105_add_pro_plan.php index 05f74ebdf40b..cbc714971f1d 100644 --- a/app/database/migrations/2014_04_03_191105_add_pro_plan.php +++ b/app/database/migrations/2014_04_03_191105_add_pro_plan.php @@ -14,7 +14,7 @@ class AddProPlan extends Migration { { Schema::table('accounts', function($table) { - $table->date('pro_plan_paid'); + $table->date('pro_plan_paid')->nullable(); }); } diff --git a/app/database/migrations/2014_04_17_145108_add_custom_fields.php b/app/database/migrations/2014_04_17_145108_add_custom_fields.php index ac88c4012b70..f6ff7c8f45a1 100644 --- a/app/database/migrations/2014_04_17_145108_add_custom_fields.php +++ b/app/database/migrations/2014_04_17_145108_add_custom_fields.php @@ -14,20 +14,20 @@ class AddCustomFields extends Migration { { Schema::table('accounts', function($table) { - $table->string('custom_label1'); - $table->string('custom_value1'); + $table->string('custom_label1')->nullable(); + $table->string('custom_value1')->nullable(); - $table->string('custom_label2'); - $table->string('custom_value2'); + $table->string('custom_label2')->nullable(); + $table->string('custom_value2')->nullable(); - $table->string('custom_client_label1'); - $table->string('custom_client_label2'); + $table->string('custom_client_label1')->nullable(); + $table->string('custom_client_label2')->nullable(); }); Schema::table('clients', function($table) { - $table->string('custom_value1'); - $table->string('custom_value2'); + $table->string('custom_value1')->nullable(); + $table->string('custom_value2')->nullable(); }); } diff --git a/app/database/migrations/2014_04_29_174315_add_advanced_settings.php b/app/database/migrations/2014_04_29_174315_add_advanced_settings.php index 589bc6a7450b..ae91740d21f3 100644 --- a/app/database/migrations/2014_04_29_174315_add_advanced_settings.php +++ b/app/database/migrations/2014_04_29_174315_add_advanced_settings.php @@ -14,8 +14,8 @@ class AddAdvancedSettings extends Migration { { Schema::table('accounts', function($table) { - $table->string('primary_color'); - $table->string('secondary_color'); + $table->string('primary_color')->nullable(); + $table->string('secondary_color')->nullable(); }); Schema::table('payments', function($table) diff --git a/app/database/migrations/2014_05_17_175626_add_quotes.php b/app/database/migrations/2014_05_17_175626_add_quotes.php index 5079117d7ba2..6299ad124dc0 100644 --- a/app/database/migrations/2014_05_17_175626_add_quotes.php +++ b/app/database/migrations/2014_05_17_175626_add_quotes.php @@ -14,7 +14,7 @@ class AddQuotes extends Migration { { Schema::table('invoices', function($table) { - $table->boolean('is_quote'); + $table->boolean('is_quote')->default(0); $table->unsignedInteger('quote_id')->nullable(); $table->unsignedInteger('quote_invoice_id')->nullable(); }); diff --git a/app/database/migrations/2014_07_17_205900_support_hiding_quantity.php b/app/database/migrations/2014_07_17_205900_support_hiding_quantity.php index d055e4e908cb..5a8ed681bc8b 100644 --- a/app/database/migrations/2014_07_17_205900_support_hiding_quantity.php +++ b/app/database/migrations/2014_07_17_205900_support_hiding_quantity.php @@ -14,14 +14,14 @@ class SupportHidingQuantity extends Migration { { Schema::table('accounts', function($table) { - $table->boolean('hide_quantity'); - $table->boolean('hide_paid_to_date'); + $table->boolean('hide_quantity')->default(0); + $table->boolean('hide_paid_to_date')->default(0); - $table->string('custom_invoice_label1'); - $table->string('custom_invoice_label2'); + $table->string('custom_invoice_label1')->nullable(); + $table->string('custom_invoice_label2')->nullable(); - $table->boolean('custom_invoice_taxes1'); - $table->boolean('custom_invoice_taxes2'); + $table->boolean('custom_invoice_taxes1')->nullable(); + $table->boolean('custom_invoice_taxes2')->nullable(); }); Schema::table('invoices', function($table) diff --git a/app/database/seeds/ConstantsSeeder.php b/app/database/seeds/ConstantsSeeder.php index 7ebe2a382de9..fd69b39bb503 100755 --- a/app/database/seeds/ConstantsSeeder.php +++ b/app/database/seeds/ConstantsSeeder.php @@ -129,8 +129,10 @@ class ConstantsSeeder extends Seeder Currency::create(array('name' => 'Danish Krone', 'code' => 'DKK', 'symbol' => 'kr ', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.')); Currency::create(array('name' => 'Israeli Shekel', 'code' => 'ILS', 'symbol' => 'NIS ', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.')); Currency::create(array('name' => 'Singapore Dollar', 'code' => 'SGD', 'symbol' => 'SGD ', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.')); - Currency::create(array('name' => 'Swedish Krona', 'code' => 'SEK', 'symbol' => 'kr', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.')); - Currency::create(array('name' => 'Norske Kroner', 'code' => 'NOK', 'symbol' => 'kr', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.')); + Currency::create(array('name' => 'Swedish Krona', 'code' => 'SEK', 'symbol' => 'kr ', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.')); + Currency::create(array('name' => 'Norske Kroner', 'code' => 'NOK', 'symbol' => 'kr ', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.')); + Currency::create(array('name' => 'Kenyan Shilling', 'code' => 'KES', 'symbol' => 'KSh ', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.')); + Currency::create(array('name' => 'Canadian Dollar', 'code' => 'CAD', 'symbol' => 'C$', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.')); DatetimeFormat::create(array('format' => 'd/M/Y g:i a', 'label' => '10/Mar/2013')); DatetimeFormat::create(array('format' => 'd-M-Yk g:i a', 'label' => '10-Mar-2013')); @@ -148,6 +150,9 @@ class ConstantsSeeder extends Seeder DateFormat::create(array('format' => 'F j, Y', 'picker_format' => 'MM d, yyyy', 'label' => 'March 10, 2013')); DateFormat::create(array('format' => 'D M j, Y', 'picker_format' => 'D MM d, yyyy', 'label' => 'Mon March 10, 2013')); + PaymentLibrary::create(['name' => 'Omnipay']); + PaymentLibrary::create(['name' => 'PHP-Payments']); + /* d, dd: Numeric date, no leading zero and leading zero, respectively. Eg, 5, 05. D, DD: Abbreviated and full weekday names, respectively. Eg, Mon, Monday. diff --git a/app/lang/de/texts.php b/app/lang/de/texts.php index 19e3da3aae1a..f2f89bea2d06 100644 --- a/app/lang/de/texts.php +++ b/app/lang/de/texts.php @@ -404,5 +404,13 @@ return array( 'pending' => 'Pending', 'deleted_user' => 'Successfully deleted user', 'limit_users' => 'Sorry, this will exceed the limit of ' . MAX_NUM_USERS . ' users', - + + 'confirm_email_invoice' => 'Are you sure you want to email this invoice?', + 'confirm_email_quote' => 'Are you sure you want to email this quote?', + 'confirm_recurring_email_invoice' => 'Are you sure you want this invoice emailed?', + + 'cancel_account' => 'Cancel Account', + 'cancel_account_message' => 'Warning: This will permanently erase all of your data, there is no undo.', + 'go_back' => 'Go Back', + ); diff --git a/app/lang/en/texts.php b/app/lang/en/texts.php index a5b919fff342..b8648c28f0be 100644 --- a/app/lang/en/texts.php +++ b/app/lang/en/texts.php @@ -420,4 +420,12 @@ return array( 'deleted_user' => 'Successfully deleted user', 'limit_users' => 'Sorry, this will exceed the limit of ' . MAX_NUM_USERS . ' users', + 'confirm_email_invoice' => 'Are you sure you want to email this invoice?', + 'confirm_email_quote' => 'Are you sure you want to email this quote?', + 'confirm_recurring_email_invoice' => 'Are you sure you want this invoice emailed?', + + 'cancel_account' => 'Cancel Account', + 'cancel_account_message' => 'Warning: This will permanently erase all of your data, there is no undo.', + 'go_back' => 'Go Back', + ); \ No newline at end of file diff --git a/app/lang/es/texts.php b/app/lang/es/texts.php index af1ee8f9e90d..2335ce1c3afd 100644 --- a/app/lang/es/texts.php +++ b/app/lang/es/texts.php @@ -402,5 +402,13 @@ return array( 'pending' => 'Pending', 'deleted_user' => 'Successfully deleted user', 'limit_users' => 'Sorry, this will exceed the limit of ' . MAX_NUM_USERS . ' users', - + + 'confirm_email_invoice' => 'Are you sure you want to email this invoice?', + 'confirm_email_quote' => 'Are you sure you want to email this quote?', + 'confirm_recurring_email_invoice' => 'Are you sure you want this invoice emailed?', + + 'cancel_account' => 'Cancel Account', + 'cancel_account_message' => 'Warning: This will permanently erase all of your data, there is no undo.', + 'go_back' => 'Go Back', + ); diff --git a/app/lang/fr/texts.php b/app/lang/fr/texts.php index 881ac3f5a746..462785a93869 100644 --- a/app/lang/fr/texts.php +++ b/app/lang/fr/texts.php @@ -404,5 +404,13 @@ return array( 'pending' => 'Pending', 'deleted_user' => 'Successfully deleted user', 'limit_users' => 'Sorry, this will exceed the limit of ' . MAX_NUM_USERS . ' users', - + + 'confirm_email_invoice' => 'Are you sure you want to email this invoice?', + 'confirm_email_quote' => 'Are you sure you want to email this quote?', + 'confirm_recurring_email_invoice' => 'Are you sure you want this invoice emailed?', + + 'cancel_account' => 'Cancel Account', + 'cancel_account_message' => 'Warning: This will permanently erase all of your data, there is no undo.', + 'go_back' => 'Go Back', + ); diff --git a/app/lang/it/texts.php b/app/lang/it/texts.php index 66a7aa5968d5..c81c33eab1cd 100644 --- a/app/lang/it/texts.php +++ b/app/lang/it/texts.php @@ -404,5 +404,13 @@ return array( 'pending' => 'Pending', 'deleted_user' => 'Successfully deleted user', 'limit_users' => 'Sorry, this will exceed the limit of ' . MAX_NUM_USERS . ' users', + + 'confirm_email_invoice' => 'Are you sure you want to email this invoice?', + 'confirm_email_quote' => 'Are you sure you want to email this quote?', + 'confirm_recurring_email_invoice' => 'Are you sure you want this invoice emailed?', + + 'cancel_account' => 'Cancel Account', + 'cancel_account_message' => 'Warning: This will permanently erase all of your data, there is no undo.', + 'go_back' => 'Go Back', ); diff --git a/app/lang/lt/texts.php b/app/lang/lt/texts.php index f349196f630f..d6e5a05821ba 100644 --- a/app/lang/lt/texts.php +++ b/app/lang/lt/texts.php @@ -420,6 +420,13 @@ return array( 'deleted_user' => 'Successfully deleted user', 'limit_users' => 'Sorry, this will exceed the limit of ' . MAX_NUM_USERS . ' users', + 'confirm_email_invoice' => 'Are you sure you want to email this invoice?', + 'confirm_email_quote' => 'Are you sure you want to email this quote?', + 'confirm_recurring_email_invoice' => 'Are you sure you want this invoice emailed?', + + 'cancel_account' => 'Cancel Account', + 'cancel_account_message' => 'Warning: This will permanently erase all of your data, there is no undo.', + 'go_back' => 'Go Back', ); diff --git a/app/lang/nb_NO/texts.php b/app/lang/nb_NO/texts.php index 4e9983b765e1..abed26d260a7 100644 --- a/app/lang/nb_NO/texts.php +++ b/app/lang/nb_NO/texts.php @@ -420,4 +420,12 @@ return array( 'deleted_user' => 'Bruker slettet', 'limit_users' => 'Dessverre, vil dette overstiger grensen på ' . MAX_NUM_USERS . ' brukere', + 'confirm_email_invoice' => 'Are you sure you want to email this invoice?', + 'confirm_email_quote' => 'Are you sure you want to email this quote?', + 'confirm_recurring_email_invoice' => 'Are you sure you want this invoice emailed?', + + 'cancel_account' => 'Cancel Account', + 'cancel_account_message' => 'Warning: This will permanently erase all of your data, there is no undo.', + 'go_back' => 'Go Back', + ); \ No newline at end of file diff --git a/app/lang/nl/texts.php b/app/lang/nl/texts.php index 28f4d8302492..5ad10e249578 100644 --- a/app/lang/nl/texts.php +++ b/app/lang/nl/texts.php @@ -405,5 +405,13 @@ return array( 'pending' => 'Pending', 'deleted_user' => 'Successfully deleted user', 'limit_users' => 'Sorry, this will exceed the limit of ' . MAX_NUM_USERS . ' users', + + 'confirm_email_invoice' => 'Are you sure you want to email this invoice?', + 'confirm_email_quote' => 'Are you sure you want to email this quote?', + 'confirm_recurring_email_invoice' => 'Are you sure you want this invoice emailed?', + 'cancel_account' => 'Cancel Account', + 'cancel_account_message' => 'Warning: This will permanently erase all of your data, there is no undo.', + 'go_back' => 'Go Back', + ); diff --git a/app/lang/pt_BR/texts.php b/app/lang/pt_BR/texts.php index d941e9926b35..5aab09b6b887 100644 --- a/app/lang/pt_BR/texts.php +++ b/app/lang/pt_BR/texts.php @@ -393,5 +393,13 @@ return array( 'pending' => 'Pending', 'deleted_user' => 'Successfully deleted user', 'limit_users' => 'Sorry, this will exceed the limit of ' . MAX_NUM_USERS . ' users', + + 'confirm_email_invoice' => 'Are you sure you want to email this invoice?', + 'confirm_email_quote' => 'Are you sure you want to email this quote?', + 'confirm_recurring_email_invoice' => 'Are you sure you want this invoice emailed?', + 'cancel_account' => 'Cancel Account', + 'cancel_account_message' => 'Warning: This will permanently erase all of your data, there is no undo.', + 'go_back' => 'Go Back', + ); diff --git a/app/models/Activity.php b/app/models/Activity.php index f177e9dada8e..c3a02ee67f5d 100755 --- a/app/models/Activity.php +++ b/app/models/Activity.php @@ -119,7 +119,7 @@ class Activity extends Eloquent $adjustment = 0; $client = $invoice->client; - if (!$invoice->is_quote) + if (!$invoice->is_quote && !$invoice->is_recurring) { $adjustment = $invoice->amount; $client->balance = $client->balance + $adjustment; @@ -170,11 +170,12 @@ class Activity extends Eloquent public static function updateInvoice($invoice) { + $client = $invoice->client; + if ($invoice->is_deleted && !$invoice->getOriginal('is_deleted')) { - if (!$invoice->is_quote) + if (!$invoice->is_quote && !$invoice->is_recurring) { - $client = $invoice->client; $client->balance = $client->balance - $invoice->balance; $client->paid_to_date = $client->paid_to_date - ($invoice->amount - $invoice->balance); $client->save(); @@ -198,11 +199,13 @@ class Activity extends Eloquent return; } - $backupInvoice = Invoice::with('invoice_items', 'client.account', 'client.contacts')->find($invoice->id); + $backupInvoice = Invoice::with('invoice_items', 'client.account', 'client.contacts')->find($invoice->id); - $client = $invoice->client; - $client->balance = $client->balance + $diff; - $client->save(); + if (!$invoice->is_quote && !$invoice->is_recurring) + { + $client->balance = $client->balance + $diff; + $client->save(); + } $activity = Activity::getBlank($invoice); $activity->client_id = $invoice->client_id; @@ -210,7 +213,7 @@ class Activity extends Eloquent $activity->activity_type_id = $invoice->is_quote ? ACTIVITY_TYPE_UPDATE_QUOTE : ACTIVITY_TYPE_UPDATE_INVOICE; $activity->message = Utils::encodeActivity(Auth::user(), 'updated', $invoice); $activity->balance = $client->balance; - $activity->adjustment = $invoice->is_quote ? 0 : $diff; + $activity->adjustment = $invoice->is_quote || $invoice->is_recurring ? 0 : $diff; $activity->json_backup = $backupInvoice->hidePrivateFields()->toJSON(); $activity->save(); } @@ -265,13 +268,13 @@ class Activity extends Eloquent { $activity = Activity::getBlank($client); $activity->contact_id = $payment->contact_id; - $activity->message = Utils::encodeActivity($payment->invitation->contact, 'entered ' . $payment->getName()); + $activity->message = Utils::encodeActivity($payment->invitation->contact, 'entered ' . $payment->getName() . ' for ', $payment->invoice); } else { $activity = Activity::getBlank(); - $message = $payment->payment_type_id == PAYMENT_TYPE_CREDIT ? 'applied credit' : 'entered ' . $payment->getName(); - $activity->message = Utils::encodeActivity(Auth::user(), $message); + $message = $payment->payment_type_id == PAYMENT_TYPE_CREDIT ? 'applied credit for ' : 'entered ' . $payment->getName() . ' for '; + $activity->message = Utils::encodeActivity(Auth::user(), $message, $payment->invoice); } $activity->payment_id = $payment->id; diff --git a/app/models/Gateway.php b/app/models/Gateway.php index bb6afda0a3ef..7d84a7db32ec 100755 --- a/app/models/Gateway.php +++ b/app/models/Gateway.php @@ -21,7 +21,7 @@ class Gateway extends Eloquent if ($paymentLibrary->id == PAYMENT_LIBRARY_OMNIPAY) { - $fields = Omnipay::create($this->provider)->getDefaultParameters(); + $fields = Omnipay::create($this->provider)->getDefaultParameters(); } else { diff --git a/app/models/PaymentLibrary.php b/app/models/PaymentLibrary.php index b8550c212aee..4e790713a096 100644 --- a/app/models/PaymentLibrary.php +++ b/app/models/PaymentLibrary.php @@ -3,6 +3,7 @@ class PaymentLibrary extends Eloquent { protected $table = 'payment_libraries'; + public $timestamps = true; public function gateways() { diff --git a/app/ninja/mailers/Mailer.php b/app/ninja/mailers/Mailer.php index 162bd8d9fcfa..43c2d60eaebc 100755 --- a/app/ninja/mailers/Mailer.php +++ b/app/ninja/mailers/Mailer.php @@ -1,6 +1,7 @@ to($toEmail)->from($fromEmail, $fromName)->sender($fromEmail, $fromName) - ->replyTo($fromEmail, $fromName)->returnPath($fromEmail)->subject($subject); + ->replyTo($replyEmail, $fromName)->subject($subject); }); } } \ No newline at end of file diff --git a/app/ninja/mailers/UserMailer.php b/app/ninja/mailers/UserMailer.php index 066db805d653..f4042cd8f4fb 100755 --- a/app/ninja/mailers/UserMailer.php +++ b/app/ninja/mailers/UserMailer.php @@ -23,7 +23,18 @@ class UserMailer extends Mailer { 'invitationMessage' => $invitor ? trans('texts.invitation_message', ['invitor' => $invitor->getDisplayName()]) : '' ]; - $this->sendTo($user->email, CONTACT_EMAIL, CONTACT_NAME, $subject, $view, $data); + if ($invitor) + { + $fromEmail = $invitor->email; + $fromName = $invitor->getDisplayName(); + } + else + { + $fromEmail = CONTACT_EMAIL; + $fromName = CONTACT_NAME; + } + + $this->sendTo($user->email, $fromEmail, $fromName, $subject, $view, $data); } public function sendNotification(User $user, Invoice $invoice, $notificationType, Payment $payment = null) @@ -46,7 +57,7 @@ class UserMailer extends Mailer { 'invoiceLink' => SITE_URL . "/{$entityType}s/{$invoice->public_id}" ]; - if ($payment) + if ($payment) { $data['paymentAmount'] = Utils::formatMoney($payment->amount, $invoice->client->currency_id); } diff --git a/app/ninja/repositories/ClientRepository.php b/app/ninja/repositories/ClientRepository.php index b665b0e33553..4b56bc135f37 100755 --- a/app/ninja/repositories/ClientRepository.php +++ b/app/ninja/repositories/ClientRepository.php @@ -188,7 +188,7 @@ class ClientRepository public function bulk($ids, $action) { - $clients = Client::scope($ids)->get(); + $clients = Client::withTrashed()->scope($ids)->get(); foreach ($clients as $client) { diff --git a/app/ninja/repositories/CreditRepository.php b/app/ninja/repositories/CreditRepository.php index 704ebc54c1e2..1300bd5dc95b 100755 --- a/app/ninja/repositories/CreditRepository.php +++ b/app/ninja/repositories/CreditRepository.php @@ -66,7 +66,7 @@ class CreditRepository return 0; } - $credits = Credit::scope($ids)->get(); + $credits = Credit::withTrashed()->scope($ids)->get(); foreach ($credits as $credit) { diff --git a/app/ninja/repositories/InvoiceRepository.php b/app/ninja/repositories/InvoiceRepository.php index 66923e4157ed..dad05fbd6fa4 100755 --- a/app/ninja/repositories/InvoiceRepository.php +++ b/app/ninja/repositories/InvoiceRepository.php @@ -435,7 +435,7 @@ class InvoiceRepository return 0; } - $invoices = Invoice::scope($ids)->get(); + $invoices = Invoice::withTrashed()->scope($ids)->get(); foreach ($invoices as $invoice) { diff --git a/app/ninja/repositories/PaymentRepository.php b/app/ninja/repositories/PaymentRepository.php index 2cf96ceeae2e..f19b2ffb5830 100755 --- a/app/ninja/repositories/PaymentRepository.php +++ b/app/ninja/repositories/PaymentRepository.php @@ -112,7 +112,7 @@ class PaymentRepository return 0; } - $payments = Payment::scope($ids)->get(); + $payments = Payment::withTrashed()->scope($ids)->get(); foreach ($payments as $payment) { diff --git a/app/routes.php b/app/routes.php index df96bf68a293..bcd098c9058a 100755 --- a/app/routes.php +++ b/app/routes.php @@ -22,6 +22,9 @@ //dd(gethostname()); //Log::error('test'); +Route::get('install', 'AccountController@install'); +Route::get('update', 'AccountController@update'); +Route::get('reset', 'AccountController@reset'); Route::get('/', 'HomeController@showIndex'); Route::get('/rocksteady', 'HomeController@showIndex'); @@ -33,7 +36,7 @@ Route::post('/contact_submit', 'HomeController@doContactUs'); Route::get('/faq', 'HomeController@showFaq'); Route::get('/features', 'HomeController@showFeatures'); Route::get('/testimonials', 'HomeController@showTestimonials'); -Route::get('/compare-online-invoicing-sites', 'HomeController@showCompare'); +Route::get('/compare-online-invoicing', 'HomeController@showCompare'); Route::get('log_error', 'HomeController@logError'); Route::get('invoice_now', 'HomeController@invoiceNow'); @@ -52,7 +55,6 @@ Route::post('signup/validate', 'AccountController@checkEmail'); Route::post('signup/submit', 'AccountController@submitSignup'); - // Confide routes Route::get('login', 'UserController@login'); Route::post('login', 'UserController@do_login'); @@ -81,6 +83,7 @@ Route::group(array('before' => 'auth'), function() Route::get('company/advanced_settings/chart_builder', 'ReportController@report'); Route::post('company/advanced_settings/chart_builder', 'ReportController@report'); + Route::post('company/cancel_account', 'AccountController@cancelAccount'); Route::get('account/getSearchData', array('as' => 'getSearchData', 'uses' => 'AccountController@getSearchData')); Route::get('company/{section?}/{sub_section?}', 'AccountController@showSection'); Route::post('company/{section?}/{sub_section?}', 'AccountController@doSection'); @@ -136,9 +139,9 @@ Route::group(array('prefix' => 'api/v1', 'before' => 'auth.basic'), function() Route::post('api/hooks', 'IntegrationController@subscribe'); }); -define('CONTACT_EMAIL', 'contact@invoiceninja.com'); -define('CONTACT_NAME', 'Invoice Ninja'); -define('SITE_URL', 'https://www.invoiceninja.com'); +define('CONTACT_EMAIL', Config::get('mail.from.address')); +define('CONTACT_NAME', Config::get('mail.from.name')); +define('SITE_URL', Config::get('app.url')); define('ENV_DEVELOPMENT', 'local'); define('ENV_STAGING', 'staging'); @@ -231,7 +234,7 @@ define('NINJA_ACCOUNT_KEY', 'zg4ylmzDkdkPOT8yoKQw9LTWaoZJx79h'); define('NINJA_GATEWAY_ID', GATEWAY_AUTHORIZE_NET); define('NINJA_GATEWAY_CONFIG', '{"apiLoginId":"626vWcD5","transactionKey":"4bn26TgL9r4Br4qJ","testMode":"","developerMode":""}'); define('NINJA_URL', 'https://www.invoiceninja.com'); -define('NINJA_VERSION', '1.3.1'); +define('NINJA_VERSION', '1.3.3'); define('PRO_PLAN_PRICE', 50); define('LICENSE_PRICE', 30.00); diff --git a/app/views/accounts/details.blade.php b/app/views/accounts/details.blade.php index c1e96f3b7fb5..41571258ae12 100755 --- a/app/views/accounts/details.blade.php +++ b/app/views/accounts/details.blade.php @@ -17,11 +17,13 @@ )) }} {{ Former::populate($account) }} - {{ Former::populateField('first_name', $account->users()->first()->first_name) }} - {{ Former::populateField('last_name', $account->users()->first()->last_name) }} - {{ Former::populateField('email', $account->users()->first()->email) }} - {{ Former::populateField('phone', $account->users()->first()->phone) }} - + @if ($showUser) + {{ Former::populateField('first_name', $account->users()->first()->first_name) }} + {{ Former::populateField('last_name', $account->users()->first()->last_name) }} + {{ Former::populateField('email', $account->users()->first()->email) }} + {{ Former::populateField('phone', $account->users()->first()->phone) }} + @endif +
@@ -56,11 +58,13 @@
- {{ Former::legend('users') }} - {{ Former::text('first_name') }} - {{ Former::text('last_name') }} - {{ Former::text('email') }} - {{ Former::text('phone') }} + @if ($showUser) + {{ Former::legend('users') }} + {{ Former::text('first_name') }} + {{ Former::text('last_name') }} + {{ Former::text('email') }} + {{ Former::text('phone') }} + @endif {{ Former::legend('localization') }} {{ Former::select('language_id')->addOption('','') diff --git a/app/views/accounts/import_export.blade.php b/app/views/accounts/import_export.blade.php index e9a72ee1b2cd..fd802d177632 100755 --- a/app/views/accounts/import_export.blade.php +++ b/app/views/accounts/import_export.blade.php @@ -1,17 +1,60 @@ @extends('accounts.nav') @section('content') - @parent +@parent - {{ Former::open_for_files('company/import_map')->addClass('col-md-9 col-md-offset-1') }} - {{ Former::legend('import_clients') }} - {{ Former::file('file')->label(trans('texts.csv_file')) }} - {{ Former::actions( Button::lg_info_submit(trans('texts.upload'))->append_with_icon('open') ) }} - {{ Former::close() }} +{{ Former::open_for_files('company/import_map')->addClass('col-md-9 col-md-offset-1') }} +{{ Former::legend('import_clients') }} +{{ Former::file('file')->label(trans('texts.csv_file')) }} +{{ Former::actions( Button::lg_info_submit(trans('texts.upload'))->append_with_icon('open') ) }} +{{ Former::close() }} - {{ Former::open('company/export')->addClass('col-md-9 col-md-offset-1') }} - {{ Former::legend('export_clients') }} - {{ Former::actions( Button::lg_primary_submit(trans('texts.download'))->append_with_icon('download-alt') ) }} - {{ Former::close() }} +{{ Former::open('company/export')->addClass('col-md-9 col-md-offset-1') }} +{{ Former::legend('export_clients') }} +{{ Former::actions( Button::lg_primary_submit(trans('texts.download'))->append_with_icon('download-alt') ) }} +{{ Former::close() }} + +

 

+

 

+ +{{ Former::open('company/cancel_account')->addClass('col-md-9 col-md-offset-1 cancel-account') }} +{{ Former::legend('cancel_account') }} +{{ Former::actions( Button::lg_danger_button(trans('texts.cancel_account'), ['onclick' => 'showConfirm()'])->append_with_icon('trash') ) }} + + + +{{ Former::close() }} + + + @stop \ No newline at end of file diff --git a/app/views/accounts/product.blade.php b/app/views/accounts/product.blade.php index 6893beac28af..daa4dc01c7b6 100644 --- a/app/views/accounts/product.blade.php +++ b/app/views/accounts/product.blade.php @@ -3,7 +3,9 @@ @section('content') @parent - {{ Former::open($url)->method($method)->addClass('col-md-8 col-md-offset-2 warn-on-exit') }} + {{ Former::open($url)->method($method) + ->rules(['product_key' => 'required|max:20']) + ->addClass('col-md-8 col-md-offset-2 warn-on-exit') }} {{ Former::legend($title) }} diff --git a/app/views/emails/invoice_html.blade.php b/app/views/emails/invoice_html.blade.php index 8c32f6bfab12..2db78c6e72cb 100755 --- a/app/views/emails/invoice_html.blade.php +++ b/app/views/emails/invoice_html.blade.php @@ -19,8 +19,8 @@ @if ($showNinjaFooter)

- {{ trans('texts.ninja_email_footer', ['site' => 'Invoice Ninja']) }} + {{ trans('texts.ninja_email_footer', ['site' => 'Invoice Ninja']) }} @endif - \ No newline at end of file + diff --git a/app/views/emails/invoice_text.blade.php b/app/views/emails/invoice_text.blade.php index 954cfcf925ef..4797df81badc 100755 --- a/app/views/emails/invoice_text.blade.php +++ b/app/views/emails/invoice_text.blade.php @@ -12,5 +12,5 @@ @if ($showNinjaFooter) {{ trans('texts.ninja_email_footer', ['site' => 'Invoice Ninja']) }} -https://www.invoiceninja.com -@endif \ No newline at end of file +{{ NINJA_URL }} +@endif diff --git a/app/views/emails/payment_confirmation_html.blade.php b/app/views/emails/payment_confirmation_html.blade.php index 9f224df389d7..c1dffbac19a0 100644 --- a/app/views/emails/payment_confirmation_html.blade.php +++ b/app/views/emails/payment_confirmation_html.blade.php @@ -18,8 +18,8 @@ @if ($showNinjaFooter)

- {{ trans('texts.ninja_email_footer', ['site' => 'Invoice Ninja']) }} + {{ trans('texts.ninja_email_footer', ['site' => 'Invoice Ninja']) }} @endif - \ No newline at end of file + diff --git a/app/views/emails/payment_confirmation_text.blade.php b/app/views/emails/payment_confirmation_text.blade.php index 9b6b7384812b..0d2b7a1c5438 100644 --- a/app/views/emails/payment_confirmation_text.blade.php +++ b/app/views/emails/payment_confirmation_text.blade.php @@ -11,5 +11,5 @@ @if ($showNinjaFooter) {{ trans('texts.ninja_email_footer', ['site' => 'Invoice Ninja']) }} -https://www.invoiceninja.com -@endif \ No newline at end of file +{{ NINJA_URL }} +@endif diff --git a/app/views/header.blade.php b/app/views/header.blade.php index d84b14aa2060..991f6e5a7367 100755 --- a/app/views/header.blade.php +++ b/app/views/header.blade.php @@ -385,7 +385,8 @@ Want something changed? We're {{ link_to('https://github.com/hillelcoren/invoice @endif -@if (!Utils::isNinjaProd() && !Utils::isNinjaDev()) +{{-- Per our license, please do not remove or modify this link. --}} +@if (!Utils::isNinja())

{{ trans('texts.powered_by') }} InvoiceNinja.com
@endif diff --git a/app/views/invoices/edit.blade.php b/app/views/invoices/edit.blade.php index 094bb7d728ed..f0d72ebe9729 100755 --- a/app/views/invoices/edit.blade.php +++ b/app/views/invoices/edit.blade.php @@ -723,17 +723,19 @@ } function onEmailClick() { - @if (Auth::user()->confirmed) - if (confirm('Are you sure you want to email this {{ $entityType }}?')) { + if (confirm('{{ trans("texts.confirm_email_$entityType") }}')) { submitAction('email'); } - @else - submitAction('email'); - @endif } function onSaveClick() { - submitAction(''); + if (model.invoice().is_recurring()) { + if (confirm('{{ trans("texts.confirm_recurring_email_$entityType") }}')) { + submitAction(''); + } + } else { + submitAction(''); + } } function submitAction(value) { diff --git a/app/views/master.blade.php b/app/views/master.blade.php index 92c802cc6476..6ee2b16b7925 100755 --- a/app/views/master.blade.php +++ b/app/views/master.blade.php @@ -9,9 +9,9 @@ - + - + @@ -20,7 +20,6 @@ - @@ -33,7 +32,7 @@ $.ajax({ type: 'GET', url: '{{ URL::to('log_error') }}', - data: 'error='+encodeURIComponent(e)+'&url='+encodeURIComponent(window.location) + data: 'error='+encodeURIComponent(e.message + ' - ' + e.filename + ': ' + e.lineno)+'&url='+encodeURIComponent(window.location) }); } catch(err) {} return false; @@ -94,7 +93,6 @@ @yield('body') -