From 4268c18f8acfad23932a362f406ae292d8b7d32a Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Fri, 25 Sep 2015 12:57:40 +0300 Subject: [PATCH] Fixed money format in PDF for EU --- app/Console/Kernel.php | 67 ++++++++++++------- app/Events/UserSignedUp.php | 21 ++++++ app/Exceptions/Handler.php | 15 +++-- app/Http/Controllers/AccountController.php | 16 +++-- app/Http/Controllers/AppController.php | 3 +- app/Http/Controllers/InvoiceController.php | 1 - app/Http/Controllers/TaskController.php | 8 +++ app/Http/Middleware/StartupCheck.php | 22 ++++-- app/Http/routes.php | 4 +- app/Listeners/HandleUserLoggedIn.php | 5 +- app/Listeners/HandleUserSignedUp.php | 37 ++++++++++ app/Models/Account.php | 7 -- app/Models/Invoice.php | 2 +- app/Models/Language.php | 5 ++ app/Models/User.php | 25 +++++-- app/Ninja/Mailers/ContactMailer.php | 2 +- app/Ninja/Repositories/AccountRepository.php | 7 +- app/Ninja/Repositories/TaskRepository.php | 16 ++++- app/Providers/AppServiceProvider.php | 20 ++++++ app/Providers/EventServiceProvider.php | 3 + config/session.php | 2 +- ...015_02_17_131714_support_token_billing.php | 4 +- database/seeds/PaymentLibrariesSeeder.php | 20 +++--- database/seeds/UserTableSeeder.php | 6 ++ public/js/built.js | 2 +- public/js/pdf.pdfmake.js | 2 +- .../views/accounts/account_gateway.blade.php | 4 +- resources/views/header.blade.php | 3 +- resources/views/invoices/edit.blade.php | 2 +- resources/views/tasks/edit.blade.php | 59 +++++++++------- 30 files changed, 279 insertions(+), 111 deletions(-) create mode 100644 app/Events/UserSignedUp.php create mode 100644 app/Listeners/HandleUserSignedUp.php diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 25b6d0c7ad45..fd97865beadc 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -1,34 +1,51 @@ -command('inspire') - // ->hourly(); - } + /** + * Define the application's command schedule. + * + * @param \Illuminate\Console\Scheduling\Schedule $schedule + * @return void + */ + protected function schedule(Schedule $schedule) + { + $logFile = storage_path() . '/logs/cron.log'; + $schedule + ->command('ninja:send-invoices --force') + ->sendOutputTo($logFile) + ->withoutOverlapping() + ->hourly(); + + $schedule + ->command('ninja:send-reminders --force') + ->sendOutputTo($logFile) + ->daily(); + + if (Utils::isNinja()) { + $schedule + ->command('ninja:send-renewals --force') + ->sendOutputTo($logFile) + ->daily(); + } + } } diff --git a/app/Events/UserSignedUp.php b/app/Events/UserSignedUp.php new file mode 100644 index 000000000000..99e8b22456c2 --- /dev/null +++ b/app/Events/UserSignedUp.php @@ -0,0 +1,21 @@ +with('sign_up', Input::get('sign_up')); @@ -151,7 +153,7 @@ class AccountController extends BaseController public function showSection($section = ACCOUNT_DETAILS, $subSection = false) { if ($section == ACCOUNT_DETAILS) { - $primaryUser = Auth::user()->account->getPrimaryUser(); + $primaryUser = Auth::user()->account->users()->orderBy('id')->first(); $data = [ 'account' => Account::with('users')->findOrFail(Auth::user()->account_id), 'countries' => Cache::get('countries'), @@ -721,6 +723,7 @@ class AccountController extends BaseController $account->save(); if (Auth::user()->id === $user->id) { + $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')); @@ -837,11 +840,10 @@ class AccountController extends BaseController public function doRegister() { $affiliate = Affiliate::where('affiliate_key', '=', SELF_HOST_AFFILIATE_KEY)->first(); - $email = trim(Input::get('email')); - - if (!$email || $email == 'user@example.com') { - return ''; + + if (!$email || $email == TEST_USERNAME) { + return RESULT_FAILURE; } $license = new License(); @@ -855,7 +857,7 @@ class AccountController extends BaseController $license->is_claimed = 1; $license->save(); - return ''; + return RESULT_SUCCESS; } public function cancelAccount() diff --git a/app/Http/Controllers/AppController.php b/app/Http/Controllers/AppController.php index b9f56236bfa5..21becbc7e067 100644 --- a/app/Http/Controllers/AppController.php +++ b/app/Http/Controllers/AppController.php @@ -90,7 +90,8 @@ class AppController extends BaseController "MAIL_HOST={$mail['host']}\n". "MAIL_USERNAME={$mail['username']}\n". "MAIL_FROM_NAME={$mail['from']['name']}\n". - "MAIL_PASSWORD={$mail['password']}"; + "MAIL_PASSWORD={$mail['password']}\n\n". + "PHANTOMJS_CLOUD_KEY='a-demo-key-with-low-quota-per-ip-address'"; // Write Config Settings $fp = fopen(base_path()."/.env", 'w'); diff --git a/app/Http/Controllers/InvoiceController.php b/app/Http/Controllers/InvoiceController.php index 094dd1c09a5c..3545b548f611 100644 --- a/app/Http/Controllers/InvoiceController.php +++ b/app/Http/Controllers/InvoiceController.php @@ -12,7 +12,6 @@ use DB; use Event; use URL; use Datatable; -use finfo; use Request; use DropdownButton; use App\Models\Invoice; diff --git a/app/Http/Controllers/TaskController.php b/app/Http/Controllers/TaskController.php index bb259260f790..59e2439f0ea3 100644 --- a/app/Http/Controllers/TaskController.php +++ b/app/Http/Controllers/TaskController.php @@ -216,6 +216,14 @@ class TaskController extends BaseController return self::bulk(); } + if ($validator = $this->taskRepo->getErrors(Input::all())) { + $url = $publicId ? 'tasks/'.$publicId.'/edit' : 'tasks/create'; + Session::flash('error', trans('texts.task_errors')); + return Redirect::to($url) + ->withErrors($validator) + ->withInput(); + } + $task = $this->taskRepo->save($publicId, Input::all()); Session::flash('message', trans($publicId ? 'texts.updated_task' : 'texts.created_task')); diff --git a/app/Http/Middleware/StartupCheck.php b/app/Http/Middleware/StartupCheck.php index f7a4d72dbf6a..cc3709683818 100644 --- a/app/Http/Middleware/StartupCheck.php +++ b/app/Http/Middleware/StartupCheck.php @@ -26,10 +26,8 @@ class StartupCheck public function handle($request, Closure $next) { // Ensure all request are over HTTPS in production - if (App::environment() == ENV_PRODUCTION) { - if (!Request::secure()) { - return Redirect::secure(Request::getRequestUri()); - } + if (App::environment() == ENV_PRODUCTION && !Request::secure()) { + return Redirect::secure(Request::getRequestUri()); } // If the database doens't yet exist we'll skip the rest @@ -37,7 +35,19 @@ class StartupCheck return $next($request); } - // check the application is up to date and for any news feed messages + // Check if a new version was installed + if (!Utils::isNinja()) { + $file = storage_path() . '/version.txt'; + $version = @file_get_contents($file); + if ($version != NINJA_VERSION) { + $handle = fopen($file, 'w'); + fwrite($handle, NINJA_VERSION); + fclose($handle); + return Redirect::to('/update'); + } + } + + // Check the application is up to date and for any news feed messages if (Auth::check()) { $count = Session::get(SESSION_COUNTER, 0); Session::put(SESSION_COUNTER, ++$count); @@ -160,8 +170,8 @@ class StartupCheck } } } - + // Show message to IE 8 and before users if (isset($_SERVER['HTTP_USER_AGENT']) && preg_match('/(?i)msie [2-8]/', $_SERVER['HTTP_USER_AGENT'])) { Session::flash('error', trans('texts.old_browser')); } diff --git a/app/Http/routes.php b/app/Http/routes.php index 8ca91495ff18..755506200483 100644 --- a/app/Http/routes.php +++ b/app/Http/routes.php @@ -391,6 +391,7 @@ if (!defined('CONTACT_EMAIL')) { define('OUTDATE_BROWSER_URL', 'http://browsehappy.com/'); define('PDFMAKE_DOCS', 'http://pdfmake.org/playground.html'); define('PHANTOMJS_CLOUD', 'http://api.phantomjscloud.com/single/browser/v1/'); + define('GITHUB_RELEASES', 'https://github.com/hillelcoren/invoice-ninja/releases'); define('REFERRAL_PROGRAM_URL', false); define('COUNT_FREE_DESIGNS', 4); @@ -460,7 +461,6 @@ if (!defined('CONTACT_EMAIL')) { } } -/* // Log all SQL queries to laravel.log Event::listen('illuminate.query', function($query, $bindings, $time, $name) { @@ -485,7 +485,7 @@ Event::listen('illuminate.query', function($query, $bindings, $time, $name) Log::info($query, $data); }); -*/ + /* if (Auth::check() && Auth::user()->id === 1) diff --git a/app/Listeners/HandleUserLoggedIn.php b/app/Listeners/HandleUserLoggedIn.php index 26f7cc455fc7..5e65af0397f8 100644 --- a/app/Listeners/HandleUserLoggedIn.php +++ b/app/Listeners/HandleUserLoggedIn.php @@ -5,6 +5,7 @@ use Auth; use Carbon; use Session; use App\Events\UserLoggedIn; +use App\Events\UserSignedUp; use App\Ninja\Repositories\AccountRepository; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Contracts\Queue\ShouldBeQueued; @@ -33,8 +34,8 @@ class HandleUserLoggedIn { { $account = Auth::user()->account; - if (!Utils::isNinja() && Auth::user()->id == 1 && empty($account->last_login)) { - $this->accountRepo->registerUser(Auth::user()); + if (empty($account->last_login)) { + event(new UserSignedUp()); } $account->last_login = Carbon::now()->toDateTimeString(); diff --git a/app/Listeners/HandleUserSignedUp.php b/app/Listeners/HandleUserSignedUp.php new file mode 100644 index 000000000000..8d45d3e5a62a --- /dev/null +++ b/app/Listeners/HandleUserSignedUp.php @@ -0,0 +1,37 @@ +accountRepo = $accountRepo; + } + + /** + * Handle the event. + * + * @param UserSignedUp $event + * @return void + */ + public function handle(UserSignedUp $event) + { + if (!Utils::isNinjaProd()) { + $this->accountRepo->registerUser(Auth::user()); + } + } + +} diff --git a/app/Models/Account.php b/app/Models/Account.php index 7f80f7b80998..6817275a8a99 100644 --- a/app/Models/Account.php +++ b/app/Models/Account.php @@ -25,13 +25,6 @@ class Account extends Eloquent return $this->hasMany('App\Models\User'); } - public function getPrimaryUser() - { - return $this->hasMany('App\Models\User') - ->whereRaw('public_id = 0 OR public_id IS NULL') - ->first(); - } - public function clients() { return $this->hasMany('App\Models\Client'); diff --git a/app/Models/Invoice.php b/app/Models/Invoice.php index 52dea6021744..7e0f1ced2db6 100644 --- a/app/Models/Invoice.php +++ b/app/Models/Invoice.php @@ -21,7 +21,7 @@ class Invoice extends EntityModel public function user() { - return $this->belongsTo('App\Models\User'); + return $this->belongsTo('App\Models\User')->withTrashed(); } public function client() diff --git a/app/Models/Language.php b/app/Models/Language.php index d1e757936808..084c2fe86da7 100644 --- a/app/Models/Language.php +++ b/app/Models/Language.php @@ -5,4 +5,9 @@ use Eloquent; class Language extends Eloquent { public $timestamps = false; + + public function getName() + { + return $this->name; + } } diff --git a/app/Models/User.php b/app/Models/User.php index 93b263a55c63..de750d4e71dc 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -5,6 +5,7 @@ use Auth; use Event; use App\Libraries\Utils; use App\Events\UserSettingsChanged; +use App\Events\UserSignedUp; use Illuminate\Auth\Authenticatable; use Illuminate\Database\Eloquent\Model; use Illuminate\Auth\Passwords\CanResetPassword; @@ -35,7 +36,7 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon * * @var array */ - protected $hidden = ['password', 'remember_token']; + protected $hidden = ['password', 'remember_token', 'confirmation_code']; use SoftDeletes; protected $dates = ['deleted_at']; @@ -203,20 +204,30 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon } } - public static function updateUser($user) + public static function onUpdatingUser($user) { - if ($user->password != !$user->getOriginal('password')) { + if ($user->password != $user->getOriginal('password')) { $user->failed_logins = 0; } } + public static function onUpdatedUser($user) + { + if (!$user->getOriginal('email') + || $user->getOriginal('email') == TEST_USERNAME + || $user->getOriginal('username') == TEST_USERNAME) { + event(new UserSignedUp()); + } + + event(new UserSettingsChanged()); + } + } User::updating(function ($user) { - User::updateUser($user); + User::onUpdatingUser($user); }); User::updated(function ($user) { - Event::fire(new UserSettingsChanged()); -}); - + User::onUpdatedUser($user); +}); \ No newline at end of file diff --git a/app/Ninja/Mailers/ContactMailer.php b/app/Ninja/Mailers/ContactMailer.php index 4f4a91ec764e..3dc5305c4861 100644 --- a/app/Ninja/Mailers/ContactMailer.php +++ b/app/Ninja/Mailers/ContactMailer.php @@ -38,7 +38,7 @@ class ContactMailer extends Mailer } else { $user = $invitation->user; if ($invitation->user->trashed()) { - $user = $account->getPrimaryUser(); + $user = $account->users()->orderBy('id')->first(); } } diff --git a/app/Ninja/Repositories/AccountRepository.php b/app/Ninja/Repositories/AccountRepository.php index ace26aac3f49..d2e4af8b8702 100644 --- a/app/Ninja/Repositories/AccountRepository.php +++ b/app/Ninja/Repositories/AccountRepository.php @@ -233,7 +233,11 @@ class AccountRepository public function registerUser($user) { - $url = (Utils::isNinjaDev() ? '' : NINJA_APP_URL) . '/signup/register'; + if ($user->email == TEST_USERNAME) { + return false; + } + + $url = (Utils::isNinjaDev() ? SITE_URL : NINJA_APP_URL) . '/signup/register'; $data = ''; $fields = [ 'first_name' => urlencode($user->first_name), @@ -250,6 +254,7 @@ class AccountRepository curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, count($fields)); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_exec($ch); curl_close($ch); } diff --git a/app/Ninja/Repositories/TaskRepository.php b/app/Ninja/Repositories/TaskRepository.php index 693a1a96b7f2..da84feba7c47 100644 --- a/app/Ninja/Repositories/TaskRepository.php +++ b/app/Ninja/Repositories/TaskRepository.php @@ -45,8 +45,22 @@ class TaskRepository return $query; } + public function getErrors($input) + { + $rules = [ + 'time_log' => 'time_log', + ]; + $validator = \Validator::make($input, $rules); + + if ($validator->fails()) { + return $validator; + } + + return false; + } + public function save($publicId, $data) - { + { if ($publicId) { $task = Task::scope($publicId)->firstOrFail(); } else { diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 4d01f44b50a4..8cf422da913d 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -116,6 +116,26 @@ class AppServiceProvider extends ServiceProvider { return $credit >= $amount; }); + // check that the time log elements don't overlap + Validator::extend('time_log', function($attribute, $value, $parameters) { + $lastTime = 0; + $value = json_decode($value); + array_multisort($value); + foreach ($value as $timeLog) { + list($startTime, $endTime) = $timeLog; + if (!$endTime) { + continue; + } + if ($startTime < $lastTime || $startTime > $endTime) { + return false; + } + if ($endTime < min($startTime, $lastTime)) { + return false; + } + $lastTime = max($lastTime, $endTime); + } + return true; + }); Validator::extend('less_than', function($attribute, $value, $parameters) { return floatval($value) <= floatval($parameters[0]); diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index 3ce33b355412..739c958686c0 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -11,6 +11,9 @@ class EventServiceProvider extends ServiceProvider { * @var array */ protected $listen = [ + 'App\Events\UserSignedUp' => [ + 'App\Listeners\HandleUserSignedUp', + ], 'App\Events\UserLoggedIn' => [ 'App\Listeners\HandleUserLoggedIn', ], diff --git a/config/session.php b/config/session.php index a00d15e74be3..a04d728f4cb0 100644 --- a/config/session.php +++ b/config/session.php @@ -29,7 +29,7 @@ return [ | */ - 'lifetime' => env('SESSION_LIFETIME', 120), + 'lifetime' => env('SESSION_LIFETIME', 1), 'expire_on_close' => false, diff --git a/database/migrations/2015_02_17_131714_support_token_billing.php b/database/migrations/2015_02_17_131714_support_token_billing.php index 0022d44cf2ef..f4c940c0f1bb 100644 --- a/database/migrations/2015_02_17_131714_support_token_billing.php +++ b/database/migrations/2015_02_17_131714_support_token_billing.php @@ -14,7 +14,7 @@ class SupportTokenBilling extends Migration { { Schema::table('accounts', function($table) { - $table->smallInteger('token_billing_type_id')->default(TOKEN_BILLING_OPT_IN); + $table->smallInteger('token_billing_type_id')->default(TOKEN_BILLING_ALWAYS); }); Schema::create('account_gateway_tokens', function($table) @@ -35,7 +35,7 @@ class SupportTokenBilling extends Migration { $table->foreign('client_id')->references('id')->on('clients')->onDelete('cascade'); }); - DB::table('accounts')->update(['token_billing_type_id' => TOKEN_BILLING_OPT_IN]); + DB::table('accounts')->update(['token_billing_type_id' => TOKEN_BILLING_ALWAYS]); } /** diff --git a/database/seeds/PaymentLibrariesSeeder.php b/database/seeds/PaymentLibrariesSeeder.php index d7f5ff50d115..e1367bd0c9d9 100644 --- a/database/seeds/PaymentLibrariesSeeder.php +++ b/database/seeds/PaymentLibrariesSeeder.php @@ -70,27 +70,27 @@ class PaymentLibrariesSeeder extends Seeder $currencies = [ ['name' => 'US Dollar', 'code' => 'USD', 'symbol' => '$', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'], ['name' => 'Pound Sterling', 'code' => 'GBP', 'symbol' => '£', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'], - ['name' => 'Euro', 'code' => 'EUR', 'symbol' => '€', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'], - ['name' => 'South African Rand', 'code' => 'ZAR', 'symbol' => 'R', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'], - ['name' => 'Danish Krone', 'code' => 'DKK', 'symbol' => 'kr ', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'], + ['name' => 'Euro', 'code' => 'EUR', 'symbol' => '€', 'precision' => '2', 'thousand_separator' => '.', 'decimal_separator' => ','], + ['name' => 'South African Rand', 'code' => 'ZAR', 'symbol' => 'R', 'precision' => '2', 'thousand_separator' => '.', 'decimal_separator' => ','], + ['name' => 'Danish Krone', 'code' => 'DKK', 'symbol' => 'kr ', 'precision' => '2', 'thousand_separator' => '.', 'decimal_separator' => ','], ['name' => 'Israeli Shekel', 'code' => 'ILS', 'symbol' => 'NIS ', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'], - ['name' => 'Swedish Krona', 'code' => 'SEK', 'symbol' => 'kr ', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'], + ['name' => 'Swedish Krona', 'code' => 'SEK', 'symbol' => 'kr ', 'precision' => '2', 'thousand_separator' => '.', 'decimal_separator' => ','], ['name' => 'Kenyan Shilling', 'code' => 'KES', 'symbol' => 'KSh ', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'], ['name' => 'Canadian Dollar', 'code' => 'CAD', 'symbol' => 'C$', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'], ['name' => 'Philippine Peso', 'code' => 'PHP', 'symbol' => 'P ', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'], ['name' => 'Indian Rupee', 'code' => 'INR', 'symbol' => 'Rs. ', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'], ['name' => 'Australian Dollar', 'code' => 'AUD', 'symbol' => '$', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'], ['name' => 'Singapore Dollar', 'code' => 'SGD', 'symbol' => 'SGD ', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'], - ['name' => 'Norske Kroner', 'code' => 'NOK', 'symbol' => 'kr ', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'], + ['name' => 'Norske Kroner', 'code' => 'NOK', 'symbol' => 'kr ', 'precision' => '2', 'thousand_separator' => '.', 'decimal_separator' => ','], ['name' => 'New Zealand Dollar', 'code' => 'NZD', 'symbol' => '$', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'], - ['name' => 'Vietnamese Dong', 'code' => 'VND', 'symbol' => 'VND ', 'precision' => '0', 'thousand_separator' => ',', 'decimal_separator' => '.'], - ['name' => 'Swiss Franc', 'code' => 'CHF', 'symbol' => 'CHF ', 'precision' => '2', 'thousand_separator' => '\'', 'decimal_separator' => '.'], + ['name' => 'Vietnamese Dong', 'code' => 'VND', 'symbol' => 'VND ', 'precision' => '0', 'thousand_separator' => '.', 'decimal_separator' => ','], + ['name' => 'Swiss Franc', 'code' => 'CHF', 'symbol' => 'CHF ', 'precision' => '2', 'thousand_separator' => '\'', 'decimal_separator' => ','], ['name' => 'Guatemalan Quetzal', 'code' => 'GTQ', 'symbol' => 'Q', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'], ['name' => 'Malaysian Ringgit', 'code' => 'MYR', 'symbol' => 'RM', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'], - ['name' => 'Brazilian Real', 'code' => 'BRL', 'symbol' => 'R$', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'], + ['name' => 'Brazilian Real', 'code' => 'BRL', 'symbol' => 'R$', 'precision' => '2', 'thousand_separator' => '.', 'decimal_separator' => ','], ['name' => 'Thai baht', 'code' => 'THB', 'symbol' => 'THB ', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'], ['name' => 'Nigerian Naira', 'code' => 'NGN', 'symbol' => 'NGN ', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'], - ['name' => 'Argentine Peso', 'code' => 'ARS', 'symbol' => '$', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'], + ['name' => 'Argentine Peso', 'code' => 'ARS', 'symbol' => '$', 'precision' => '2', 'thousand_separator' => '.', 'decimal_separator' => ','], ['name' => 'Bangladeshi Taka', 'code' => 'BDT', 'symbol' => 'Tk', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'], ]; @@ -98,6 +98,8 @@ class PaymentLibrariesSeeder extends Seeder $record = Currency::whereCode($currency['code'])->first(); if ($record) { $record->name = $currency['name']; + $record->thousand_separator = $currency['thousand_separator']; + $record->decimal_separator = $currency['decimal_separator']; $record->save(); } else { Currency::create($currency); diff --git a/database/seeds/UserTableSeeder.php b/database/seeds/UserTableSeeder.php index 82226be35b06..51b88a3136f8 100644 --- a/database/seeds/UserTableSeeder.php +++ b/database/seeds/UserTableSeeder.php @@ -2,6 +2,7 @@ use App\Models\User; use App\Models\Account; +use App\Models\Affiliate; class UserTableSeeder extends Seeder { @@ -26,6 +27,11 @@ class UserTableSeeder extends Seeder 'registered' => true, 'confirmed' => true, ]); + + Affiliate::create([ + 'affiliate_key' => SELF_HOST_AFFILIATE_KEY + ]); + } } \ No newline at end of file diff --git a/public/js/built.js b/public/js/built.js index 49efc7c1f491..ff9a7a3d9810 100644 --- a/public/js/built.js +++ b/public/js/built.js @@ -31834,7 +31834,7 @@ NINJA.invoiceLines = function(invoice) { } // show at most one blank line - if (shownItem && (!cost || cost == '0.00') && !notes && !productKey) { + if (shownItem && (!cost || cost == '0.00' || cost == '0,00') && !notes && !productKey) { continue; } diff --git a/public/js/pdf.pdfmake.js b/public/js/pdf.pdfmake.js index d4a76e5da70f..9801387a403a 100644 --- a/public/js/pdf.pdfmake.js +++ b/public/js/pdf.pdfmake.js @@ -278,7 +278,7 @@ NINJA.invoiceLines = function(invoice) { } // show at most one blank line - if (shownItem && (!cost || cost == '0.00') && !notes && !productKey) { + if (shownItem && (!cost || cost == '0.00' || cost == '0,00') && !notes && !productKey) { continue; } diff --git a/resources/views/accounts/account_gateway.blade.php b/resources/views/accounts/account_gateway.blade.php index 2aa79c2dbb68..5b6a7860a474 100644 --- a/resources/views/accounts/account_gateway.blade.php +++ b/resources/views/accounts/account_gateway.blade.php @@ -76,7 +76,9 @@ @endif @if ($gateway->id == GATEWAY_STRIPE) - {!! Former::select('token_billing_type_id')->options($tokenBillingOptions)->help(trans('texts.token_billing_help')) !!} + {!! Former::select('token_billing_type_id') + ->options($tokenBillingOptions) + ->help(trans('texts.token_billing_help')) !!} @endif diff --git a/resources/views/header.blade.php b/resources/views/header.blade.php index de492e3e9476..7bf2c20f0212 100644 --- a/resources/views/header.blade.php +++ b/resources/views/header.blade.php @@ -637,7 +637,8 @@ @if (!Utils::isNinjaProd())

 

- {{ trans('texts.powered_by') }} InvoiceNinja.com | + {{ trans('texts.powered_by') }} InvoiceNinja.com - + {!! link_to(GITHUB_RELEASES, 'v' . NINJA_VERSION, ['target' => '_blank']) !!} | @if (Auth::user()->account->isWhiteLabel()) {{ trans('texts.white_labeled') }} @else diff --git a/resources/views/invoices/edit.blade.php b/resources/views/invoices/edit.blade.php index 894b210959f0..5aa57cb2fd76 100644 --- a/resources/views/invoices/edit.blade.php +++ b/resources/views/invoices/edit.blade.php @@ -1847,7 +1847,7 @@ } @if ($data) - window.model = new ViewModel({!! $data !!}); + window.model = new ViewModel({!! $data !!}); @else window.model = new ViewModel(); model.addTaxRate(); diff --git a/resources/views/tasks/edit.blade.php b/resources/views/tasks/edit.blade.php index 882ccc9b7784..b1cafebc3ceb 100644 --- a/resources/views/tasks/edit.blade.php +++ b/resources/views/tasks/edit.blade.php @@ -180,15 +180,7 @@ if (!timeLog.isEmpty()) { data.push([timeLog.startTime(),timeLog.endTime()]); } - @if ($task && !$task->is_running) - if (!timeLog.isStartValid() || !timeLog.isEndValid()) { - alert("{!! trans('texts.task_errors') !!}"); - showTimeDetails(); - return; - } - @endif - - } + } $('#invoice_id').val(invoice_id); $('#time_log').val(JSON.stringify(data)); $('#action').val(action); @@ -279,6 +271,15 @@ }; } + function loadTimeLog(data) { + model.time_log.removeAll(); + data = JSON.parse(data); + for (var i=0; i timeLog.endTime()) { startValid = false; } @@ -323,9 +329,6 @@ timeLog.isStartValid(startValid); timeLog.isEndValid(endValid); } - if (!hasEmpty) { - self.addItem(); - } } self.addItem = function() { @@ -360,7 +363,7 @@ if (val == 'timer') { $('#datetime-details').hide(); } else { - $('#datetime-details').fadeIn(); + $('#datetime-details').fadeIn(); } $('#start-button').toggle(); $('#save-button').toggle(); @@ -384,6 +387,12 @@ tock({{ $duration }}); @endif @endif + + @if (Session::has('error')) + loadTimeLog({!! json_encode(Input::old('time_log')) !!}); + model.showTimeOverlaps(); + showTimeDetails(); + @endif });