mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-09 12:42:36 +01:00
Fixed money format in PDF for EU
This commit is contained in:
parent
6b063abe9a
commit
4268c18f8a
@ -1,34 +1,51 @@
|
||||
<?php namespace App\Console;
|
||||
<?php namespace app\Console;
|
||||
|
||||
use Utils;
|
||||
use Illuminate\Console\Scheduling\Schedule;
|
||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||
|
||||
class Kernel extends ConsoleKernel {
|
||||
|
||||
/**
|
||||
* The Artisan commands provided by your application.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $commands = [
|
||||
'App\Console\Commands\SendRecurringInvoices',
|
||||
'App\Console\Commands\CreateRandomData',
|
||||
'App\Console\Commands\ResetData',
|
||||
'App\Console\Commands\CheckData',
|
||||
class Kernel extends ConsoleKernel
|
||||
{
|
||||
/**
|
||||
* The Artisan commands provided by your application.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $commands = [
|
||||
'App\Console\Commands\SendRecurringInvoices',
|
||||
'App\Console\Commands\CreateRandomData',
|
||||
'App\Console\Commands\ResetData',
|
||||
'App\Console\Commands\CheckData',
|
||||
'App\Console\Commands\SendRenewalInvoices',
|
||||
'App\Console\Commands\SendReminders',
|
||||
];
|
||||
];
|
||||
|
||||
/**
|
||||
* Define the application's command schedule.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Schedule $schedule
|
||||
* @return void
|
||||
*/
|
||||
protected function schedule(Schedule $schedule)
|
||||
{
|
||||
// $schedule->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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
21
app/Events/UserSignedUp.php
Normal file
21
app/Events/UserSignedUp.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php namespace App\Events;
|
||||
|
||||
use App\Events\Event;
|
||||
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class UserSignedUp extends Event {
|
||||
|
||||
use SerializesModels;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
}
|
@ -27,11 +27,13 @@ class Handler extends ExceptionHandler {
|
||||
*/
|
||||
public function report(Exception $e)
|
||||
{
|
||||
Utils::logError(Utils::getErrorString($e));
|
||||
return false;
|
||||
|
||||
//return parent::report($e);
|
||||
}
|
||||
if (Utils::isNinja()) {
|
||||
Utils::logError(Utils::getErrorString($e));
|
||||
return false;
|
||||
} else {
|
||||
return parent::report($e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render an exception into an HTTP response.
|
||||
@ -41,8 +43,7 @@ class Handler extends ExceptionHandler {
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function render($request, Exception $e)
|
||||
{
|
||||
|
||||
{
|
||||
if ($e instanceof ModelNotFoundException) {
|
||||
return Redirect::to('/');
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ use App\Models\InvoiceDesign;
|
||||
use App\Ninja\Repositories\AccountRepository;
|
||||
use App\Ninja\Mailers\UserMailer;
|
||||
use App\Ninja\Mailers\ContactMailer;
|
||||
use App\Events\UserSignedUp;
|
||||
use App\Events\UserLoggedIn;
|
||||
use App\Events\UserSettingsChanged;
|
||||
|
||||
@ -109,7 +110,8 @@ class AccountController extends BaseController
|
||||
}
|
||||
|
||||
Auth::login($user, true);
|
||||
Event::fire(new UserLoggedIn());
|
||||
event(new UserSignedUp());
|
||||
event(new UserLoggedIn());
|
||||
|
||||
$redirectTo = Input::get('redirect_to', 'invoices/create');
|
||||
return Redirect::to($redirectTo)->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()
|
||||
|
@ -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');
|
||||
|
@ -12,7 +12,6 @@ use DB;
|
||||
use Event;
|
||||
use URL;
|
||||
use Datatable;
|
||||
use finfo;
|
||||
use Request;
|
||||
use DropdownButton;
|
||||
use App\Models\Invoice;
|
||||
|
@ -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'));
|
||||
|
||||
|
@ -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'));
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
|
37
app/Listeners/HandleUserSignedUp.php
Normal file
37
app/Listeners/HandleUserSignedUp.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php namespace App\Listeners;
|
||||
|
||||
use Utils;
|
||||
use Auth;
|
||||
use App\Events\UserSignedUp;
|
||||
use App\Ninja\Repositories\AccountRepository;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldBeQueued;
|
||||
|
||||
class HandleUserSignedUp {
|
||||
|
||||
protected $accountRepo;
|
||||
|
||||
/**
|
||||
* Create the event handler.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(AccountRepository $accountRepo)
|
||||
{
|
||||
$this->accountRepo = $accountRepo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the event.
|
||||
*
|
||||
* @param UserSignedUp $event
|
||||
* @return void
|
||||
*/
|
||||
public function handle(UserSignedUp $event)
|
||||
{
|
||||
if (!Utils::isNinjaProd()) {
|
||||
$this->accountRepo->registerUser(Auth::user());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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');
|
||||
|
@ -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()
|
||||
|
@ -5,4 +5,9 @@ use Eloquent;
|
||||
class Language extends Eloquent
|
||||
{
|
||||
public $timestamps = false;
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
});
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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]);
|
||||
|
@ -11,6 +11,9 @@ class EventServiceProvider extends ServiceProvider {
|
||||
* @var array
|
||||
*/
|
||||
protected $listen = [
|
||||
'App\Events\UserSignedUp' => [
|
||||
'App\Listeners\HandleUserSignedUp',
|
||||
],
|
||||
'App\Events\UserLoggedIn' => [
|
||||
'App\Listeners\HandleUserLoggedIn',
|
||||
],
|
||||
|
@ -29,7 +29,7 @@ return [
|
||||
|
|
||||
*/
|
||||
|
||||
'lifetime' => env('SESSION_LIFETIME', 120),
|
||||
'lifetime' => env('SESSION_LIFETIME', 1),
|
||||
|
||||
'expire_on_close' => false,
|
||||
|
||||
|
@ -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]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
</div>
|
||||
|
||||
|
@ -637,7 +637,8 @@
|
||||
@if (!Utils::isNinjaProd())
|
||||
<p> </p>
|
||||
<div class="container">
|
||||
{{ trans('texts.powered_by') }} <a href="https://www.invoiceninja.com/?utm_source=powered_by" target="_blank">InvoiceNinja.com</a> |
|
||||
{{ trans('texts.powered_by') }} <a href="https://www.invoiceninja.com/?utm_source=powered_by" target="_blank">InvoiceNinja.com</a> -
|
||||
{!! link_to(GITHUB_RELEASES, 'v' . NINJA_VERSION, ['target' => '_blank']) !!} |
|
||||
@if (Auth::user()->account->isWhiteLabel())
|
||||
{{ trans('texts.white_labeled') }}
|
||||
@else
|
||||
|
@ -1847,7 +1847,7 @@
|
||||
}
|
||||
|
||||
@if ($data)
|
||||
window.model = new ViewModel({!! $data !!});
|
||||
window.model = new ViewModel({!! $data !!});
|
||||
@else
|
||||
window.model = new ViewModel();
|
||||
model.addTaxRate();
|
||||
|
@ -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<data.length; i++) {
|
||||
model.time_log.push(new TimeModel(data[i]));
|
||||
}
|
||||
model.time_log.push(new TimeModel());
|
||||
}
|
||||
|
||||
function ViewModel(data) {
|
||||
var self = this;
|
||||
self.time_log = ko.observableArray();
|
||||
@ -287,31 +288,36 @@
|
||||
data = JSON.parse(data.time_log);
|
||||
for (var i=0; i<data.length; i++) {
|
||||
self.time_log.push(new TimeModel(data[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
self.time_log.push(new TimeModel());
|
||||
|
||||
self.removeItem = function(item) {
|
||||
self.time_log.remove(item);
|
||||
self.refresh();
|
||||
self.removeItem = function(item) {
|
||||
self.time_log.remove(item);
|
||||
self.refresh();
|
||||
}
|
||||
|
||||
self.refresh = function() {
|
||||
var hasEmpty = false;
|
||||
var lastTime = 0;
|
||||
self.time_log.sort(function(left, right) {
|
||||
if (left.isEmpty() || right.isEmpty()) {
|
||||
return -1;
|
||||
for (var i=0; i<self.time_log().length; i++) {
|
||||
var timeLog = self.time_log()[i];
|
||||
if (timeLog.isEmpty()) {
|
||||
hasEmpty = true;
|
||||
}
|
||||
return left.startTime() - right.startTime();
|
||||
});
|
||||
}
|
||||
if (!hasEmpty) {
|
||||
self.addItem();
|
||||
}
|
||||
}
|
||||
|
||||
self.showTimeOverlaps = function() {
|
||||
var lastTime = 0;
|
||||
for (var i=0; i<self.time_log().length; i++) {
|
||||
var timeLog = self.time_log()[i];
|
||||
var startValid = true;
|
||||
var endValid = true;
|
||||
if (timeLog.isEmpty()) {
|
||||
hasEmpty = true;
|
||||
} else {
|
||||
if (!timeLog.isEmpty()) {
|
||||
if (timeLog.startTime() < lastTime || timeLog.startTime() > 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
|
||||
});
|
||||
|
||||
</script>
|
||||
|
Loading…
Reference in New Issue
Block a user