mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-09-20 00:11:35 +02:00
Working on multi-user support
This commit is contained in:
parent
4b177e160d
commit
051ba95b7b
@ -4,6 +4,6 @@ return array(
|
||||
|
||||
//'TAG_MANAGER_KEY' => '',
|
||||
//'ANALYTICS_KEY' => '',
|
||||
//'NINJA_PROD' => true,
|
||||
//'NINJA_DEV' => true,
|
||||
|
||||
);
|
||||
|
@ -11,20 +11,53 @@
|
||||
|
||||
use ninja\repositories\AccountRepository;
|
||||
use ninja\mailers\ContactMailer;
|
||||
use ninja\mailers\UserMailer;
|
||||
|
||||
class UserController extends BaseController {
|
||||
|
||||
protected $accountRepo;
|
||||
protected $contactMailer;
|
||||
protected $userMailer;
|
||||
|
||||
public function __construct(AccountRepository $accountRepo, ContactMailer $contactMailer)
|
||||
public function __construct(AccountRepository $accountRepo, ContactMailer $contactMailer, UserMailer $userMailer)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->accountRepo = $accountRepo;
|
||||
$this->contactMailer = $contactMailer;
|
||||
$this->userMailer = $userMailer;
|
||||
}
|
||||
|
||||
public function getDatatable()
|
||||
{
|
||||
$query = DB::table('users')
|
||||
->where('users.account_id', '=', Auth::user()->account_id)
|
||||
->where('users.deleted_at', '=', null)
|
||||
->where('users.public_id', '>', 0)
|
||||
->select('users.public_id', 'users.first_name', 'users.last_name', 'users.email', 'users.confirmed', 'users.public_id');
|
||||
|
||||
|
||||
return Datatable::query($query)
|
||||
->addColumn('first_name', function($model) { return link_to('users/' . $model->public_id . '/edit', $model->first_name . ' ' . $model->last_name); })
|
||||
->addColumn('email', function($model) { return $model->email; })
|
||||
->addColumn('confirmed', function($model) { return $model->confirmed ? trans('texts.active') : trans('texts.pending'); })
|
||||
->addColumn('dropdown', function($model)
|
||||
{
|
||||
return '<div class="btn-group tr-action" style="visibility:hidden;">
|
||||
<button type="button" class="btn btn-xs btn-default dropdown-toggle" data-toggle="dropdown">
|
||||
'.trans('texts.select').' <span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li><a href="' . URL::to('users/'.$model->public_id) . '/edit">'.uctrans('texts.edit_user').'</a></li>
|
||||
<li class="divider"></li>
|
||||
<li><a href="javascript:deleteUser(' . $model->public_id. ')">'.uctrans('texts.delete_user').'</a></li>
|
||||
</ul>
|
||||
</div>';
|
||||
})
|
||||
->orderColumns(['first_name', 'email', 'confirmed'])
|
||||
->make();
|
||||
}
|
||||
|
||||
public function setTheme()
|
||||
{
|
||||
$user = User::find(Auth::user()->id);
|
||||
@ -45,50 +78,146 @@ class UserController extends BaseController {
|
||||
return Redirect::to('/dashboard');
|
||||
}
|
||||
|
||||
public function edit($publicId)
|
||||
{
|
||||
$user = User::where('account_id', '=', Auth::user()->account_id)
|
||||
->where('public_id', '=', $publicId)->firstOrFail();
|
||||
|
||||
$data = [
|
||||
'showBreadcrumbs' => false,
|
||||
'user' => $user,
|
||||
'method' => 'PUT',
|
||||
'url' => 'users/' . $publicId,
|
||||
'title' => trans('texts.edit_user')
|
||||
];
|
||||
|
||||
return View::make('users.edit', $data);
|
||||
}
|
||||
|
||||
public function update($publicId)
|
||||
{
|
||||
return $this->save($publicId);
|
||||
}
|
||||
|
||||
public function store()
|
||||
{
|
||||
return $this->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the form for account creation
|
||||
*
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
return View::make(Config::get('confide::signup_form'));
|
||||
if (!Auth::user()->confirmed)
|
||||
{
|
||||
Session::flash('error', trans('texts.register_to_add_user'));
|
||||
return Redirect::to('company/advanced_settings/user_management');
|
||||
}
|
||||
|
||||
if (Utils::isNinja())
|
||||
{
|
||||
$count = User::where('account_id', '=', Auth::user()->account_id)->count();
|
||||
if ($count >= MAX_NUM_USERS)
|
||||
{
|
||||
Session::flash('error', trans('texts.limit_users'));
|
||||
return Redirect::to('company/advanced_settings/user_management');
|
||||
}
|
||||
}
|
||||
|
||||
$data = [
|
||||
'showBreadcrumbs' => false,
|
||||
'user' => null,
|
||||
'method' => 'POST',
|
||||
'url' => 'users',
|
||||
'title' => trans('texts.add_user')
|
||||
];
|
||||
|
||||
return View::make('users.edit', $data);
|
||||
}
|
||||
|
||||
public function delete()
|
||||
{
|
||||
$userPublicId = Input::get('userPublicId');
|
||||
$user = User::where('account_id', '=', Auth::user()->account_id)
|
||||
->where('public_id', '=', $userPublicId)->firstOrFail();
|
||||
|
||||
$user->delete();
|
||||
|
||||
Session::flash('message', trans('texts.deleted_user'));
|
||||
return Redirect::to('company/advanced_settings/user_management');
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores new account
|
||||
*
|
||||
*/
|
||||
public function store()
|
||||
public function save($userPublicId = false)
|
||||
{
|
||||
$user = new User;
|
||||
$rules = [
|
||||
'first_name' => 'required',
|
||||
'last_name' => 'required',
|
||||
];
|
||||
|
||||
$user->username = Input::get( 'username' );
|
||||
$user->email = Input::get( 'email' );
|
||||
$user->password = Input::get( 'password' );
|
||||
|
||||
// The password confirmation will be removed from model
|
||||
// before saving. This field will be used in Ardent's
|
||||
// auto validation.
|
||||
$user->password_confirmation = Input::get( 'password_confirmation' );
|
||||
|
||||
// Save if valid. Password field will be hashed before save
|
||||
$user->save();
|
||||
|
||||
if ( $user->id )
|
||||
if ($userPublicId)
|
||||
{
|
||||
// Redirect with success message, You may replace "Lang::get(..." for your custom message.
|
||||
return Redirect::action('UserController@login')
|
||||
->with( 'notice', Lang::get('confide::confide.alerts.account_created') );
|
||||
$user = User::where('account_id', '=', Auth::user()->account_id)
|
||||
->where('public_id', '=', $userPublicId)->firstOrFail();
|
||||
|
||||
$rules['email'] = 'required|email|unique:users,email,' . $user->id . ',id';
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get validation errors (see Ardent package)
|
||||
$error = $user->errors()->all(':message');
|
||||
|
||||
return Redirect::action('UserController@create')
|
||||
->withInput(Input::except('password'))
|
||||
->with( 'error', $error );
|
||||
$rules['email'] = 'required|email|unique:users';
|
||||
}
|
||||
|
||||
$validator = Validator::make(Input::all(), $rules);
|
||||
|
||||
if ($validator->fails())
|
||||
{
|
||||
return Redirect::to($userPublicId ? 'users/edit' : 'users/create')->withInput()->withErrors($validator);
|
||||
}
|
||||
|
||||
if ($userPublicId)
|
||||
{
|
||||
$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(Input::get('email'));
|
||||
}
|
||||
else
|
||||
{
|
||||
$lastUser = User::withTrashed()->where('account_id', '=', Auth::user()->account_id)
|
||||
->orderBy('public_id', 'DESC')->first();
|
||||
|
||||
$user = new User;
|
||||
$user->account_id = Auth::user()->account_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(Input::get('email'));
|
||||
$user->registered = true;
|
||||
$user->password = str_random(RANDOM_KEY_LENGTH);
|
||||
$user->password_confirmation = $user->password;
|
||||
$user->public_id = $lastUser->public_id + 1;
|
||||
}
|
||||
|
||||
$user->save();
|
||||
|
||||
if (!$user->confirmed)
|
||||
{
|
||||
$this->userMailer->sendConfirmation($user, Auth::user());
|
||||
$message = trans('texts.sent_invite');
|
||||
}
|
||||
else
|
||||
{
|
||||
$message = trans('texts.updated_user');
|
||||
}
|
||||
|
||||
Session::flash('message', $message);
|
||||
|
||||
return Redirect::to('company/advanced_settings/user_management');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -183,21 +312,34 @@ class UserController extends BaseController {
|
||||
public function confirm( $code )
|
||||
{
|
||||
if ( Confide::confirm( $code ) )
|
||||
{
|
||||
{
|
||||
$notice_msg = trans('texts.confide.confirmation');
|
||||
|
||||
$user = User::where('confirmation_code', '=', $code)->get()->first();
|
||||
$user->confirmation_code = '';
|
||||
$user->save();
|
||||
|
||||
if (Session::has(REQUESTED_PRO_PLAN))
|
||||
if ($user->public_id)
|
||||
{
|
||||
Session::forget(REQUESTED_PRO_PLAN);
|
||||
Auth::login($user);
|
||||
|
||||
if ($invoice = $this->accountRepo->enableProPlan())
|
||||
return Redirect::to('user/reset');
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Session::has(REQUESTED_PRO_PLAN))
|
||||
{
|
||||
$this->contactMailer->sendInvoice($invoice);
|
||||
$notice_msg = trans('texts.pro_plan_success');
|
||||
}
|
||||
}
|
||||
Session::forget(REQUESTED_PRO_PLAN);
|
||||
|
||||
return Redirect::action('UserController@login')->with( 'message', $notice_msg );
|
||||
if ($invoice = $this->accountRepo->enableProPlan())
|
||||
{
|
||||
$this->contactMailer->sendInvoice($invoice);
|
||||
$notice_msg = trans('texts.pro_plan_success');
|
||||
}
|
||||
}
|
||||
|
||||
return Redirect::action('UserController@login')->with( 'message', $notice_msg );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -249,7 +391,7 @@ class UserController extends BaseController {
|
||||
* Shows the change password form with the given token
|
||||
*
|
||||
*/
|
||||
public function reset_password( $token )
|
||||
public function reset_password( $token = false )
|
||||
{
|
||||
return View::make(Config::get('confide::reset_password_form'))
|
||||
->with('token', $token);
|
||||
@ -260,26 +402,49 @@ class UserController extends BaseController {
|
||||
*
|
||||
*/
|
||||
public function do_reset_password()
|
||||
{
|
||||
$input = array(
|
||||
'token'=>Input::get( 'token' ),
|
||||
'password'=>Input::get( 'password' ),
|
||||
'password_confirmation'=>Input::get( 'password_confirmation' ),
|
||||
);
|
||||
|
||||
// By passing an array with the token, password and confirmation
|
||||
if( Confide::resetPassword( $input ) )
|
||||
{
|
||||
if (Auth::check())
|
||||
{
|
||||
$notice_msg = trans('texts.confide.password_reset');
|
||||
return Redirect::action('UserController@login')
|
||||
->with( 'notice', $notice_msg );
|
||||
$rules = [
|
||||
'password' => 'required|between:4,11|confirmed',
|
||||
'password_confirmation' => 'between:4,11',
|
||||
];
|
||||
$validator = Validator::make(Input::all(), $rules);
|
||||
|
||||
if ($validator->fails())
|
||||
{
|
||||
return Redirect::to('user/reset')->withInput()->withErrors($validator);
|
||||
}
|
||||
|
||||
$user = Auth::user();
|
||||
$user->password = Input::get('password');
|
||||
$user->save();
|
||||
|
||||
Session::flash('message', trans('texts.confide.password_reset'));
|
||||
return Redirect::to('/dashboard');
|
||||
}
|
||||
else
|
||||
{
|
||||
$error_msg = trans('texts.confide.wrong_password_reset');
|
||||
return Redirect::action('UserController@reset_password', array('token'=>$input['token']))
|
||||
->withInput()
|
||||
->with( 'error', $error_msg );
|
||||
$input = array(
|
||||
'token'=>Input::get( 'token' ),
|
||||
'password'=>Input::get( 'password' ),
|
||||
'password_confirmation'=>Input::get( 'password_confirmation' ),
|
||||
);
|
||||
|
||||
// By passing an array with the token, password and confirmation
|
||||
if( Confide::resetPassword( $input ) )
|
||||
{
|
||||
$notice_msg = trans('texts.confide.password_reset');
|
||||
return Redirect::action('UserController@login')
|
||||
->with( 'notice', $notice_msg );
|
||||
}
|
||||
else
|
||||
{
|
||||
$error_msg = trans('texts.confide.wrong_password_reset');
|
||||
return Redirect::action('UserController@reset_password', array('token'=>$input['token']))
|
||||
->withInput()
|
||||
->with( 'error', $error_msg );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -400,11 +400,24 @@ return array(
|
||||
'invoice_fields' => 'Invoice Fields',
|
||||
'invoice_options' => 'Invoice Options',
|
||||
'hide_quantity' => 'Hide quantity',
|
||||
'hide_quantity_help' => 'All line items will have a quantity of one',
|
||||
'hide_quantity_help' => 'If your line items quantities are always 1, then you can declutter invoices by no longer displaying this field.',
|
||||
'hide_paid_to_date' => 'Hide paid to date',
|
||||
'hide_paid_to_date_help' => 'Hide until a payment is made',
|
||||
'hide_paid_to_date_help' => 'Only display the "Paid to Date" area on your invoices once a payment has been received.',
|
||||
|
||||
'charge_taxes' => 'Charge taxes',
|
||||
'user_management' => 'User Management',
|
||||
'add_user' => 'Add User',
|
||||
'send_invite' => 'Send invitation',
|
||||
'sent_invite' => 'Successfully sent invitation',
|
||||
'updated_user' => 'Successfully updated user',
|
||||
'invitation_message' => 'You\'ve been invited by :invitor. ',
|
||||
'register_to_add_user' => 'Please sign up to add a user',
|
||||
'user_state' => 'State',
|
||||
'edit_user' => 'Edit User',
|
||||
'delete_user' => 'Delete User',
|
||||
'active' => 'Active',
|
||||
'pending' => 'Pending',
|
||||
'deleted_user' => 'Successfully deleted user',
|
||||
'limit_users' => 'Sorry, this will exceed the limit of ' . MAX_NUM_USERS . ' users',
|
||||
|
||||
);
|
||||
|
||||
);
|
@ -8,7 +8,7 @@ use Utils;
|
||||
|
||||
class UserMailer extends Mailer {
|
||||
|
||||
public function sendConfirmation(User $user)
|
||||
public function sendConfirmation(User $user, User $invitor = null)
|
||||
{
|
||||
if (!$user->email)
|
||||
{
|
||||
@ -19,7 +19,8 @@ class UserMailer extends Mailer {
|
||||
$subject = trans('texts.confirmation_subject');
|
||||
|
||||
$data = [
|
||||
'user' => $user
|
||||
'user' => $user,
|
||||
'invitationMessage' => $invitor ? trans('texts.invitation_message', ['invitor' => $invitor->getDisplayName()]) : ''
|
||||
];
|
||||
|
||||
$this->sendTo($user->email, CONTACT_EMAIL, CONTACT_NAME, $subject, $view, $data);
|
||||
|
@ -261,8 +261,8 @@ class InvoiceRepository
|
||||
$total *= (100 - $invoice->discount) / 100;
|
||||
}
|
||||
|
||||
$invoice->custom_value1 = $data['custom_value1'];
|
||||
$invoice->custom_value2 = $data['custom_value2'];
|
||||
$invoice->custom_value1 = round($data['custom_value1'], 2);
|
||||
$invoice->custom_value2 = round($data['custom_value2'], 2);
|
||||
$invoice->custom_taxes1 = $data['custom_taxes1'] ? true : false;
|
||||
$invoice->custom_taxes2 = $data['custom_taxes2'] ? true : false;
|
||||
|
||||
|
@ -57,7 +57,7 @@ Route::post('login', 'UserController@do_login');
|
||||
Route::get('user/confirm/{code}', 'UserController@confirm');
|
||||
Route::get('forgot_password', 'UserController@forgot_password');
|
||||
Route::post('forgot_password', 'UserController@do_forgot_password');
|
||||
Route::get('user/reset/{token}', 'UserController@reset_password');
|
||||
Route::get('user/reset/{token?}', 'UserController@reset_password');
|
||||
Route::post('user/reset', 'UserController@do_reset_password');
|
||||
Route::get('logout', 'UserController@logout');
|
||||
|
||||
@ -67,18 +67,15 @@ Route::group(array('before' => 'auth'), function()
|
||||
Route::get('dashboard', 'DashboardController@index');
|
||||
Route::get('view_archive/{entity_type}/{visible}', 'AccountController@setTrashVisible');
|
||||
Route::get('force_inline_pdf', 'UserController@forcePDFJS');
|
||||
|
||||
Route::get('api/users', array('as'=>'api.users', 'uses'=>'UserController@getDatatable'));
|
||||
Route::resource('users', 'UserController');
|
||||
Route::post('users/delete', 'UserController@delete');
|
||||
|
||||
Route::get('api/products', array('as'=>'api.products', 'uses'=>'ProductController@getDatatable'));
|
||||
Route::resource('products', 'ProductController');
|
||||
Route::get('products/{product_id}/archive', 'ProductController@archive');
|
||||
|
||||
/*
|
||||
Route::get('company/products/{product_id}/edit', 'ProductController@showProduct');
|
||||
Route::get('company/products/{product_id}/archive', 'ProductController@archiveProduct');
|
||||
Route::get('company/products/create', 'ProductController@createProduct');
|
||||
Route::post('company/products/{product_id?}', 'AccountController@saveProduct');
|
||||
*/
|
||||
|
||||
Route::get('company/advanced_settings/chart_builder', 'ReportController@report');
|
||||
Route::post('company/advanced_settings/chart_builder', 'ReportController@report');
|
||||
|
||||
@ -163,14 +160,16 @@ define('ACCOUNT_ADVANCED_SETTINGS', 'advanced_settings');
|
||||
define('ACCOUNT_CUSTOM_FIELDS', 'custom_fields');
|
||||
define('ACCOUNT_INVOICE_DESIGN', 'invoice_design');
|
||||
define('ACCOUNT_CHART_BUILDER', 'chart_builder');
|
||||
|
||||
define('ACCOUNT_USER_MANAGEMENT', 'user_management');
|
||||
|
||||
|
||||
define('DEFAULT_INVOICE_NUMBER', '0001');
|
||||
define('RECENTLY_VIEWED_LIMIT', 8);
|
||||
define('LOGGED_ERROR_LIMIT', 100);
|
||||
define('RANDOM_KEY_LENGTH', 32);
|
||||
define('MAX_NUM_CLIENTS', 500);
|
||||
define('MAX_NUM_CLIENTS_PRO', 5000);
|
||||
define('MAX_NUM_CLIENTS_PRO', 20000);
|
||||
define('MAX_NUM_USERS', 5);
|
||||
|
||||
define('INVOICE_STATUS_DRAFT', 1);
|
||||
define('INVOICE_STATUS_SENT', 2);
|
||||
|
@ -58,9 +58,15 @@ $monolog->pushHandler(new Monolog\Handler\SyslogHandler('intranet', 'user', Logg
|
||||
|
||||
App::error(function(Exception $exception, $code)
|
||||
{
|
||||
Utils::logError($exception . ' ' . $code);
|
||||
|
||||
return Response::view('error', ['hideHeader' => true, 'error' => "A {$code} error occurred."], $code);
|
||||
if (Utils::isNinjaProd())
|
||||
{
|
||||
Utils::logError($exception . ' ' . $code);
|
||||
return Response::view('error', ['hideHeader' => true, 'error' => "A {$code} error occurred."], $code);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
|
@ -2,6 +2,7 @@
|
||||
{{ HTML::nav_link('company/advanced_settings/custom_fields', 'custom_fields') }}
|
||||
{{ HTML::nav_link('company/advanced_settings/invoice_design', 'invoice_design') }}
|
||||
{{ HTML::nav_link('company/advanced_settings/chart_builder', 'chart_builder') }}
|
||||
{{ HTML::nav_link('company/advanced_settings/user_management', 'user_management') }}
|
||||
</ul>
|
||||
<p> </p>
|
||||
|
||||
|
@ -28,10 +28,10 @@
|
||||
->setOptions('bFilter', false)
|
||||
->setOptions('bAutoWidth', false)
|
||||
->setOptions('aoColumns', [[ "sWidth"=> "20%" ], [ "sWidth"=> "45%" ], ["sWidth"=> "20%"], ["sWidth"=> "15%" ]])
|
||||
->setOptions('aoColumnDefs', [['bSortable'=>false, 'aTargets'=>[3]]])
|
||||
->render('datatable') }}
|
||||
|
||||
<script>
|
||||
|
||||
window.onDatatableReady = function() {
|
||||
$('tbody tr').mouseover(function() {
|
||||
$(this).closest('tr').find('.tr-action').css('visibility','visible');
|
||||
@ -42,8 +42,6 @@
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
52
app/views/accounts/user_management.blade.php
Normal file
52
app/views/accounts/user_management.blade.php
Normal file
@ -0,0 +1,52 @@
|
||||
@extends('accounts.nav')
|
||||
|
||||
@section('content')
|
||||
@parent
|
||||
@include('accounts.nav_advanced')
|
||||
|
||||
{{ Button::success_link(URL::to('users/create'), trans("texts.add_user"), array('class' => 'pull-right'))->append_with_icon('plus-sign') }}
|
||||
|
||||
{{ Datatable::table()
|
||||
->addColumn(
|
||||
trans('texts.name'),
|
||||
trans('texts.email'),
|
||||
trans('texts.user_state'),
|
||||
trans('texts.action'))
|
||||
->setUrl(url('api/users/'))
|
||||
->setOptions('sPaginationType', 'bootstrap')
|
||||
->setOptions('bFilter', false)
|
||||
->setOptions('bAutoWidth', false)
|
||||
->setOptions('aoColumns', [[ "sWidth"=> "20%" ], [ "sWidth"=> "45%" ], ["sWidth"=> "20%"], ["sWidth"=> "15%" ]])
|
||||
->setOptions('aoColumnDefs', [['bSortable'=>false, 'aTargets'=>[3]]])
|
||||
->render('datatable') }}
|
||||
|
||||
|
||||
{{ Former::open('users/delete')->addClass('user-form') }}
|
||||
<div style="display:none">
|
||||
{{ Former::text('userPublicId') }}
|
||||
</div>
|
||||
{{ Former::close() }}
|
||||
|
||||
<script>
|
||||
window.onDatatableReady = function() {
|
||||
$('tbody tr').mouseover(function() {
|
||||
$(this).closest('tr').find('.tr-action').css('visibility','visible');
|
||||
}).mouseout(function() {
|
||||
$dropdown = $(this).closest('tr').find('.tr-action');
|
||||
if (!$dropdown.hasClass('open')) {
|
||||
$dropdown.css('visibility','hidden');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function deleteUser(id) {
|
||||
if (!confirm('Are you sure?')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$('#userPublicId').val(id);
|
||||
$('form.user-form').submit();
|
||||
}
|
||||
</script>
|
||||
|
||||
@stop
|
@ -9,7 +9,7 @@
|
||||
|
||||
|
||||
{{ Former::open($url)->addClass('col-md-10 col-md-offset-1 warn-on-exit')->method($method)->rules(array(
|
||||
'client' => 'required',
|
||||
'client' => 'required',
|
||||
'amount' => 'required',
|
||||
)); }}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
<h1>{{ trans('texts.confirmation_header') }}</h1>
|
||||
|
||||
{{ trans('texts.confirmation_message') }}<p/>
|
||||
{{ $invitationMessage . trans('texts.confirmation_message') }}<p/>
|
||||
<a href='{{{ URL::to("user/confirm/{$user->confirmation_code}") }}}'>
|
||||
{{{ URL::to("user/confirm/{$user->confirmation_code}") }}}
|
||||
</a><p/>
|
||||
|
@ -1,6 +1,6 @@
|
||||
{{ trans('texts.confirmation_header') }}
|
||||
|
||||
{{ trans('texts.confirmation_message') }}
|
||||
{{ $invitationMessage . trans('texts.confirmation_message') }}
|
||||
{{{ URL::to("user/confirm/{$user->confirmation_code}") }}}
|
||||
|
||||
{{ trans('texts.email_signature') }}
|
||||
|
@ -187,7 +187,7 @@
|
||||
<td class="hide-border" colspan="3"/>
|
||||
<td style="display:none" class="hide-border" data-bind="visible: $root.invoice_item_taxes.show"/>
|
||||
<td colspan="{{ $account->hide_quantity ? 1 : 2 }}">{{ $account->custom_invoice_label1 }}</td>
|
||||
<td style="text-align: right"><input class="form-control" data-bind="value: custom_value1, valueUpdate: 'afterkeydown'"/></td>
|
||||
<td style="text-align: right;padding-right: 28px" colspan="2"><input class="form-control" data-bind="value: custom_value1, valueUpdate: 'afterkeydown'"/></td>
|
||||
</tr>
|
||||
@endif
|
||||
|
||||
@ -196,7 +196,7 @@
|
||||
<td class="hide-border" colspan="3"/>
|
||||
<td style="display:none" class="hide-border" data-bind="visible: $root.invoice_item_taxes.show"/>
|
||||
<td colspan="{{ $account->hide_quantity ? 1 : 2 }}">{{ $account->custom_invoice_label2 }}</td>
|
||||
<td style="text-align: right"><input class="form-control" data-bind="value: custom_value2, valueUpdate: 'afterkeydown'"/></td>
|
||||
<td style="text-align: right;padding-right: 28px" colspan="2"><input class="form-control" data-bind="value: custom_value2, valueUpdate: 'afterkeydown'"/></td>
|
||||
</tr>
|
||||
@endif
|
||||
|
||||
@ -215,7 +215,7 @@
|
||||
<td class="hide-border" colspan="3"/>
|
||||
<td style="display:none" class="hide-border" data-bind="visible: $root.invoice_item_taxes.show"/>
|
||||
<td colspan="{{ $account->hide_quantity ? 1 : 2 }}">{{ $account->custom_invoice_label1 }}</td>
|
||||
<td style="text-align: right"><input class="form-control" data-bind="value: custom_value1, valueUpdate: 'afterkeydown'"/></td>
|
||||
<td style="text-align: right;padding-right: 28px" colspan="2"><input class="form-control" data-bind="value: custom_value1, valueUpdate: 'afterkeydown'"/></td>
|
||||
</tr>
|
||||
@endif
|
||||
|
||||
@ -224,7 +224,7 @@
|
||||
<td class="hide-border" colspan="3"/>
|
||||
<td style="display:none" class="hide-border" data-bind="visible: $root.invoice_item_taxes.show"/>
|
||||
<td colspan="{{ $account->hide_quantity ? 1 : 2 }}">{{ $account->custom_invoice_label2 }}</td>
|
||||
<td style="text-align: right"><input class="form-control" data-bind="value: custom_value2, valueUpdate: 'afterkeydown'"/></td>
|
||||
<td style="text-align: right;padding-right: 28px" colspan="2"><input class="form-control" data-bind="value: custom_value2, valueUpdate: 'afterkeydown'"/></td>
|
||||
</tr>
|
||||
@endif
|
||||
|
||||
@ -561,7 +561,7 @@
|
||||
}, 1);
|
||||
});
|
||||
|
||||
@if ($client || $invoice)
|
||||
@if ($client || $invoice || count($clients) == 0)
|
||||
$('#invoice_number').focus();
|
||||
@else
|
||||
$('.client_select input.form-control').focus();
|
||||
@ -1016,9 +1016,7 @@
|
||||
|
||||
refreshPDF();
|
||||
model.clientBackup = false;
|
||||
$('#clientModal').modal('hide');
|
||||
|
||||
$('#invoice_number').focus();
|
||||
$('#clientModal').modal('hide');
|
||||
}
|
||||
|
||||
self.clientLinkText = ko.computed(function() {
|
||||
|
@ -36,7 +36,7 @@
|
||||
<div class="pro col-md-4">
|
||||
|
||||
<div class="cell">Pro Plan<span class="glyphicon glyphicon-star"></div>
|
||||
<div class="cell"><div class="hide-desktop">Number of clients per account</div><span style="color: #2299c0; font-size: 16px;">5,000</span></div>
|
||||
<div class="cell"><div class="hide-desktop">Number of clients per account</div><span style="color: #2299c0; font-size: 16px;">Unlimited</span></div>
|
||||
<div class="cell"><div class="hide-desktop">Unlimited client invoices</div><span class="glyphicon glyphicon-ok"></div>
|
||||
<div class="cell"><div class="hide-desktop">Add your company logo</div><span class="glyphicon glyphicon-ok"></div>
|
||||
<div class="cell"><div class="hide-desktop">Live .PDF invoice creation</div><span class="glyphicon glyphicon-ok"></div>
|
||||
|
29
app/views/users/edit.blade.php
Normal file
29
app/views/users/edit.blade.php
Normal file
@ -0,0 +1,29 @@
|
||||
@extends('accounts.nav')
|
||||
|
||||
@section('content')
|
||||
@parent
|
||||
|
||||
{{ Former::open($url)->method($method)->addClass('col-md-8 col-md-offset-2 warn-on-exit')->rules(array(
|
||||
'first_name' => 'required',
|
||||
'last_name' => 'required',
|
||||
'email' => 'required|email',
|
||||
)); }}
|
||||
|
||||
{{ Former::legend($title) }}
|
||||
|
||||
@if ($user)
|
||||
{{ Former::populate($user) }}
|
||||
@endif
|
||||
|
||||
{{ Former::text('first_name') }}
|
||||
{{ Former::text('last_name') }}
|
||||
{{ Former::text('email') }}
|
||||
|
||||
{{ Former::actions(
|
||||
Button::lg_success_submit(trans($user && $user->confirmed ? 'texts.save' : 'texts.send_invite'))->append_with_icon($user && $user->confirmed ? 'floppy-disk' : 'send'),
|
||||
Button::lg_default_link('company/advanced_settings/user_management', 'Cancel')->append_with_icon('remove-circle')
|
||||
) }}
|
||||
|
||||
{{ Former::close() }}
|
||||
|
||||
@stop
|
@ -57,8 +57,8 @@
|
||||
'password_confirmation' => 'required',
|
||||
)); }}
|
||||
|
||||
<h2 class="form-signin-heading">Passord Reset</h2>
|
||||
<input type="hidden" name="token" value="{{{ $token }}}">
|
||||
<h2 class="form-signin-heading">Set Passord</h2><p/>
|
||||
<input type="hidden" name="token" value="{{{ $token }}}">
|
||||
|
||||
<p>
|
||||
{{ Former::password('password') }}
|
||||
|
@ -1,6 +1,5 @@
|
||||
<?php
|
||||
|
||||
|
||||
/*
|
||||
require_once 'google/appengine/api/app_identity/AppIdentityService.php';
|
||||
use \google\appengine\api\app_identity\AppIdentityService;
|
||||
@ -126,4 +125,8 @@ require $framework.'/Illuminate/Foundation/start.php';
|
||||
|
|
||||
*/
|
||||
|
||||
return $app;
|
||||
// http://stackoverflow.com/questions/20293116/override-http-headers-default-settings-x-frame-options
|
||||
App::forgetMiddleware('Illuminate\Http\FrameGuard');
|
||||
|
||||
|
||||
return $app;
|
@ -47261,19 +47261,19 @@ function displaySubtotals(doc, layout, invoice, y, rightAlignTitleX)
|
||||
{'discount': invoice.discount_amount > 0 ? formatMoney(invoice.discount_amount, invoice.client.currency_id) : false}
|
||||
];
|
||||
|
||||
if (NINJA.parseFloat(invoice.custom_value1) && NINJA.parseFloat(invoice.custom_taxes1)) {
|
||||
if (NINJA.parseFloat(invoice.custom_value1) && invoice.custom_taxes1 == '1') {
|
||||
data.push({'custom_invoice_label1': formatMoney(invoice.custom_value1, invoice.client.currency_id) })
|
||||
}
|
||||
if (NINJA.parseFloat(invoice.custom_value2) && NINJA.parseFloat(invoice.custom_taxes2)) {
|
||||
if (NINJA.parseFloat(invoice.custom_value2) && invoice.custom_taxes2 == '1') {
|
||||
data.push({'custom_invoice_label2': formatMoney(invoice.custom_value2, invoice.client.currency_id) })
|
||||
}
|
||||
|
||||
data.push({'tax': invoice.tax_amount > 0 ? formatMoney(invoice.tax_amount, invoice.client.currency_id) : false});
|
||||
|
||||
if (NINJA.parseFloat(invoice.custom_value1) && !NINJA.parseFloat(invoice.custom_taxes1)) {
|
||||
if (NINJA.parseFloat(invoice.custom_value1) && invoice.custom_taxes1 != '1') {
|
||||
data.push({'custom_invoice_label1': formatMoney(invoice.custom_value1, invoice.client.currency_id) })
|
||||
}
|
||||
if (NINJA.parseFloat(invoice.custom_value2) && !NINJA.parseFloat(invoice.custom_taxes2)) {
|
||||
if (NINJA.parseFloat(invoice.custom_value2) && invoice.custom_taxes2 != '1') {
|
||||
data.push({'custom_invoice_label2': formatMoney(invoice.custom_value2, invoice.client.currency_id) })
|
||||
}
|
||||
|
||||
@ -47433,10 +47433,10 @@ function calculateAmounts(invoice) {
|
||||
}
|
||||
|
||||
// custom fields with taxes
|
||||
if (NINJA.parseFloat(invoice.custom_value1) && NINJA.parseFloat(invoice.custom_taxes1)) {
|
||||
if (NINJA.parseFloat(invoice.custom_value1) && invoice.custom_taxes1 == '1') {
|
||||
total += roundToTwo(invoice.custom_value1);
|
||||
}
|
||||
if (NINJA.parseFloat(invoice.custom_value2) && NINJA.parseFloat(invoice.custom_taxes2)) {
|
||||
if (NINJA.parseFloat(invoice.custom_value2) && invoice.custom_taxes2 == '1') {
|
||||
total += roundToTwo(invoice.custom_value2);
|
||||
}
|
||||
|
||||
@ -47453,10 +47453,10 @@ function calculateAmounts(invoice) {
|
||||
}
|
||||
|
||||
// custom fields w/o with taxes
|
||||
if (NINJA.parseFloat(invoice.custom_value1) && !NINJA.parseFloat(invoice.custom_taxes1)) {
|
||||
if (NINJA.parseFloat(invoice.custom_value1) && invoice.custom_taxes1 != '1') {
|
||||
total += roundToTwo(invoice.custom_value1);
|
||||
}
|
||||
if (NINJA.parseFloat(invoice.custom_value2) && !NINJA.parseFloat(invoice.custom_taxes2)) {
|
||||
if (NINJA.parseFloat(invoice.custom_value2) && invoice.custom_taxes2 != '1') {
|
||||
total += roundToTwo(invoice.custom_value2);
|
||||
}
|
||||
|
||||
|
@ -1336,19 +1336,19 @@ function displaySubtotals(doc, layout, invoice, y, rightAlignTitleX)
|
||||
{'discount': invoice.discount_amount > 0 ? formatMoney(invoice.discount_amount, invoice.client.currency_id) : false}
|
||||
];
|
||||
|
||||
if (NINJA.parseFloat(invoice.custom_value1) && NINJA.parseFloat(invoice.custom_taxes1)) {
|
||||
if (NINJA.parseFloat(invoice.custom_value1) && invoice.custom_taxes1 == '1') {
|
||||
data.push({'custom_invoice_label1': formatMoney(invoice.custom_value1, invoice.client.currency_id) })
|
||||
}
|
||||
if (NINJA.parseFloat(invoice.custom_value2) && NINJA.parseFloat(invoice.custom_taxes2)) {
|
||||
if (NINJA.parseFloat(invoice.custom_value2) && invoice.custom_taxes2 == '1') {
|
||||
data.push({'custom_invoice_label2': formatMoney(invoice.custom_value2, invoice.client.currency_id) })
|
||||
}
|
||||
|
||||
data.push({'tax': invoice.tax_amount > 0 ? formatMoney(invoice.tax_amount, invoice.client.currency_id) : false});
|
||||
|
||||
if (NINJA.parseFloat(invoice.custom_value1) && !NINJA.parseFloat(invoice.custom_taxes1)) {
|
||||
if (NINJA.parseFloat(invoice.custom_value1) && invoice.custom_taxes1 != '1') {
|
||||
data.push({'custom_invoice_label1': formatMoney(invoice.custom_value1, invoice.client.currency_id) })
|
||||
}
|
||||
if (NINJA.parseFloat(invoice.custom_value2) && !NINJA.parseFloat(invoice.custom_taxes2)) {
|
||||
if (NINJA.parseFloat(invoice.custom_value2) && invoice.custom_taxes2 != '1') {
|
||||
data.push({'custom_invoice_label2': formatMoney(invoice.custom_value2, invoice.client.currency_id) })
|
||||
}
|
||||
|
||||
@ -1508,10 +1508,10 @@ function calculateAmounts(invoice) {
|
||||
}
|
||||
|
||||
// custom fields with taxes
|
||||
if (NINJA.parseFloat(invoice.custom_value1) && NINJA.parseFloat(invoice.custom_taxes1)) {
|
||||
if (NINJA.parseFloat(invoice.custom_value1) && invoice.custom_taxes1 == '1') {
|
||||
total += roundToTwo(invoice.custom_value1);
|
||||
}
|
||||
if (NINJA.parseFloat(invoice.custom_value2) && NINJA.parseFloat(invoice.custom_taxes2)) {
|
||||
if (NINJA.parseFloat(invoice.custom_value2) && invoice.custom_taxes2 == '1') {
|
||||
total += roundToTwo(invoice.custom_value2);
|
||||
}
|
||||
|
||||
@ -1528,10 +1528,10 @@ function calculateAmounts(invoice) {
|
||||
}
|
||||
|
||||
// custom fields w/o with taxes
|
||||
if (NINJA.parseFloat(invoice.custom_value1) && !NINJA.parseFloat(invoice.custom_taxes1)) {
|
||||
if (NINJA.parseFloat(invoice.custom_value1) && invoice.custom_taxes1 != '1') {
|
||||
total += roundToTwo(invoice.custom_value1);
|
||||
}
|
||||
if (NINJA.parseFloat(invoice.custom_value2) && !NINJA.parseFloat(invoice.custom_taxes2)) {
|
||||
if (NINJA.parseFloat(invoice.custom_value2) && invoice.custom_taxes2 != '1') {
|
||||
total += roundToTwo(invoice.custom_value2);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user