2017-01-30 21:40:43 +02:00
< ? php
2015-03-17 07:45:25 +10:00
2017-01-30 21:40:43 +02:00
namespace App\Ninja\Repositories ;
use App\Models\Account ;
2017-03-31 18:02:56 +03:00
use App\Models\AccountEmailSettings ;
2015-03-31 12:38:24 +03:00
use App\Models\AccountGateway ;
2019-01-30 22:00:26 +11:00
use App\Models\AccountTicketSettings ;
2017-01-30 21:40:43 +02:00
use App\Models\AccountToken ;
use App\Models\Client ;
use App\Models\Company ;
use App\Models\Contact ;
use App\Models\Credit ;
2015-03-31 12:38:24 +03:00
use App\Models\Invitation ;
use App\Models\Invoice ;
use App\Models\InvoiceItem ;
2015-04-05 22:15:37 +03:00
use App\Models\Language ;
2015-03-24 17:35:20 +10:00
use App\Models\User ;
2015-06-16 22:35:35 +03:00
use App\Models\UserAccount ;
2017-05-15 16:49:58 +03:00
use App\Models\LookupUser ;
2017-01-30 21:40:43 +02:00
use Auth ;
use Input ;
use Request ;
use Schema ;
use Session ;
use stdClass ;
use URL ;
use Utils ;
use Validator ;
2015-03-24 17:35:20 +10:00
2015-03-17 07:45:25 +10:00
class AccountRepository
{
2017-03-24 14:51:24 +03:00
public function create ( $firstName = '' , $lastName = '' , $email = '' , $password = '' , $company = false )
2015-03-17 07:45:25 +10:00
{
2017-03-24 14:51:24 +03:00
if ( ! $company ) {
2018-03-11 08:50:11 +02:00
if ( Utils :: isNinja ()) {
$this -> checkForSpammer ();
}
2017-03-24 14:51:24 +03:00
$company = new Company ();
$company -> utm_source = Input :: get ( 'utm_source' );
$company -> utm_medium = Input :: get ( 'utm_medium' );
$company -> utm_campaign = Input :: get ( 'utm_campaign' );
$company -> utm_term = Input :: get ( 'utm_term' );
$company -> utm_content = Input :: get ( 'utm_content' );
2017-05-14 12:11:38 +03:00
$company -> referral_code = Session :: get ( SESSION_REFERRAL_CODE );
2017-08-06 10:45:13 +03:00
2017-08-14 17:51:10 +03:00
if ( Input :: get ( 'utm_campaign' )) {
if ( env ( 'PROMO_CAMPAIGN' ) && hash_equals ( Input :: get ( 'utm_campaign' ), env ( 'PROMO_CAMPAIGN' ))) {
2017-08-25 13:46:32 +03:00
$company -> applyDiscount ( . 75 );
2019-01-30 22:00:26 +11:00
} elseif ( env ( 'PARTNER_CAMPAIGN' ) && hash_equals ( Input :: get ( 'utm_campaign' ), env ( 'PARTNER_CAMPAIGN' ))) {
2017-08-25 13:46:32 +03:00
$company -> applyFreeYear ();
2019-01-30 22:00:26 +11:00
} elseif ( env ( 'EDUCATION_CAMPAIGN' ) && hash_equals ( Input :: get ( 'utm_campaign' ), env ( 'EDUCATION_CAMPAIGN' ))) {
$company -> applyFreeYear ( 2 );
2017-08-14 17:51:10 +03:00
}
2017-11-28 10:35:20 +02:00
} else {
2017-12-06 15:43:41 +02:00
//$company->applyDiscount(.5);
//session()->flash('warning', $company->present()->promoMessage());
2017-08-14 17:03:34 +03:00
}
2017-03-24 14:51:24 +03:00
$company -> save ();
}
2016-05-13 12:23:13 +03:00
2015-03-17 07:45:25 +10:00
$account = new Account ();
$account -> ip = Request :: getClientIp ();
2017-04-02 20:46:01 +03:00
$account -> account_key = strtolower ( str_random ( RANDOM_KEY_LENGTH ));
2016-04-18 22:35:18 -04:00
$account -> company_id = $company -> id ;
2017-12-01 09:28:01 +02:00
$account -> currency_id = DEFAULT_CURRENCY ;
2015-03-17 07:45:25 +10:00
2017-10-22 18:44:49 +03:00
// Set default language/currency based on IP
2018-03-28 22:11:35 +03:00
// TODO Disabled until GDPR implications are understood
/*
2017-11-10 12:21:27 +02:00
if ( \Cache :: get ( 'currencies' )) {
2018-02-16 11:05:44 +02:00
if ( $data = unserialize ( @ file_get_contents ( 'http://www.geoplugin.net/php.gp?ip=' . $account -> ip ))) {
$currencyCode = strtolower ( $data [ 'geoplugin_currencyCode' ]);
$countryCode = strtolower ( $data [ 'geoplugin_countryCode' ]);
2017-10-22 18:44:49 +03:00
2018-02-16 11:05:44 +02:00
$currency = \Cache :: get ( 'currencies' ) -> filter ( function ( $item ) use ( $currencyCode ) {
return strtolower ( $item -> code ) == $currencyCode ;
}) -> first ();
if ( $currency ) {
$account -> currency_id = $currency -> id ;
}
2017-10-22 18:44:49 +03:00
2018-02-16 11:05:44 +02:00
$country = \Cache :: get ( 'countries' ) -> filter ( function ( $item ) use ( $countryCode ) {
return strtolower ( $item -> iso_3166_2 ) == $countryCode || strtolower ( $item -> iso_3166_3 ) == $countryCode ;
}) -> first ();
if ( $country ) {
$account -> country_id = $country -> id ;
}
2017-10-22 18:44:49 +03:00
2018-02-16 11:05:44 +02:00
$language = \Cache :: get ( 'languages' ) -> filter ( function ( $item ) use ( $countryCode ) {
return strtolower ( $item -> locale ) == $countryCode ;
}) -> first ();
if ( $language ) {
$account -> language_id = $language -> id ;
}
2017-11-10 12:21:27 +02:00
}
2015-03-17 07:45:25 +10:00
}
2018-03-28 22:11:35 +03:00
*/
2015-03-17 07:45:25 +10:00
$account -> save ();
$user = new User ();
2017-01-30 21:40:43 +02:00
if ( ! $firstName && ! $lastName && ! $email && ! $password ) {
2017-04-02 20:46:01 +03:00
$user -> password = strtolower ( str_random ( RANDOM_KEY_LENGTH ));
$user -> username = strtolower ( str_random ( RANDOM_KEY_LENGTH ));
2015-03-29 15:37:42 +03:00
} else {
$user -> first_name = $firstName ;
$user -> last_name = $lastName ;
$user -> email = $user -> username = $email ;
2017-01-30 21:40:43 +02:00
if ( ! $password ) {
2017-04-02 20:46:01 +03:00
$password = strtolower ( str_random ( RANDOM_KEY_LENGTH ));
2015-10-11 17:41:09 +03:00
}
2015-03-29 15:37:42 +03:00
$user -> password = bcrypt ( $password );
}
2017-01-30 21:40:43 +02:00
$user -> confirmed = ! Utils :: isNinja ();
$user -> registered = ! Utils :: isNinja () || $email ;
2015-03-29 15:37:42 +03:00
2017-01-30 21:40:43 +02:00
if ( ! $user -> confirmed ) {
2017-04-02 20:46:01 +03:00
$user -> confirmation_code = strtolower ( str_random ( RANDOM_KEY_LENGTH ));
2015-04-05 22:15:37 +03:00
}
2015-03-29 15:37:42 +03:00
$account -> users () -> save ( $user );
2015-03-17 07:45:25 +10:00
2017-03-31 18:02:56 +03:00
$emailSettings = new AccountEmailSettings ();
$account -> account_email_settings () -> save ( $emailSettings );
2019-01-30 22:00:26 +11:00
$accountTicketSettings = new AccountTicketSettings ();
$accountTicketSettings -> ticket_master_id = $user -> id ;
$accountTicketSettings -> ticket_number_start = 1 ;
$account -> account_ticket_settings () -> save ( $accountTicketSettings );
2015-03-17 07:45:25 +10:00
return $account ;
}
2018-03-11 08:50:11 +02:00
private function checkForSpammer ()
{
2018-03-11 09:20:35 +02:00
$ip = Request :: getClientIp ();
2018-07-24 21:32:30 +03:00
// Apple's IP for their test accounts
if ( $ip == '17.200.11.44' ) {
return ;
}
2018-03-18 16:46:55 +02:00
$count = Account :: whereIp ( $ip ) -> whereHas ( 'users' , function ( $query ) {
2018-03-18 16:48:14 +02:00
$query -> whereRegistered ( true );
2018-03-18 16:46:55 +02:00
}) -> count ();
2018-03-11 09:20:35 +02:00
2019-12-03 11:27:30 +02:00
if ( $count >= 15 ) {
abort ();
2018-03-11 08:50:11 +02:00
}
}
2016-05-08 21:29:49 +03:00
public function getSearchData ( $user )
2015-03-17 07:45:25 +10:00
{
2016-05-08 21:29:49 +03:00
$data = $this -> getAccountSearchData ( $user );
2016-02-22 23:23:28 +02:00
2016-05-08 21:29:49 +03:00
$data [ 'navigation' ] = $user -> is_admin ? $this -> getNavigationSearchData () : [];
2016-02-22 23:23:28 +02:00
return $data ;
}
2016-05-08 21:29:49 +03:00
private function getAccountSearchData ( $user )
2015-03-17 07:45:25 +10:00
{
2016-05-08 21:29:49 +03:00
$account = $user -> account ;
2016-05-13 12:23:13 +03:00
2016-02-25 23:33:48 +02:00
$data = [
2016-02-28 22:43:43 +02:00
'clients' => [],
'contacts' => [],
'invoices' => [],
'quotes' => [],
2016-02-25 23:33:48 +02:00
];
2016-03-14 10:09:18 +02:00
// include custom client fields in search
2018-04-04 16:24:59 +03:00
if ( $account -> customLabel ( 'client1' )) {
$data [ $account -> present () -> customLabel ( 'client1' )] = [];
2016-03-14 10:09:18 +02:00
}
2018-04-04 16:24:59 +03:00
if ( $account -> customLabel ( 'client2' )) {
$data [ $account -> present () -> customLabel ( 'client2' )] = [];
2016-03-14 10:09:18 +02:00
}
2018-08-08 23:05:45 +03:00
if ( $account -> customLabel ( 'invoice_text1' )) {
$data [ $account -> present () -> customLabel ( 'invoice_text1' )] = [];
}
if ( $account -> customLabel ( 'invoice_text2' )) {
$data [ $account -> present () -> customLabel ( 'invoice_text2' )] = [];
}
2016-05-13 12:23:13 +03:00
2018-06-07 20:08:34 +10:00
if ( $user -> hasPermission ([ 'view_client' , 'view_invoice' ], true )) {
2016-05-08 21:29:49 +03:00
$clients = Client :: scope ()
-> with ( 'contacts' , 'invoices' )
2018-02-14 15:55:53 +02:00
-> withTrashed ()
2017-11-30 21:24:02 +02:00
-> with ([ 'contacts' , 'invoices' => function ( $query ) use ( $user ) {
2018-02-14 15:55:53 +02:00
$query -> withTrashed ();
2017-11-30 21:24:02 +02:00
}]) -> get ();
2016-05-08 21:29:49 +03:00
} else {
$clients = Client :: scope ()
-> where ( 'user_id' , '=' , $user -> id )
2018-02-14 15:55:53 +02:00
-> withTrashed ()
2017-01-30 18:05:31 +02:00
-> with ([ 'contacts' , 'invoices' => function ( $query ) use ( $user ) {
2018-02-14 15:55:53 +02:00
$query -> withTrashed ()
2017-11-30 21:24:02 +02:00
-> where ( 'user_id' , '=' , $user -> id );
2016-05-08 21:29:49 +03:00
}]) -> get ();
}
2016-05-13 12:23:13 +03:00
2016-02-25 23:33:48 +02:00
foreach ( $clients as $client ) {
2018-04-12 22:51:10 +03:00
if ( ! $client -> is_deleted ) {
if ( $client -> name ) {
$data [ 'clients' ][] = [
'value' => ( $client -> id_number ? $client -> id_number . ': ' : '' ) . $client -> name ,
'tokens' => implode ( ',' , [ $client -> name , $client -> id_number , $client -> vat_number , $client -> work_phone ]),
'url' => $client -> present () -> url ,
];
}
2016-03-14 10:09:18 +02:00
2018-04-12 22:51:10 +03:00
if ( $client -> custom_value1 ) {
$data [ $account -> present () -> customLabel ( 'client1' )][] = [
'value' => " { $client -> custom_value1 } : " . $client -> getDisplayName (),
'tokens' => $client -> custom_value1 ,
'url' => $client -> present () -> url ,
];
}
if ( $client -> custom_value2 ) {
$data [ $account -> present () -> customLabel ( 'client2' )][] = [
'value' => " { $client -> custom_value2 } : " . $client -> getDisplayName (),
'tokens' => $client -> custom_value2 ,
'url' => $client -> present () -> url ,
];
}
2015-03-17 07:45:25 +10:00
2018-04-12 22:51:10 +03:00
foreach ( $client -> contacts as $contact ) {
$data [ 'contacts' ][] = [
'value' => $contact -> getSearchName (),
'tokens' => implode ( ',' , [ $contact -> first_name , $contact -> last_name , $contact -> email , $contact -> phone ]),
'url' => $client -> present () -> url ,
];
}
2015-03-17 07:45:25 +10:00
}
2016-02-25 23:33:48 +02:00
foreach ( $client -> invoices as $invoice ) {
$entityType = $invoice -> getEntityType ();
2016-02-28 22:43:43 +02:00
$data [ " { $entityType } s " ][] = [
2016-02-25 23:33:48 +02:00
'value' => $invoice -> getDisplayName () . ': ' . $client -> getDisplayName (),
2016-12-25 12:48:26 +02:00
'tokens' => implode ( ',' , [ $invoice -> invoice_number , $invoice -> po_number ]),
2016-02-25 23:33:48 +02:00
'url' => $invoice -> present () -> url ,
];
2018-06-17 10:07:55 +03:00
if ( $customValue = $invoice -> custom_text_value1 ) {
$data [ $account -> present () -> customLabel ( 'invoice_text1' )][] = [
'value' => " { $customValue } : { $invoice -> getDisplayName () } " ,
'tokens' => $customValue ,
'url' => $invoice -> present () -> url ,
];
}
if ( $customValue = $invoice -> custom_text_value2 ) {
$data [ $account -> present () -> customLabel ( 'invoice_text2' )][] = [
'value' => " { $customValue } : { $invoice -> getDisplayName () } " ,
'tokens' => $customValue ,
'url' => $invoice -> present () -> url ,
];
}
2015-03-17 07:45:25 +10:00
}
2016-02-22 23:23:28 +02:00
}
return $data ;
}
2015-03-17 07:45:25 +10:00
2016-02-22 23:23:28 +02:00
private function getNavigationSearchData ()
{
$entityTypes = [
ENTITY_INVOICE ,
ENTITY_CLIENT ,
ENTITY_QUOTE ,
ENTITY_TASK ,
ENTITY_EXPENSE ,
2016-07-06 21:35:16 +03:00
ENTITY_EXPENSE_CATEGORY ,
2016-05-05 10:28:23 +03:00
ENTITY_VENDOR ,
2016-02-22 23:23:28 +02:00
ENTITY_RECURRING_INVOICE ,
2019-01-30 22:00:26 +11:00
ENTITY_RECURRING_QUOTE ,
2016-02-22 23:23:28 +02:00
ENTITY_PAYMENT ,
2016-11-29 19:47:26 +02:00
ENTITY_CREDIT ,
ENTITY_PROJECT ,
2018-01-31 13:51:18 +02:00
ENTITY_PROPOSAL ,
2016-02-22 23:23:28 +02:00
];
foreach ( $entityTypes as $entityType ) {
$features [] = [
" new_ { $entityType } " ,
2017-01-30 21:40:43 +02:00
Utils :: pluralizeEntityType ( $entityType ) . '/create' ,
2016-02-22 23:23:28 +02:00
];
$features [] = [
2016-07-06 21:35:16 +03:00
'list_' . Utils :: pluralizeEntityType ( $entityType ),
2017-01-30 21:40:43 +02:00
Utils :: pluralizeEntityType ( $entityType ),
2016-02-22 23:23:28 +02:00
];
}
2016-05-05 22:31:11 +03:00
$features = array_merge ( $features , [
[ 'dashboard' , '/dashboard' ],
2017-01-22 12:09:29 +02:00
[ 'reports' , '/reports' ],
2017-09-13 16:45:20 +03:00
[ 'calendar' , '/calendar' ],
2017-12-19 22:08:49 +02:00
[ 'kanban' , '/tasks/kanban' ],
2016-05-05 22:31:11 +03:00
[ 'customize_design' , '/settings/customize_design' ],
[ 'new_tax_rate' , '/tax_rates/create' ],
[ 'new_product' , '/products/create' ],
[ 'new_user' , '/users/create' ],
[ 'custom_fields' , '/settings/invoice_settings' ],
[ 'invoice_number' , '/settings/invoice_settings' ],
2016-09-05 21:40:02 +03:00
[ 'buy_now_buttons' , '/settings/client_portal#buy_now' ],
2016-09-05 15:28:59 +03:00
[ 'invoice_fields' , '/settings/invoice_design#invoice_fields' ],
2016-05-05 22:31:11 +03:00
]);
2016-02-24 22:58:42 +02:00
2016-02-22 23:23:28 +02:00
$settings = array_merge ( Account :: $basicSettings , Account :: $advancedSettings );
2017-01-30 18:05:31 +02:00
if ( ! Utils :: isNinjaProd ()) {
2016-05-05 10:28:23 +03:00
$settings [] = ACCOUNT_SYSTEM_SETTINGS ;
}
2016-02-22 23:23:28 +02:00
foreach ( $settings as $setting ) {
$features [] = [
$setting ,
" /settings/ { $setting } " ,
];
}
foreach ( $features as $feature ) {
$data [] = [
'value' => trans ( 'texts.' . $feature [ 0 ]),
2016-03-14 10:09:18 +02:00
'tokens' => trans ( 'texts.' . $feature [ 0 ]),
2017-01-30 21:40:43 +02:00
'url' => URL :: to ( $feature [ 1 ]),
2015-03-17 07:45:25 +10:00
];
}
return $data ;
}
2016-07-14 12:46:00 +03:00
public function enablePlan ( $plan , $credit = 0 )
2015-03-17 07:45:25 +10:00
{
2016-02-29 13:25:32 +02:00
$account = Auth :: user () -> account ;
$client = $this -> getNinjaClient ( $account );
2016-07-14 12:46:00 +03:00
$invitation = $this -> createNinjaInvoice ( $client , $account , $plan , $credit );
2015-03-17 07:45:25 +10:00
return $invitation ;
}
2016-07-14 22:58:48 +03:00
public function createNinjaCredit ( $client , $amount )
{
$account = $this -> getNinjaAccount ();
$lastCredit = Credit :: withTrashed () -> whereAccountId ( $account -> id ) -> orderBy ( 'public_id' , 'DESC' ) -> first ();
$publicId = $lastCredit ? ( $lastCredit -> public_id + 1 ) : 1 ;
$credit = new Credit ();
$credit -> public_id = $publicId ;
$credit -> account_id = $account -> id ;
$credit -> user_id = $account -> users () -> first () -> id ;
$credit -> client_id = $client -> id ;
$credit -> amount = $amount ;
$credit -> save ();
return $credit ;
}
2016-07-14 12:46:00 +03:00
public function createNinjaInvoice ( $client , $clientAccount , $plan , $credit = 0 )
2015-03-17 07:45:25 +10:00
{
2016-07-11 20:08:43 +03:00
$term = $plan [ 'term' ];
$plan_cost = $plan [ 'price' ];
$num_users = $plan [ 'num_users' ];
$plan = $plan [ 'plan' ];
2016-04-16 18:34:39 -04:00
if ( $credit < 0 ) {
$credit = 0 ;
}
2016-05-13 12:23:13 +03:00
2015-05-08 11:21:29 +03:00
$account = $this -> getNinjaAccount ();
$lastInvoice = Invoice :: withTrashed () -> whereAccountId ( $account -> id ) -> orderBy ( 'public_id' , 'DESC' ) -> first ();
2016-12-15 12:52:10 +02:00
$renewalDate = $clientAccount -> getRenewalDate ();
2015-05-08 11:21:29 +03:00
$publicId = $lastInvoice ? ( $lastInvoice -> public_id + 1 ) : 1 ;
2016-12-15 12:52:10 +02:00
2015-03-17 07:45:25 +10:00
$invoice = new Invoice ();
2016-12-05 10:11:33 +02:00
$invoice -> is_public = true ;
2015-03-17 07:45:25 +10:00
$invoice -> account_id = $account -> id ;
$invoice -> user_id = $account -> users () -> first () -> id ;
$invoice -> public_id = $publicId ;
$invoice -> client_id = $client -> id ;
2017-01-04 10:11:32 +02:00
$invoice -> invoice_number = $account -> getNextNumber ( $invoice );
2016-12-15 12:52:10 +02:00
$invoice -> invoice_date = $renewalDate -> format ( 'Y-m-d' );
2016-04-16 18:34:39 -04:00
$invoice -> amount = $invoice -> balance = $plan_cost - $credit ;
2016-08-25 17:32:26 +03:00
$invoice -> invoice_type_id = INVOICE_TYPE_STANDARD ;
2016-12-14 16:19:16 +02:00
// check for promo/discount
$clientCompany = $clientAccount -> company ;
2016-12-15 12:52:10 +02:00
if ( $clientCompany -> hasActivePromo () || $clientCompany -> hasActiveDiscount ( $renewalDate )) {
2016-12-14 16:19:16 +02:00
$discount = $invoice -> amount * $clientCompany -> discount ;
$invoice -> discount = $clientCompany -> discount * 100 ;
$invoice -> amount -= $discount ;
$invoice -> balance -= $discount ;
}
2015-03-17 07:45:25 +10:00
$invoice -> save ();
2016-04-16 18:34:39 -04:00
if ( $credit ) {
$credit_item = InvoiceItem :: createNew ( $invoice );
$credit_item -> qty = 1 ;
$credit_item -> cost = - $credit ;
$credit_item -> notes = trans ( 'texts.plan_credit_description' );
$credit_item -> product_key = trans ( 'texts.plan_credit_product' );
$invoice -> invoice_items () -> save ( $credit_item );
}
2016-05-13 12:23:13 +03:00
2016-04-16 18:34:39 -04:00
$item = InvoiceItem :: createNew ( $invoice );
2015-03-17 07:45:25 +10:00
$item -> qty = 1 ;
2016-04-16 18:34:39 -04:00
$item -> cost = $plan_cost ;
$item -> notes = trans ( " texts. { $plan } _plan_ { $term } _description " );
2016-05-13 12:23:13 +03:00
2016-07-11 20:08:43 +03:00
if ( $plan == PLAN_ENTERPRISE ) {
$min = Utils :: getMinNumUsers ( $num_users );
$item -> notes .= " \n \n ### " . trans ( 'texts.min_to_max_users' , [ 'min' => $min , 'max' => $num_users ]);
}
2016-04-16 18:34:39 -04:00
// Don't change this without updating the regex in PaymentService->createPayment()
$item -> product_key = 'Plan - ' . ucfirst ( $plan ) . ' (' . ucfirst ( $term ) . ')' ;
2015-03-17 07:45:25 +10:00
$invoice -> invoice_items () -> save ( $item );
2016-05-13 12:23:13 +03:00
2017-05-28 13:19:48 +03:00
$invitation = Invitation :: createNew ( $invoice );
2015-03-17 07:45:25 +10:00
$invitation -> invoice_id = $invoice -> id ;
$invitation -> contact_id = $client -> contacts () -> first () -> id ;
2017-04-02 20:46:01 +03:00
$invitation -> invitation_key = strtolower ( str_random ( RANDOM_KEY_LENGTH ));
2015-03-17 07:45:25 +10:00
$invitation -> save ();
return $invitation ;
}
public function getNinjaAccount ()
{
2017-05-25 20:29:47 +03:00
$account = Account :: where ( 'account_key' , 'LIKE' , substr ( NINJA_ACCOUNT_KEY , 0 , 30 ) . '%' ) -> orderBy ( 'id' ) -> first ();
2015-03-17 07:45:25 +10:00
if ( $account ) {
return $account ;
} else {
2017-01-08 17:52:38 +02:00
$company = new Company ();
$company -> save ();
2015-03-17 07:45:25 +10:00
$account = new Account ();
$account -> name = 'Invoice Ninja' ;
$account -> work_email = 'contact@invoiceninja.com' ;
$account -> work_phone = '(800) 763-1948' ;
$account -> account_key = NINJA_ACCOUNT_KEY ;
2017-01-08 17:52:38 +02:00
$account -> company_id = $company -> id ;
2015-03-17 07:45:25 +10:00
$account -> save ();
2017-04-16 17:22:07 +03:00
$emailSettings = new AccountEmailSettings ();
$account -> account_email_settings () -> save ( $emailSettings );
2015-03-17 07:45:25 +10:00
$user = new User ();
$user -> registered = true ;
$user -> confirmed = true ;
2017-05-01 15:17:52 +03:00
$user -> email = NINJA_ACCOUNT_EMAIL ;
$user -> username = NINJA_ACCOUNT_EMAIL ;
$user -> password = strtolower ( str_random ( RANDOM_KEY_LENGTH ));
2015-03-17 07:45:25 +10:00
$user -> first_name = 'Invoice' ;
$user -> last_name = 'Ninja' ;
$user -> notify_sent = true ;
$user -> notify_paid = true ;
$account -> users () -> save ( $user );
2019-01-30 22:00:26 +11:00
$account_ticket_settings = new AccountTicketSettings ();
$account_ticket_settings -> ticket_master_id = $user -> id ;
$account -> account_ticket_settings () -> save ( $account_ticket_settings );
2016-05-13 12:23:13 +03:00
if ( $config = env ( NINJA_GATEWAY_CONFIG )) {
$accountGateway = new AccountGateway ();
$accountGateway -> user_id = $user -> id ;
$accountGateway -> gateway_id = NINJA_GATEWAY_ID ;
$accountGateway -> public_id = 1 ;
$accountGateway -> setConfig ( json_decode ( $config ));
$account -> account_gateways () -> save ( $accountGateway );
}
2015-03-17 07:45:25 +10:00
}
return $account ;
}
2015-05-08 11:21:29 +03:00
public function getNinjaClient ( $account )
2015-03-17 07:45:25 +10:00
{
2015-05-08 11:21:29 +03:00
$account -> load ( 'users' );
$ninjaAccount = $this -> getNinjaAccount ();
2016-05-08 15:37:32 +03:00
$ninjaUser = $ninjaAccount -> getPrimaryUser ();
$client = Client :: whereAccountId ( $ninjaAccount -> id )
-> wherePublicId ( $account -> id )
-> first ();
2015-03-17 07:45:25 +10:00
2017-01-30 21:40:43 +02:00
if ( ! $client ) {
2015-03-17 07:45:25 +10:00
$client = new Client ();
2015-05-08 11:21:29 +03:00
$client -> public_id = $account -> id ;
2016-05-08 15:37:32 +03:00
$client -> account_id = $ninjaAccount -> id ;
$client -> user_id = $ninjaUser -> id ;
2015-03-17 07:45:25 +10:00
$client -> currency_id = 1 ;
2017-05-08 11:38:57 +03:00
foreach ([ 'name' , 'address1' , 'address2' , 'city' , 'state' , 'postal_code' , 'country_id' , 'work_phone' , 'language_id' , 'vat_number' ] as $field ) {
$client -> $field = $account -> $field ;
}
$client -> save ();
2015-03-17 07:45:25 +10:00
$contact = new Contact ();
2016-05-08 15:37:32 +03:00
$contact -> user_id = $ninjaUser -> id ;
2015-03-17 07:45:25 +10:00
$contact -> account_id = $ninjaAccount -> id ;
2015-05-08 11:21:29 +03:00
$contact -> public_id = $account -> id ;
2017-05-03 19:26:03 +03:00
$contact -> contact_key = strtolower ( str_random ( RANDOM_KEY_LENGTH ));
2015-03-17 07:45:25 +10:00
$contact -> is_primary = true ;
2017-05-08 11:38:57 +03:00
foreach ([ 'first_name' , 'last_name' , 'email' , 'phone' ] as $field ) {
$contact -> $field = $account -> users () -> first () -> $field ;
}
$client -> contacts () -> save ( $contact );
2015-03-17 07:45:25 +10:00
}
2016-05-13 12:23:13 +03:00
2015-03-17 07:45:25 +10:00
return $client ;
}
2015-11-03 21:03:24 +02:00
public function findByKey ( $key )
{
$account = Account :: whereAccountKey ( $key )
-> with ( 'clients.invoices.invoice_items' , 'clients.contacts' )
-> firstOrFail ();
return $account ;
}
2015-10-11 17:41:09 +03:00
public function unlinkUserFromOauth ( $user )
{
$user -> oauth_provider_id = null ;
$user -> oauth_user_id = null ;
$user -> save ();
}
public function updateUserFromOauth ( $user , $firstName , $lastName , $email , $providerId , $oauthUserId )
{
2017-05-15 16:49:58 +03:00
if ( ! LookupUser :: validateField ( 'oauth_user_key' , $providerId . '-' . $oauthUserId )) {
return trans ( 'texts.oauth_taken' );
}
2017-05-15 16:58:07 +03:00
// TODO remove once multi-db is enabled
if ( User :: whereOauthUserId ( $oauthUserId ) -> count () > 0 ) {
return trans ( 'texts.oauth_taken' );
}
2017-01-30 21:40:43 +02:00
if ( ! $user -> registered ) {
2015-10-11 17:41:09 +03:00
$rules = [ 'email' => 'email|required|unique:users,email,' . $user -> id . ',id' ];
$validator = Validator :: make ([ 'email' => $email ], $rules );
2017-05-01 21:46:31 +03:00
2015-10-11 17:41:09 +03:00
if ( $validator -> fails ()) {
$messages = $validator -> messages ();
return $messages -> first ( 'email' );
}
2017-05-15 16:49:58 +03:00
if ( ! LookupUser :: validateField ( 'email' , $email , $user )) {
2017-05-01 21:46:31 +03:00
return trans ( 'texts.email_taken' );
}
2015-10-11 17:41:09 +03:00
$user -> email = $email ;
$user -> first_name = $firstName ;
$user -> last_name = $lastName ;
$user -> registered = true ;
2016-02-11 17:12:27 +02:00
2016-04-19 10:28:27 -04:00
$user -> account -> startTrial ( PLAN_PRO );
2015-10-11 17:41:09 +03:00
}
$user -> oauth_provider_id = $providerId ;
$user -> oauth_user_id = $oauthUserId ;
$user -> save ();
return true ;
}
public function registerNinjaUser ( $user )
2015-03-17 07:45:25 +10:00
{
2017-12-14 13:57:21 +02:00
if ( ! $user || $user -> email == TEST_USERNAME ) {
2015-09-25 12:57:40 +03:00
return false ;
}
$url = ( Utils :: isNinjaDev () ? SITE_URL : NINJA_APP_URL ) . '/signup/register' ;
2015-03-17 07:45:25 +10:00
$data = '' ;
$fields = [
2015-05-08 11:21:29 +03:00
'first_name' => urlencode ( $user -> first_name ),
'last_name' => urlencode ( $user -> last_name ),
'email' => urlencode ( $user -> email ),
];
2015-03-17 07:45:25 +10:00
foreach ( $fields as $key => $value ) {
$data .= $key . '=' . $value . '&' ;
}
rtrim ( $data , '&' );
$ch = curl_init ();
curl_setopt ( $ch , CURLOPT_URL , $url );
curl_setopt ( $ch , CURLOPT_POST , count ( $fields ));
curl_setopt ( $ch , CURLOPT_POSTFIELDS , $data );
2015-09-25 12:57:40 +03:00
curl_setopt ( $ch , CURLOPT_RETURNTRANSFER , true );
2015-03-17 07:45:25 +10:00
curl_exec ( $ch );
curl_close ( $ch );
}
2015-06-16 22:35:35 +03:00
2015-10-11 17:41:09 +03:00
public function findUserByOauth ( $providerId , $oauthUserId )
{
return User :: where ( 'oauth_user_id' , $oauthUserId )
-> where ( 'oauth_provider_id' , $providerId )
-> first ();
}
2015-11-03 21:03:24 +02:00
public function findUsers ( $user , $with = null )
{
$accounts = $this -> findUserAccounts ( $user -> id );
if ( $accounts ) {
return $this -> getUserAccounts ( $accounts , $with );
} else {
return [ $user ];
}
}
2017-01-29 22:07:44 +02:00
public function findUser ( $user , $accountKey )
{
$users = $this -> findUsers ( $user , 'account' );
foreach ( $users as $user ) {
if ( $accountKey && hash_equals ( $user -> account -> account_key , $accountKey )) {
return $user ;
}
}
return false ;
}
2015-06-16 22:35:35 +03:00
public function findUserAccounts ( $userId1 , $userId2 = false )
{
2017-01-30 21:40:43 +02:00
if ( ! Schema :: hasTable ( 'user_accounts' )) {
2015-08-03 22:08:07 +03:00
return false ;
}
2015-06-16 22:35:35 +03:00
$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' ]);
}
2015-11-03 21:03:24 +02:00
public function getUserAccounts ( $record , $with = null )
{
2017-01-30 21:40:43 +02:00
if ( ! $record ) {
2015-06-16 22:35:35 +03:00
return false ;
}
$userIds = [];
2017-01-30 21:40:43 +02:00
for ( $i = 1 ; $i <= 5 ; $i ++ ) {
2015-06-16 22:35:35 +03:00
$field = " user_id $i " ;
if ( $record -> $field ) {
$userIds [] = $record -> $field ;
}
}
$users = User :: with ( 'account' )
2015-11-03 21:03:24 +02:00
-> whereIn ( 'id' , $userIds );
if ( $with ) {
$users -> with ( $with );
}
2016-05-13 12:23:13 +03:00
2015-11-03 21:03:24 +02:00
return $users -> get ();
}
public function prepareUsersData ( $record )
{
2017-01-30 21:40:43 +02:00
if ( ! $record ) {
2015-11-04 15:10:41 +02:00
return false ;
}
2015-11-03 21:03:24 +02:00
$users = $this -> getUserAccounts ( $record );
2015-06-16 22:35:35 +03:00
$data = [];
foreach ( $users as $user ) {
$item = new stdClass ();
$item -> id = $record -> id ;
$item -> user_id = $user -> id ;
2016-04-18 22:35:18 -04:00
$item -> public_id = $user -> public_id ;
2015-06-16 22:35:35 +03:00
$item -> user_name = $user -> getDisplayName ();
$item -> account_id = $user -> account -> id ;
$item -> account_name = $user -> account -> getDisplayName ();
2016-03-22 16:19:55 -04:00
$item -> logo_url = $user -> account -> hasLogo () ? $user -> account -> getLogoUrl () : null ;
2015-06-16 22:35:35 +03:00
$data [] = $item ;
}
return $data ;
}
2017-01-30 18:05:31 +02:00
public function loadAccounts ( $userId )
{
2015-06-16 22:35:35 +03:00
$record = self :: findUserAccounts ( $userId );
2017-01-30 21:40:43 +02:00
2015-06-16 22:35:35 +03:00
return self :: prepareUsersData ( $record );
}
2017-01-30 18:05:31 +02:00
public function associateAccounts ( $userId1 , $userId2 )
{
2015-06-16 22:35:35 +03:00
$record = self :: findUserAccounts ( $userId1 , $userId2 );
if ( $record ) {
foreach ([ $userId1 , $userId2 ] as $userId ) {
2017-01-30 21:40:43 +02:00
if ( ! $record -> hasUserId ( $userId )) {
2015-06-16 22:35:35 +03:00
$record -> setUserId ( $userId );
}
}
} else {
$record = new UserAccount ();
$record -> user_id1 = $userId1 ;
$record -> user_id2 = $userId2 ;
}
$record -> save ();
2017-03-24 14:51:24 +03:00
return $this -> loadAccounts ( $userId1 );
2015-06-16 22:35:35 +03:00
}
2017-01-30 18:05:31 +02:00
public function unlinkAccount ( $account )
{
2015-07-07 23:08:16 +03:00
foreach ( $account -> users as $user ) {
if ( $userAccount = self :: findUserAccounts ( $user -> id )) {
$userAccount -> removeUserId ( $user -> id );
$userAccount -> save ();
}
}
}
2015-06-16 22:35:35 +03:00
2017-01-30 18:05:31 +02:00
public function unlinkUser ( $userAccountId , $userId )
{
2015-07-07 23:08:16 +03:00
$userAccount = UserAccount :: whereId ( $userAccountId ) -> first ();
if ( $userAccount -> hasUserId ( $userId )) {
2015-06-16 22:35:35 +03:00
$userAccount -> removeUserId ( $userId );
$userAccount -> save ();
}
2016-05-13 12:23:13 +03:00
2016-04-18 22:35:18 -04:00
$user = User :: whereId ( $userId ) -> first ();
2016-05-13 12:23:13 +03:00
2017-01-30 21:40:43 +02:00
if ( ! $user -> public_id && $user -> account -> hasMultipleAccounts ()) {
2016-04-18 22:35:18 -04:00
$company = Company :: create ();
$company -> save ();
$user -> account -> company_id = $company -> id ;
$user -> account -> save ();
}
2015-06-16 22:35:35 +03:00
}
2015-09-17 22:01:06 +03:00
public function findWithReminders ()
{
2019-01-30 22:00:26 +11:00
return Account :: whereHas ( 'account_email_settings' , function ( $query ) {
2019-04-29 00:39:47 +02:00
$query -> whereRaw ( 'enable_reminder1 = 1 OR enable_reminder2 = 1 OR enable_reminder3 = 1 OR enable_reminder4 = 1 OR enable_quote_reminder1 = 1 OR enable_quote_reminder2 = 1 OR enable_quote_reminder3 = 1 OR enable_quote_reminder4 = 1' );
2019-01-30 22:00:26 +11:00
}) -> get ();
2015-09-17 22:01:06 +03:00
}
2015-09-21 00:05:02 +03:00
2017-07-18 21:15:51 +03:00
public function findWithFees ()
{
return Account :: whereHas ( 'account_email_settings' , function ( $query ) {
$query -> where ( 'late_fee1_amount' , '>' , 0 )
-> orWhere ( 'late_fee1_percent' , '>' , 0 )
-> orWhere ( 'late_fee2_amount' , '>' , 0 )
-> orWhere ( 'late_fee2_percent' , '>' , 0 )
-> orWhere ( 'late_fee3_amount' , '>' , 0 )
2019-04-29 00:39:47 +02:00
-> orWhere ( 'late_fee3_percent' , '>' , 0 )
-> orWhere ( 'late_fee_quote1_amount' , '>' , 0 )
-> orWhere ( 'late_fee_quote1_percent' , '>' , 0 )
-> orWhere ( 'late_fee_quote2_amount' , '>' , 0 )
-> orWhere ( 'late_fee_quote2_percent' , '>' , 0 )
-> orWhere ( 'late_fee_quote3_amount' , '>' , 0 )
-> orWhere ( 'late_fee_quote3_percent' , '>' , 0 );
2017-07-18 21:15:51 +03:00
}) -> get ();
}
2016-07-21 15:35:23 +03:00
public function createTokens ( $user , $name )
2015-11-02 00:10:20 +02:00
{
2015-11-02 20:43:22 +02:00
$name = trim ( $name ) ? : 'TOKEN' ;
2015-11-03 21:03:24 +02:00
$users = $this -> findUsers ( $user );
2016-05-13 12:23:13 +03:00
2015-11-03 21:03:24 +02:00
foreach ( $users as $user ) {
if ( $token = AccountToken :: whereUserId ( $user -> id ) -> whereName ( $name ) -> first ()) {
continue ;
}
2015-11-02 00:10:20 +02:00
2015-11-03 21:03:24 +02:00
$token = AccountToken :: createNew ( $user );
$token -> name = $name ;
2017-04-02 20:46:01 +03:00
$token -> token = strtolower ( str_random ( RANDOM_KEY_LENGTH ));
2015-11-03 21:03:24 +02:00
$token -> save ();
}
2015-11-02 00:10:20 +02:00
}
2015-11-12 22:36:28 +02:00
2016-07-21 15:35:23 +03:00
public function getUserAccountId ( $account )
2015-11-12 22:36:28 +02:00
{
$user = $account -> users () -> first ();
$userAccount = $this -> findUserAccounts ( $user -> id );
return $userAccount ? $userAccount -> id : false ;
}
2016-02-03 14:41:40 +02:00
2016-07-21 15:35:23 +03:00
public function save ( $data , $account )
2016-02-03 14:41:40 +02:00
{
$account -> fill ( $data );
$account -> save ();
}
2015-03-17 07:45:25 +10:00
}