mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-07 12:24:29 -04:00
Enhancements to API (#3088)
* working on email throttling * Fixes for invitaiton links * pass custom fields as object * Add user agent to company token * Update company token transformer * Remove prefix setting from CompanySettings * Implement user agent on company token & provide better error handling for undefined relationships includes * Fix bulk actions * Working on updating/creating a company user * Fixes for tests
This commit is contained in:
parent
170340cdfa
commit
69efd4d574
@ -71,37 +71,28 @@ class CompanySettings extends BaseSettings
|
|||||||
/* Counters */
|
/* Counters */
|
||||||
public $invoice_number_pattern = '';
|
public $invoice_number_pattern = '';
|
||||||
public $invoice_number_counter = 1;
|
public $invoice_number_counter = 1;
|
||||||
public $invoice_number_prefix = '';
|
|
||||||
|
|
||||||
public $quote_number_prefix = '';
|
|
||||||
public $quote_number_pattern = '';
|
public $quote_number_pattern = '';
|
||||||
public $quote_number_counter = 1;
|
public $quote_number_counter = 1;
|
||||||
|
|
||||||
public $client_number_prefix = '';
|
|
||||||
public $client_number_pattern = '';
|
public $client_number_pattern = '';
|
||||||
public $client_number_counter = 1;
|
public $client_number_counter = 1;
|
||||||
|
|
||||||
public $credit_number_prefix = '';
|
|
||||||
public $credit_number_pattern = '';
|
public $credit_number_pattern = '';
|
||||||
public $credit_number_counter = 1;
|
public $credit_number_counter = 1;
|
||||||
|
|
||||||
public $task_number_prefix = '';
|
|
||||||
public $task_number_pattern = '';
|
public $task_number_pattern = '';
|
||||||
public $task_number_counter = 1;
|
public $task_number_counter = 1;
|
||||||
|
|
||||||
public $expense_number_prefix = '';
|
|
||||||
public $expense_number_pattern = '';
|
public $expense_number_pattern = '';
|
||||||
public $expense_number_counter = 1;
|
public $expense_number_counter = 1;
|
||||||
|
|
||||||
public $vendor_number_prefix = '';
|
|
||||||
public $vendor_number_pattern = '';
|
public $vendor_number_pattern = '';
|
||||||
public $vendor_number_counter = 1;
|
public $vendor_number_counter = 1;
|
||||||
|
|
||||||
public $ticket_number_prefix = '';
|
|
||||||
public $ticket_number_pattern = '';
|
public $ticket_number_pattern = '';
|
||||||
public $ticket_number_counter = 1;
|
public $ticket_number_counter = 1;
|
||||||
|
|
||||||
public $payment_number_prefix = '';
|
|
||||||
public $payment_number_pattern = '';
|
public $payment_number_pattern = '';
|
||||||
public $payment_number_counter = 1;
|
public $payment_number_counter = 1;
|
||||||
|
|
||||||
@ -260,19 +251,14 @@ class CompanySettings extends BaseSettings
|
|||||||
'embed_documents' => 'bool',
|
'embed_documents' => 'bool',
|
||||||
'all_pages_header' => 'bool',
|
'all_pages_header' => 'bool',
|
||||||
'all_pages_footer' => 'bool',
|
'all_pages_footer' => 'bool',
|
||||||
'task_number_prefix' => 'string',
|
|
||||||
'task_number_pattern' => 'string',
|
'task_number_pattern' => 'string',
|
||||||
'task_number_counter' => 'int',
|
'task_number_counter' => 'int',
|
||||||
'expense_number_prefix' => 'string',
|
|
||||||
'expense_number_pattern' => 'string',
|
'expense_number_pattern' => 'string',
|
||||||
'expense_number_counter' => 'int',
|
'expense_number_counter' => 'int',
|
||||||
'vendor_number_prefix' => 'string',
|
|
||||||
'vendor_number_pattern' => 'string',
|
'vendor_number_pattern' => 'string',
|
||||||
'vendor_number_counter' => 'int',
|
'vendor_number_counter' => 'int',
|
||||||
'ticket_number_prefix' => 'string',
|
|
||||||
'ticket_number_pattern' => 'string',
|
'ticket_number_pattern' => 'string',
|
||||||
'ticket_number_counter' => 'int',
|
'ticket_number_counter' => 'int',
|
||||||
'payment_number_prefix' => 'string',
|
|
||||||
'payment_number_pattern' => 'string',
|
'payment_number_pattern' => 'string',
|
||||||
'payment_number_counter' => 'int',
|
'payment_number_counter' => 'int',
|
||||||
'reply_to_email' => 'string',
|
'reply_to_email' => 'string',
|
||||||
@ -287,10 +273,8 @@ class CompanySettings extends BaseSettings
|
|||||||
'city' => 'string',
|
'city' => 'string',
|
||||||
'company_logo' => 'string',
|
'company_logo' => 'string',
|
||||||
'country_id' => 'string',
|
'country_id' => 'string',
|
||||||
'client_number_prefix' => 'string',
|
|
||||||
'client_number_pattern' => 'string',
|
'client_number_pattern' => 'string',
|
||||||
'client_number_counter' => 'integer',
|
'client_number_counter' => 'integer',
|
||||||
'credit_number_prefix' => 'string',
|
|
||||||
'credit_number_pattern' => 'string',
|
'credit_number_pattern' => 'string',
|
||||||
'credit_number_counter' => 'integer',
|
'credit_number_counter' => 'integer',
|
||||||
'currency_id' => 'string',
|
'currency_id' => 'string',
|
||||||
@ -320,7 +304,6 @@ class CompanySettings extends BaseSettings
|
|||||||
'email_template_reminder_endless' => 'string',
|
'email_template_reminder_endless' => 'string',
|
||||||
'enable_client_portal_password' => 'bool',
|
'enable_client_portal_password' => 'bool',
|
||||||
'inclusive_taxes' => 'bool',
|
'inclusive_taxes' => 'bool',
|
||||||
'invoice_number_prefix' => 'string',
|
|
||||||
'invoice_number_pattern' => 'string',
|
'invoice_number_pattern' => 'string',
|
||||||
'invoice_number_counter' => 'integer',
|
'invoice_number_counter' => 'integer',
|
||||||
'invoice_design_id' => 'string',
|
'invoice_design_id' => 'string',
|
||||||
@ -336,7 +319,6 @@ class CompanySettings extends BaseSettings
|
|||||||
'phone' => 'string',
|
'phone' => 'string',
|
||||||
'postal_code' => 'string',
|
'postal_code' => 'string',
|
||||||
'quote_design_id' => 'string',
|
'quote_design_id' => 'string',
|
||||||
'quote_number_prefix' => 'string',
|
|
||||||
'quote_number_pattern' => 'string',
|
'quote_number_pattern' => 'string',
|
||||||
'quote_number_counter' => 'integer',
|
'quote_number_counter' => 'integer',
|
||||||
'quote_terms' => 'string',
|
'quote_terms' => 'string',
|
||||||
|
@ -22,6 +22,7 @@ use Illuminate\Validation\ValidationException;
|
|||||||
use Symfony\Component\Debug\Exception\FatalThrowableError;
|
use Symfony\Component\Debug\Exception\FatalThrowableError;
|
||||||
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
|
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
|
||||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||||
|
use Illuminate\Database\Eloquent\RelationNotFoundException;
|
||||||
|
|
||||||
class Handler extends ExceptionHandler
|
class Handler extends ExceptionHandler
|
||||||
{
|
{
|
||||||
@ -70,15 +71,15 @@ class Handler extends ExceptionHandler
|
|||||||
public function render($request, Exception $exception)
|
public function render($request, Exception $exception)
|
||||||
{
|
{
|
||||||
|
|
||||||
if ($exception instanceof ModelNotFoundException)
|
if ($exception instanceof ModelNotFoundException && $request->expectsJson())
|
||||||
{
|
{
|
||||||
return response()->json(['message'=>'Record not found'],400);
|
return response()->json(['message'=>'Record not found'],400);
|
||||||
}
|
}
|
||||||
else if($exception instanceof ThrottleRequestsException)
|
else if($exception instanceof ThrottleRequestsException && $request->expectsJson())
|
||||||
{
|
{
|
||||||
return response()->json(['message'=>'Too many requests'],429);
|
return response()->json(['message'=>'Too many requests'],429);
|
||||||
}
|
}
|
||||||
else if($exception instanceof FatalThrowableError)
|
else if($exception instanceof FatalThrowableError && $request->expectsJson())
|
||||||
{
|
{
|
||||||
return response()->json(['message'=>'Fatal error'], 500);
|
return response()->json(['message'=>'Fatal error'], 500);
|
||||||
}
|
}
|
||||||
@ -95,15 +96,18 @@ class Handler extends ExceptionHandler
|
|||||||
'message' => ctrans('texts.token_expired'),
|
'message' => ctrans('texts.token_expired'),
|
||||||
'message-type' => 'danger']);
|
'message-type' => 'danger']);
|
||||||
}
|
}
|
||||||
else if ($exception instanceof NotFoundHttpException) {
|
else if ($exception instanceof NotFoundHttpException && $request->expectsJson()) {
|
||||||
return response()->json(['message'=>'Route does not exist'],404);
|
return response()->json(['message'=>'Route does not exist'],404);
|
||||||
}
|
}
|
||||||
else if($exception instanceof MethodNotAllowedHttpException){
|
else if($exception instanceof MethodNotAllowedHttpException && $request->expectsJson()){
|
||||||
return response()->json(['message'=>'Method not support for this route'],404);
|
return response()->json(['message'=>'Method not support for this route'],404);
|
||||||
}
|
}
|
||||||
else if ($exception instanceof ValidationException && $request->expectsJson()) {
|
else if ($exception instanceof ValidationException && $request->expectsJson()) {
|
||||||
return response()->json(['message' => 'The given data was invalid.', 'errors' => $exception->validator->getMessageBag()], 422);
|
return response()->json(['message' => 'The given data was invalid.', 'errors' => $exception->validator->getMessageBag()], 422);
|
||||||
}
|
}
|
||||||
|
else if ($exception instanceof RelationNotFoundException && $request->expectsJson()) {
|
||||||
|
return response()->json(['message' => $exception->getMessage()], 400);
|
||||||
|
}
|
||||||
|
|
||||||
return parent::render($request, $exception);
|
return parent::render($request, $exception);
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ class CompanyFactory
|
|||||||
$company->company_key = $this->createHash();
|
$company->company_key = $this->createHash();
|
||||||
$company->settings = CompanySettings::defaults();
|
$company->settings = CompanySettings::defaults();
|
||||||
$company->db = config('database.default');
|
$company->db = config('database.default');
|
||||||
|
$company->custom_fields = (object) ['custom1' => '1', 'custom2' => '2', 'custom3'=>3];
|
||||||
$company->domain = '';
|
$company->domain = '';
|
||||||
|
|
||||||
return $company;
|
return $company;
|
||||||
|
30
app/Factory/CompanyUserFactory.php
Normal file
30
app/Factory/CompanyUserFactory.php
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2019. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Factory;
|
||||||
|
|
||||||
|
use App\Models\CompanyUser;
|
||||||
|
|
||||||
|
class CompanyUserFactory
|
||||||
|
{
|
||||||
|
|
||||||
|
public static function create($user_id, $company_id, $account_id) :CompanyUser
|
||||||
|
{
|
||||||
|
|
||||||
|
$company_user = new CompanyUser;
|
||||||
|
$company_user->user_id = $user_id;
|
||||||
|
$company_user->company_id = $company_id;
|
||||||
|
$company_user->account_id = $account_id;
|
||||||
|
|
||||||
|
return $company_user;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -139,6 +139,7 @@ class AccountController extends BaseController
|
|||||||
$account = CreateAccount::dispatchNow($request->all());
|
$account = CreateAccount::dispatchNow($request->all());
|
||||||
|
|
||||||
$ct = CompanyUser::whereUserId(auth()->user()->id);
|
$ct = CompanyUser::whereUserId(auth()->user()->id);
|
||||||
|
|
||||||
return $this->listResponse($ct);
|
return $this->listResponse($ct);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ class InvitationController extends Controller
|
|||||||
public function router(string $entity, string $invitation_key)
|
public function router(string $entity, string $invitation_key)
|
||||||
{
|
{
|
||||||
$key = $entity.'_id';
|
$key = $entity.'_id';
|
||||||
$entity_obj = ucfirst($entity).'Invitation';
|
$entity_obj = 'App\Models\\'.ucfirst($entity).'Invitation';
|
||||||
|
|
||||||
$invitation = $entity_obj::whereRaw("BINARY `key`= ?", [$invitation_key])->first();
|
$invitation = $entity_obj::whereRaw("BINARY `key`= ?", [$invitation_key])->first();
|
||||||
|
|
||||||
@ -40,7 +40,9 @@ class InvitationController extends Controller
|
|||||||
|
|
||||||
if((bool)$invitation->contact->client->getSetting('enable_client_portal_password') !== false)
|
if((bool)$invitation->contact->client->getSetting('enable_client_portal_password') !== false)
|
||||||
$this->middleware('auth:contact');
|
$this->middleware('auth:contact');
|
||||||
|
else
|
||||||
|
auth()->guard('contact')->login($invitation->contact, false);
|
||||||
|
|
||||||
$invitation->markViewed();
|
$invitation->markViewed();
|
||||||
|
|
||||||
return redirect()->route('client.'.$entity.'.show', [$entity => $this->encodePrimaryKey($invitation->{$key})]);
|
return redirect()->route('client.'.$entity.'.show', [$entity => $this->encodePrimaryKey($invitation->{$key})]);
|
||||||
|
@ -228,7 +228,7 @@ class CompanyController extends BaseController
|
|||||||
/*
|
/*
|
||||||
* Create token
|
* Create token
|
||||||
*/
|
*/
|
||||||
$company_token = CreateCompanyToken::dispatchNow($company, auth()->user());
|
$company_token = CreateCompanyToken::dispatchNow($company, auth()->user(), request()->server('HTTP_USER_AGENT'));
|
||||||
|
|
||||||
$this->entity_transformer = CompanyUserTransformer::class;
|
$this->entity_transformer = CompanyUserTransformer::class;
|
||||||
$this->entity_type = CompanyUser::class;
|
$this->entity_type = CompanyUser::class;
|
||||||
|
@ -519,7 +519,7 @@ class InvoiceController extends BaseController
|
|||||||
|
|
||||||
$ids = request()->input('ids');
|
$ids = request()->input('ids');
|
||||||
|
|
||||||
$invoices = Invoice::withTrashed()->find($ids);
|
$invoices = Invoice::withTrashed()->find($this->transformKeys($ids));
|
||||||
|
|
||||||
$invoices->each(function ($invoice, $key) use($action){
|
$invoices->each(function ($invoice, $key) use($action){
|
||||||
|
|
||||||
@ -528,8 +528,7 @@ class InvoiceController extends BaseController
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
//todo need to return the updated dataset
|
return $this->listResponse(Invoice::withTrashed()->whereIn('id', $this->transformKeys($ids)));
|
||||||
return $this->listResponse(Invoice::withTrashed()->whereIn('id', $ids));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,9 +7,11 @@
|
|||||||
* @OA\Property(property="size_id", type="string", example="1", description="The company size ID"),
|
* @OA\Property(property="size_id", type="string", example="1", description="The company size ID"),
|
||||||
* @OA\Property(property="industry_id", type="string", example="1", description="The company industry ID"),
|
* @OA\Property(property="industry_id", type="string", example="1", description="The company industry ID"),
|
||||||
* @OA\Property(property="portal_mode", type="string", example="subdomain", description="Determines the client facing urls ie: subdomain,domain,iframe"),
|
* @OA\Property(property="portal_mode", type="string", example="subdomain", description="Determines the client facing urls ie: subdomain,domain,iframe"),
|
||||||
|
* @OA\Property(property="domain", type="string", example="http://acmeco.invoicing.co", description="Determines the client facing url "),
|
||||||
* @OA\Property(property="portal_domain", type="string", example="https://subdomain.invoicing.co", description="The fully qualified domain for client facing URLS"),
|
* @OA\Property(property="portal_domain", type="string", example="https://subdomain.invoicing.co", description="The fully qualified domain for client facing URLS"),
|
||||||
* @OA\Property(property="enabled_tax_rates", type="integer", example="1", description="Number of taxes rates used per entity"),
|
* @OA\Property(property="enabled_tax_rates", type="integer", example="1", description="Number of taxes rates used per entity"),
|
||||||
* @OA\Property(property="fill_products", type="boolean", example=true, description="Toggles filling a product description based on product key"),
|
* @OA\Property(property="fill_products", type="boolean", example=true, description="Toggles filling a product description based on product key"),
|
||||||
|
* @OA\Property(property="enable_invoice_quantity", type="boolean", example=true, description="Toggles filling a product description based on product key"),
|
||||||
* @OA\Property(property="convert_products", type="boolean", example=true, description="___________"),
|
* @OA\Property(property="convert_products", type="boolean", example=true, description="___________"),
|
||||||
* @OA\Property(property="update_products", type="boolean", example=true, description="Toggles updating a product description which description changes"),
|
* @OA\Property(property="update_products", type="boolean", example=true, description="Toggles updating a product description which description changes"),
|
||||||
* @OA\Property(property="custom_fields", type="object", description="Custom fields map"),
|
* @OA\Property(property="custom_fields", type="object", description="Custom fields map"),
|
||||||
|
@ -35,32 +35,23 @@
|
|||||||
* @OA\Property(property="auto_convert_quote", type="boolean", example=true, description="____________"),
|
* @OA\Property(property="auto_convert_quote", type="boolean", example=true, description="____________"),
|
||||||
* @OA\Property(property="inclusive_taxes", type="boolean", example=true, description="____________"),
|
* @OA\Property(property="inclusive_taxes", type="boolean", example=true, description="____________"),
|
||||||
* @OA\Property(property="translations", type="object", example="", description="JSON payload of customized translations"),
|
* @OA\Property(property="translations", type="object", example="", description="JSON payload of customized translations"),
|
||||||
* @OA\Property(property="task_number_prefix", type="string", example="R", description="This string is prepended to the task number"),
|
|
||||||
* @OA\Property(property="task_number_pattern", type="string", example="{$year}-{$counter}", description="Allows customisation of the task number pattern"),
|
* @OA\Property(property="task_number_pattern", type="string", example="{$year}-{$counter}", description="Allows customisation of the task number pattern"),
|
||||||
* @OA\Property(property="task_number_counter", type="integer", example="1", description="____________"),
|
* @OA\Property(property="task_number_counter", type="integer", example="1", description="____________"),
|
||||||
* @OA\Property(property="expense_number_prefix", type="string", example="R", description="This string is prepended to the expense number"),
|
|
||||||
* @OA\Property(property="expense_number_pattern", type="string", example="{$year}-{$counter}", description="Allows customisation of the expense number pattern"),
|
* @OA\Property(property="expense_number_pattern", type="string", example="{$year}-{$counter}", description="Allows customisation of the expense number pattern"),
|
||||||
* @OA\Property(property="expense_number_counter", type="integer", example="1", description="____________"),
|
* @OA\Property(property="expense_number_counter", type="integer", example="1", description="____________"),
|
||||||
* @OA\Property(property="vendor_number_prefix", type="string", example="R", description="This string is prepended to the vendor number"),
|
|
||||||
* @OA\Property(property="vendor_number_pattern", type="string", example="{$year}-{$counter}", description="Allows customisation of the vendor number pattern"),
|
* @OA\Property(property="vendor_number_pattern", type="string", example="{$year}-{$counter}", description="Allows customisation of the vendor number pattern"),
|
||||||
* @OA\Property(property="vendor_number_counter", type="integer", example="1", description="____________"),
|
* @OA\Property(property="vendor_number_counter", type="integer", example="1", description="____________"),
|
||||||
* @OA\Property(property="ticket_number_prefix", type="string", example="R", description="This string is prepended to the ticket number"),
|
|
||||||
* @OA\Property(property="ticket_number_pattern", type="string", example="{$year}-{$counter}", description="Allows customisation of the ticket number pattern"),
|
* @OA\Property(property="ticket_number_pattern", type="string", example="{$year}-{$counter}", description="Allows customisation of the ticket number pattern"),
|
||||||
* @OA\Property(property="ticket_number_counter", type="integer", example="1", description="____________"),
|
* @OA\Property(property="ticket_number_counter", type="integer", example="1", description="____________"),
|
||||||
*
|
*
|
||||||
* @OA\Property(property="payment_number_prefix", type="string", example="R", description="This string is prepended to the payment number"),
|
|
||||||
* @OA\Property(property="payment_number_pattern", type="string", example="{$year}-{$counter}", description="Allows customisation of the payment number pattern"),
|
* @OA\Property(property="payment_number_pattern", type="string", example="{$year}-{$counter}", description="Allows customisation of the payment number pattern"),
|
||||||
* @OA\Property(property="payment_number_counter", type="integer", example="1", description="____________"),
|
* @OA\Property(property="payment_number_counter", type="integer", example="1", description="____________"),
|
||||||
* @OA\Property(property="invoice_number_prefix", type="string", example="R", description="This string is prepended to the invoice number"),
|
|
||||||
* @OA\Property(property="invoice_number_pattern", type="string", example="{$year}-{$counter}", description="Allows customisation of the invoice number pattern"),
|
* @OA\Property(property="invoice_number_pattern", type="string", example="{$year}-{$counter}", description="Allows customisation of the invoice number pattern"),
|
||||||
* @OA\Property(property="invoice_number_counter", type="integer", example="1", description="____________"),
|
* @OA\Property(property="invoice_number_counter", type="integer", example="1", description="____________"),
|
||||||
* @OA\Property(property="quote_number_prefix", type="string", example="R", description="This string is prepended to the quote number"),
|
|
||||||
* @OA\Property(property="quote_number_pattern", type="string", example="{$year}-{$counter}", description="Allows customisation of the quote number pattern"),
|
* @OA\Property(property="quote_number_pattern", type="string", example="{$year}-{$counter}", description="Allows customisation of the quote number pattern"),
|
||||||
* @OA\Property(property="quote_number_counter", type="integer", example="1", description="____________"),
|
* @OA\Property(property="quote_number_counter", type="integer", example="1", description="____________"),
|
||||||
* @OA\Property(property="client_number_prefix", type="string", example="R", description="This string is prepended to the client number"),
|
|
||||||
* @OA\Property(property="client_number_pattern", type="string", example="{$year}-{$counter}", description="Allows customisation of the client number pattern"),
|
* @OA\Property(property="client_number_pattern", type="string", example="{$year}-{$counter}", description="Allows customisation of the client number pattern"),
|
||||||
* @OA\Property(property="client_number_counter", type="integer", example="1", description="____________"),
|
* @OA\Property(property="client_number_counter", type="integer", example="1", description="____________"),
|
||||||
* @OA\Property(property="credit_number_prefix", type="string", example="R", description="This string is prepended to the credit number"),
|
|
||||||
* @OA\Property(property="credit_number_pattern", type="string", example="{$year}-{$counter}", description="Allows customisation of the credit number pattern"),
|
* @OA\Property(property="credit_number_pattern", type="string", example="{$year}-{$counter}", description="Allows customisation of the credit number pattern"),
|
||||||
* @OA\Property(property="credit_number_counter", type="integer", example="1", description="____________"),
|
* @OA\Property(property="credit_number_counter", type="integer", example="1", description="____________"),
|
||||||
* @OA\Property(property="recurring_invoice_number_prefix", type="string", example="R", description="This string is prepended to the recurring invoice number"),
|
* @OA\Property(property="recurring_invoice_number_prefix", type="string", example="R", description="This string is prepended to the recurring invoice number"),
|
||||||
|
@ -554,7 +554,7 @@ class PaymentController extends BaseController
|
|||||||
|
|
||||||
$ids = request()->input('ids');
|
$ids = request()->input('ids');
|
||||||
|
|
||||||
$payments = Payment::withTrashed()->find($ids);
|
$payments = Payment::withTrashed()->find($this->transformKeys($ids));
|
||||||
|
|
||||||
$payments->each(function ($payment, $key) use($action){
|
$payments->each(function ($payment, $key) use($action){
|
||||||
|
|
||||||
@ -563,8 +563,7 @@ class PaymentController extends BaseController
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
//todo need to return the updated dataset
|
return $this->listResponse(Payment::withTrashed()->whereIn('id', $this->transformKeys($ids)));
|
||||||
return $this->listResponse(Payment::withTrashed()->whereIn('id', $ids));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -470,17 +470,16 @@ class ProductController extends BaseController
|
|||||||
|
|
||||||
$ids = request()->input('ids');
|
$ids = request()->input('ids');
|
||||||
|
|
||||||
$products = Product::withTrashed()->find($ids);
|
$products = Product::withTrashed()->find($this->transformKeys($ids));
|
||||||
|
|
||||||
$products->each(function ($product, $key) use($action){
|
$products->each(function ($product, $key) use($action){
|
||||||
|
|
||||||
if(auth()->user()->can('edit', $product))
|
if(auth()->user()->can('edit', $product))
|
||||||
ActionEntity::dispatchNow($product, $action);
|
$this->product_repo->{$action}($product);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
//todo need to return the updated dataset
|
return $this->listResponse(Product::withTrashed()->whereIn('id', $this->transformKeys($ids)));
|
||||||
return response()->json([], 200);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -507,17 +507,16 @@ class QuoteController extends BaseController
|
|||||||
|
|
||||||
$ids = request()->input('ids');
|
$ids = request()->input('ids');
|
||||||
|
|
||||||
$quotes = Quote::withTrashed()->find($ids);
|
$quotes = Quote::withTrashed()->find($this->transformKeys($ids));
|
||||||
|
|
||||||
$quotes->each(function ($quote, $key) use($action){
|
$quotes->each(function ($quote, $key) use($action){
|
||||||
|
|
||||||
if(auth()->user()->can('edit', $quote))
|
if(auth()->user()->can('edit', $quote))
|
||||||
$this->quote_repo->{$action}($quote);
|
$this->product_repo->{$action}($quote);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
//todo need to return the updated dataset
|
return $this->listResponse(Quote::withTrashed()->whereIn('id', $this->transformKeys($ids)));
|
||||||
return $this->listResponse(Quote::withTrashed()->whereIn('id', $ids));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -517,7 +517,7 @@ class RecurringInvoiceController extends BaseController
|
|||||||
|
|
||||||
$ids = request()->input('ids');
|
$ids = request()->input('ids');
|
||||||
|
|
||||||
$recurring_invoices = RecurringInvoice::withTrashed()->find($ids);
|
$recurring_invoices = RecurringInvoice::withTrashed()->find($this->transformKeys($ids));
|
||||||
|
|
||||||
$recurring_invoices->each(function ($recurring_invoice, $key) use($action){
|
$recurring_invoices->each(function ($recurring_invoice, $key) use($action){
|
||||||
|
|
||||||
@ -526,8 +526,7 @@ class RecurringInvoiceController extends BaseController
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
//todo need to return the updated dataset
|
return $this->listResponse(RecurringInvoice::withTrashed()->whereIn('id', $this->transformKeys($ids)));
|
||||||
return $this->listResponse(RecurringInvoice::withTrashed()->whereIn('id', $ids));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -610,7 +609,7 @@ class RecurringInvoiceController extends BaseController
|
|||||||
// return $this->itemResponse($recurring_invoice);
|
// return $this->itemResponse($recurring_invoice);
|
||||||
break;
|
break;
|
||||||
case 'clone_to_quote':
|
case 'clone_to_quote':
|
||||||
// $quote = CloneRecurringInvoiceToQuoteFactory::create($recurring_invoice, auth()->user()->id);
|
// $recurring_invoice = CloneRecurringInvoiceToQuoteFactory::create($recurring_invoice, auth()->user()->id);
|
||||||
// todo build the quote transformer and return response here
|
// todo build the quote transformer and return response here
|
||||||
break;
|
break;
|
||||||
case 'history':
|
case 'history':
|
||||||
|
@ -515,7 +515,7 @@ class RecurringQuoteController extends BaseController
|
|||||||
|
|
||||||
$ids = request()->input('ids');
|
$ids = request()->input('ids');
|
||||||
|
|
||||||
$recurring_quotes = RecurringQuote::withTrashed()->find($ids);
|
$recurring_quotes = RecurringQuote::withTrashed()->find($this->transformKeys($ids));
|
||||||
|
|
||||||
$recurring_quotes->each(function ($recurring_quote, $key) use($action){
|
$recurring_quotes->each(function ($recurring_quote, $key) use($action){
|
||||||
|
|
||||||
@ -524,8 +524,7 @@ class RecurringQuoteController extends BaseController
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
//todo need to return the updated dataset
|
return $this->listResponse(RecurringQuote::withTrashed()->whereIn('id', $this->transformKeys($ids)));
|
||||||
return $this->listResponse(RecurringQuote::withTrashed()->whereIn('id', $ids));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,7 +213,7 @@ class UserController extends BaseController
|
|||||||
'settings' => $request->input('settings'),
|
'settings' => $request->input('settings'),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
CreateCompanyToken::dispatchNow($company, $user);
|
CreateCompanyToken::dispatchNow($company, $user, request()->server('HTTP_USER_AGENT'));
|
||||||
|
|
||||||
$user->load('companies');
|
$user->load('companies');
|
||||||
|
|
||||||
@ -514,9 +514,7 @@ class UserController extends BaseController
|
|||||||
|
|
||||||
$ids = request()->input('ids');
|
$ids = request()->input('ids');
|
||||||
|
|
||||||
$ids = $this->transformKeys($ids);
|
$users = User::withTrashed()->find($this->transformKeys($ids));
|
||||||
|
|
||||||
$users = User::withTrashed()->find($ids);
|
|
||||||
|
|
||||||
$users->each(function ($user, $key) use($action){
|
$users->each(function ($user, $key) use($action){
|
||||||
|
|
||||||
@ -525,8 +523,7 @@ class UserController extends BaseController
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
//todo need to return the updated dataset
|
return $this->listResponse(User::withTrashed()->whereIn('id', $this->transformKeys($ids)));
|
||||||
return $this->listResponse(User::withTrashed()->whereIn('id', $ids));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ class StoreUserRequest extends Request
|
|||||||
public function authorize() : bool
|
public function authorize() : bool
|
||||||
{
|
{
|
||||||
|
|
||||||
return auth()->user()->can('create', User::class);
|
return auth()->user()->isAdmin();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,7 +40,6 @@ class StoreUserRequest extends Request
|
|||||||
'first_name' => 'required|string|max:100',
|
'first_name' => 'required|string|max:100',
|
||||||
'last_name' => 'required|string:max:100',
|
'last_name' => 'required|string:max:100',
|
||||||
'email' => new NewUniqueUserRule(),
|
'email' => new NewUniqueUserRule(),
|
||||||
'is_admin' => 'required',
|
|
||||||
];
|
];
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -49,16 +48,34 @@ class StoreUserRequest extends Request
|
|||||||
{
|
{
|
||||||
$input = $this->all();
|
$input = $this->all();
|
||||||
|
|
||||||
if(!isset($input['is_admin']))
|
if(isset($input['company_user']))
|
||||||
$input['is_admin'] = null;
|
{
|
||||||
|
|
||||||
if(!isset($input['permissions']))
|
if(!isset($input['company_user']['permissions']))
|
||||||
$input['permissions'] = json_encode([]);
|
$input['company_user']['permissions'] = '';
|
||||||
|
|
||||||
if(!isset($input['settings']))
|
if(!isset($input['company_user']['settings']))
|
||||||
$input['settings'] = json_encode(DefaultSettings::userSettings());
|
$input['company_user']['settings'] = json_encode(DefaultSettings::userSettings());
|
||||||
|
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
$input['company_user'] = [
|
||||||
|
'settings' => json_encode(DefaultSettings::userSettings()),
|
||||||
|
'permissions' => '',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
$this->replace($input);
|
$this->replace($input);
|
||||||
|
|
||||||
|
return $this->all();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function messages()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'company_user' => 'T',
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ class CreateAccount
|
|||||||
/*
|
/*
|
||||||
* Create token
|
* Create token
|
||||||
*/
|
*/
|
||||||
$company_token = CreateCompanyToken::dispatchNow($company, $user);
|
$company_token = CreateCompanyToken::dispatchNow($company, $user, $this->request['user_agent']);
|
||||||
/*
|
/*
|
||||||
* Login user
|
* Login user
|
||||||
*/
|
*/
|
||||||
|
@ -29,16 +29,19 @@ class CreateCompanyToken implements ShouldQueue
|
|||||||
|
|
||||||
protected $user;
|
protected $user;
|
||||||
|
|
||||||
|
protected $user_agent;
|
||||||
/**
|
/**
|
||||||
* Create a new job instance.
|
* Create a new job instance.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function __construct(Company $company, User $user)
|
public function __construct(Company $company, User $user, string $user_agent)
|
||||||
{
|
{
|
||||||
$this->company = $company;
|
$this->company = $company;
|
||||||
|
|
||||||
$this->user = $user;
|
$this->user = $user;
|
||||||
|
|
||||||
|
$this->user_agent = $user_agent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -55,6 +58,7 @@ class CreateCompanyToken implements ShouldQueue
|
|||||||
'token' => Str::random(64),
|
'token' => Str::random(64),
|
||||||
'name' => $this->user->first_name. ' '. $this->user->last_name,
|
'name' => $this->user->first_name. ' '. $this->user->last_name,
|
||||||
'company_id' => $this->company->id,
|
'company_id' => $this->company->id,
|
||||||
|
'user_agent' => $this->user_agent,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return $ct;
|
return $ct;
|
||||||
|
@ -70,7 +70,7 @@ class CreateUser
|
|||||||
'is_owner' => $this->company_owner,
|
'is_owner' => $this->company_owner,
|
||||||
'is_admin' => 1,
|
'is_admin' => 1,
|
||||||
'is_locked' => 0,
|
'is_locked' => 0,
|
||||||
'permissions' => json_encode([]),
|
'permissions' => '',
|
||||||
'settings' => json_encode(DefaultSettings::userSettings()),
|
'settings' => json_encode(DefaultSettings::userSettings()),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -178,11 +178,12 @@ class MultiDB
|
|||||||
|
|
||||||
public static function findAndSetDbByInvitation($entity, $invitation_key)
|
public static function findAndSetDbByInvitation($entity, $invitation_key)
|
||||||
{
|
{
|
||||||
$entity.'Invitation';
|
|
||||||
|
$class = 'App\Models\\'.ucfirst($entity).'Invitation';
|
||||||
|
|
||||||
foreach (self::$dbs as $db)
|
foreach (self::$dbs as $db)
|
||||||
{
|
{
|
||||||
if($invite = $entity::on($db)->whereKey($invitation_key)->first())
|
if($invite = $class::on($db)->whereRaw("BINARY `key`= ?",[$invitation_key])->first())
|
||||||
{
|
{
|
||||||
self::setDb($db);
|
self::setDb($db);
|
||||||
return true;
|
return true;
|
||||||
|
@ -59,6 +59,7 @@ class Client extends BaseModel
|
|||||||
];
|
];
|
||||||
|
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
|
'currency_id',
|
||||||
'name',
|
'name',
|
||||||
'website',
|
'website',
|
||||||
'private_notes',
|
'private_notes',
|
||||||
|
@ -53,6 +53,17 @@ class Company extends BaseModel
|
|||||||
'enable_product_cost',
|
'enable_product_cost',
|
||||||
'enable_product_quantity',
|
'enable_product_quantity',
|
||||||
'default_quantity',
|
'default_quantity',
|
||||||
|
'enable_invoice_quantity',
|
||||||
|
'enabled_tax_rates',
|
||||||
|
'portal_mode',
|
||||||
|
'portal_domain',
|
||||||
|
'convert_products',
|
||||||
|
'update_products',
|
||||||
|
'custom_surcharge_taxes1',
|
||||||
|
'custom_surcharge_taxes2',
|
||||||
|
'custom_surcharge_taxes3',
|
||||||
|
'custom_surcharge_taxes4',
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $hidden = [
|
protected $hidden = [
|
||||||
|
@ -23,12 +23,20 @@ class CompanyUser extends Pivot
|
|||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
'permissions' => 'object',
|
|
||||||
'updated_at' => 'timestamp',
|
'updated_at' => 'timestamp',
|
||||||
'created_at' => 'timestamp',
|
'created_at' => 'timestamp',
|
||||||
'deleted_at' => 'timestamp',
|
'deleted_at' => 'timestamp',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
protected $fillable = [
|
||||||
|
'account_id',
|
||||||
|
'permissions',
|
||||||
|
'settings',
|
||||||
|
'is_admin',
|
||||||
|
'is_owner',
|
||||||
|
'is_locked'
|
||||||
|
];
|
||||||
|
|
||||||
public function account()
|
public function account()
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Account::class);
|
return $this->belongsTo(Account::class);
|
||||||
|
@ -73,7 +73,7 @@ class ClientRepository extends BaseRepository
|
|||||||
$contacts = $this->contact_repo->save($data['contacts'], $client);
|
$contacts = $this->contact_repo->save($data['contacts'], $client);
|
||||||
|
|
||||||
|
|
||||||
if($data['name'] == '')
|
if(empty($data['name']))
|
||||||
$data['name'] = $client->present()->name();
|
$data['name'] = $client->present()->name();
|
||||||
|
|
||||||
|
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
namespace App\Repositories;
|
namespace App\Repositories;
|
||||||
|
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
|
use App\Models\CompanyUser;
|
||||||
|
use App\Factory\CompanyUserFactory;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -50,9 +52,24 @@ class UserRepository extends BaseRepository
|
|||||||
{
|
{
|
||||||
|
|
||||||
$user->fill($data);
|
$user->fill($data);
|
||||||
|
|
||||||
$user->save();
|
$user->save();
|
||||||
|
|
||||||
|
if($data['company_user'])
|
||||||
|
{
|
||||||
|
|
||||||
|
$company = auth()->user()->company();
|
||||||
|
$account_id = $company->account->id;
|
||||||
|
|
||||||
|
$cu = CompanyUser::whereUserId($user->id)->whereCompanyId($company->id)->first();
|
||||||
|
|
||||||
|
if(!$cu)
|
||||||
|
$cu = CompanyUserFactory::create($user->id, $company->id, $account_id);
|
||||||
|
|
||||||
|
$cu->fill($data['company_user']);
|
||||||
|
$cu->save();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return $user;
|
return $user;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,7 @@ class CompanyTokenTransformer extends EntityTransformer
|
|||||||
return [
|
return [
|
||||||
'token' => $company_token->token,
|
'token' => $company_token->token,
|
||||||
'name' => $company_token->name ?: '',
|
'name' => $company_token->name ?: '',
|
||||||
|
'user_agent' => $company_token->user_agent ?: 'Unidentified',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,6 +68,8 @@ class CompanyTransformer extends EntityTransformer
|
|||||||
*/
|
*/
|
||||||
public function transform(Company $company)
|
public function transform(Company $company)
|
||||||
{
|
{
|
||||||
|
$std = new \stdClass;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'id' => (string)$this->encodePrimaryKey($company->id),
|
'id' => (string)$this->encodePrimaryKey($company->id),
|
||||||
'company_key' => (string)$company->company_key ?: '',
|
'company_key' => (string)$company->company_key ?: '',
|
||||||
@ -81,7 +83,7 @@ class CompanyTransformer extends EntityTransformer
|
|||||||
'enable_product_cost' => (bool)$company->enable_product_cost,
|
'enable_product_cost' => (bool)$company->enable_product_cost,
|
||||||
'enable_product_quantity' => (bool)$company->enable_product_quantity,
|
'enable_product_quantity' => (bool)$company->enable_product_quantity,
|
||||||
'default_quantity' => (bool)$company->default_quantity,
|
'default_quantity' => (bool)$company->default_quantity,
|
||||||
'custom_fields' => (string) $company->custom_fields,
|
'custom_fields' => $company->custom_fields ?: $std,
|
||||||
'size_id' => (string) $company->size_id ?: '',
|
'size_id' => (string) $company->size_id ?: '',
|
||||||
'industry_id' => (string) $company->industry_id ?: '',
|
'industry_id' => (string) $company->industry_id ?: '',
|
||||||
'first_month_of_year' => (string) $company->first_month_of_year ?: '',
|
'first_month_of_year' => (string) $company->first_month_of_year ?: '',
|
||||||
|
@ -61,10 +61,9 @@ trait GeneratesCounter
|
|||||||
|
|
||||||
//Return a valid counter
|
//Return a valid counter
|
||||||
$pattern = $client->getSetting('invoice_number_pattern');
|
$pattern = $client->getSetting('invoice_number_pattern');
|
||||||
$prefix = $client->getSetting('invoice_number_prefix');
|
|
||||||
$padding = $client->getSetting('counter_padding');
|
$padding = $client->getSetting('counter_padding');
|
||||||
|
|
||||||
$invoice_number = $this->checkEntityNumber(Invoice::class, $client, $counter, $padding, $prefix, $pattern);
|
$invoice_number = $this->checkEntityNumber(Invoice::class, $client, $counter, $padding, $pattern);
|
||||||
|
|
||||||
$this->incrementCounter($counter_entity, 'invoice_number_counter');
|
$this->incrementCounter($counter_entity, 'invoice_number_counter');
|
||||||
|
|
||||||
@ -126,9 +125,9 @@ trait GeneratesCounter
|
|||||||
|
|
||||||
//Return a valid counter
|
//Return a valid counter
|
||||||
$pattern = '';
|
$pattern = '';
|
||||||
$prefix = $client->company->settings->recurring_invoice_number_prefix;
|
$padding = $client->getSetting('counter_padding');
|
||||||
$padding = $client->company->settings->counter_padding;
|
$invoice_number = $this->checkEntityNumber(Invoice::class, $client, $counter, $padding, $pattern);
|
||||||
$invoice_number = $this->checkEntityNumber(Invoice::class, $client, $counter, $padding, $prefix, $pattern);
|
$invoice_number = $this->prefixCounter($invoice_number, $client->getSetting('recurring_number_prefix'));
|
||||||
|
|
||||||
//increment the correct invoice_number Counter (company vs client)
|
//increment the correct invoice_number Counter (company vs client)
|
||||||
if($is_client_counter)
|
if($is_client_counter)
|
||||||
@ -155,7 +154,7 @@ trait GeneratesCounter
|
|||||||
$counter = $client->getSetting('client_number_counter' );
|
$counter = $client->getSetting('client_number_counter' );
|
||||||
$setting_entity = $client->getSettingEntity('client_number_counter');
|
$setting_entity = $client->getSettingEntity('client_number_counter');
|
||||||
|
|
||||||
$client_number = $this->checkEntityNumber(Client::class, $client, $counter, $client->getSetting('counter_padding'), $client->getSetting('client_number_prefix'), $client->getSetting('client_number_pattern'));
|
$client_number = $this->checkEntityNumber(Client::class, $client, $counter, $client->getSetting('counter_padding'), $client->getSetting('client_number_pattern'));
|
||||||
|
|
||||||
$this->incrementCounter($setting_entity, 'client_number_counter');
|
$this->incrementCounter($setting_entity, 'client_number_counter');
|
||||||
|
|
||||||
@ -183,11 +182,10 @@ trait GeneratesCounter
|
|||||||
* @param Collection $entity The entity ie App\Models\Client, Invoice, Quote etc
|
* @param Collection $entity The entity ie App\Models\Client, Invoice, Quote etc
|
||||||
* @param integer $counter The counter
|
* @param integer $counter The counter
|
||||||
* @param integer $padding The padding
|
* @param integer $padding The padding
|
||||||
* @param string $prefix The prefix
|
*
|
||||||
*
|
|
||||||
* @return string The padded and prefixed invoice number
|
* @return string The padded and prefixed invoice number
|
||||||
*/
|
*/
|
||||||
private function checkEntityNumber($class, $client, $counter, $padding, $prefix, $pattern)
|
private function checkEntityNumber($class, $client, $counter, $padding, $pattern)
|
||||||
{
|
{
|
||||||
$check = false;
|
$check = false;
|
||||||
|
|
||||||
@ -195,10 +193,7 @@ trait GeneratesCounter
|
|||||||
|
|
||||||
$number = $this->padCounter($counter, $padding);
|
$number = $this->padCounter($counter, $padding);
|
||||||
|
|
||||||
if(isset($prefix) && strlen($prefix) >= 1)
|
$number = $this->applyNumberPattern($client, $number, $pattern);
|
||||||
$number = $this->prefixCounter($number, $prefix);
|
|
||||||
else
|
|
||||||
$number = $this->applyNumberPattern($client, $number, $pattern);
|
|
||||||
|
|
||||||
if($class == Invoice::class || $class == RecurringInvoice::class)
|
if($class == Invoice::class || $class == RecurringInvoice::class)
|
||||||
$check = $class::whereCompanyId($client->company_id)->whereInvoiceNumber($number)->withTrashed()->first();
|
$check = $class::whereCompanyId($client->company_id)->whereInvoiceNumber($number)->withTrashed()->first();
|
||||||
|
@ -52,14 +52,14 @@ trait Inviteable
|
|||||||
|
|
||||||
switch ($this->company->portal_mode) {
|
switch ($this->company->portal_mode) {
|
||||||
case 'subdomain':
|
case 'subdomain':
|
||||||
return $domain . $entity_type .'/'. $this->key;
|
return $domain .'client/'. $entity_type .'/'. $this->key;
|
||||||
break;
|
break;
|
||||||
case 'iframe':
|
case 'iframe':
|
||||||
return $domain . $entity_type .'/'. $this->key;
|
return $domain .'client/'. $entity_type .'/'. $this->key;
|
||||||
//return $domain . $entity_type .'/'. $this->contact->client->client_hash .'/'. $this->key;
|
//return $domain . $entity_type .'/'. $this->contact->client->client_hash .'/'. $this->key;
|
||||||
break;
|
break;
|
||||||
case 'domain':
|
case 'domain':
|
||||||
return $domain . $entity_type .'/'. $this->key;
|
return $domain .'client/'. $entity_type .'/'. $this->key;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,8 @@ $factory->define(App\Models\Company::class, function (Faker $faker) {
|
|||||||
'ip' => $faker->ipv4,
|
'ip' => $faker->ipv4,
|
||||||
'db' => config('database.default'),
|
'db' => config('database.default'),
|
||||||
'settings' => CompanySettings::defaults(),
|
'settings' => CompanySettings::defaults(),
|
||||||
|
'custom_fields' => (object) ['custom1' => '1', 'custom2' => '2', 'custom3'=>3],
|
||||||
|
|
||||||
// 'address1' => $faker->secondaryAddress,
|
// 'address1' => $faker->secondaryAddress,
|
||||||
// 'address2' => $faker->address,
|
// 'address2' => $faker->address,
|
||||||
// 'city' => $faker->city,
|
// 'city' => $faker->city,
|
||||||
|
@ -152,6 +152,7 @@ class CreateUsersTable extends Migration
|
|||||||
$table->boolean('custom_surcharge_taxes2')->default(false);
|
$table->boolean('custom_surcharge_taxes2')->default(false);
|
||||||
$table->boolean('custom_surcharge_taxes3')->default(false);
|
$table->boolean('custom_surcharge_taxes3')->default(false);
|
||||||
$table->boolean('custom_surcharge_taxes4')->default(false);
|
$table->boolean('custom_surcharge_taxes4')->default(false);
|
||||||
|
$table->boolean('enable_invoice_quantity')->default(true);
|
||||||
$table->boolean('show_product_cost')->default(false);
|
$table->boolean('show_product_cost')->default(false);
|
||||||
$table->unsignedInteger('enabled_tax_rates')->default(1);
|
$table->unsignedInteger('enabled_tax_rates')->default(1);
|
||||||
|
|
||||||
@ -195,6 +196,7 @@ class CreateUsersTable extends Migration
|
|||||||
$table->boolean('is_owner')->default(false);
|
$table->boolean('is_owner')->default(false);
|
||||||
$table->boolean('is_admin')->default(false);
|
$table->boolean('is_admin')->default(false);
|
||||||
$table->boolean('is_locked')->default(false); // locks user out of account
|
$table->boolean('is_locked')->default(false); // locks user out of account
|
||||||
|
$table->timestamps(6);
|
||||||
|
|
||||||
$table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade');
|
$table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade');
|
||||||
$table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
|
$table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
|
||||||
@ -271,7 +273,8 @@ class CreateUsersTable extends Migration
|
|||||||
$table->unsignedInteger('user_id');
|
$table->unsignedInteger('user_id');
|
||||||
$table->string('token')->nullable();
|
$table->string('token')->nullable();
|
||||||
$table->string('name')->nullable();
|
$table->string('name')->nullable();
|
||||||
|
$table->string('user_agent')->nullable();
|
||||||
|
|
||||||
$table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade');
|
$table->foreign('company_id')->references('id')->on('companies')->onDelete('cascade');
|
||||||
$table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
|
$table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
|
||||||
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
|
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
|
||||||
|
@ -66,7 +66,7 @@ class PaymentLibrariesSeeder extends Seeder
|
|||||||
['name' => 'GoCardless', 'provider' => 'GoCardlessV2\Redirect', 'sort_order' => 9, 'is_offsite' => true, 'key' => 'b9886f9257f0c6ee7c302f1c74475f6c', 'fields' => '{"accessToken":"","webhookSecret":"","testMode":true}'],
|
['name' => 'GoCardless', 'provider' => 'GoCardlessV2\Redirect', 'sort_order' => 9, 'is_offsite' => true, 'key' => 'b9886f9257f0c6ee7c302f1c74475f6c', 'fields' => '{"accessToken":"","webhookSecret":"","testMode":true}'],
|
||||||
['name' => 'PagSeguro', 'provider' => 'PagSeguro', 'key' => 'ef498756b54db63c143af0ec433da803', 'fields' => '{"email":"","token":"","sandbox":false}'],
|
['name' => 'PagSeguro', 'provider' => 'PagSeguro', 'key' => 'ef498756b54db63c143af0ec433da803', 'fields' => '{"email":"","token":"","sandbox":false}'],
|
||||||
['name' => 'PAYMILL', 'provider' => 'Paymill', 'key' => 'ca52f618a39367a4c944098ebf977e1c', 'fields' => '{"apiKey":""}'],
|
['name' => 'PAYMILL', 'provider' => 'Paymill', 'key' => 'ca52f618a39367a4c944098ebf977e1c', 'fields' => '{"apiKey":""}'],
|
||||||
['name' => 'Custom', 'provider' => 'Custom2', 'is_offsite' => true, 'sort_order' => 21, 'key' => '54faab2ab6e3223dbe848b1686490baa', 'fields' => '{"text":"","name":""}'],
|
['name' => 'Custom', 'provider' => 'Custom', 'is_offsite' => true, 'sort_order' => 21, 'key' => '54faab2ab6e3223dbe848b1686490baa', 'fields' => '{"name":"","text":""}'],
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach ($gateways as $gateway) {
|
foreach ($gateways as $gateway) {
|
||||||
|
@ -93,7 +93,7 @@ class RandomDataSeeder extends Seeder
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
||||||
factory(\App\Models\Client::class, 20)->create(['user_id' => $user->id, 'company_id' => $company->id])->each(function ($c) use ($user, $company){
|
factory(\App\Models\Client::class, 10)->create(['user_id' => $user->id, 'company_id' => $company->id])->each(function ($c) use ($user, $company){
|
||||||
|
|
||||||
factory(\App\Models\ClientContact::class,1)->create([
|
factory(\App\Models\ClientContact::class,1)->create([
|
||||||
'user_id' => $user->id,
|
'user_id' => $user->id,
|
||||||
@ -102,7 +102,7 @@ class RandomDataSeeder extends Seeder
|
|||||||
'is_primary' => 1
|
'is_primary' => 1
|
||||||
]);
|
]);
|
||||||
|
|
||||||
factory(\App\Models\ClientContact::class,10)->create([
|
factory(\App\Models\ClientContact::class,5)->create([
|
||||||
'user_id' => $user->id,
|
'user_id' => $user->id,
|
||||||
'client_id' => $c->id,
|
'client_id' => $c->id,
|
||||||
'company_id' => $company->id
|
'company_id' => $company->id
|
||||||
@ -111,10 +111,10 @@ class RandomDataSeeder extends Seeder
|
|||||||
});
|
});
|
||||||
|
|
||||||
/** Product Factory */
|
/** Product Factory */
|
||||||
factory(\App\Models\Product::class,50)->create(['user_id' => $user->id, 'company_id' => $company->id]);
|
factory(\App\Models\Product::class,20)->create(['user_id' => $user->id, 'company_id' => $company->id]);
|
||||||
|
|
||||||
/** Invoice Factory */
|
/** Invoice Factory */
|
||||||
factory(\App\Models\Invoice::class,50)->create(['user_id' => $user->id, 'company_id' => $company->id, 'client_id' => $client->id]);
|
factory(\App\Models\Invoice::class,20)->create(['user_id' => $user->id, 'company_id' => $company->id, 'client_id' => $client->id]);
|
||||||
|
|
||||||
$invoices = Invoice::cursor();
|
$invoices = Invoice::cursor();
|
||||||
$invoice_repo = new InvoiceRepository();
|
$invoice_repo = new InvoiceRepository();
|
||||||
@ -162,7 +162,7 @@ class RandomDataSeeder extends Seeder
|
|||||||
});
|
});
|
||||||
|
|
||||||
/** Recurring Invoice Factory */
|
/** Recurring Invoice Factory */
|
||||||
factory(\App\Models\RecurringInvoice::class,20)->create(['user_id' => $user->id, 'company_id' => $company->id, 'client_id' => $client->id]);
|
factory(\App\Models\RecurringInvoice::class,10)->create(['user_id' => $user->id, 'company_id' => $company->id, 'client_id' => $client->id]);
|
||||||
|
|
||||||
// factory(\App\Models\Payment::class,20)->create(['user_id' => $user->id, 'company_id' => $company->id, 'client_id' => $client->id, 'settings' => ClientSettings::buildClientSettings($company->settings, $client->settings)]);
|
// factory(\App\Models\Payment::class,20)->create(['user_id' => $user->id, 'company_id' => $company->id, 'client_id' => $client->id, 'settings' => ClientSettings::buildClientSettings($company->settings, $client->settings)]);
|
||||||
|
|
||||||
|
@ -239,9 +239,7 @@ class PaymentTest extends TestCase
|
|||||||
|
|
||||||
}
|
}
|
||||||
catch(ValidationException $e) {
|
catch(ValidationException $e) {
|
||||||
\Log::error('in the validator');
|
|
||||||
$message = json_decode($e->validator->getMessageBag(),1);
|
$message = json_decode($e->validator->getMessageBag(),1);
|
||||||
\Log::error($message);
|
|
||||||
$this->assertNotNull($message);
|
$this->assertNotNull($message);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@ use App\DataMapper\ClientSettings;
|
|||||||
use App\DataMapper\CompanySettings;
|
use App\DataMapper\CompanySettings;
|
||||||
use App\DataMapper\DefaultSettings;
|
use App\DataMapper\DefaultSettings;
|
||||||
use App\Factory\ClientFactory;
|
use App\Factory\ClientFactory;
|
||||||
|
use App\Factory\CompanyUserFactory;
|
||||||
use App\Factory\InvoiceFactory;
|
use App\Factory\InvoiceFactory;
|
||||||
use App\Factory\InvoiceItemFactory;
|
use App\Factory\InvoiceItemFactory;
|
||||||
use App\Factory\InvoiceToRecurringInvoiceFactory;
|
use App\Factory\InvoiceToRecurringInvoiceFactory;
|
||||||
@ -103,6 +104,11 @@ trait MockAccountData
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$cu = CompanyUserFactory::create($this->user->id, $this->company->id, $this->account->id);
|
||||||
|
$cu->is_owner = true;
|
||||||
|
$cu->is_admin = true;
|
||||||
|
$cu->save();
|
||||||
|
|
||||||
$this->token = \Illuminate\Support\Str::random(64);
|
$this->token = \Illuminate\Support\Str::random(64);
|
||||||
|
|
||||||
$company_token = CompanyToken::create([
|
$company_token = CompanyToken::create([
|
||||||
@ -113,14 +119,14 @@ trait MockAccountData
|
|||||||
'token' => $this->token,
|
'token' => $this->token,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->user->companies()->attach($this->company->id, [
|
// $this->user->companies()->attach($this->company->id, [
|
||||||
'account_id' => $this->account->id,
|
// 'account_id' => $this->account->id,
|
||||||
'is_owner' => 1,
|
// 'is_owner' => 1,
|
||||||
'is_admin' => 1,
|
// 'is_admin' => 1,
|
||||||
'is_locked' => 0,
|
// 'is_locked' => 0,
|
||||||
'permissions' => json_encode([]),
|
// 'permissions' => '',
|
||||||
'settings' => json_encode(DefaultSettings::userSettings()),
|
// 'settings' => json_encode(DefaultSettings::userSettings()),
|
||||||
]);
|
// ]);
|
||||||
|
|
||||||
$this->client = ClientFactory::create($this->company->id, $this->user->id);
|
$this->client = ClientFactory::create($this->company->id, $this->user->id);
|
||||||
$this->client->save();
|
$this->client->save();
|
||||||
|
@ -66,7 +66,6 @@ class GeneratesCounterTest extends TestCase
|
|||||||
public function testInvoiceNumberPattern()
|
public function testInvoiceNumberPattern()
|
||||||
{
|
{
|
||||||
$settings = $this->client->company->settings;
|
$settings = $this->client->company->settings;
|
||||||
$settings->invoice_number_prefix = '';
|
|
||||||
$settings->invoice_number_counter = 1;
|
$settings->invoice_number_counter = 1;
|
||||||
$settings->invoice_number_pattern = '{$year}-{$counter}';
|
$settings->invoice_number_pattern = '{$year}-{$counter}';
|
||||||
|
|
||||||
@ -89,7 +88,6 @@ class GeneratesCounterTest extends TestCase
|
|||||||
public function testInvoiceClientNumberPattern()
|
public function testInvoiceClientNumberPattern()
|
||||||
{
|
{
|
||||||
$settings = $this->company->settings;
|
$settings = $this->company->settings;
|
||||||
$settings->client_number_prefix = '';
|
|
||||||
$settings->client_number_pattern = '{$year}-{$clientCounter}';
|
$settings->client_number_pattern = '{$year}-{$clientCounter}';
|
||||||
$settings->client_number_counter = 10;
|
$settings->client_number_counter = 10;
|
||||||
|
|
||||||
@ -155,7 +153,6 @@ class GeneratesCounterTest extends TestCase
|
|||||||
public function testInvoicePrefix()
|
public function testInvoicePrefix()
|
||||||
{
|
{
|
||||||
$settings = $this->company->settings;
|
$settings = $this->company->settings;
|
||||||
$settings->invoice_number_prefix = 'X';
|
|
||||||
$this->company->settings = $settings;
|
$this->company->settings = $settings;
|
||||||
$this->company->save();
|
$this->company->save();
|
||||||
|
|
||||||
@ -165,11 +162,11 @@ class GeneratesCounterTest extends TestCase
|
|||||||
|
|
||||||
$invoice_number = $this->getNextInvoiceNumber($cliz);
|
$invoice_number = $this->getNextInvoiceNumber($cliz);
|
||||||
|
|
||||||
$this->assertEquals($invoice_number, 'X0001');
|
$this->assertEquals($invoice_number, '0007');
|
||||||
|
|
||||||
$invoice_number = $this->getNextInvoiceNumber($cliz);
|
$invoice_number = $this->getNextInvoiceNumber($cliz);
|
||||||
|
|
||||||
$this->assertEquals($invoice_number, 'X0002');
|
$this->assertEquals($invoice_number, '0008');
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -190,7 +187,6 @@ class GeneratesCounterTest extends TestCase
|
|||||||
public function testClientNumberPrefix()
|
public function testClientNumberPrefix()
|
||||||
{
|
{
|
||||||
$settings = $this->company->settings;
|
$settings = $this->company->settings;
|
||||||
$settings->client_number_prefix = 'C';
|
|
||||||
$this->company->settings = $settings;
|
$this->company->settings = $settings;
|
||||||
$this->company->save();
|
$this->company->save();
|
||||||
|
|
||||||
@ -200,11 +196,11 @@ class GeneratesCounterTest extends TestCase
|
|||||||
|
|
||||||
$client_number = $this->getNextClientNumber($cliz);
|
$client_number = $this->getNextClientNumber($cliz);
|
||||||
|
|
||||||
$this->assertEquals($client_number, 'C0001');
|
$this->assertEquals($client_number, '0001');
|
||||||
|
|
||||||
$client_number = $this->getNextClientNumber($cliz);
|
$client_number = $this->getNextClientNumber($cliz);
|
||||||
|
|
||||||
$this->assertEquals($client_number, 'C0002');
|
$this->assertEquals($client_number, '0002');
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -212,7 +208,6 @@ class GeneratesCounterTest extends TestCase
|
|||||||
public function testClientNumberPattern()
|
public function testClientNumberPattern()
|
||||||
{
|
{
|
||||||
$settings = $this->company->settings;
|
$settings = $this->company->settings;
|
||||||
$settings->client_number_prefix = '';
|
|
||||||
$settings->client_number_pattern = '{$year}-{$user_id}-{$counter}';
|
$settings->client_number_pattern = '{$year}-{$user_id}-{$counter}';
|
||||||
$this->company->settings = $settings;
|
$this->company->settings = $settings;
|
||||||
$this->company->save();
|
$this->company->save();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user