mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-10 05:02:36 +01:00
Set Invitations as a default include for invoices (#3362)
* Working on importing company gateways * Fix for companyuser settings object * Migrate client_gateway_tokens * Working on Notificaitons * Working on notifications * Failsafe for user-company * unlink files * Set DB for jobs * Always have a fallback for company_id * Fixes for user model * Formatting for MultiDB * Working on Company Ledger Tests * Fixes for contact request * Set Invitations as a default include for invoices
This commit is contained in:
parent
c97d664d31
commit
3d31f810c0
@ -83,6 +83,14 @@ class CreateTestData extends Command
|
|||||||
'account_id' => $account->id,
|
'account_id' => $account->id,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$settings = $company->settings;
|
||||||
|
|
||||||
|
$settings->system_notifications_slack = config('ninja.notification.slack');
|
||||||
|
$settings->system_notifications_email = config('ninja.contact.email');
|
||||||
|
|
||||||
|
$company->settings = $settings;
|
||||||
|
$company->save();
|
||||||
|
|
||||||
$account->default_company_id = $company->id;
|
$account->default_company_id = $company->id;
|
||||||
$account->save();
|
$account->save();
|
||||||
|
|
||||||
@ -167,6 +175,15 @@ class CreateTestData extends Command
|
|||||||
'account_id' => $account->id,
|
'account_id' => $account->id,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
$settings = $company->settings;
|
||||||
|
|
||||||
|
$settings->system_notifications_slack = config('ninja.notification.slack');
|
||||||
|
$settings->system_notifications_email = config('ninja.contact.email');
|
||||||
|
|
||||||
|
$company->settings = $settings;
|
||||||
|
$company->save();
|
||||||
|
|
||||||
$account->default_company_id = $company->id;
|
$account->default_company_id = $company->id;
|
||||||
$account->save();
|
$account->save();
|
||||||
|
|
||||||
@ -265,6 +282,14 @@ class CreateTestData extends Command
|
|||||||
'account_id' => $account->id,
|
'account_id' => $account->id,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$settings = $company->settings;
|
||||||
|
|
||||||
|
$settings->system_notifications_slack = config('ninja.notification.slack');
|
||||||
|
$settings->system_notifications_email = config('ninja.contact.email');
|
||||||
|
|
||||||
|
$company->settings = $settings;
|
||||||
|
$company->save();
|
||||||
|
|
||||||
$account->default_company_id = $company->id;
|
$account->default_company_id = $company->id;
|
||||||
$account->save();
|
$account->save();
|
||||||
|
|
||||||
|
@ -193,6 +193,9 @@ class CompanySettings extends BaseSettings {
|
|||||||
public $client_online_payment_notification = true;
|
public $client_online_payment_notification = true;
|
||||||
public $client_manual_payment_notification = true;
|
public $client_manual_payment_notification = true;
|
||||||
|
|
||||||
|
public $system_notifications_slack = '';
|
||||||
|
public $system_notifications_email = '';
|
||||||
|
|
||||||
/* Company Meta data that we can use to build sub companies*/
|
/* Company Meta data that we can use to build sub companies*/
|
||||||
|
|
||||||
public $name = '';
|
public $name = '';
|
||||||
@ -220,6 +223,8 @@ class CompanySettings extends BaseSettings {
|
|||||||
public $pdf_variables = [];
|
public $pdf_variables = [];
|
||||||
|
|
||||||
public static $casts = [
|
public static $casts = [
|
||||||
|
'system_notifications_slack' => 'string',
|
||||||
|
'system_notifications_email' => 'string',
|
||||||
'portal_design_id' => 'string',
|
'portal_design_id' => 'string',
|
||||||
'late_fee_endless_percent' => 'float',
|
'late_fee_endless_percent' => 'float',
|
||||||
'late_fee_endless_amount' => 'float',
|
'late_fee_endless_amount' => 'float',
|
||||||
@ -401,9 +406,11 @@ class CompanySettings extends BaseSettings {
|
|||||||
* @return object
|
* @return object
|
||||||
*/
|
*/
|
||||||
public static function defaults():\stdClass {
|
public static function defaults():\stdClass {
|
||||||
|
|
||||||
$config = json_decode(config('ninja.settings'));
|
$config = json_decode(config('ninja.settings'));
|
||||||
|
|
||||||
$data = (object) get_class_vars(CompanySettings::class );
|
$data = (object) get_class_vars(CompanySettings::class );
|
||||||
|
|
||||||
unset($data->casts);
|
unset($data->casts);
|
||||||
unset($data->protected_fields);
|
unset($data->protected_fields);
|
||||||
|
|
||||||
@ -415,7 +422,7 @@ class CompanySettings extends BaseSettings {
|
|||||||
$data->date_format_id = (string) config('ninja.i18n.date_format_id');
|
$data->date_format_id = (string) config('ninja.i18n.date_format_id');
|
||||||
$data->country_id = (string) config('ninja.i18n.country_id');
|
$data->country_id = (string) config('ninja.i18n.country_id');
|
||||||
$data->translations = (object) [];
|
$data->translations = (object) [];
|
||||||
$data->pdf_variables = (array) self::getEntityVariableDefaults();
|
$data->pdf_variables = (array) self::getEntityVariableDefaults();
|
||||||
|
|
||||||
// $data->email_subject_invoice = EmailTemplateDefaults::emailInvoiceSubject();
|
// $data->email_subject_invoice = EmailTemplateDefaults::emailInvoiceSubject();
|
||||||
// $data->email_template_invoice = EmailTemplateDefaults:: emailInvoiceTemplate();
|
// $data->email_template_invoice = EmailTemplateDefaults:: emailInvoiceTemplate();
|
||||||
|
@ -213,8 +213,8 @@ class CompanyController extends BaseController
|
|||||||
'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' => DefaultSettings::userSettings(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -520,7 +520,7 @@ class InvoiceController extends BaseController {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ZipInvoices::dispatch($invoices, $invoices->first()->company);
|
ZipInvoices::dispatch($invoices, $invoices->first()->company, auth()->user()->email);
|
||||||
|
|
||||||
return response()->json(['message' => 'Email Sent!'],200);
|
return response()->json(['message' => 'Email Sent!'],200);
|
||||||
}
|
}
|
||||||
|
@ -28,8 +28,8 @@ class TokenAuth
|
|||||||
public function handle($request, Closure $next)
|
public function handle($request, Closure $next)
|
||||||
{
|
{
|
||||||
if ($request->header('X-API-TOKEN') && ($company_token = CompanyToken::with(['user','company'])->whereRaw("BINARY `token`= ?", [$request->header('X-API-TOKEN')])->first())) {
|
if ($request->header('X-API-TOKEN') && ($company_token = CompanyToken::with(['user','company'])->whereRaw("BINARY `token`= ?", [$request->header('X-API-TOKEN')])->first())) {
|
||||||
$user = $company_token->user;
|
|
||||||
|
|
||||||
|
$user = $company_token->user;
|
||||||
|
|
||||||
$error = [
|
$error = [
|
||||||
'message' => 'User inactive',
|
'message' => 'User inactive',
|
||||||
@ -49,6 +49,12 @@ class TokenAuth
|
|||||||
*/
|
*/
|
||||||
$user->setCompany($company_token->company);
|
$user->setCompany($company_token->company);
|
||||||
|
|
||||||
|
config(['ninja.company_id' => $company_token->company->id]);
|
||||||
|
|
||||||
|
app('queue')->createPayloadUsing(function () use($company_token) {
|
||||||
|
return ['db' => $company_token->company->db];
|
||||||
|
});
|
||||||
|
|
||||||
//user who once existed, but has been soft deleted
|
//user who once existed, but has been soft deleted
|
||||||
if ($user->company_user->is_locked) {
|
if ($user->company_user->is_locked) {
|
||||||
$error = [
|
$error = [
|
||||||
|
@ -70,12 +70,12 @@ class StoreClientRequest extends Request
|
|||||||
|
|
||||||
if(isset($input['contacts']))
|
if(isset($input['contacts']))
|
||||||
{
|
{
|
||||||
foreach($input['contacts'] as $contact)
|
foreach($input['contacts'] as $key => $contact)
|
||||||
{
|
{
|
||||||
if(is_numeric($contact['id']))
|
if(is_numeric($contact['id']))
|
||||||
unset($contact['id']);
|
unset($input['contacts'][$key]['id']);
|
||||||
elseif(is_string($contact['id']))
|
elseif(is_string($contact['id']))
|
||||||
$contact['id'] = $this->decodePrimaryKey($contact['id']);
|
$input['contacts'][$key]['id'] = $this->decodePrimaryKey($contact['id']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,12 +81,12 @@ class UpdateClientRequest extends Request
|
|||||||
|
|
||||||
if(isset($input['contacts']))
|
if(isset($input['contacts']))
|
||||||
{
|
{
|
||||||
foreach($input['contacts'] as $contact)
|
foreach($input['contacts'] as $key => $contact)
|
||||||
{
|
{
|
||||||
if(is_numeric($contact['id']))
|
if(is_numeric($contact['id']))
|
||||||
unset($contact['id']);
|
unset($input['contacts'][$key]['id']);
|
||||||
elseif(is_string($contact['id']))
|
elseif(is_string($contact['id']))
|
||||||
$contact['id'] = $this->decodePrimaryKey($contact['id']);
|
$input['contacts'][$key]['id'] = $this->decodePrimaryKey($contact['id']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,8 +92,14 @@ class CreateAccount
|
|||||||
|
|
||||||
$user->fresh();
|
$user->fresh();
|
||||||
|
|
||||||
Notification::route('slack', config('ninja.notification.slack'))
|
$company->notification(new NewAccountCreated($user, $company))->run();
|
||||||
->notify(new NewAccountCreated($user, $company));
|
|
||||||
|
// $user->route('slack', $company->settings->system_notifications_slack)
|
||||||
|
// ->route('mail', $company->settings->system_notifications_email)
|
||||||
|
// ->notify(new NewAccountCreated($user, $company));
|
||||||
|
|
||||||
|
// Notification::route('slack', config('ninja.notification.slack'))
|
||||||
|
// ->notify(new NewAccountCreated($user, $company));
|
||||||
|
|
||||||
return $account;
|
return $account;
|
||||||
}
|
}
|
||||||
|
@ -35,19 +35,17 @@ class ApplyCreditPayment implements ShouldQueue
|
|||||||
|
|
||||||
public $amount;
|
public $amount;
|
||||||
|
|
||||||
private $company;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new job instance.
|
* Create a new job instance.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function __construct(Credit $credit, Payment $payment, float $amount, Company $company)
|
public function __construct(Credit $credit, Payment $payment, float $amount)
|
||||||
{
|
{
|
||||||
$this->credit = $credit;
|
$this->credit = $credit;
|
||||||
$this->payment = $payment;
|
$this->payment = $payment;
|
||||||
$this->amount = $amount;
|
$this->amount = $amount;
|
||||||
$this->company = $company;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -58,7 +56,6 @@ class ApplyCreditPayment implements ShouldQueue
|
|||||||
*/
|
*/
|
||||||
public function handle()
|
public function handle()
|
||||||
{
|
{
|
||||||
MultiDB::setDB($this->company->db);
|
|
||||||
|
|
||||||
/* Update Pivot Record amount */
|
/* Update Pivot Record amount */
|
||||||
$this->payment->credits->each(function ($cred) {
|
$this->payment->credits->each(function ($cred) {
|
||||||
|
@ -16,7 +16,6 @@ use App\Events\Credit\CreditWasEmailedAndFailed;
|
|||||||
use App\Jobs\Util\SystemLogger;
|
use App\Jobs\Util\SystemLogger;
|
||||||
use App\Libraries\MultiDB;
|
use App\Libraries\MultiDB;
|
||||||
use App\Mail\TemplateEmail;
|
use App\Mail\TemplateEmail;
|
||||||
use App\Models\Company;
|
|
||||||
use App\Models\Credit;
|
use App\Models\Credit;
|
||||||
use App\Models\SystemLog;
|
use App\Models\SystemLog;
|
||||||
use Illuminate\Bus\Queueable;
|
use Illuminate\Bus\Queueable;
|
||||||
@ -34,18 +33,15 @@ class EmailCredit implements ShouldQueue
|
|||||||
|
|
||||||
public $message_array = [];
|
public $message_array = [];
|
||||||
|
|
||||||
private $company;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new job instance.
|
* Create a new job instance.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function __construct(Credit $credit, Company $company)
|
public function __construct(Credit $credit)
|
||||||
{
|
{
|
||||||
$this->credit = $credit;
|
$this->credit = $credit;
|
||||||
|
|
||||||
$this->company = $company;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -56,9 +52,6 @@ class EmailCredit implements ShouldQueue
|
|||||||
*/
|
*/
|
||||||
public function handle()
|
public function handle()
|
||||||
{
|
{
|
||||||
/*Jobs are not multi-db aware, need to set! */
|
|
||||||
MultiDB::setDB($this->company->db);
|
|
||||||
|
|
||||||
//todo - change runtime config of mail driver if necessary
|
//todo - change runtime config of mail driver if necessary
|
||||||
|
|
||||||
$template_style = $this->credit->client->getSetting('email_style');
|
$template_style = $this->credit->client->getSetting('email_style');
|
||||||
|
@ -21,20 +21,16 @@ class StoreCredit implements ShouldQueue
|
|||||||
|
|
||||||
protected $data;
|
protected $data;
|
||||||
|
|
||||||
private $company;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new job instance.
|
* Create a new job instance.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function __construct(Credit $credit, array $data, Company $company)
|
public function __construct(Credit $credit, array $data)
|
||||||
{
|
{
|
||||||
$this->credit = $credit;
|
$this->credit = $credit;
|
||||||
|
|
||||||
$this->data = $data;
|
$this->data = $data;
|
||||||
|
|
||||||
$this->company = $company;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
namespace App\Jobs\Cron;
|
namespace App\Jobs\Cron;
|
||||||
|
|
||||||
use App\Jobs\RecurringInvoice\SendRecurring;
|
use App\Jobs\RecurringInvoice\SendRecurring;
|
||||||
|
use App\Libraries\MultiDB;
|
||||||
use App\Models\RecurringInvoice;
|
use App\Models\RecurringInvoice;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
|
@ -63,8 +63,6 @@ class CreateInvoicePdf implements ShouldQueue {
|
|||||||
|
|
||||||
public function handle() {
|
public function handle() {
|
||||||
|
|
||||||
MultiDB::setDB($this->company->db);
|
|
||||||
|
|
||||||
$this->invoice->load('client');
|
$this->invoice->load('client');
|
||||||
|
|
||||||
if(!$this->contact)
|
if(!$this->contact)
|
||||||
|
@ -54,7 +54,6 @@ class EmailInvoice implements ShouldQueue
|
|||||||
|
|
||||||
public function handle()
|
public function handle()
|
||||||
{
|
{
|
||||||
MultiDB::setDb($this->company->db);
|
|
||||||
|
|
||||||
Mail::to($this->invoice_invitation->contact->email, $this->invoice_invitation->contact->present()->name())
|
Mail::to($this->invoice_invitation->contact->email, $this->invoice_invitation->contact->present()->name())
|
||||||
->send(new TemplateEmail($this->email_builder,
|
->send(new TemplateEmail($this->email_builder,
|
||||||
|
@ -64,8 +64,6 @@ class StoreInvoice implements ShouldQueue
|
|||||||
*/
|
*/
|
||||||
public function handle(InvoiceRepository $invoice_repo) : ?Invoice
|
public function handle(InvoiceRepository $invoice_repo) : ?Invoice
|
||||||
{
|
{
|
||||||
MultiDB::setDB($this->company->db);
|
|
||||||
|
|
||||||
$payment = false;
|
$payment = false;
|
||||||
|
|
||||||
// /* Test if we should auto-bill the invoice */
|
// /* Test if we should auto-bill the invoice */
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
namespace App\Jobs\Invoice;
|
namespace App\Jobs\Invoice;
|
||||||
|
|
||||||
|
use App\Jobs\Util\UnlinkFile;
|
||||||
use App\Libraries\MultiDB;
|
use App\Libraries\MultiDB;
|
||||||
use App\Mail\DownloadInvoices;
|
use App\Mail\DownloadInvoices;
|
||||||
use App\Models\Company;
|
use App\Models\Company;
|
||||||
@ -20,10 +21,10 @@ use Illuminate\Contracts\Queue\ShouldQueue;
|
|||||||
use Illuminate\Foundation\Bus\Dispatchable;
|
use Illuminate\Foundation\Bus\Dispatchable;
|
||||||
use Illuminate\Queue\InteractsWithQueue;
|
use Illuminate\Queue\InteractsWithQueue;
|
||||||
use Illuminate\Queue\SerializesModels;
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
use Illuminate\Support\Facades\Mail;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
use ZipStream\Option\Archive;
|
use ZipStream\Option\Archive;
|
||||||
use ZipStream\ZipStream;
|
use ZipStream\ZipStream;
|
||||||
use Illuminate\Support\Facades\Mail;
|
|
||||||
|
|
||||||
class ZipInvoices implements ShouldQueue
|
class ZipInvoices implements ShouldQueue
|
||||||
{
|
{
|
||||||
@ -33,17 +34,21 @@ class ZipInvoices implements ShouldQueue
|
|||||||
|
|
||||||
private $company;
|
private $company;
|
||||||
|
|
||||||
|
private $email;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated confirm to be deleted
|
* @deprecated confirm to be deleted
|
||||||
* Create a new job instance.
|
* Create a new job instance.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function __construct($invoices, Company $company)
|
public function __construct($invoices, Company $company, $email)
|
||||||
{
|
{
|
||||||
$this->invoices = $invoices;
|
$this->invoices = $invoices;
|
||||||
|
|
||||||
$this->company = $company;
|
$this->company = $company;
|
||||||
|
|
||||||
|
$this->email = $email;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -54,7 +59,6 @@ class ZipInvoices implements ShouldQueue
|
|||||||
*/
|
*/
|
||||||
public function handle()
|
public function handle()
|
||||||
{
|
{
|
||||||
MultiDB::setDB($this->company->db);
|
|
||||||
|
|
||||||
$tempStream = fopen('php://memory', 'w+');
|
$tempStream = fopen('php://memory', 'w+');
|
||||||
|
|
||||||
@ -78,9 +82,9 @@ class ZipInvoices implements ShouldQueue
|
|||||||
|
|
||||||
fclose($tempStream);
|
fclose($tempStream);
|
||||||
|
|
||||||
//fire email here
|
Mail::to($this->email)
|
||||||
Mail::to(config('ninja.contact.ninja_official_contact'))
|
->send(new DownloadInvoices(Storage::disk(config('filesystems.default'))->url($path . $file_name), $this->company));
|
||||||
->send(new DownloadInvoices(Storage::disk(config('filesystems.default'))->url($path . $file_name)));
|
|
||||||
|
|
||||||
|
UnlinkFile::dispatch(config('filesystems.default'), $path . $file_name)->delay(now()->addHours(1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,6 @@ class PaymentNotification implements ShouldQueue
|
|||||||
*/
|
*/
|
||||||
public function handle()
|
public function handle()
|
||||||
{
|
{
|
||||||
MultiDB::setDB($this->company->db);
|
|
||||||
|
|
||||||
//notification for the payment.
|
//notification for the payment.
|
||||||
//
|
//
|
||||||
|
@ -15,12 +15,17 @@ use App\Factory\RecurringInvoiceToInvoiceFactory;
|
|||||||
use App\Models\Invoice;
|
use App\Models\Invoice;
|
||||||
use App\Models\RecurringInvoice;
|
use App\Models\RecurringInvoice;
|
||||||
use App\Utils\Traits\GeneratesCounter;
|
use App\Utils\Traits\GeneratesCounter;
|
||||||
|
use Illuminate\Bus\Queueable;
|
||||||
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Queue\InteractsWithQueue;
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Foundation\Bus\Dispatchable;
|
||||||
|
|
||||||
class SendRecurring
|
class SendRecurring implements ShouldQueue
|
||||||
{
|
{
|
||||||
|
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||||
use GeneratesCounter;
|
use GeneratesCounter;
|
||||||
|
|
||||||
public $recurring_invoice;
|
public $recurring_invoice;
|
||||||
@ -46,7 +51,6 @@ class SendRecurring
|
|||||||
*/
|
*/
|
||||||
public function handle() : void
|
public function handle() : void
|
||||||
{
|
{
|
||||||
MultiDb::setDb($this->db);
|
|
||||||
|
|
||||||
// Generate Standard Invoice
|
// Generate Standard Invoice
|
||||||
$invoice = RecurringInvoiceToInvoiceFactory::create($this->recurring_invoice);
|
$invoice = RecurringInvoiceToInvoiceFactory::create($this->recurring_invoice);
|
||||||
|
@ -14,12 +14,15 @@ use App\Factory\QuoteFactory;
|
|||||||
use App\Factory\TaxRateFactory;
|
use App\Factory\TaxRateFactory;
|
||||||
use App\Factory\UserFactory;
|
use App\Factory\UserFactory;
|
||||||
use App\Http\Requests\Company\UpdateCompanyRequest;
|
use App\Http\Requests\Company\UpdateCompanyRequest;
|
||||||
|
use App\Http\ValidationRules\ValidCompanyGatewayFeesAndLimitsRule;
|
||||||
use App\Http\ValidationRules\ValidUserForCompany;
|
use App\Http\ValidationRules\ValidUserForCompany;
|
||||||
use App\Jobs\Company\CreateCompanyToken;
|
use App\Jobs\Company\CreateCompanyToken;
|
||||||
use App\Libraries\MultiDB;
|
use App\Libraries\MultiDB;
|
||||||
use App\Mail\MigrationFailed;
|
use App\Mail\MigrationFailed;
|
||||||
use App\Models\Client;
|
use App\Models\Client;
|
||||||
|
use App\Models\ClientGatewayToken;
|
||||||
use App\Models\Company;
|
use App\Models\Company;
|
||||||
|
use App\Models\CompanyGateway;
|
||||||
use App\Models\Credit;
|
use App\Models\Credit;
|
||||||
use App\Models\Document;
|
use App\Models\Document;
|
||||||
use App\Models\Invoice;
|
use App\Models\Invoice;
|
||||||
@ -37,6 +40,7 @@ use App\Repositories\PaymentRepository;
|
|||||||
use App\Repositories\ProductRepository;
|
use App\Repositories\ProductRepository;
|
||||||
use App\Repositories\QuoteRepository;
|
use App\Repositories\QuoteRepository;
|
||||||
use App\Repositories\UserRepository;
|
use App\Repositories\UserRepository;
|
||||||
|
use App\Utils\Traits\CompanyGatewayFeesAndLimitsSaver;
|
||||||
use Illuminate\Bus\Queueable;
|
use Illuminate\Bus\Queueable;
|
||||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
use Illuminate\Foundation\Bus\Dispatchable;
|
use Illuminate\Foundation\Bus\Dispatchable;
|
||||||
@ -49,6 +53,7 @@ use Illuminate\Support\Str;
|
|||||||
class Import implements ShouldQueue
|
class Import implements ShouldQueue
|
||||||
{
|
{
|
||||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||||
|
use CompanyGatewayFeesAndLimitsSaver;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array
|
* @var array
|
||||||
@ -64,7 +69,18 @@ class Import implements ShouldQueue
|
|||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
private $available_imports = [
|
private $available_imports = [
|
||||||
'company', 'users', 'tax_rates', 'clients', 'products', 'invoices', 'quotes', 'payments', 'credits', 'documents',
|
'company',
|
||||||
|
'users',
|
||||||
|
'tax_rates',
|
||||||
|
'clients',
|
||||||
|
'products',
|
||||||
|
'invoices',
|
||||||
|
'quotes',
|
||||||
|
'payments',
|
||||||
|
'credits',
|
||||||
|
'company_gateways',
|
||||||
|
'documents',
|
||||||
|
'client_gateway_tokens',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -110,6 +126,7 @@ class Import implements ShouldQueue
|
|||||||
*/
|
*/
|
||||||
public function handle()
|
public function handle()
|
||||||
{
|
{
|
||||||
|
|
||||||
try {
|
try {
|
||||||
foreach ($this->data as $key => $resource) {
|
foreach ($this->data as $key => $resource) {
|
||||||
|
|
||||||
@ -143,7 +160,7 @@ class Import implements ShouldQueue
|
|||||||
$validator = Validator::make($data, $rules);
|
$validator = Validator::make($data, $rules);
|
||||||
|
|
||||||
if ($validator->fails()) {
|
if ($validator->fails()) {
|
||||||
\Log::error($validator->errors());
|
// \Log::error($validator->errors());
|
||||||
throw new MigrationValidatorFailed($validator->errors());
|
throw new MigrationValidatorFailed($validator->errors());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -548,11 +565,84 @@ class Import implements ShouldQueue
|
|||||||
|
|
||||||
$this->ids['documents'] = [
|
$this->ids['documents'] = [
|
||||||
"documents_{$old_user_key}" => [
|
"documents_{$old_user_key}" => [
|
||||||
'old' => $old_user_key,
|
'old' => $resource['id'],
|
||||||
'new' => $document->id,
|
'new' => $document->id,
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private function processCompanyGateways(array $data) :void
|
||||||
|
{
|
||||||
|
CompanyGateway::unguard();
|
||||||
|
|
||||||
|
$rules = [
|
||||||
|
'*.gateway_key' => 'required',
|
||||||
|
'*.fees_and_limits' => new ValidCompanyGatewayFeesAndLimitsRule(),
|
||||||
|
];
|
||||||
|
|
||||||
|
$validator = Validator::make($data, $rules);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
throw new MigrationValidatorFailed($validator->errors());
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($data as $resource) {
|
||||||
|
|
||||||
|
$modified = $resource;
|
||||||
|
|
||||||
|
$modified['user_id'] = $this->processUserId($resource);
|
||||||
|
$modified['company_id'] = $this->company->id;
|
||||||
|
|
||||||
|
unset($modified['id']);
|
||||||
|
|
||||||
|
if (isset($modified['config'])) {
|
||||||
|
$modified['config'] = encrypt($modified['config']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($modified['fees_and_limits'])) {
|
||||||
|
$modified['fees_and_limits'] = $this->cleanFeesAndLimits($modified['fees_and_limits']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$company_gateway = CompanyGateway::create($modified);
|
||||||
|
|
||||||
|
$old_user_key = array_key_exists('user_id', $resource) ?? $this->user->id;
|
||||||
|
|
||||||
|
$this->ids['company_gateways'] = [
|
||||||
|
"company_gateways_{$old_user_key}" => [
|
||||||
|
'old' => $resource['id'],
|
||||||
|
'new' => $company_gateway->id,
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private function processClientGatewayTokens(array $data) :void
|
||||||
|
{
|
||||||
|
ClientGatewayToken::unguard();
|
||||||
|
|
||||||
|
foreach ($data as $resource) {
|
||||||
|
|
||||||
|
$modified = $resource;
|
||||||
|
|
||||||
|
unset($modified['id']);
|
||||||
|
|
||||||
|
$modified['company_id'] = $this->company->id;
|
||||||
|
$modified['client_id'] = $this->transformId('clients', $resource['client_id']);
|
||||||
|
|
||||||
|
$cgt = ClientGatewayToken::Create($modified);
|
||||||
|
|
||||||
|
$old_user_key = array_key_exists('user_id', $resource) ?? $this->user->id;
|
||||||
|
|
||||||
|
$this->ids['client_gateway_tokens'] = [
|
||||||
|
"client_gateway_tokens_{$old_user_key}" => [
|
||||||
|
'old' => $resource['id'],
|
||||||
|
'new' => $cgt->id,
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
38
app/Jobs/Util/UnlinkFile.php
Normal file
38
app/Jobs/Util/UnlinkFile.php
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Jobs\Util;
|
||||||
|
|
||||||
|
use App\Utils\Traits\BulkOptions;
|
||||||
|
use Illuminate\Bus\Queueable;
|
||||||
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
|
use Illuminate\Foundation\Bus\Dispatchable;
|
||||||
|
use Illuminate\Queue\InteractsWithQueue;
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
|
||||||
|
class UnlinkFile implements ShouldQueue
|
||||||
|
{
|
||||||
|
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||||
|
|
||||||
|
protected $file_path;
|
||||||
|
|
||||||
|
protected $disk;
|
||||||
|
|
||||||
|
public function __construct(string $disk, string $file_path)
|
||||||
|
{
|
||||||
|
$this->file_path = $file_path;
|
||||||
|
$this->disk = $disk;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the job.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
|
||||||
|
Storage::disk($this->disk)->delete($this->file_path);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Mail;
|
namespace App\Mail;
|
||||||
|
|
||||||
|
use App\Models\Company;
|
||||||
use App\Utils\Ninja;
|
use App\Utils\Ninja;
|
||||||
use Illuminate\Bus\Queueable;
|
use Illuminate\Bus\Queueable;
|
||||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
@ -14,9 +15,13 @@ class DownloadInvoices extends Mailable
|
|||||||
|
|
||||||
public $file_path;
|
public $file_path;
|
||||||
|
|
||||||
public function __construct($file_path)
|
public $company;
|
||||||
|
|
||||||
|
public function __construct($file_path, Company $company)
|
||||||
{
|
{
|
||||||
$this->file_path = $file_path;
|
$this->file_path = $file_path;
|
||||||
|
|
||||||
|
$this->company = $company;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -27,10 +32,17 @@ class DownloadInvoices extends Mailable
|
|||||||
public function build()
|
public function build()
|
||||||
{
|
{
|
||||||
|
|
||||||
return $this->from(config('mail.from.address')) //todo this needs to be fixed to handle the hosted version
|
return $this->subject(ctrans('texts.download_files'))
|
||||||
->subject(ctrans('texts.download_documents',['size'=>'']))
|
->markdown('email.admin.download_files',
|
||||||
->markdown('email.admin.download_files', [
|
[
|
||||||
'file_path' => $this->file_path
|
'url' => $this->file_path,
|
||||||
]);
|
'logo' => $this->company->present()->logo,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// return $this->from(config('mail.from.address')) //todo this needs to be fixed to handle the hosted version
|
||||||
|
// ->subject(ctrans('texts.download_documents',['size'=>'']))
|
||||||
|
// ->markdown('email.admin.download_files', [
|
||||||
|
// 'file_path' => $this->file_path
|
||||||
|
// ]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,11 +32,13 @@ use App\Models\TaxRate;
|
|||||||
use App\Models\Timezone;
|
use App\Models\Timezone;
|
||||||
use App\Models\Traits\AccountTrait;
|
use App\Models\Traits\AccountTrait;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
|
use App\Services\Notification\NotificationService;
|
||||||
use App\Utils\Ninja;
|
use App\Utils\Ninja;
|
||||||
use App\Utils\Traits\CompanySettingsSaver;
|
use App\Utils\Traits\CompanySettingsSaver;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
use App\Utils\Traits\ThrottlesEmail;
|
use App\Utils\Traits\ThrottlesEmail;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Notifications\Notification;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
use Laracasts\Presenter\PresentableTrait;
|
use Laracasts\Presenter\PresentableTrait;
|
||||||
|
|
||||||
@ -300,7 +302,8 @@ class Company extends BaseModel
|
|||||||
|
|
||||||
public function company_users()
|
public function company_users()
|
||||||
{
|
{
|
||||||
return $this->hasMany(CompanyUser::class)->withTimestamps();
|
//return $this->hasMany(CompanyUser::class)->withTimestamps();
|
||||||
|
return $this->hasMany(CompanyUser::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function owner()
|
public function owner()
|
||||||
@ -320,4 +323,19 @@ class Company extends BaseModel
|
|||||||
{
|
{
|
||||||
return 'https://' . $this->subdomain . config('ninja.app_domain');
|
return 'https://' . $this->subdomain . config('ninja.app_domain');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function notification(Notification $notification)
|
||||||
|
{
|
||||||
|
return new NotificationService($this, $notification);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function routeNotificationForSlack($notification)
|
||||||
|
{
|
||||||
|
//todo need to return the company channel here for hosted users
|
||||||
|
//else the env variable for selfhosted
|
||||||
|
if(config('ninja.environment') == 'selfhosted')
|
||||||
|
return config('ninja.notification.slack');
|
||||||
|
else
|
||||||
|
return $this->settings->system_notifications_slack;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -152,7 +152,10 @@ class User extends Authenticatable implements MustVerifyEmail
|
|||||||
*/
|
*/
|
||||||
public function getCompany()
|
public function getCompany()
|
||||||
{
|
{
|
||||||
return $this->company;
|
if($this->company)
|
||||||
|
return $this->company;
|
||||||
|
|
||||||
|
return Company::find( config('ninja.company_id') );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -298,7 +301,13 @@ class User extends Authenticatable implements MustVerifyEmail
|
|||||||
{
|
{
|
||||||
//todo need to return the company channel here for hosted users
|
//todo need to return the company channel here for hosted users
|
||||||
//else the env variable for selfhosted
|
//else the env variable for selfhosted
|
||||||
return config('ninja.notification.slack');
|
if(config('ninja.environment') == 'selfhosted')
|
||||||
|
return config('ninja.notification.slack');
|
||||||
|
|
||||||
|
if($this->company())
|
||||||
|
return $this->company()->settings->system_notifications_slack;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Notifications;
|
namespace App\Notifications;
|
||||||
|
|
||||||
|
use App\Mail\Signup\NewSignup;
|
||||||
use Illuminate\Bus\Queueable;
|
use Illuminate\Bus\Queueable;
|
||||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
use Illuminate\Notifications\Messages\MailMessage;
|
use Illuminate\Notifications\Messages\MailMessage;
|
||||||
@ -36,7 +37,8 @@ class NewAccountCreated extends Notification implements ShouldQueue
|
|||||||
*/
|
*/
|
||||||
public function via($notifiable)
|
public function via($notifiable)
|
||||||
{
|
{
|
||||||
return ['slack'];
|
//return ['mail'];
|
||||||
|
return ['slack','mail'];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -47,10 +49,25 @@ class NewAccountCreated extends Notification implements ShouldQueue
|
|||||||
*/
|
*/
|
||||||
public function toMail($notifiable)
|
public function toMail($notifiable)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
$user_name = $this->user->first_name . " " . $this->user->last_name;
|
||||||
|
$email = $this->user->email;
|
||||||
|
$ip = $this->user->ip;
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'title' => ctrans('texts.new_signup'),
|
||||||
|
'message' => ctrans('texts.new_signup_text', ['user' => $user_name, 'email' => $email, 'ip' => $ip]),
|
||||||
|
'url' => config('ninja.web_url'),
|
||||||
|
'button' => ctrans('texts.account_login'),
|
||||||
|
'signature' => '',
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
return (new MailMessage)
|
return (new MailMessage)
|
||||||
->line('The introduction to the notification.')
|
->subject(ctrans('texts.new_signup'))
|
||||||
->action('Notification Action', url('/'))
|
->markdown('email.admin.generic', $data);
|
||||||
->line('Thank you for using our application!');
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -68,6 +85,9 @@ class NewAccountCreated extends Notification implements ShouldQueue
|
|||||||
|
|
||||||
public function toSlack($notifiable)
|
public function toSlack($notifiable)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
$this->user->setCompany($this->company);
|
||||||
|
|
||||||
$user_name = $this->user->first_name . " " . $this->user->last_name;
|
$user_name = $this->user->first_name . " " . $this->user->last_name;
|
||||||
$email = $this->user->email;
|
$email = $this->user->email;
|
||||||
$ip = $this->user->ip;
|
$ip = $this->user->ip;
|
||||||
|
@ -39,6 +39,7 @@ use App\Listeners\Invoice\InvoiceEmailFailedActivity;
|
|||||||
use App\Listeners\Invoice\UpdateInvoiceActivity;
|
use App\Listeners\Invoice\UpdateInvoiceActivity;
|
||||||
use App\Listeners\Invoice\UpdateInvoiceInvitations;
|
use App\Listeners\Invoice\UpdateInvoiceInvitations;
|
||||||
use App\Listeners\SendVerificationNotification;
|
use App\Listeners\SendVerificationNotification;
|
||||||
|
use App\Listeners\SetDBListener;
|
||||||
use App\Listeners\User\UpdateUserLastLogin;
|
use App\Listeners\User\UpdateUserLastLogin;
|
||||||
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
|
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
|
||||||
|
|
||||||
|
58
app/Providers/MultiDBProvider.php
Normal file
58
app/Providers/MultiDBProvider.php
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Providers;
|
||||||
|
|
||||||
|
use App\Libraries\MultiDB;
|
||||||
|
use Illuminate\Support\ServiceProvider;
|
||||||
|
|
||||||
|
class MultiDBProvider extends ServiceProvider
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Bootstrap services.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function boot()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register services.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function register()
|
||||||
|
{
|
||||||
|
if($this->app->runningInConsole()){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$this->app['events']->listen(\Illuminate\Queue\Events\JobProcessing::class, function($event) {
|
||||||
|
|
||||||
|
if (isset($event->job->payload()['db'])) {
|
||||||
|
|
||||||
|
//\Log::error("Provider Setting DB = ".$event->job->payload()['db']);
|
||||||
|
|
||||||
|
MultiDB::setDb($event->job->payload()['db']);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,40 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Invoice Ninja (https://invoiceninja.com)
|
|
||||||
*
|
|
||||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
|
||||||
*
|
|
||||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
|
||||||
*
|
|
||||||
* @license https://opensource.org/licenses/AAL
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace App\Providers;
|
|
||||||
|
|
||||||
use App\Providers\UserSignedUp;
|
|
||||||
use Illuminate\Queue\InteractsWithQueue;
|
|
||||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
|
||||||
|
|
||||||
class SendConfirmationNotification
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Create the event listener.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle the event.
|
|
||||||
*
|
|
||||||
* @param UserSignedUp $event
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function handle(UserSignedUp $event)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,45 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Invoice Ninja (https://invoiceninja.com)
|
|
||||||
*
|
|
||||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
|
||||||
*
|
|
||||||
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
|
||||||
*
|
|
||||||
* @license https://opensource.org/licenses/AAL
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace App\Providers;
|
|
||||||
|
|
||||||
use Illuminate\Broadcasting\Channel;
|
|
||||||
use Illuminate\Queue\SerializesModels;
|
|
||||||
use Illuminate\Broadcasting\PrivateChannel;
|
|
||||||
use Illuminate\Broadcasting\PresenceChannel;
|
|
||||||
use Illuminate\Foundation\Events\Dispatchable;
|
|
||||||
use Illuminate\Broadcasting\InteractsWithSockets;
|
|
||||||
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
|
||||||
|
|
||||||
class UserSignedUp
|
|
||||||
{
|
|
||||||
use Dispatchable, InteractsWithSockets, SerializesModels;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new event instance.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the channels the event should broadcast on.
|
|
||||||
*
|
|
||||||
* @return \Illuminate\Broadcasting\Channel|array
|
|
||||||
*/
|
|
||||||
public function broadcastOn()
|
|
||||||
{
|
|
||||||
return new PrivateChannel('channel-name');
|
|
||||||
}
|
|
||||||
}
|
|
@ -23,13 +23,12 @@ class ClientContactRepository extends BaseRepository
|
|||||||
{
|
{
|
||||||
public function save(array $data, Client $client) : void
|
public function save(array $data, Client $client) : void
|
||||||
{
|
{
|
||||||
|
|
||||||
if(isset($data['contacts']))
|
if(isset($data['contacts']))
|
||||||
$contacts = collect($data['contacts']);
|
$contacts = collect($data['contacts']);
|
||||||
else
|
else
|
||||||
$contacts = collect();
|
$contacts = collect();
|
||||||
|
|
||||||
collect($client->contacts->pluck('id'))->diff($contacts->pluck('id'))->each(function ($contact) {
|
$client->contacts->pluck('id')->diff($contacts->pluck('id'))->each(function ($contact) {
|
||||||
ClientContact::destroy($contact);
|
ClientContact::destroy($contact);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -43,7 +42,7 @@ class ClientContactRepository extends BaseRepository
|
|||||||
|
|
||||||
//loop and update/create contacts
|
//loop and update/create contacts
|
||||||
$contacts->each(function ($contact) use ($client) {
|
$contacts->each(function ($contact) use ($client) {
|
||||||
//$update_contact = null;
|
$update_contact = null;
|
||||||
|
|
||||||
if (isset($contact['id'])) {
|
if (isset($contact['id'])) {
|
||||||
$update_contact = ClientContact::find($contact['id']);
|
$update_contact = ClientContact::find($contact['id']);
|
||||||
|
@ -51,7 +51,8 @@ class CreditRepository extends BaseRepository
|
|||||||
$credit->fill($data);
|
$credit->fill($data);
|
||||||
$credit->save();
|
$credit->save();
|
||||||
|
|
||||||
$credit->number = $credit->client->getNextCreditNumber($credit->client);
|
if(!$credit->number)
|
||||||
|
$credit->number = $credit->client->getNextCreditNumber($credit->client);
|
||||||
|
|
||||||
if (isset($data['invitations'])) {
|
if (isset($data['invitations'])) {
|
||||||
$invitations = collect($data['invitations']);
|
$invitations = collect($data['invitations']);
|
||||||
|
@ -66,16 +66,20 @@ class InvoiceRepository extends BaseRepository {
|
|||||||
$invitations = collect($data['invitations']);
|
$invitations = collect($data['invitations']);
|
||||||
|
|
||||||
/* Get array of Keys which have been removed from the invitations array and soft delete each invitation */
|
/* Get array of Keys which have been removed from the invitations array and soft delete each invitation */
|
||||||
collect($invoice->invitations->pluck('key'))->diff($invitations->pluck('key'))->each(function ($invitation) {
|
$invoice->invitations->pluck('key')->diff($invitations->pluck('key'))->each(function ($invitation) {
|
||||||
InvoiceInvitation::whereRaw("BINARY `key`= ?", [$invitation])->delete();
|
|
||||||
|
$invite = $this->getInvitationByKey($invitation);
|
||||||
|
|
||||||
|
if($invite)
|
||||||
|
$invite->forceDelete();
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
foreach ($data['invitations'] as $invitation) {
|
foreach ($data['invitations'] as $invitation) {
|
||||||
$inv = false;
|
$inv = false;
|
||||||
|
|
||||||
if (array_key_exists('key', $invitation)) {
|
if (array_key_exists('key', $invitation)) {
|
||||||
// $inv = InvoiceInvitation::whereKey($invitation['key'])->first();
|
$inv = $this->getInvitationByKey($invitation['key']);
|
||||||
$inv = InvoiceInvitation::whereRaw("BINARY `key`= ?", [$invitation['key']])->first();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$inv) {
|
if (!$inv) {
|
||||||
|
@ -102,7 +102,7 @@ class QuoteRepository extends BaseRepository
|
|||||||
return $quote->fresh();
|
return $quote->fresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getInvitationByKey($key) :QuoteInvitation
|
public function getInvitationByKey($key) :?QuoteInvitation
|
||||||
{
|
{
|
||||||
return QuoteInvitation::whereRaw("BINARY `key`= ?", [$key])->first();
|
return QuoteInvitation::whereRaw("BINARY `key`= ?", [$key])->first();
|
||||||
}
|
}
|
||||||
|
42
app/Services/Notification/NotificationService.php
Normal file
42
app/Services/Notification/NotificationService.php
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Services\Notification;
|
||||||
|
|
||||||
|
use App\Models\Company;
|
||||||
|
use App\Services\AbstractService;
|
||||||
|
use Illuminate\Notifications\Notification as Notifiable;
|
||||||
|
use Illuminate\Support\Facades\Notification;
|
||||||
|
|
||||||
|
class NotificationService extends AbstractService
|
||||||
|
{
|
||||||
|
|
||||||
|
public $company;
|
||||||
|
|
||||||
|
public $notification;
|
||||||
|
|
||||||
|
public function __construct(Company $company, Notifiable $notification)
|
||||||
|
{
|
||||||
|
|
||||||
|
$this->company = $company;
|
||||||
|
|
||||||
|
$this->notification = $notification;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
|
||||||
|
$this->company->owner()->notify($this->notification);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -21,7 +21,7 @@ class InvoiceTransformer extends EntityTransformer
|
|||||||
use MakesHash;
|
use MakesHash;
|
||||||
|
|
||||||
protected $defaultIncludes = [
|
protected $defaultIncludes = [
|
||||||
// 'invoice_items',
|
'invitations'
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $availableIncludes = [
|
protected $availableIncludes = [
|
||||||
@ -88,6 +88,7 @@ class InvoiceTransformer extends EntityTransformer
|
|||||||
'amount' => (float) $invoice->amount,
|
'amount' => (float) $invoice->amount,
|
||||||
'balance' => (float) $invoice->balance,
|
'balance' => (float) $invoice->balance,
|
||||||
'client_id' => (string) $this->encodePrimaryKey($invoice->client_id),
|
'client_id' => (string) $this->encodePrimaryKey($invoice->client_id),
|
||||||
|
'vendor_id' => (string) $this->encodePrimaryKey($invoice->vendor_id),
|
||||||
'status_id' => (string) ($invoice->status_id ?: 1),
|
'status_id' => (string) ($invoice->status_id ?: 1),
|
||||||
'design_id' => (string) ($invoice->design_id ?: 1),
|
'design_id' => (string) ($invoice->design_id ?: 1),
|
||||||
'updated_at' => (int)$invoice->updated_at,
|
'updated_at' => (int)$invoice->updated_at,
|
||||||
|
@ -179,6 +179,7 @@ return [
|
|||||||
App\Providers\RouteServiceProvider::class,
|
App\Providers\RouteServiceProvider::class,
|
||||||
App\Providers\ComposerServiceProvider::class,
|
App\Providers\ComposerServiceProvider::class,
|
||||||
Codedge\Updater\UpdaterServiceProvider::class,
|
Codedge\Updater\UpdaterServiceProvider::class,
|
||||||
|
App\Providers\MultiDBProvider::class,
|
||||||
|
|
||||||
],
|
],
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ return [
|
|||||||
'date_time_format' => 'Y-m-d H:i',
|
'date_time_format' => 'Y-m-d H:i',
|
||||||
'daily_email_limit' => 300,
|
'daily_email_limit' => 300,
|
||||||
'error_email' => env('ERROR_EMAIL', ''),
|
'error_email' => env('ERROR_EMAIL', ''),
|
||||||
|
'company_id' => 0,
|
||||||
|
|
||||||
'environment' => env('NINJA_ENVIRONMENT', 'selfhost'), // 'hosted', 'development', 'selfhost', 'reseller'
|
'environment' => env('NINJA_ENVIRONMENT', 'selfhost'), // 'hosted', 'development', 'selfhost', 'reseller'
|
||||||
|
|
||||||
|
@ -9,8 +9,8 @@ $factory->define(App\Models\Client::class, function (Faker $faker) {
|
|||||||
'name' => $faker->name(),
|
'name' => $faker->name(),
|
||||||
'website' => $faker->url,
|
'website' => $faker->url,
|
||||||
'private_notes' => $faker->text(200),
|
'private_notes' => $faker->text(200),
|
||||||
'balance' => $faker->numberBetween(0,1000),
|
'balance' => 0,
|
||||||
'paid_to_date' => $faker->numberBetween(0,10000),
|
'paid_to_date' => 0,
|
||||||
'vat_number' => $faker->text(25),
|
'vat_number' => $faker->text(25),
|
||||||
'id_number' => $faker->text(20),
|
'id_number' => $faker->text(20),
|
||||||
'custom_value1' => $faker->text(20),
|
'custom_value1' => $faker->text(20),
|
||||||
|
@ -67,6 +67,7 @@ class CreateUsersTable extends Migration
|
|||||||
$table->string('decimal_separator');
|
$table->string('decimal_separator');
|
||||||
$table->string('code');
|
$table->string('code');
|
||||||
$table->boolean('swap_currency_symbol')->default(false);
|
$table->boolean('swap_currency_symbol')->default(false);
|
||||||
|
$table->decimal('exchange_rate', 6, 6);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -261,6 +262,7 @@ class CreateUsersTable extends Migration
|
|||||||
$table->unsignedInteger('avatar_width')->nullable();
|
$table->unsignedInteger('avatar_width')->nullable();
|
||||||
$table->unsignedInteger('avatar_height')->nullable();
|
$table->unsignedInteger('avatar_height')->nullable();
|
||||||
$table->unsignedInteger('avatar_size')->nullable();
|
$table->unsignedInteger('avatar_size')->nullable();
|
||||||
|
|
||||||
$table->datetime('last_login')->nullable();
|
$table->datetime('last_login')->nullable();
|
||||||
$table->mediumText('signature')->nullable();
|
$table->mediumText('signature')->nullable();
|
||||||
$table->string('password');
|
$table->string('password');
|
||||||
|
@ -3113,6 +3113,19 @@ $LANG = array(
|
|||||||
'next_send_date' => 'Next send date',
|
'next_send_date' => 'Next send date',
|
||||||
'cycles_remaining' => 'Cycles remaining',
|
'cycles_remaining' => 'Cycles remaining',
|
||||||
'i_understand_delete' => 'I understand, delete',
|
'i_understand_delete' => 'I understand, delete',
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
'download_files' => 'Download Files',
|
||||||
|
'download_timeframe' => 'Use this link to download your files, the link will expire in 1 hour.',
|
||||||
|
'new_signup' => 'New Signup',
|
||||||
|
'new_signup_text' => 'A new account has been created by :user - :email - from IP address: :ip'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return $LANG;
|
return $LANG;
|
||||||
|
@ -1,20 +1,25 @@
|
|||||||
@component('mail::layout')
|
@component('email.components.layout')
|
||||||
|
|
||||||
{{-- Header --}}
|
|
||||||
@slot('header')
|
@slot('header')
|
||||||
@component('mail::header', ['url' => config('app.url')])
|
@component('email.components.header', ['p' => ''])
|
||||||
Download
|
<img src="{{ $logo }}" alt="Company Logo" style="display: block">
|
||||||
@endcomponent
|
@endcomponent
|
||||||
@endslot
|
@endslot
|
||||||
|
|
||||||
{{-- Body --}}
|
@lang('texts.download_timeframe')
|
||||||
{{ $file_path }}
|
|
||||||
|
@component('email.components.button', ['url' => $url])
|
||||||
|
@lang('texts.download')
|
||||||
|
@endcomponent
|
||||||
|
|
||||||
|
@slot('signature')
|
||||||
|
InvoiceNinja
|
||||||
|
@endslot
|
||||||
|
|
||||||
{{-- Footer --}}
|
|
||||||
@slot('footer')
|
@slot('footer')
|
||||||
@component('mail::footer')
|
@component('email.components.footer', ['url' => 'https://invoiceninja.com', 'url_text' => '© InvoiceNinja'])
|
||||||
© {{ date('Y') }} {{ config('ninja.app_name') }}.
|
For any info, please visit InvoiceNinja.
|
||||||
@endcomponent
|
@endcomponent
|
||||||
@endslot
|
@endslot
|
||||||
|
|
||||||
@endcomponent
|
@endcomponent
|
25
resources/views/email/admin/generic.blade.php
Normal file
25
resources/views/email/admin/generic.blade.php
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
@component('email.components.layout')
|
||||||
|
|
||||||
|
@slot('header')
|
||||||
|
@component('email.components.header', ['p' => ''])
|
||||||
|
@lang($title)
|
||||||
|
@endcomponent
|
||||||
|
@endslot
|
||||||
|
|
||||||
|
@lang($message)
|
||||||
|
|
||||||
|
@component('email.components.button', ['url' => $url])
|
||||||
|
@lang($button)
|
||||||
|
@endcomponent
|
||||||
|
|
||||||
|
@slot('signature')
|
||||||
|
{{ $signature }}
|
||||||
|
@endslot
|
||||||
|
|
||||||
|
@slot('footer')
|
||||||
|
@component('email.components.footer', ['url' => 'https://invoiceninja.com', 'url_text' => '© InvoiceNinja'])
|
||||||
|
For any info, please visit InvoiceNinja.
|
||||||
|
@endcomponent
|
||||||
|
@endslot
|
||||||
|
|
||||||
|
@endcomponent
|
@ -1,4 +1,8 @@
|
|||||||
|
@if()
|
||||||
|
@component('email.components.layout-dark')
|
||||||
|
@else
|
||||||
@component('email.components.layout')
|
@component('email.components.layout')
|
||||||
|
@endif
|
||||||
|
|
||||||
@slot('header')
|
@slot('header')
|
||||||
@component('email.components.header', ['p' => 'Your upgrade has completed!'])
|
@component('email.components.header', ['p' => 'Your upgrade has completed!'])
|
||||||
|
150
tests/Integration/CompanyLedgerTest.php
Normal file
150
tests/Integration/CompanyLedgerTest.php
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\Integration;
|
||||||
|
|
||||||
|
use App\DataMapper\CompanySettings;
|
||||||
|
use App\Events\Invoice\InvoiceWasCreated;
|
||||||
|
use App\Events\Invoice\InvoiceWasUpdated;
|
||||||
|
use App\Events\Payment\PaymentWasCreated;
|
||||||
|
use App\Factory\CompanyUserFactory;
|
||||||
|
use App\Jobs\Invoice\MarkInvoicePaid;
|
||||||
|
use App\Models\Account;
|
||||||
|
use App\Models\Activity;
|
||||||
|
use App\Models\Company;
|
||||||
|
use App\Models\CompanyLedger;
|
||||||
|
use App\Models\CompanyToken;
|
||||||
|
use App\Models\Invoice;
|
||||||
|
use App\Models\Payment;
|
||||||
|
use App\Models\User;
|
||||||
|
use App\Utils\Traits\MakesHash;
|
||||||
|
use Illuminate\Foundation\Testing\Concerns\InteractsWithDatabase;
|
||||||
|
use Illuminate\Foundation\Testing\DatabaseMigrations;
|
||||||
|
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||||
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
use Illuminate\Support\Facades\Hash;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Tests\MockAccountData;
|
||||||
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
/** @test*/
|
||||||
|
|
||||||
|
class CompanyLedgerTest extends TestCase
|
||||||
|
{
|
||||||
|
use DatabaseTransactions;
|
||||||
|
use MakesHash;
|
||||||
|
|
||||||
|
public $company;
|
||||||
|
|
||||||
|
public $client;
|
||||||
|
|
||||||
|
public $user;
|
||||||
|
|
||||||
|
public $token;
|
||||||
|
|
||||||
|
public $account;
|
||||||
|
|
||||||
|
public function setUp() :void
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
/* Warm up the cache !*/
|
||||||
|
$cached_tables = config('ninja.cached_tables');
|
||||||
|
|
||||||
|
foreach ($cached_tables as $name => $class) {
|
||||||
|
|
||||||
|
// check that the table exists in case the migration is pending
|
||||||
|
if (! Schema::hasTable((new $class())->getTable())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ($name == 'payment_terms') {
|
||||||
|
$orderBy = 'num_days';
|
||||||
|
} elseif ($name == 'fonts') {
|
||||||
|
$orderBy = 'sort_order';
|
||||||
|
} elseif (in_array($name, ['currencies', 'industries', 'languages', 'countries', 'banks'])) {
|
||||||
|
$orderBy = 'name';
|
||||||
|
} else {
|
||||||
|
$orderBy = 'id';
|
||||||
|
}
|
||||||
|
$tableData = $class::orderBy($orderBy)->get();
|
||||||
|
if ($tableData->count()) {
|
||||||
|
Cache::forever($name, $tableData);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->account = factory(\App\Models\Account::class)->create();
|
||||||
|
$this->company = factory(\App\Models\Company::class)->create([
|
||||||
|
'account_id' => $this->account->id,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$settings = CompanySettings::defaults();
|
||||||
|
|
||||||
|
$settings->company_logo = 'https://www.invoiceninja.com/wp-content/uploads/2019/01/InvoiceNinja-Logo-Round-300x300.png';
|
||||||
|
$settings->website = 'www.invoiceninja.com';
|
||||||
|
$settings->address1 = 'Address 1';
|
||||||
|
$settings->address2 = 'Address 2';
|
||||||
|
$settings->city = 'City';
|
||||||
|
$settings->state = 'State';
|
||||||
|
$settings->postal_code = 'Postal Code';
|
||||||
|
$settings->phone = '555-343-2323';
|
||||||
|
$settings->email = 'user@example.com';
|
||||||
|
$settings->country_id = '840';
|
||||||
|
$settings->vat_number = 'vat number';
|
||||||
|
$settings->id_number = 'id number';
|
||||||
|
|
||||||
|
$this->company->settings = $settings;
|
||||||
|
$this->company->save();
|
||||||
|
|
||||||
|
$this->account->default_company_id = $this->company->id;
|
||||||
|
$this->account->save();
|
||||||
|
|
||||||
|
$this->user = User::whereEmail('user@example.com')->first();
|
||||||
|
|
||||||
|
if(!$this->user){
|
||||||
|
$this->user = factory(\App\Models\User::class)->create([
|
||||||
|
'password' => Hash::make('ALongAndBriliantPassword'),
|
||||||
|
'confirmation_code' => $this->createDbHash(config('database.default'))
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$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);
|
||||||
|
|
||||||
|
$company_token = CompanyToken::create([
|
||||||
|
'user_id' => $this->user->id,
|
||||||
|
'company_id' => $this->company->id,
|
||||||
|
'account_id' => $this->account->id,
|
||||||
|
'name' => 'test token',
|
||||||
|
'token' => $this->token,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->client = factory(\App\Models\Client::class)->create([
|
||||||
|
'user_id' => $this->user->id,
|
||||||
|
'company_id' => $this->company->id,
|
||||||
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
factory(\App\Models\ClientContact::class,1)->create([
|
||||||
|
'user_id' => $this->user->id,
|
||||||
|
'client_id' => $this->client->id,
|
||||||
|
'company_id' => $this->company->id,
|
||||||
|
'is_primary' => 1,
|
||||||
|
'send_email' => true,
|
||||||
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testBaseLine()
|
||||||
|
{
|
||||||
|
|
||||||
|
$this->assertEquals($this->company->invoices->count(), 0);
|
||||||
|
$this->assertEquals($this->company->clients->count(), 1);
|
||||||
|
$this->assertEquals($this->client->balance, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -10,7 +10,9 @@ use App\Jobs\Util\StartMigration;
|
|||||||
use App\Mail\MigrationFailed;
|
use App\Mail\MigrationFailed;
|
||||||
use App\Models\Client;
|
use App\Models\Client;
|
||||||
use App\Models\ClientContact;
|
use App\Models\ClientContact;
|
||||||
|
use App\Models\ClientGatewayToken;
|
||||||
use App\Models\Company;
|
use App\Models\Company;
|
||||||
|
use App\Models\CompanyGateway;
|
||||||
use App\Models\Credit;
|
use App\Models\Credit;
|
||||||
use App\Models\Document;
|
use App\Models\Document;
|
||||||
use App\Models\Invoice;
|
use App\Models\Invoice;
|
||||||
@ -329,10 +331,9 @@ class ImportTest extends TestCase
|
|||||||
$this->invoice->forceDelete();
|
$this->invoice->forceDelete();
|
||||||
$this->quote->forceDelete();
|
$this->quote->forceDelete();
|
||||||
|
|
||||||
// $migration_file = base_path() . '/tests/Unit/Migration/migration.json';
|
// $migration_file = base_path() . '/tests/Unit/Migration/migration.json';
|
||||||
|
|
||||||
// $this->migration_array = json_decode(file_get_contents($migration_file), 1);
|
|
||||||
|
|
||||||
|
// $this->migration_array = json_decode(file_get_contents($migration_file), 1);
|
||||||
|
|
||||||
Import::dispatchNow($this->migration_array, $this->company, $this->user);
|
Import::dispatchNow($this->migration_array, $this->company, $this->user);
|
||||||
|
|
||||||
@ -407,7 +408,7 @@ class ImportTest extends TestCase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*foreach ($this->migration_array['credits'] as $key => $credit) {
|
foreach ($this->migration_array['credits'] as $key => $credit) {
|
||||||
|
|
||||||
// The Import::processCredits() does insert the credit record with number: 0053,
|
// The Import::processCredits() does insert the credit record with number: 0053,
|
||||||
// .. however this part of the code doesn't see it at all.
|
// .. however this part of the code doesn't see it at all.
|
||||||
@ -418,7 +419,36 @@ class ImportTest extends TestCase
|
|||||||
if (!$record) {
|
if (!$record) {
|
||||||
$differences['credits']['missing'][] = $credit['id'];
|
$differences['credits']['missing'][] = $credit['id'];
|
||||||
}
|
}
|
||||||
}*/
|
}
|
||||||
|
|
||||||
|
|
||||||
|
foreach ($this->migration_array['company_gateways'] as $key => $company_gateway) {
|
||||||
|
|
||||||
|
// The Import::processCredits() does insert the credit record with number: 0053,
|
||||||
|
// .. however this part of the code doesn't see it at all.
|
||||||
|
|
||||||
|
$record = CompanyGateway::where('gateway_key' ,$company_gateway['gateway_key'])
|
||||||
|
->first();
|
||||||
|
|
||||||
|
if (!$record) {
|
||||||
|
$differences['company_gateways']['missing'][] = $company_gateway['id'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($this->migration_array['client_gateway_tokens'] as $key => $cgt) {
|
||||||
|
|
||||||
|
// The Import::processCredits() does insert the credit record with number: 0053,
|
||||||
|
// .. however this part of the code doesn't see it at all.
|
||||||
|
|
||||||
|
$record = ClientGatewayToken::where('token' ,$cgt['token'])
|
||||||
|
->first();
|
||||||
|
|
||||||
|
if (!$record) {
|
||||||
|
$differences['client_gateway_tokens']['missing'][] = $cgt['id'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//@TODO we can uncomment tests for documents when we have imported expenses.
|
||||||
|
|
||||||
// foreach ($this->migration_array['documents'] as $key => $document) {
|
// foreach ($this->migration_array['documents'] as $key => $document) {
|
||||||
|
|
||||||
@ -433,7 +463,8 @@ class ImportTest extends TestCase
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
\Log::error($differences);
|
//\Log::error($differences);
|
||||||
|
|
||||||
$this->assertCount(0, $differences);
|
$this->assertCount(0, $differences);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -453,6 +484,18 @@ class ImportTest extends TestCase
|
|||||||
$this->assertGreaterThan($original, ClientContact::count());
|
$this->assertGreaterThan($original, ClientContact::count());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testClientGatewayTokensImport()
|
||||||
|
{
|
||||||
|
$this->invoice->forceDelete();
|
||||||
|
$this->quote->forceDelete();
|
||||||
|
|
||||||
|
$original = ClientGatewayToken::count();
|
||||||
|
|
||||||
|
Import::dispatchNow($this->migration_array, $this->company, $this->user);
|
||||||
|
|
||||||
|
$this->assertGreaterThan($original, ClientGatewayToken::count());
|
||||||
|
}
|
||||||
|
|
||||||
public function testDocumentsImport()
|
public function testDocumentsImport()
|
||||||
{
|
{
|
||||||
$this->invoice->forceDelete();
|
$this->invoice->forceDelete();
|
||||||
@ -462,11 +505,11 @@ class ImportTest extends TestCase
|
|||||||
|
|
||||||
Import::dispatchNow($this->migration_array, $this->company, $this->user);
|
Import::dispatchNow($this->migration_array, $this->company, $this->user);
|
||||||
|
|
||||||
$this->assertGreaterThan($original, Document::count());
|
// $this->assertGreaterThan($original, Document::count());
|
||||||
|
|
||||||
$document = Document::first();
|
$document = Document::first();
|
||||||
|
|
||||||
$this->assertNotNull(Invoice::find($document->documentable_id)->documents);
|
// $this->assertNotNull(Invoice::find($document->documentable_id)->documents);
|
||||||
$this->assertNotNull($document->documentable);
|
// $this->assertNotNull($document->documentable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
"invoice_text1": "Service Date"
|
"invoice_text1": "Service Date"
|
||||||
},
|
},
|
||||||
"created_at": "2020-02-11",
|
"created_at": "2020-02-11",
|
||||||
"updated_at": "2020-02-21",
|
"updated_at": "2020-02-22",
|
||||||
"settings": {
|
"settings": {
|
||||||
"timezone_id": "15",
|
"timezone_id": "15",
|
||||||
"date_format_id": "1",
|
"date_format_id": "1",
|
||||||
@ -114,7 +114,7 @@
|
|||||||
"google_2fa_secret": null,
|
"google_2fa_secret": null,
|
||||||
"accepted_terms_version": "1.0.1",
|
"accepted_terms_version": "1.0.1",
|
||||||
"password": "$2y$10$pDVj9LrItbYsvEenqOQe7.fSgdiIYzoLF86YnVtVVMLJzaBDI4iHC",
|
"password": "$2y$10$pDVj9LrItbYsvEenqOQe7.fSgdiIYzoLF86YnVtVVMLJzaBDI4iHC",
|
||||||
"remember_token": "dhZnqoBgFsxcBn2tesbAfgQ9US4TkxCsHaF8HjqN0IQuoAZ7Ptfiw3jNZY4U",
|
"remember_token": "nMizwyeTun32YxDB1NPpdiWzb0kMeAgDBlvJCFAgUwOA8yo8qwiEGpG1xwUS",
|
||||||
"created_at": "2020-02-11",
|
"created_at": "2020-02-11",
|
||||||
"updated_at": "2020-02-11",
|
"updated_at": "2020-02-11",
|
||||||
"deleted_at": null
|
"deleted_at": null
|
||||||
@ -17126,134 +17126,6 @@
|
|||||||
"deleted_at": null
|
"deleted_at": null
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"documents": [
|
|
||||||
{
|
|
||||||
"id": 1,
|
|
||||||
"user_id": 1,
|
|
||||||
"company_id": 1,
|
|
||||||
"invoice_id": 28,
|
|
||||||
"expense_id": null,
|
|
||||||
"path": "zuom5k2exmedyhztpgnkmwhwkzzxpbtk\/f8e8b45317131b60cd3177c13a5761ab278da43d.pdf",
|
|
||||||
"preview": "",
|
|
||||||
"name": "0019.pdf",
|
|
||||||
"type": "pdf",
|
|
||||||
"disk": "documents",
|
|
||||||
"hash": "f8e8b45317131b60cd3177c13a5761ab278da43d",
|
|
||||||
"size": 51397,
|
|
||||||
"width": null,
|
|
||||||
"height": null,
|
|
||||||
"created_at": "2020-02-18",
|
|
||||||
"updated_at": "2020-02-18"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 2,
|
|
||||||
"user_id": 1,
|
|
||||||
"company_id": 1,
|
|
||||||
"invoice_id": null,
|
|
||||||
"expense_id": null,
|
|
||||||
"path": "zuom5k2exmedyhztpgnkmwhwkzzxpbtk\/ddbba2265fe3e3d5ed1ce72bcc3e67e6dc6d9a2e.pdf",
|
|
||||||
"preview": "",
|
|
||||||
"name": "0001.pdf",
|
|
||||||
"type": "pdf",
|
|
||||||
"disk": "documents",
|
|
||||||
"hash": "ddbba2265fe3e3d5ed1ce72bcc3e67e6dc6d9a2e",
|
|
||||||
"size": 49393,
|
|
||||||
"width": null,
|
|
||||||
"height": null,
|
|
||||||
"created_at": "2020-02-18",
|
|
||||||
"updated_at": "2020-02-18"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 3,
|
|
||||||
"user_id": 1,
|
|
||||||
"company_id": 1,
|
|
||||||
"invoice_id": null,
|
|
||||||
"expense_id": 60,
|
|
||||||
"path": "zuom5k2exmedyhztpgnkmwhwkzzxpbtk\/858c794d4988ebcce27e01adb1cd8b2ba98d5668.pdf",
|
|
||||||
"preview": "",
|
|
||||||
"name": "0001.pdf",
|
|
||||||
"type": "pdf",
|
|
||||||
"disk": "documents",
|
|
||||||
"hash": "858c794d4988ebcce27e01adb1cd8b2ba98d5668",
|
|
||||||
"size": 51250,
|
|
||||||
"width": null,
|
|
||||||
"height": null,
|
|
||||||
"created_at": "2020-02-18",
|
|
||||||
"updated_at": "2020-02-18"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 4,
|
|
||||||
"user_id": 1,
|
|
||||||
"company_id": 1,
|
|
||||||
"invoice_id": 28,
|
|
||||||
"expense_id": null,
|
|
||||||
"path": "zuom5k2exmedyhztpgnkmwhwkzzxpbtk\/ed80d3d94084cefa54d41d3989fb99a757747276.pdf",
|
|
||||||
"preview": "",
|
|
||||||
"name": "Invoice_0028 (11).pdf",
|
|
||||||
"type": "pdf",
|
|
||||||
"disk": "documents",
|
|
||||||
"hash": "ed80d3d94084cefa54d41d3989fb99a757747276",
|
|
||||||
"size": 74468,
|
|
||||||
"width": null,
|
|
||||||
"height": null,
|
|
||||||
"created_at": "2020-02-21",
|
|
||||||
"updated_at": "2020-02-21"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 5,
|
|
||||||
"user_id": 1,
|
|
||||||
"company_id": 1,
|
|
||||||
"invoice_id": null,
|
|
||||||
"expense_id": 51,
|
|
||||||
"path": "zuom5k2exmedyhztpgnkmwhwkzzxpbtk\/c81cf7f4bae0c1e32b87835a39d056110a0d63ec.pdf",
|
|
||||||
"preview": "",
|
|
||||||
"name": "Invoice_0028 (8).pdf",
|
|
||||||
"type": "pdf",
|
|
||||||
"disk": "documents",
|
|
||||||
"hash": "c81cf7f4bae0c1e32b87835a39d056110a0d63ec",
|
|
||||||
"size": 28390,
|
|
||||||
"width": null,
|
|
||||||
"height": null,
|
|
||||||
"created_at": "2020-02-21",
|
|
||||||
"updated_at": "2020-02-21"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 6,
|
|
||||||
"user_id": 1,
|
|
||||||
"company_id": 1,
|
|
||||||
"invoice_id": null,
|
|
||||||
"expense_id": 51,
|
|
||||||
"path": "zuom5k2exmedyhztpgnkmwhwkzzxpbtk\/7ce4feb538a975856e29c47709698b5b792ec3b4.pdf",
|
|
||||||
"preview": "",
|
|
||||||
"name": "Invoice_0028 (6).pdf",
|
|
||||||
"type": "pdf",
|
|
||||||
"disk": "documents",
|
|
||||||
"hash": "7ce4feb538a975856e29c47709698b5b792ec3b4",
|
|
||||||
"size": 29613,
|
|
||||||
"width": null,
|
|
||||||
"height": null,
|
|
||||||
"created_at": "2020-02-21",
|
|
||||||
"updated_at": "2020-02-21"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 7,
|
|
||||||
"user_id": 1,
|
|
||||||
"company_id": 1,
|
|
||||||
"invoice_id": null,
|
|
||||||
"expense_id": 51,
|
|
||||||
"path": "zuom5k2exmedyhztpgnkmwhwkzzxpbtk\/1bbf0c9bd9024ceb83064daeeab9386d68097410.pdf",
|
|
||||||
"preview": "",
|
|
||||||
"name": "Invoice_0028 (5).pdf",
|
|
||||||
"type": "pdf",
|
|
||||||
"disk": "documents",
|
|
||||||
"hash": "1bbf0c9bd9024ceb83064daeeab9386d68097410",
|
|
||||||
"size": 28268,
|
|
||||||
"width": null,
|
|
||||||
"height": null,
|
|
||||||
"created_at": "2020-02-21",
|
|
||||||
"updated_at": "2020-02-21"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"company_gateways": [
|
"company_gateways": [
|
||||||
{
|
{
|
||||||
"id": 3,
|
"id": 3,
|
||||||
@ -17264,19 +17136,33 @@
|
|||||||
"show_billing_address": null,
|
"show_billing_address": null,
|
||||||
"show_shipping_address": 1,
|
"show_shipping_address": 1,
|
||||||
"update_details": null,
|
"update_details": null,
|
||||||
"config": "{\"apiKey\":\"sk_test_faU9gVB7Hx19fCTo0e5ggZ0x\",\"publishableKey\":\"pk_test_iRPDj3jLiQs0Guae0lvSHaOD\",\"plaidClientId\":\"\",\"plaidSecret\":\"\",\"plaidPublicKey\":\"\",\"enableAlipay\":true,\"enableSofort\":true,\"enableSepa\":false,\"enableBitcoin\":false,\"enableApplePay\":true,\"enableAch\":true}",
|
"config": {
|
||||||
"fees_and_limits": {
|
"apiKey": "sk_test_faU9gVB7Hx19fCTo0e5ggZ0x",
|
||||||
"min_limit": 234,
|
"publishableKey": "pk_test_iRPDj3jLiQs0Guae0lvSHaOD",
|
||||||
"max_limit": 65317,
|
"plaidClientId": "",
|
||||||
"fee_amount": "0.00",
|
"plaidSecret": "",
|
||||||
"fee_percent": "0.000",
|
"plaidPublicKey": "",
|
||||||
"tax_name1": null,
|
"enableAlipay": true,
|
||||||
"tax_rate1": null,
|
"enableSofort": true,
|
||||||
"tax_name2": null,
|
"enableSepa": false,
|
||||||
"tax_rate2": null,
|
"enableBitcoin": false,
|
||||||
"tax_name3": "",
|
"enableApplePay": true,
|
||||||
"tax_rate3": 0
|
"enableAch": true
|
||||||
},
|
},
|
||||||
|
"fees_and_limits": [
|
||||||
|
{
|
||||||
|
"min_limit": 234,
|
||||||
|
"max_limit": 65317,
|
||||||
|
"fee_amount": "0.00",
|
||||||
|
"fee_percent": "0.000",
|
||||||
|
"tax_name1": null,
|
||||||
|
"tax_rate1": null,
|
||||||
|
"tax_name2": null,
|
||||||
|
"tax_rate2": null,
|
||||||
|
"tax_name3": "",
|
||||||
|
"tax_rate3": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
"custom_value1": "",
|
"custom_value1": "",
|
||||||
"custom_value2": "",
|
"custom_value2": "",
|
||||||
"custom_value3": "",
|
"custom_value3": "",
|
||||||
@ -17291,7 +17177,19 @@
|
|||||||
"show_billing_address": null,
|
"show_billing_address": null,
|
||||||
"show_shipping_address": 1,
|
"show_shipping_address": 1,
|
||||||
"update_details": null,
|
"update_details": null,
|
||||||
"config": "{\"apiKey\":\"sk_test_faU9gVB7Hx19fCTo0e5ggZ0x\",\"publishableKey\":\"pk_test_iRPDj3jLiQs0Guae0lvSHaOD\",\"plaidClientId\":\"\",\"plaidSecret\":\"\",\"plaidPublicKey\":\"\",\"enableAlipay\":true,\"enableSofort\":true,\"enableSepa\":false,\"enableBitcoin\":false,\"enableApplePay\":true,\"enableAch\":true}",
|
"config": {
|
||||||
|
"apiKey": "sk_test_faU9gVB7Hx19fCTo0e5ggZ0x",
|
||||||
|
"publishableKey": "pk_test_iRPDj3jLiQs0Guae0lvSHaOD",
|
||||||
|
"plaidClientId": "",
|
||||||
|
"plaidSecret": "",
|
||||||
|
"plaidPublicKey": "",
|
||||||
|
"enableAlipay": true,
|
||||||
|
"enableSofort": true,
|
||||||
|
"enableSepa": false,
|
||||||
|
"enableBitcoin": false,
|
||||||
|
"enableApplePay": true,
|
||||||
|
"enableAch": true
|
||||||
|
},
|
||||||
"fees_and_limits": {},
|
"fees_and_limits": {},
|
||||||
"custom_value1": "",
|
"custom_value1": "",
|
||||||
"custom_value2": "",
|
"custom_value2": "",
|
||||||
@ -17307,19 +17205,33 @@
|
|||||||
"show_billing_address": null,
|
"show_billing_address": null,
|
||||||
"show_shipping_address": 1,
|
"show_shipping_address": 1,
|
||||||
"update_details": null,
|
"update_details": null,
|
||||||
"config": "{\"apiKey\":\"sk_test_faU9gVB7Hx19fCTo0e5ggZ0x\",\"publishableKey\":\"pk_test_iRPDj3jLiQs0Guae0lvSHaOD\",\"plaidClientId\":\"\",\"plaidSecret\":\"\",\"plaidPublicKey\":\"\",\"enableAlipay\":true,\"enableSofort\":true,\"enableSepa\":false,\"enableBitcoin\":false,\"enableApplePay\":true,\"enableAch\":true}",
|
"config": {
|
||||||
"fees_and_limits": {
|
"apiKey": "sk_test_faU9gVB7Hx19fCTo0e5ggZ0x",
|
||||||
"min_limit": 147,
|
"publishableKey": "pk_test_iRPDj3jLiQs0Guae0lvSHaOD",
|
||||||
"max_limit": 53254,
|
"plaidClientId": "",
|
||||||
"fee_amount": "0.00",
|
"plaidSecret": "",
|
||||||
"fee_percent": "0.000",
|
"plaidPublicKey": "",
|
||||||
"tax_name1": null,
|
"enableAlipay": true,
|
||||||
"tax_rate1": null,
|
"enableSofort": true,
|
||||||
"tax_name2": null,
|
"enableSepa": false,
|
||||||
"tax_rate2": null,
|
"enableBitcoin": false,
|
||||||
"tax_name3": "",
|
"enableApplePay": true,
|
||||||
"tax_rate3": 0
|
"enableAch": true
|
||||||
},
|
},
|
||||||
|
"fees_and_limits": [
|
||||||
|
{
|
||||||
|
"min_limit": 147,
|
||||||
|
"max_limit": 53254,
|
||||||
|
"fee_amount": "0.00",
|
||||||
|
"fee_percent": "0.000",
|
||||||
|
"tax_name1": null,
|
||||||
|
"tax_rate1": null,
|
||||||
|
"tax_name2": null,
|
||||||
|
"tax_rate2": null,
|
||||||
|
"tax_name3": "",
|
||||||
|
"tax_rate3": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
"custom_value1": "",
|
"custom_value1": "",
|
||||||
"custom_value2": "",
|
"custom_value2": "",
|
||||||
"custom_value3": "",
|
"custom_value3": "",
|
||||||
@ -17334,19 +17246,33 @@
|
|||||||
"show_billing_address": null,
|
"show_billing_address": null,
|
||||||
"show_shipping_address": 1,
|
"show_shipping_address": 1,
|
||||||
"update_details": null,
|
"update_details": null,
|
||||||
"config": "{\"apiKey\":\"sk_test_faU9gVB7Hx19fCTo0e5ggZ0x\",\"publishableKey\":\"pk_test_iRPDj3jLiQs0Guae0lvSHaOD\",\"plaidClientId\":\"\",\"plaidSecret\":\"\",\"plaidPublicKey\":\"\",\"enableAlipay\":true,\"enableSofort\":true,\"enableSepa\":false,\"enableBitcoin\":false,\"enableApplePay\":true,\"enableAch\":true}",
|
"config": {
|
||||||
"fees_and_limits": {
|
"apiKey": "sk_test_faU9gVB7Hx19fCTo0e5ggZ0x",
|
||||||
"min_limit": 155,
|
"publishableKey": "pk_test_iRPDj3jLiQs0Guae0lvSHaOD",
|
||||||
"max_limit": 72857,
|
"plaidClientId": "",
|
||||||
"fee_amount": "0.00",
|
"plaidSecret": "",
|
||||||
"fee_percent": "0.000",
|
"plaidPublicKey": "",
|
||||||
"tax_name1": null,
|
"enableAlipay": true,
|
||||||
"tax_rate1": null,
|
"enableSofort": true,
|
||||||
"tax_name2": null,
|
"enableSepa": false,
|
||||||
"tax_rate2": null,
|
"enableBitcoin": false,
|
||||||
"tax_name3": "",
|
"enableApplePay": true,
|
||||||
"tax_rate3": 0
|
"enableAch": true
|
||||||
},
|
},
|
||||||
|
"fees_and_limits": [
|
||||||
|
{
|
||||||
|
"min_limit": 155,
|
||||||
|
"max_limit": 72857,
|
||||||
|
"fee_amount": "0.00",
|
||||||
|
"fee_percent": "0.000",
|
||||||
|
"tax_name1": null,
|
||||||
|
"tax_rate1": null,
|
||||||
|
"tax_name2": null,
|
||||||
|
"tax_rate2": null,
|
||||||
|
"tax_name3": "",
|
||||||
|
"tax_rate3": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
"custom_value1": "",
|
"custom_value1": "",
|
||||||
"custom_value2": "",
|
"custom_value2": "",
|
||||||
"custom_value3": "",
|
"custom_value3": "",
|
||||||
@ -17361,19 +17287,33 @@
|
|||||||
"show_billing_address": null,
|
"show_billing_address": null,
|
||||||
"show_shipping_address": 1,
|
"show_shipping_address": 1,
|
||||||
"update_details": null,
|
"update_details": null,
|
||||||
"config": "{\"apiKey\":\"sk_test_faU9gVB7Hx19fCTo0e5ggZ0x\",\"publishableKey\":\"pk_test_iRPDj3jLiQs0Guae0lvSHaOD\",\"plaidClientId\":\"\",\"plaidSecret\":\"\",\"plaidPublicKey\":\"\",\"enableAlipay\":true,\"enableSofort\":true,\"enableSepa\":false,\"enableBitcoin\":false,\"enableApplePay\":true,\"enableAch\":true}",
|
"config": {
|
||||||
"fees_and_limits": {
|
"apiKey": "sk_test_faU9gVB7Hx19fCTo0e5ggZ0x",
|
||||||
"min_limit": 139,
|
"publishableKey": "pk_test_iRPDj3jLiQs0Guae0lvSHaOD",
|
||||||
"max_limit": 71349,
|
"plaidClientId": "",
|
||||||
"fee_amount": "0.00",
|
"plaidSecret": "",
|
||||||
"fee_percent": "0.000",
|
"plaidPublicKey": "",
|
||||||
"tax_name1": null,
|
"enableAlipay": true,
|
||||||
"tax_rate1": null,
|
"enableSofort": true,
|
||||||
"tax_name2": null,
|
"enableSepa": false,
|
||||||
"tax_rate2": null,
|
"enableBitcoin": false,
|
||||||
"tax_name3": "",
|
"enableApplePay": true,
|
||||||
"tax_rate3": 0
|
"enableAch": true
|
||||||
},
|
},
|
||||||
|
"fees_and_limits": [
|
||||||
|
{
|
||||||
|
"min_limit": 139,
|
||||||
|
"max_limit": 71349,
|
||||||
|
"fee_amount": "0.00",
|
||||||
|
"fee_percent": "0.000",
|
||||||
|
"tax_name1": null,
|
||||||
|
"tax_rate1": null,
|
||||||
|
"tax_name2": null,
|
||||||
|
"tax_rate2": null,
|
||||||
|
"tax_name3": "",
|
||||||
|
"tax_rate3": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
"custom_value1": "",
|
"custom_value1": "",
|
||||||
"custom_value2": "",
|
"custom_value2": "",
|
||||||
"custom_value3": "",
|
"custom_value3": "",
|
||||||
@ -17388,19 +17328,33 @@
|
|||||||
"show_billing_address": null,
|
"show_billing_address": null,
|
||||||
"show_shipping_address": 1,
|
"show_shipping_address": 1,
|
||||||
"update_details": null,
|
"update_details": null,
|
||||||
"config": "{\"apiKey\":\"sk_test_faU9gVB7Hx19fCTo0e5ggZ0x\",\"publishableKey\":\"pk_test_iRPDj3jLiQs0Guae0lvSHaOD\",\"plaidClientId\":\"\",\"plaidSecret\":\"\",\"plaidPublicKey\":\"\",\"enableAlipay\":true,\"enableSofort\":true,\"enableSepa\":false,\"enableBitcoin\":false,\"enableApplePay\":true,\"enableAch\":true}",
|
"config": {
|
||||||
"fees_and_limits": {
|
"apiKey": "sk_test_faU9gVB7Hx19fCTo0e5ggZ0x",
|
||||||
"min_limit": 151,
|
"publishableKey": "pk_test_iRPDj3jLiQs0Guae0lvSHaOD",
|
||||||
"max_limit": 74365,
|
"plaidClientId": "",
|
||||||
"fee_amount": "0.00",
|
"plaidSecret": "",
|
||||||
"fee_percent": "0.000",
|
"plaidPublicKey": "",
|
||||||
"tax_name1": null,
|
"enableAlipay": true,
|
||||||
"tax_rate1": null,
|
"enableSofort": true,
|
||||||
"tax_name2": null,
|
"enableSepa": false,
|
||||||
"tax_rate2": null,
|
"enableBitcoin": false,
|
||||||
"tax_name3": "",
|
"enableApplePay": true,
|
||||||
"tax_rate3": 0
|
"enableAch": true
|
||||||
},
|
},
|
||||||
|
"fees_and_limits": [
|
||||||
|
{
|
||||||
|
"min_limit": 151,
|
||||||
|
"max_limit": 74365,
|
||||||
|
"fee_amount": "0.00",
|
||||||
|
"fee_percent": "0.000",
|
||||||
|
"tax_name1": null,
|
||||||
|
"tax_rate1": null,
|
||||||
|
"tax_name2": null,
|
||||||
|
"tax_rate2": null,
|
||||||
|
"tax_name3": "",
|
||||||
|
"tax_rate3": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
"custom_value1": "",
|
"custom_value1": "",
|
||||||
"custom_value2": "",
|
"custom_value2": "",
|
||||||
"custom_value3": "",
|
"custom_value3": "",
|
||||||
|
Loading…
Reference in New Issue
Block a user