mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-08 12:12:48 +01:00
Added multi-company support
This commit is contained in:
parent
ef08b3c5fe
commit
67dff394b4
@ -19,3 +19,5 @@ MAIL_USERNAME
|
||||
MAIL_FROM_ADDRESS
|
||||
MAIL_FROM_NAME
|
||||
MAIL_PASSWORD
|
||||
|
||||
ALLOW_NEW_ACCOUNTS
|
@ -1,8 +1,10 @@
|
||||
<?php namespace App\Exceptions;
|
||||
|
||||
use Redirect;
|
||||
use Utils;
|
||||
use Exception;
|
||||
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||||
|
||||
class Handler extends ExceptionHandler {
|
||||
|
||||
@ -40,6 +42,11 @@ class Handler extends ExceptionHandler {
|
||||
*/
|
||||
public function render($request, Exception $e)
|
||||
{
|
||||
|
||||
if ($e instanceof ModelNotFoundException) {
|
||||
return Redirect::to('/');
|
||||
}
|
||||
|
||||
if (Utils::isNinjaProd()) {
|
||||
$data = [
|
||||
'error' => get_class($e),
|
||||
|
@ -77,7 +77,9 @@ class AccountController extends BaseController
|
||||
{
|
||||
if (Auth::check()) {
|
||||
return Redirect::to('invoices/create');
|
||||
} elseif (!Utils::isNinja() && Account::count() > 0) {
|
||||
}
|
||||
|
||||
if (!Utils::isNinja() && !Utils::allowNewAccounts() && Account::count() > 0) {
|
||||
return Redirect::to('/login');
|
||||
}
|
||||
|
||||
@ -728,7 +730,7 @@ class AccountController extends BaseController
|
||||
$email = trim(Input::get('email'));
|
||||
|
||||
if (!$email || $email == 'user@example.com') {
|
||||
return RESULT_SUCCESS;
|
||||
return '';
|
||||
}
|
||||
|
||||
$license = new License();
|
||||
@ -742,7 +744,7 @@ class AccountController extends BaseController
|
||||
$license->is_claimed = 1;
|
||||
$license->save();
|
||||
|
||||
return RESULT_SUCCESS;
|
||||
return '';
|
||||
}
|
||||
|
||||
public function cancelAccount()
|
||||
@ -762,6 +764,7 @@ class AccountController extends BaseController
|
||||
$account->forceDelete();
|
||||
|
||||
Auth::logout();
|
||||
Session::flush();
|
||||
|
||||
return Redirect::to('/')->with('clearGuestKey', true);
|
||||
}
|
||||
|
@ -3,10 +3,12 @@
|
||||
use Auth;
|
||||
use Event;
|
||||
use Utils;
|
||||
use Session;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\User;
|
||||
use App\Events\UserLoggedIn;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Ninja\Repositories\AccountRepository;
|
||||
use Illuminate\Contracts\Auth\Guard;
|
||||
use Illuminate\Contracts\Auth\Registrar;
|
||||
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
|
||||
@ -28,6 +30,7 @@ class AuthController extends Controller {
|
||||
|
||||
protected $loginPath = '/login';
|
||||
protected $redirectTo = '/dashboard';
|
||||
protected $accountRepo;
|
||||
|
||||
/**
|
||||
* Create a new authentication controller instance.
|
||||
@ -36,12 +39,13 @@ class AuthController extends Controller {
|
||||
* @param \Illuminate\Contracts\Auth\Registrar $registrar
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Guard $auth, Registrar $registrar)
|
||||
public function __construct(Guard $auth, Registrar $registrar, AccountRepository $repo)
|
||||
{
|
||||
$this->auth = $auth;
|
||||
$this->registrar = $registrar;
|
||||
$this->accountRepo = $repo;
|
||||
|
||||
$this->middleware('guest', ['except' => 'getLogout']);
|
||||
//$this->middleware('guest', ['except' => 'getLogout']);
|
||||
}
|
||||
|
||||
public function getLoginWrapper()
|
||||
@ -55,13 +59,36 @@ class AuthController extends Controller {
|
||||
|
||||
public function postLoginWrapper(Request $request)
|
||||
{
|
||||
$userId = Auth::check() ? Auth::user()->id : null;
|
||||
$response = self::postLogin($request);
|
||||
|
||||
if (Auth::check()) {
|
||||
Event::fire(new UserLoggedIn());
|
||||
|
||||
if (Utils::isPro()) {
|
||||
$users = false;
|
||||
// we're linking a new account
|
||||
if ($userId && Auth::user()->id != $userId) {
|
||||
$users = $this->accountRepo->associateAccounts($userId, Auth::user()->id);
|
||||
Session::flash('message', trans('texts.associated_accounts'));
|
||||
// check if other accounts are linked
|
||||
} else {
|
||||
$users = $this->accountRepo->loadAccounts(Auth::user()->id);
|
||||
}
|
||||
|
||||
Session::put(SESSION_USER_ACCOUNTS, $users);
|
||||
}
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function getLogoutWrapper()
|
||||
{
|
||||
$response = self::getLogout();
|
||||
|
||||
Session::flush();
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
@ -45,6 +45,11 @@ class HomeController extends BaseController
|
||||
|
||||
public function invoiceNow()
|
||||
{
|
||||
if (Auth::check() && Input::get('logout')) {
|
||||
Auth::user()->clearSession();
|
||||
Auth::logout();
|
||||
}
|
||||
|
||||
if (Auth::check()) {
|
||||
return Redirect::to('invoices/create')->with('sign_up', Input::get('sign_up'));
|
||||
} else {
|
||||
|
@ -630,8 +630,9 @@ class PaymentController extends BaseController
|
||||
$invoice = $invitation->invoice;
|
||||
$accountGateway = $invoice->client->account->getGatewayByType(Session::get('payment_type'));
|
||||
|
||||
if ($invoice->account->account_key == NINJA_ACCOUNT_KEY) {
|
||||
$account = Account::find($invoice->client->public_id);
|
||||
if ($invoice->account->account_key == NINJA_ACCOUNT_KEY
|
||||
&& $invoice->amount == PRO_PLAN_PRICE) {
|
||||
$account = Account::with('users')->find($invoice->client->public_id);
|
||||
if ($account->pro_plan_paid && $account->pro_plan_paid != '0000-00-00') {
|
||||
$date = DateTime::createFromFormat('Y-m-d', $account->pro_plan_paid);
|
||||
$account->pro_plan_paid = $date->modify('+1 year')->format('Y-m-d');
|
||||
@ -639,6 +640,9 @@ class PaymentController extends BaseController
|
||||
$account->pro_plan_paid = date_create()->format('Y-m-d');
|
||||
}
|
||||
$account->save();
|
||||
|
||||
$user = $account->users()->first();
|
||||
$this->accountRepo->syncAccounts($user->id, $account->pro_plan_paid);
|
||||
}
|
||||
|
||||
$payment = Payment::createNew($invitation);
|
||||
|
@ -7,6 +7,7 @@ use DB;
|
||||
use Event;
|
||||
use Input;
|
||||
use View;
|
||||
use Request;
|
||||
use Redirect;
|
||||
use Session;
|
||||
use URL;
|
||||
@ -309,10 +310,8 @@ class UserController extends BaseController
|
||||
}
|
||||
}
|
||||
|
||||
Session::forget('news_feed_id');
|
||||
Session::forget('news_feed_message');
|
||||
|
||||
Auth::logout();
|
||||
Session::flush();
|
||||
|
||||
return Redirect::to('/')->with('clearGuestKey', true);
|
||||
}
|
||||
@ -342,4 +341,32 @@ class UserController extends BaseController
|
||||
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
public function switchAccount($newUserId)
|
||||
{
|
||||
$oldUserId = Auth::user()->id;
|
||||
$referer = Request::header('referer');
|
||||
$account = $this->accountRepo->findUserAccounts($newUserId, $oldUserId);
|
||||
|
||||
if ($account) {
|
||||
if ($account->hasUserId($newUserId) && $account->hasUserId($oldUserId)) {
|
||||
Auth::loginUsingId($newUserId);
|
||||
Auth::user()->account->loadLocalizationSettings();
|
||||
}
|
||||
}
|
||||
|
||||
return Redirect::to($referer);
|
||||
}
|
||||
|
||||
public function unlinkAccount($userAccountId, $userId)
|
||||
{
|
||||
$this->accountRepo->unlinkAccount($userAccountId, $userId);
|
||||
$referer = Request::header('referer');
|
||||
|
||||
$users = $this->accountRepo->loadAccounts(Auth::user()->id);
|
||||
Session::put(SESSION_USER_ACCOUNTS, $users);
|
||||
|
||||
Session::flash('message', trans('texts.unlinked_account'));
|
||||
return Redirect::to($referer);
|
||||
}
|
||||
}
|
||||
|
@ -67,8 +67,7 @@ get('/signup', array('as' => 'signup', 'uses' => 'Auth\AuthController@getRegiste
|
||||
post('/signup', array('as' => 'signup', 'uses' => 'Auth\AuthController@postRegister'));
|
||||
get('/login', array('as' => 'login', 'uses' => 'Auth\AuthController@getLoginWrapper'));
|
||||
post('/login', array('as' => 'login', 'uses' => 'Auth\AuthController@postLoginWrapper'));
|
||||
//get('/logout', array('as' => 'logout', 'uses' => 'Auth\AuthController@getLogoutWrapper'));
|
||||
get('/logout', array('as' => 'logout', 'uses' => 'Auth\AuthController@getLogout'));
|
||||
get('/logout', array('as' => 'logout', 'uses' => 'Auth\AuthController@getLogoutWrapper'));
|
||||
get('/forgot', array('as' => 'forgot', 'uses' => 'Auth\PasswordController@getEmail'));
|
||||
post('/forgot', array('as' => 'forgot', 'uses' => 'Auth\PasswordController@postEmail'));
|
||||
get('/password/reset/{token}', array('as' => 'forgot', 'uses' => 'Auth\PasswordController@getReset'));
|
||||
@ -95,6 +94,7 @@ Route::group(['middleware' => 'auth'], function() {
|
||||
Route::get('restore_user/{user_id}', 'UserController@restoreUser');
|
||||
Route::post('users/change_password', 'UserController@changePassword');
|
||||
Route::get('/switch_account/{user_id}', 'UserController@switchAccount');
|
||||
Route::get('/unlink_account/{user_account_id}/{user_id}', 'UserController@unlinkAccount');
|
||||
|
||||
Route::get('api/tokens', array('as'=>'api.tokens', 'uses'=>'TokenController@getDatatable'));
|
||||
Route::resource('tokens', 'TokenController');
|
||||
|
@ -51,12 +51,17 @@ class Utils
|
||||
|
||||
public static function isNinjaProd()
|
||||
{
|
||||
return isset($_ENV['NINJA_PROD']) && $_ENV['NINJA_PROD'];
|
||||
return isset($_ENV['NINJA_PROD']) && $_ENV['NINJA_PROD'] == 'true';
|
||||
}
|
||||
|
||||
public static function isNinjaDev()
|
||||
{
|
||||
return isset($_ENV['NINJA_DEV']) && $_ENV['NINJA_DEV'];
|
||||
return isset($_ENV['NINJA_DEV']) && $_ENV['NINJA_DEV'] == 'true';
|
||||
}
|
||||
|
||||
public static function allowNewAccounts()
|
||||
{
|
||||
return isset($_ENV['ALLOW_NEW_ACCOUNTS']) && $_ENV['ALLOW_NEW_ACCOUNTS'] == 'true';
|
||||
}
|
||||
|
||||
public static function isPro()
|
||||
|
@ -1,9 +1,9 @@
|
||||
<?php namespace App\Listeners;
|
||||
|
||||
use Auth;
|
||||
|
||||
use Session;
|
||||
use App\Events\UserSettingsChanged;
|
||||
|
||||
use App\Ninja\Repositories\AccountRepository;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldBeQueued;
|
||||
|
||||
@ -14,9 +14,9 @@ class HandleUserSettingsChanged {
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
public function __construct(AccountRepository $accountRepo)
|
||||
{
|
||||
//
|
||||
$this->accountRepo = $accountRepo;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -29,6 +29,9 @@ class HandleUserSettingsChanged {
|
||||
{
|
||||
$account = Auth::user()->account;
|
||||
$account->loadLocalizationSettings();
|
||||
|
||||
$users = $this->accountRepo->loadAccounts(Auth::user()->id);
|
||||
Session::put(SESSION_USER_ACCOUNTS, $users);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -128,6 +128,7 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
|
||||
return Session::get(SESSION_COUNTER, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
public function getPopOverText()
|
||||
{
|
||||
if (!Utils::isNinja() || !Auth::check() || Session::has('error')) {
|
||||
@ -146,6 +147,7 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
|
||||
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
public function afterSave($success = true, $forced = false)
|
||||
{
|
||||
@ -176,4 +178,22 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
|
||||
return 'remember_token';
|
||||
}
|
||||
|
||||
public function clearSession()
|
||||
{
|
||||
$keys = [
|
||||
RECENTLY_VIEWED,
|
||||
SESSION_USER_ACCOUNTS,
|
||||
SESSION_TIMEZONE,
|
||||
SESSION_DATE_FORMAT,
|
||||
SESSION_DATE_PICKER_FORMAT,
|
||||
SESSION_DATETIME_FORMAT,
|
||||
SESSION_CURRENCY,
|
||||
SESSION_LOCALE,
|
||||
];
|
||||
|
||||
foreach ($keys as $key) {
|
||||
Session::forget($key);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
52
app/Models/UserAccount.php
Normal file
52
app/Models/UserAccount.php
Normal file
@ -0,0 +1,52 @@
|
||||
<?php namespace App\Models;
|
||||
|
||||
use Eloquent;
|
||||
|
||||
class UserAccount extends Eloquent
|
||||
{
|
||||
public $timestamps = false;
|
||||
|
||||
public function hasUserId($userId)
|
||||
{
|
||||
if (!$userId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for ($i=1; $i<=5; $i++) {
|
||||
$field = "user_id{$i}";
|
||||
if ($this->$field && $this->$field == $userId) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function setUserId($userId)
|
||||
{
|
||||
if (self::hasUserId($userId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for ($i=1; $i<=5; $i++) {
|
||||
$field = "user_id{$i}";
|
||||
if (!$this->$field) {
|
||||
$this->$field = $userId;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function removeUserId($userId)
|
||||
{
|
||||
if (!$userId || !self::hasUserId($userId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for ($i=1; $i<=5; $i++) {
|
||||
$field = "user_id{$i}";
|
||||
if ($this->$field && $this->$field == $userId) {
|
||||
$this->$field = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -4,6 +4,8 @@ use Auth;
|
||||
use Request;
|
||||
use Session;
|
||||
use Utils;
|
||||
use DB;
|
||||
use stdClass;
|
||||
|
||||
use App\Models\AccountGateway;
|
||||
use App\Models\Invitation;
|
||||
@ -14,6 +16,7 @@ use App\Models\Language;
|
||||
use App\Models\Contact;
|
||||
use App\Models\Account;
|
||||
use App\Models\User;
|
||||
use App\Models\UserAccount;
|
||||
|
||||
class AccountRepository
|
||||
{
|
||||
@ -244,4 +247,129 @@ class AccountRepository
|
||||
curl_exec($ch);
|
||||
curl_close($ch);
|
||||
}
|
||||
|
||||
public function findUserAccounts($userId1, $userId2 = false)
|
||||
{
|
||||
$query = UserAccount::where('user_id1', '=', $userId1)
|
||||
->orWhere('user_id2', '=', $userId1)
|
||||
->orWhere('user_id3', '=', $userId1)
|
||||
->orWhere('user_id4', '=', $userId1)
|
||||
->orWhere('user_id5', '=', $userId1);
|
||||
|
||||
if ($userId2) {
|
||||
$query->orWhere('user_id1', '=', $userId2)
|
||||
->orWhere('user_id2', '=', $userId2)
|
||||
->orWhere('user_id3', '=', $userId2)
|
||||
->orWhere('user_id4', '=', $userId2)
|
||||
->orWhere('user_id5', '=', $userId2);
|
||||
}
|
||||
|
||||
return $query->first(['id', 'user_id1', 'user_id2', 'user_id3', 'user_id4', 'user_id5']);
|
||||
}
|
||||
|
||||
public function prepareUsersData($record) {
|
||||
|
||||
if (!$record) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$userIds = [];
|
||||
for ($i=1; $i<=5; $i++) {
|
||||
$field = "user_id$i";
|
||||
if ($record->$field) {
|
||||
$userIds[] = $record->$field;
|
||||
}
|
||||
}
|
||||
|
||||
$users = User::with('account')
|
||||
->whereIn('id', $userIds)
|
||||
->get();
|
||||
|
||||
$data = [];
|
||||
foreach ($users as $user) {
|
||||
$item = new stdClass();
|
||||
$item->id = $record->id;
|
||||
$item->user_id = $user->id;
|
||||
$item->user_name = $user->getDisplayName();
|
||||
$item->account_id = $user->account->id;
|
||||
$item->account_name = $user->account->getDisplayName();
|
||||
$item->pro_plan_paid = $user->account->pro_plan_paid;
|
||||
$data[] = $item;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function loadAccounts($userId) {
|
||||
$record = self::findUserAccounts($userId);
|
||||
return self::prepareUsersData($record);
|
||||
}
|
||||
|
||||
public function syncAccounts($userId, $proPlanPaid) {
|
||||
$users = self::loadAccounts($userId);
|
||||
self::syncUserAccounts($users, $proPlanPaid);
|
||||
}
|
||||
|
||||
public function syncUserAccounts($users, $proPlanPaid = false) {
|
||||
|
||||
if (!$proPlanPaid) {
|
||||
foreach ($users as $user) {
|
||||
if ($user->pro_plan_paid && $user->pro_plan_paid != '0000-00-00') {
|
||||
$proPlanPaid = $user->pro_plan_paid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$proPlanPaid) {
|
||||
return;
|
||||
}
|
||||
|
||||
$accountIds = [];
|
||||
foreach ($users as $user) {
|
||||
if ($user->pro_plan_paid != $proPlanPaid) {
|
||||
$accountIds[] = $user->account_id;
|
||||
}
|
||||
}
|
||||
|
||||
if (count($accountIds)) {
|
||||
DB::table('accounts')
|
||||
->whereIn('id', $accountIds)
|
||||
->update(['pro_plan_paid' => $proPlanPaid]);
|
||||
}
|
||||
}
|
||||
|
||||
public function associateAccounts($userId1, $userId2) {
|
||||
|
||||
$record = self::findUserAccounts($userId1, $userId2);
|
||||
|
||||
if ($record) {
|
||||
foreach ([$userId1, $userId2] as $userId) {
|
||||
if (!$record->hasUserId($userId)) {
|
||||
$record->setUserId($userId);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$record = new UserAccount();
|
||||
$record->user_id1 = $userId1;
|
||||
$record->user_id2 = $userId2;
|
||||
}
|
||||
|
||||
$record->save();
|
||||
|
||||
$users = self::prepareUsersData($record);
|
||||
self::syncUserAccounts($users);
|
||||
|
||||
return $users;
|
||||
}
|
||||
|
||||
public function unlinkAccount($userAccountId, $userId) {
|
||||
|
||||
$userAccount = UserAccount::whereId($userAccountId)->first();
|
||||
|
||||
if ($userAccount->hasUserId(Auth::user()->id)) {
|
||||
$userAccount->removeUserId($userId);
|
||||
$userAccount->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -44,6 +44,10 @@ class AppServiceProvider extends ServiceProvider {
|
||||
$str .= '<li class="divider"></li>
|
||||
<li><a href="'.URL::to('quotes').'">'.trans("texts.quotes").'</a></li>
|
||||
<li><a href="'.URL::to('quotes/create').'">'.trans("texts.new_quote").'</a></li>';
|
||||
} else if ($type == ENTITY_CLIENT) {
|
||||
$str .= '<li class="divider"></li>
|
||||
<li><a href="'.URL::to('credits').'">'.trans("texts.credits").'</a></li>
|
||||
<li><a href="'.URL::to('credits/create').'">'.trans("texts.new_credit").'</a></li>';
|
||||
}
|
||||
|
||||
$str .= '</ul>
|
||||
|
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class MultiCompanySupport extends Migration {
|
||||
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('user_accounts', function($table)
|
||||
{
|
||||
$table->increments('id');
|
||||
|
||||
$table->unsignedInteger('user_id1')->nullable();
|
||||
$table->unsignedInteger('user_id2')->nullable();
|
||||
$table->unsignedInteger('user_id3')->nullable();
|
||||
$table->unsignedInteger('user_id4')->nullable();
|
||||
$table->unsignedInteger('user_id5')->nullable();
|
||||
|
||||
$table->foreign('user_id1')->references('id')->on('users');
|
||||
$table->foreign('user_id2')->references('id')->on('users');
|
||||
$table->foreign('user_id3')->references('id')->on('users');
|
||||
$table->foreign('user_id4')->references('id')->on('users');
|
||||
$table->foreign('user_id5')->references('id')->on('users');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('user_accounts');
|
||||
}
|
||||
}
|
15
public/css/built.css
vendored
15
public/css/built.css
vendored
@ -3345,3 +3345,18 @@ button .glyphicon {
|
||||
width: 35px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
ul.user-accounts div.account {
|
||||
font-size: large;
|
||||
}
|
||||
|
||||
ul.user-accounts div.remove {
|
||||
padding-top: 14px;
|
||||
color: #BBB;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
ul.user-accounts a:hover div.remove {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
|
15
public/css/style.css
vendored
15
public/css/style.css
vendored
@ -961,3 +961,18 @@ button .glyphicon {
|
||||
width: 35px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
ul.user-accounts div.account {
|
||||
font-size: large;
|
||||
}
|
||||
|
||||
ul.user-accounts div.remove {
|
||||
padding-top: 14px;
|
||||
color: #BBB;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
ul.user-accounts a:hover div.remove {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
|
@ -696,6 +696,16 @@ return array(
|
||||
'timezone_unset' => 'Please :link to set your timezone',
|
||||
'click_here' => 'click here',
|
||||
|
||||
'email_receipt' => 'Email payment receipt to the client',
|
||||
'created_payment_emailed_client' => 'Successfully created payment and emailed client',
|
||||
'add_account' => 'Add Account',
|
||||
'untitled' => 'Untitled',
|
||||
'new_account' => 'New Account',
|
||||
'associated_accounts' => 'Successfully linked accounts',
|
||||
'unlinked_account' => 'Successfully unlinked accounts',
|
||||
'login' => 'Login',
|
||||
'or' => 'or',
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -687,6 +687,15 @@ return array(
|
||||
'timezone_unset' => 'Please :link to set your timezone',
|
||||
'click_here' => 'click here',
|
||||
|
||||
'email_receipt' => 'Email payment receipt to the client',
|
||||
'created_payment_emailed_client' => 'Successfully created payment and emailed client',
|
||||
'add_account' => 'Add Account',
|
||||
'untitled' => 'Untitled',
|
||||
'new_account' => 'New Account',
|
||||
'associated_accounts' => 'Successfully linked accounts',
|
||||
'unlinked_account' => 'Successfully unlinked accounts',
|
||||
'login' => 'Login',
|
||||
'or' => 'or',
|
||||
|
||||
|
||||
);
|
@ -696,5 +696,12 @@ return array(
|
||||
|
||||
'email_receipt' => 'Email payment receipt to the client',
|
||||
'created_payment_emailed_client' => 'Successfully created payment and emailed client',
|
||||
'add_account' => 'Add Account',
|
||||
'untitled' => 'Untitled',
|
||||
'new_account' => 'New Account',
|
||||
'associated_accounts' => 'Successfully linked accounts',
|
||||
'unlinked_account' => 'Successfully unlinked accounts',
|
||||
'login' => 'Login',
|
||||
'or' => 'or',
|
||||
|
||||
);
|
||||
|
@ -666,6 +666,15 @@ return array(
|
||||
'timezone_unset' => 'Please :link to set your timezone',
|
||||
'click_here' => 'click here',
|
||||
|
||||
'email_receipt' => 'Email payment receipt to the client',
|
||||
'created_payment_emailed_client' => 'Successfully created payment and emailed client',
|
||||
'add_account' => 'Add Account',
|
||||
'untitled' => 'Untitled',
|
||||
'new_account' => 'New Account',
|
||||
'associated_accounts' => 'Successfully linked accounts',
|
||||
'unlinked_account' => 'Successfully unlinked accounts',
|
||||
'login' => 'Login',
|
||||
'or' => 'or',
|
||||
|
||||
|
||||
);
|
@ -695,6 +695,16 @@ return array(
|
||||
'timezone_unset' => 'Please :link to set your timezone',
|
||||
'click_here' => 'click here',
|
||||
|
||||
'email_receipt' => 'Email payment receipt to the client',
|
||||
'created_payment_emailed_client' => 'Successfully created payment and emailed client',
|
||||
'add_account' => 'Add Account',
|
||||
'untitled' => 'Untitled',
|
||||
'new_account' => 'New Account',
|
||||
'associated_accounts' => 'Successfully linked accounts',
|
||||
'unlinked_account' => 'Successfully unlinked accounts',
|
||||
'login' => 'Login',
|
||||
'or' => 'or',
|
||||
|
||||
|
||||
|
||||
);
|
@ -687,6 +687,16 @@ return array(
|
||||
'timezone_unset' => 'Please :link to set your timezone',
|
||||
'click_here' => 'click here',
|
||||
|
||||
'email_receipt' => 'Email payment receipt to the client',
|
||||
'created_payment_emailed_client' => 'Successfully created payment and emailed client',
|
||||
'add_account' => 'Add Account',
|
||||
'untitled' => 'Untitled',
|
||||
'new_account' => 'New Account',
|
||||
'associated_accounts' => 'Successfully linked accounts',
|
||||
'unlinked_account' => 'Successfully unlinked accounts',
|
||||
'login' => 'Login',
|
||||
'or' => 'or',
|
||||
|
||||
|
||||
|
||||
);
|
@ -688,5 +688,15 @@ return array(
|
||||
'timezone_unset' => 'Please :link to set your timezone',
|
||||
'click_here' => 'click here',
|
||||
|
||||
'email_receipt' => 'Email payment receipt to the client',
|
||||
'created_payment_emailed_client' => 'Successfully created payment and emailed client',
|
||||
'add_account' => 'Add Account',
|
||||
'untitled' => 'Untitled',
|
||||
'new_account' => 'New Account',
|
||||
'associated_accounts' => 'Successfully linked accounts',
|
||||
'unlinked_account' => 'Successfully unlinked accounts',
|
||||
'login' => 'Login',
|
||||
'or' => 'or',
|
||||
|
||||
|
||||
);
|
||||
|
@ -690,6 +690,16 @@ return array(
|
||||
'timezone_unset' => 'Please :link to set your timezone',
|
||||
'click_here' => 'click here',
|
||||
|
||||
'email_receipt' => 'Email payment receipt to the client',
|
||||
'created_payment_emailed_client' => 'Successfully created payment and emailed client',
|
||||
'add_account' => 'Add Account',
|
||||
'untitled' => 'Untitled',
|
||||
'new_account' => 'New Account',
|
||||
'associated_accounts' => 'Successfully linked accounts',
|
||||
'unlinked_account' => 'Successfully unlinked accounts',
|
||||
'login' => 'Login',
|
||||
'or' => 'or',
|
||||
|
||||
|
||||
|
||||
);
|
||||
|
@ -697,6 +697,16 @@ return array(
|
||||
'timezone_unset' => 'Please :link to set your timezone',
|
||||
'click_here' => 'click here',
|
||||
|
||||
'email_receipt' => 'Email payment receipt to the client',
|
||||
'created_payment_emailed_client' => 'Successfully created payment and emailed client',
|
||||
'add_account' => 'Add Account',
|
||||
'untitled' => 'Untitled',
|
||||
'new_account' => 'New Account',
|
||||
'associated_accounts' => 'Successfully linked accounts',
|
||||
'unlinked_account' => 'Successfully unlinked accounts',
|
||||
'login' => 'Login',
|
||||
'or' => 'or',
|
||||
|
||||
|
||||
|
||||
);
|
||||
|
@ -695,6 +695,16 @@ return array(
|
||||
'timezone_unset' => 'Please :link to set your timezone',
|
||||
'click_here' => 'click here',
|
||||
|
||||
'email_receipt' => 'Email payment receipt to the client',
|
||||
'created_payment_emailed_client' => 'Successfully created payment and emailed client',
|
||||
'add_account' => 'Add Account',
|
||||
'untitled' => 'Untitled',
|
||||
'new_account' => 'New Account',
|
||||
'associated_accounts' => 'Successfully linked accounts',
|
||||
'unlinked_account' => 'Successfully unlinked accounts',
|
||||
'login' => 'Login',
|
||||
'or' => 'or',
|
||||
|
||||
|
||||
|
||||
);
|
@ -690,6 +690,16 @@ return array(
|
||||
'timezone_unset' => 'Please :link to set your timezone',
|
||||
'click_here' => 'click here',
|
||||
|
||||
'email_receipt' => 'Email payment receipt to the client',
|
||||
'created_payment_emailed_client' => 'Successfully created payment and emailed client',
|
||||
'add_account' => 'Add Account',
|
||||
'untitled' => 'Untitled',
|
||||
'new_account' => 'New Account',
|
||||
'associated_accounts' => 'Successfully linked accounts',
|
||||
'unlinked_account' => 'Successfully unlinked accounts',
|
||||
'login' => 'Login',
|
||||
'or' => 'or',
|
||||
|
||||
|
||||
|
||||
);
|
||||
|
@ -690,6 +690,15 @@ return array(
|
||||
'timezone_unset' => 'Please :link to set your timezone',
|
||||
'click_here' => 'click here',
|
||||
|
||||
'email_receipt' => 'Email payment receipt to the client',
|
||||
'created_payment_emailed_client' => 'Successfully created payment and emailed client',
|
||||
'add_account' => 'Add Account',
|
||||
'untitled' => 'Untitled',
|
||||
'new_account' => 'New Account',
|
||||
'associated_accounts' => 'Successfully linked accounts',
|
||||
'unlinked_account' => 'Successfully unlinked accounts',
|
||||
'login' => 'Login',
|
||||
'or' => 'or',
|
||||
|
||||
|
||||
);
|
||||
|
@ -693,6 +693,16 @@ return array(
|
||||
'timezone_unset' => 'Please :link to set your timezone',
|
||||
'click_here' => 'click here',
|
||||
|
||||
'email_receipt' => 'Email payment receipt to the client',
|
||||
'created_payment_emailed_client' => 'Successfully created payment and emailed client',
|
||||
'add_account' => 'Add Account',
|
||||
'untitled' => 'Untitled',
|
||||
'new_account' => 'New Account',
|
||||
'associated_accounts' => 'Successfully linked accounts',
|
||||
'unlinked_account' => 'Successfully unlinked accounts',
|
||||
'login' => 'Login',
|
||||
'or' => 'or',
|
||||
|
||||
|
||||
|
||||
);
|
||||
|
@ -79,7 +79,13 @@
|
||||
{!! Former::hidden('remember')->raw() !!}
|
||||
</p>
|
||||
|
||||
<p>{!! Button::success(trans('texts.lets_go'))->large()->submit()->block() !!}</p>
|
||||
<p>{!! Button::success(trans(Utils::allowNewAccounts() ? 'texts.login' : 'texts.lets_go'))->large()->submit()->block() !!}</p>
|
||||
|
||||
@if (Utils::allowNewAccounts())
|
||||
<center><p>- {{ trans('texts.or') }} -</p></center>
|
||||
<p>{!! Button::primary(trans('texts.new_account'))->asLinkTo(URL::to('/invoice_now?logout=true'))->large()->submit()->block() !!}</p>
|
||||
@endif
|
||||
|
||||
|
||||
<p class="link">
|
||||
{!! link_to('/forgot', trans('texts.forgot_password')) !!}
|
||||
|
@ -186,6 +186,13 @@
|
||||
});
|
||||
}
|
||||
|
||||
function unlinkAccount(userAccountId, userId) {
|
||||
if (confirm('{!! trans("texts.are_you_sure") !!}')) {
|
||||
window.location = '{{ URL::to('/unlink_account') }}' + '/' + userAccountId + '/' + userId;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function wordWrapText(value, width)
|
||||
{
|
||||
@if (Auth::user()->account->auto_wrap)
|
||||
@ -321,7 +328,6 @@
|
||||
{!! HTML::menu_link('task') !!}
|
||||
{!! HTML::menu_link('invoice') !!}
|
||||
{!! HTML::menu_link('payment') !!}
|
||||
{!! HTML::menu_link('credit') !!}
|
||||
</ul>
|
||||
|
||||
<div class="navbar-form navbar-right">
|
||||
@ -333,61 +339,67 @@
|
||||
@endif
|
||||
@endif
|
||||
|
||||
@if (Auth::user()->getPopOverText() && !Utils::isRegistered())
|
||||
<button id="ninjaPopOver" type="button" class="btn btn-default" data-toggle="popover" data-placement="bottom" data-content="{{ Auth::user()->getPopOverText() }}" data-html="true" style="display:none">
|
||||
{{ trans('texts.sign_up') }}
|
||||
</button>
|
||||
@endif
|
||||
|
||||
@if (Auth::user()->getPopOverText())
|
||||
<script>
|
||||
$(function() {
|
||||
if (screen.width < 1170) return;
|
||||
$('#ninjaPopOver').show().popover('show').hide();
|
||||
$('body').click(function() {
|
||||
$('#ninjaPopOver').popover('hide');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@endif
|
||||
|
||||
<div class="btn-group">
|
||||
<div class="btn-group user-dropdown">
|
||||
<button type="button" class="btn btn-default btn-sm dropdown-toggle" data-toggle="dropdown">
|
||||
<div id="myAccountButton" class="ellipsis" style="max-width:100px">
|
||||
{{ Auth::user()->getDisplayName() }}
|
||||
@if (session(SESSION_USER_ACCOUNTS) && count(session(SESSION_USER_ACCOUNTS)))
|
||||
{{ Auth::user()->account->getDisplayName() }}
|
||||
@else
|
||||
{{ Auth::user()->getDisplayName() }}
|
||||
@endif
|
||||
<span class="caret"></span>
|
||||
</div>
|
||||
</button>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<ul class="dropdown-menu user-accounts" role="menu">
|
||||
@if (session(SESSION_USER_ACCOUNTS))
|
||||
@foreach (session(SESSION_USER_ACCOUNTS) as $item)
|
||||
<li><a href='{{ URL::to("/switch_account/{$item->user_id}") }}'>
|
||||
@if ($item->user_id == Auth::user()->id)
|
||||
<b>
|
||||
@endif
|
||||
@if (count(session(SESSION_USER_ACCOUNTS)) > 1)
|
||||
<div class="pull-right glyphicon glyphicon-remove remove" onclick="return unlinkAccount({{ $item->id }}, {{ $item->user_id }})"></div>
|
||||
@endif
|
||||
<div class="account" style="padding-right:28px">{{ $item->account_name }}</div>
|
||||
<div class="user">{{ $item->user_name }}</div>
|
||||
@if ($item->user_id == Auth::user()->id)
|
||||
</b>
|
||||
@endif
|
||||
</a></li>
|
||||
@endforeach
|
||||
@else
|
||||
<li><a href='#'><b>
|
||||
<div class="account">{{ Auth::user()->account->name ?: trans('texts.untitled') }}</div>
|
||||
<div class="user">{{ Auth::user()->getDisplayName() }}</div>
|
||||
</b></a></li>
|
||||
@endif
|
||||
<li class="divider"></li>
|
||||
@if (Auth::user()->isPro() && (!session(SESSION_USER_ACCOUNTS) || count(session(SESSION_USER_ACCOUNTS)) < 5))
|
||||
<li>{!! link_to('/login', trans('texts.add_account')) !!}</li>
|
||||
@endif
|
||||
<li>{!! link_to('#', trans('texts.logout'), array('onclick'=>'logout()')) !!}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
|
||||
<span class="glyphicon glyphicon-cog" title="{{ trans('texts.settings') }}"/>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li>{!! link_to('company/details', uctrans('texts.company_details')) !!}</li>
|
||||
<li>{!! link_to('company/payments', uctrans('texts.online_payments')) !!}</li>
|
||||
<li>{!! link_to('company/products', uctrans('texts.product_library')) !!}</li>
|
||||
<li>{!! link_to('company/notifications', uctrans('texts.notifications')) !!}</li>
|
||||
<li>{!! link_to('company/import_export', uctrans('texts.import_export')) !!}</li>
|
||||
<li><a href="{{ url('company/advanced_settings/invoice_settings') }}">{!! uctrans('texts.advanced_settings') . Utils::getProLabel(ACCOUNT_ADVANCED_SETTINGS) !!}</a></li>
|
||||
|
||||
<li class="divider"></li>
|
||||
<li>{!! link_to('#', trans('texts.logout'), array('onclick'=>'logout()')) !!}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
@if (Auth::user()->getPopOverText() && Utils::isRegistered())
|
||||
<button id="ninjaPopOver" type="button" class="btn btn-default" data-toggle="popover" data-placement="bottom" data-content="{{ Auth::user()->getPopOverText() }}" data-html="true" style="display:none">
|
||||
{{ Auth::user()->getDisplayName() }}
|
||||
</button>
|
||||
@endif
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<form class="navbar-form navbar-right" role="search">
|
||||
<div class="form-group">
|
||||
<input type="text" id="search" style="width: {{ Session::get(SESSION_LOCALE) == 'en' ? 180 : 140 }}px"
|
||||
class="form-control" placeholder="{{ trans('texts.search') }}">
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
|
||||
@ -405,6 +417,15 @@
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<form class="navbar-form navbar-right" role="search">
|
||||
<div class="form-group">
|
||||
<input type="text" id="search" style="width: {{ Session::get(SESSION_LOCALE) == 'en' ? 180 : 140 }}px"
|
||||
class="form-control" placeholder="{{ trans('texts.search') }}">
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
|
||||
|
||||
</div><!-- /.navbar-collapse -->
|
||||
|
||||
|
@ -27,6 +27,8 @@
|
||||
<input id="tableFilter" type="text" style="width:140px;margin-right:17px;background-color: white !important" class="form-control pull-left" placeholder="{{ trans('texts.filter') }}"/>
|
||||
@if (Auth::user()->isPro() && $entityType == ENTITY_INVOICE)
|
||||
{!! Button::normal(trans('texts.quotes'))->asLinkTo(URL::to('/quotes'))->appendIcon(Icon::create('list')) !!}
|
||||
@elseif ($entityType == ENTITY_CLIENT)
|
||||
{!! Button::normal(trans('texts.credits'))->asLinkTo(URL::to('/credits'))->appendIcon(Icon::create('list')) !!}
|
||||
@endif
|
||||
{!! Button::primary(trans("texts.new_$entityType"))->asLinkTo(URL::to("/{$entityType}s/create"))->appendIcon(Icon::create('plus-sign')) !!}
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user