mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
validator for ExpenseMailbox property
This commit is contained in:
parent
dd9727a701
commit
36279be694
@ -11,10 +11,17 @@
|
|||||||
|
|
||||||
namespace App\Helpers\Mail\Webhook;
|
namespace App\Helpers\Mail\Webhook;
|
||||||
|
|
||||||
|
use App\Models\Company;
|
||||||
|
|
||||||
interface BaseWebhookHandler
|
interface BaseWebhookHandler
|
||||||
{
|
{
|
||||||
public function process()
|
public function process()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function matchCompany(string $email)
|
||||||
|
{
|
||||||
|
return Company::where("expense_mailbox", $email)->first();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,12 +11,21 @@
|
|||||||
|
|
||||||
namespace App\Helpers\Mail\Webhook\Postmark;
|
namespace App\Helpers\Mail\Webhook\Postmark;
|
||||||
|
|
||||||
|
use App\Factory\ExpenseFactory;
|
||||||
use App\Helpers\Mail\Webhook\BaseWebhookHandler;
|
use App\Helpers\Mail\Webhook\BaseWebhookHandler;
|
||||||
|
|
||||||
interface PostmarkWebhookHandler extends BaseWebhookHandler
|
interface PostmarkWebhookHandler extends BaseWebhookHandler
|
||||||
{
|
{
|
||||||
public function process()
|
public function process($data)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
$email = '';
|
||||||
|
|
||||||
|
$company = $this->matchCompany($email);
|
||||||
|
if (!$company)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
$expense = ExpenseFactory::create($company->id, $company->owner()->id);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ namespace App\Http\Requests\Company;
|
|||||||
|
|
||||||
use App\Http\Requests\Request;
|
use App\Http\Requests\Request;
|
||||||
use App\Http\ValidationRules\Company\ValidCompanyQuantity;
|
use App\Http\ValidationRules\Company\ValidCompanyQuantity;
|
||||||
|
use App\Http\ValidationRules\Company\ValidExpenseMailbox;
|
||||||
use App\Http\ValidationRules\Company\ValidSubdomain;
|
use App\Http\ValidationRules\Company\ValidSubdomain;
|
||||||
use App\Http\ValidationRules\ValidSettingsRule;
|
use App\Http\ValidationRules\ValidSettingsRule;
|
||||||
use App\Models\Company;
|
use App\Models\Company;
|
||||||
@ -28,7 +29,7 @@ class StoreCompanyRequest extends Request
|
|||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function authorize() : bool
|
public function authorize(): bool
|
||||||
{
|
{
|
||||||
/** @var \App\Models\User auth()->user */
|
/** @var \App\Models\User auth()->user */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
@ -55,6 +56,8 @@ class StoreCompanyRequest extends Request
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$rules['expense_mailbox'] = new ValidExpenseMailbox($this->company->key, $this->company->account->isPaid() && $this->company->account->plan == 'enterprise'); // @turbo124 check if this is right
|
||||||
|
|
||||||
return $rules;
|
return $rules;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ namespace App\Http\Requests\Company;
|
|||||||
|
|
||||||
use App\DataMapper\CompanySettings;
|
use App\DataMapper\CompanySettings;
|
||||||
use App\Http\Requests\Request;
|
use App\Http\Requests\Request;
|
||||||
|
use App\Http\ValidationRules\Company\ValidExpenseMailbox;
|
||||||
use App\Http\ValidationRules\Company\ValidSubdomain;
|
use App\Http\ValidationRules\Company\ValidSubdomain;
|
||||||
use App\Http\ValidationRules\ValidSettingsRule;
|
use App\Http\ValidationRules\ValidSettingsRule;
|
||||||
use App\Utils\Ninja;
|
use App\Utils\Ninja;
|
||||||
@ -35,7 +36,7 @@ class UpdateCompanyRequest extends Request
|
|||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function authorize() : bool
|
public function authorize(): bool
|
||||||
{
|
{
|
||||||
/** @var \App\Models\User $user */
|
/** @var \App\Models\User $user */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
@ -67,6 +68,8 @@ class UpdateCompanyRequest extends Request
|
|||||||
$rules['subdomain'] = ['nullable', 'regex:/^[a-zA-Z0-9.-]+[a-zA-Z0-9]$/', new ValidSubdomain()];
|
$rules['subdomain'] = ['nullable', 'regex:/^[a-zA-Z0-9.-]+[a-zA-Z0-9]$/', new ValidSubdomain()];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$rules['expense_mailbox'] = new ValidExpenseMailbox($this->company->key, $this->company->account->isPaid() && $this->company->account->plan == 'enterprise'); // @turbo124 check if this is right
|
||||||
|
|
||||||
return $rules;
|
return $rules;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,14 +83,14 @@ class UpdateCompanyRequest extends Request
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (array_key_exists('settings', $input)) {
|
if (array_key_exists('settings', $input)) {
|
||||||
$input['settings'] = (array)$this->filterSaveableSettings($input['settings']);
|
$input['settings'] = (array) $this->filterSaveableSettings($input['settings']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(array_key_exists('subdomain', $input) && $this->company->subdomain == $input['subdomain']) {
|
if (array_key_exists('subdomain', $input) && $this->company->subdomain == $input['subdomain']) {
|
||||||
unset($input['subdomain']);
|
unset($input['subdomain']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(array_key_exists('e_invoice_certificate_passphrase', $input) && empty($input['e_invoice_certificate_passphrase'])) {
|
if (array_key_exists('e_invoice_certificate_passphrase', $input) && empty($input['e_invoice_certificate_passphrase'])) {
|
||||||
unset($input['e_invoice_certificate_passphrase']);
|
unset($input['e_invoice_certificate_passphrase']);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,17 +118,17 @@ class UpdateCompanyRequest extends Request
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isset($settings['email_style_custom'])) {
|
if (isset($settings['email_style_custom'])) {
|
||||||
$settings['email_style_custom'] = str_replace(['{{','}}'], ['',''], $settings['email_style_custom']);
|
$settings['email_style_custom'] = str_replace(['{{', '}}'], ['', ''], $settings['email_style_custom']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! $account->isFreeHostedClient()) {
|
if (!$account->isFreeHostedClient()) {
|
||||||
return $settings;
|
return $settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
$saveable_casts = CompanySettings::$free_plan_casts;
|
$saveable_casts = CompanySettings::$free_plan_casts;
|
||||||
|
|
||||||
foreach ($settings as $key => $value) {
|
foreach ($settings as $key => $value) {
|
||||||
if (! array_key_exists($key, $saveable_casts)) {
|
if (!array_key_exists($key, $saveable_casts)) {
|
||||||
unset($settings->{$key});
|
unset($settings->{$key});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -137,7 +140,7 @@ class UpdateCompanyRequest extends Request
|
|||||||
{
|
{
|
||||||
if (Ninja::isHosted()) {
|
if (Ninja::isHosted()) {
|
||||||
$url = str_replace('http://', '', $url);
|
$url = str_replace('http://', '', $url);
|
||||||
$url = parse_url($url, PHP_URL_SCHEME) === null ? $scheme.$url : $url;
|
$url = parse_url($url, PHP_URL_SCHEME) === null ? $scheme . $url : $url;
|
||||||
}
|
}
|
||||||
|
|
||||||
return rtrim($url, '/');
|
return rtrim($url, '/');
|
||||||
|
64
app/Http/ValidationRules/Company/ValidExpenseMailbox.php
Normal file
64
app/Http/ValidationRules/Company/ValidExpenseMailbox.php
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Http\ValidationRules\Company;
|
||||||
|
|
||||||
|
use App\Libraries\MultiDB;
|
||||||
|
use App\Utils\Ninja;
|
||||||
|
use Illuminate\Contracts\Validation\Rule;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class ValidCompanyQuantity.
|
||||||
|
*/
|
||||||
|
class ValidExpenseMailbox implements Rule
|
||||||
|
{
|
||||||
|
|
||||||
|
private $validated_schema = false;
|
||||||
|
private $company_key = false;
|
||||||
|
private $isEnterprise = false;
|
||||||
|
|
||||||
|
public function __construct(string $company_key, bool $isEnterprise = false)
|
||||||
|
{
|
||||||
|
$this->company_key = $company_key;
|
||||||
|
$this->isEnterprise = $isEnterprise;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function passes($attribute, $value)
|
||||||
|
{
|
||||||
|
if (empty($value)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// early return, if we dont have any additional validation
|
||||||
|
if (!config('ninja.inbound_expense.webhook.mailbox_schema') && !(Ninja::isHosted() && config('ninja.inbound_expense.webhook.mailbox_schema_enterprise'))) {
|
||||||
|
$this->validated_schema = true;
|
||||||
|
return MultiDB::checkExpenseMailboxAvailable($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate Schema
|
||||||
|
$validated = !config('ninja.inbound_expense.webhook.mailbox_schema') || (preg_match(config('ninja.inbound_expense.webhook.mailbox_schema'), $value) && (!config('ninja.inbound_expense.webhook.mailbox_schema_hascompanykey') || str_contains($value, $this->company_key))) ? true : false;
|
||||||
|
$validated_enterprise = !config('ninja.inbound_expense.webhook.mailbox_schema_enterprise') || (Ninja::isHosted() && $this->isEnterprise && preg_match(config('ninja.inbound_expense.webhook.mailbox_schema_enterprise'), $value));
|
||||||
|
|
||||||
|
if (!$validated && !$validated_enterprise)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
$this->validated_schema = true;
|
||||||
|
return MultiDB::checkExpenseMailboxAvailable($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function message()
|
||||||
|
{
|
||||||
|
return $this->validated_schema ? ctrans('texts.expense_mailbox_taken') : ctrans('texts.expense_mailbox_invalid');
|
||||||
|
}
|
||||||
|
}
|
@ -71,18 +71,20 @@ class MultiDB
|
|||||||
'socket',
|
'socket',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
private static $protected_expense_mailboxes = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public static function getDbs() : array
|
public static function getDbs(): array
|
||||||
{
|
{
|
||||||
return self::$dbs;
|
return self::$dbs;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function checkDomainAvailable($subdomain) : bool
|
public static function checkDomainAvailable($subdomain): bool
|
||||||
{
|
{
|
||||||
|
|
||||||
if (! config('ninja.db.multi_db_enabled')) {
|
if (!config('ninja.db.multi_db_enabled')) {
|
||||||
return Company::whereSubdomain($subdomain)->count() == 0;
|
return Company::whereSubdomain($subdomain)->count() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,9 +107,35 @@ class MultiDB
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function checkUserEmailExists($email) : bool
|
public static function checkExpenseMailboxAvailable($expense_mailbox): bool
|
||||||
{
|
{
|
||||||
if (! config('ninja.db.multi_db_enabled')) {
|
|
||||||
|
if (!config('ninja.db.multi_db_enabled')) {
|
||||||
|
return Company::where("expense_mailbox", $expense_mailbox)->withTrashed()->exists();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_array($expense_mailbox, self::$protected_expense_mailboxes)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$current_db = config('database.default');
|
||||||
|
|
||||||
|
foreach (self::$dbs as $db) {
|
||||||
|
if (Company::on($db)->where("expense_mailbox", $expense_mailbox)->withTrashed()->exists()) {
|
||||||
|
self::setDb($current_db);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self::setDb($current_db);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function checkUserEmailExists($email): bool
|
||||||
|
{
|
||||||
|
if (!config('ninja.db.multi_db_enabled')) {
|
||||||
return User::where(['email' => $email])->withTrashed()->exists();
|
return User::where(['email' => $email])->withTrashed()->exists();
|
||||||
} // true >= 1 emails found / false -> == emails found
|
} // true >= 1 emails found / false -> == emails found
|
||||||
|
|
||||||
@ -139,7 +167,7 @@ class MultiDB
|
|||||||
* @param string $company_key The company key
|
* @param string $company_key The company key
|
||||||
* @return bool True|False
|
* @return bool True|False
|
||||||
*/
|
*/
|
||||||
public static function checkUserAndCompanyCoExist($email, $company_key) :bool
|
public static function checkUserAndCompanyCoExist($email, $company_key): bool
|
||||||
{
|
{
|
||||||
$current_db = config('database.default');
|
$current_db = config('database.default');
|
||||||
|
|
||||||
@ -166,9 +194,9 @@ class MultiDB
|
|||||||
* @param array $data
|
* @param array $data
|
||||||
* @return User|null
|
* @return User|null
|
||||||
*/
|
*/
|
||||||
public static function hasUser(array $data) : ?User
|
public static function hasUser(array $data): ?User
|
||||||
{
|
{
|
||||||
if (! config('ninja.db.multi_db_enabled')) {
|
if (!config('ninja.db.multi_db_enabled')) {
|
||||||
return User::where($data)->withTrashed()->first();
|
return User::where($data)->withTrashed()->first();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,9 +218,9 @@ class MultiDB
|
|||||||
* @param string $email
|
* @param string $email
|
||||||
* @return ClientContact|null
|
* @return ClientContact|null
|
||||||
*/
|
*/
|
||||||
public static function hasContact(string $email) : ?ClientContact
|
public static function hasContact(string $email): ?ClientContact
|
||||||
{
|
{
|
||||||
if (! config('ninja.db.multi_db_enabled')) {
|
if (!config('ninja.db.multi_db_enabled')) {
|
||||||
return ClientContact::where('email', $email)->withTrashed()->first();
|
return ClientContact::where('email', $email)->withTrashed()->first();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,9 +245,9 @@ class MultiDB
|
|||||||
* @param array $search
|
* @param array $search
|
||||||
* @return ClientContact|null
|
* @return ClientContact|null
|
||||||
*/
|
*/
|
||||||
public static function findContact(array $search) : ?ClientContact
|
public static function findContact(array $search): ?ClientContact
|
||||||
{
|
{
|
||||||
if (! config('ninja.db.multi_db_enabled')) {
|
if (!config('ninja.db.multi_db_enabled')) {
|
||||||
return ClientContact::where($search)->first();
|
return ClientContact::where($search)->first();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,7 +268,7 @@ class MultiDB
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function contactFindAndSetDb($token) :bool
|
public static function contactFindAndSetDb($token): bool
|
||||||
{
|
{
|
||||||
$current_db = config('database.default');
|
$current_db = config('database.default');
|
||||||
|
|
||||||
@ -257,7 +285,7 @@ class MultiDB
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function userFindAndSetDb($email) : bool
|
public static function userFindAndSetDb($email): bool
|
||||||
{
|
{
|
||||||
$current_db = config('database.default');
|
$current_db = config('database.default');
|
||||||
|
|
||||||
@ -275,7 +303,7 @@ class MultiDB
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function documentFindAndSetDb($hash) : bool
|
public static function documentFindAndSetDb($hash): bool
|
||||||
{
|
{
|
||||||
$current_db = config('database.default');
|
$current_db = config('database.default');
|
||||||
|
|
||||||
@ -293,7 +321,7 @@ class MultiDB
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function findAndSetDb($token) :bool
|
public static function findAndSetDb($token): bool
|
||||||
{
|
{
|
||||||
$current_db = config('database.default');
|
$current_db = config('database.default');
|
||||||
|
|
||||||
@ -310,7 +338,7 @@ class MultiDB
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function findAndSetDbByCompanyKey($company_key) :bool
|
public static function findAndSetDbByCompanyKey($company_key): bool
|
||||||
{
|
{
|
||||||
$current_db = config('database.default');
|
$current_db = config('database.default');
|
||||||
|
|
||||||
@ -327,7 +355,7 @@ class MultiDB
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function findAndSetDbByCompanyId($company_id) :?Company
|
public static function findAndSetDbByCompanyId($company_id): ?Company
|
||||||
{
|
{
|
||||||
$current_db = config('database.default');
|
$current_db = config('database.default');
|
||||||
|
|
||||||
@ -344,7 +372,7 @@ class MultiDB
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function findAndSetDbByShopifyName($shopify_name) :?Company
|
public static function findAndSetDbByShopifyName($shopify_name): ?Company
|
||||||
{
|
{
|
||||||
$current_db = config('database.default');
|
$current_db = config('database.default');
|
||||||
|
|
||||||
@ -361,7 +389,7 @@ class MultiDB
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function findAndSetDbByAccountKey($account_key) :bool
|
public static function findAndSetDbByAccountKey($account_key): bool
|
||||||
{
|
{
|
||||||
$current_db = config('database.default');
|
$current_db = config('database.default');
|
||||||
|
|
||||||
@ -378,7 +406,7 @@ class MultiDB
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function findAndSetDbByInappTransactionId($transaction_id) :bool
|
public static function findAndSetDbByInappTransactionId($transaction_id): bool
|
||||||
{
|
{
|
||||||
$current_db = config('database.default');
|
$current_db = config('database.default');
|
||||||
|
|
||||||
@ -396,7 +424,7 @@ class MultiDB
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static function findAndSetDbByContactKey($contact_key) :bool
|
public static function findAndSetDbByContactKey($contact_key): bool
|
||||||
{
|
{
|
||||||
$current_db = config('database.default');
|
$current_db = config('database.default');
|
||||||
|
|
||||||
@ -413,7 +441,7 @@ class MultiDB
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function findAndSetDbByVendorContactKey($contact_key) :bool
|
public static function findAndSetDbByVendorContactKey($contact_key): bool
|
||||||
{
|
{
|
||||||
$current_db = config('database.default');
|
$current_db = config('database.default');
|
||||||
|
|
||||||
@ -430,7 +458,7 @@ class MultiDB
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function findAndSetDbByClientHash($client_hash) :bool
|
public static function findAndSetDbByClientHash($client_hash): bool
|
||||||
{
|
{
|
||||||
$current_db = config('database.default');
|
$current_db = config('database.default');
|
||||||
|
|
||||||
@ -447,7 +475,7 @@ class MultiDB
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function findAndSetDbByClientId($client_id) :?Client
|
public static function findAndSetDbByClientId($client_id): ?Client
|
||||||
{
|
{
|
||||||
$current_db = config('database.default');
|
$current_db = config('database.default');
|
||||||
|
|
||||||
@ -466,7 +494,7 @@ class MultiDB
|
|||||||
|
|
||||||
public static function findAndSetDbByDomain($query_array)
|
public static function findAndSetDbByDomain($query_array)
|
||||||
{
|
{
|
||||||
if (! config('ninja.db.multi_db_enabled')) {
|
if (!config('ninja.db.multi_db_enabled')) {
|
||||||
return Company::where($query_array)->first();
|
return Company::where($query_array)->first();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -487,7 +515,7 @@ class MultiDB
|
|||||||
|
|
||||||
public static function findAndSetDbByInvitation($entity, $invitation_key)
|
public static function findAndSetDbByInvitation($entity, $invitation_key)
|
||||||
{
|
{
|
||||||
$class = 'App\Models\\'.ucfirst(Str::camel($entity)).'Invitation';
|
$class = 'App\Models\\' . ucfirst(Str::camel($entity)) . 'Invitation';
|
||||||
$current_db = config('database.default');
|
$current_db = config('database.default');
|
||||||
|
|
||||||
foreach (self::$dbs as $db) {
|
foreach (self::$dbs as $db) {
|
||||||
@ -507,12 +535,12 @@ class MultiDB
|
|||||||
* @param string $phone
|
* @param string $phone
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public static function hasPhoneNumber(string $phone) : bool
|
public static function hasPhoneNumber(string $phone): bool
|
||||||
{
|
{
|
||||||
if (! config('ninja.db.multi_db_enabled')) {
|
if (!config('ninja.db.multi_db_enabled')) {
|
||||||
return Account::where('account_sms_verification_number', $phone)->where('account_sms_verified', true)->exists();
|
return Account::where('account_sms_verification_number', $phone)->where('account_sms_verified', true)->exists();
|
||||||
}
|
}
|
||||||
|
|
||||||
$current_db = config('database.default');
|
$current_db = config('database.default');
|
||||||
|
|
||||||
foreach (self::$dbs as $db) {
|
foreach (self::$dbs as $db) {
|
||||||
@ -528,7 +556,7 @@ class MultiDB
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static function randomSubdomainGenerator(): string
|
public static function randomSubdomainGenerator(): string
|
||||||
{
|
{
|
||||||
@ -548,7 +576,7 @@ class MultiDB
|
|||||||
$string .= $consonants[rand(0, 19)];
|
$string .= $consonants[rand(0, 19)];
|
||||||
$string .= $vowels[rand(0, 4)];
|
$string .= $vowels[rand(0, 4)];
|
||||||
}
|
}
|
||||||
} while (! self::checkDomainAvailable($string));
|
} while (!self::checkDomainAvailable($string));
|
||||||
|
|
||||||
self::setDb($current_db);
|
self::setDb($current_db);
|
||||||
|
|
||||||
@ -559,7 +587,7 @@ class MultiDB
|
|||||||
* @param $database
|
* @param $database
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public static function setDB(string $database) : void
|
public static function setDB(string $database): void
|
||||||
{
|
{
|
||||||
/* This will set the database connection for the request */
|
/* This will set the database connection for the request */
|
||||||
config(['database.default' => $database]);
|
config(['database.default' => $database]);
|
||||||
|
@ -90,7 +90,7 @@ class AccountTransformer extends EntityTransformer
|
|||||||
'set_react_as_default_ap' => (bool) $account->set_react_as_default_ap,
|
'set_react_as_default_ap' => (bool) $account->set_react_as_default_ap,
|
||||||
'trial_days_left' => Ninja::isHosted() ? (int) $account->getTrialDays() : 0,
|
'trial_days_left' => Ninja::isHosted() ? (int) $account->getTrialDays() : 0,
|
||||||
'account_sms_verified' => (bool) $account->account_sms_verified,
|
'account_sms_verified' => (bool) $account->account_sms_verified,
|
||||||
'has_iap_plan' => (bool)$account->inapp_transaction_id,
|
'has_iap_plan' => (bool) $account->inapp_transaction_id,
|
||||||
'tax_api_enabled' => (bool) config('services.tax.zip_tax.key') ? true : false
|
'tax_api_enabled' => (bool) config('services.tax.zip_tax.key') ? true : false
|
||||||
|
|
||||||
];
|
];
|
||||||
|
@ -133,7 +133,7 @@ class CompanyTransformer extends EntityTransformer
|
|||||||
'show_product_details' => (bool) $company->show_product_details,
|
'show_product_details' => (bool) $company->show_product_details,
|
||||||
'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' => (object) $company->custom_fields ?? $std,
|
'custom_fields' => (object) $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 ?: '1',
|
'first_month_of_year' => (string) $company->first_month_of_year ?: '1',
|
||||||
@ -146,7 +146,7 @@ class CompanyTransformer extends EntityTransformer
|
|||||||
'enabled_modules' => (int) $company->enabled_modules,
|
'enabled_modules' => (int) $company->enabled_modules,
|
||||||
'updated_at' => (int) $company->updated_at,
|
'updated_at' => (int) $company->updated_at,
|
||||||
'archived_at' => (int) $company->deleted_at,
|
'archived_at' => (int) $company->deleted_at,
|
||||||
'created_at' =>(int) $company->created_at,
|
'created_at' => (int) $company->created_at,
|
||||||
'slack_webhook_url' => (string) $company->slack_webhook_url,
|
'slack_webhook_url' => (string) $company->slack_webhook_url,
|
||||||
'google_analytics_url' => (string) $company->google_analytics_key, //@deprecate 1-2-2021
|
'google_analytics_url' => (string) $company->google_analytics_key, //@deprecate 1-2-2021
|
||||||
'google_analytics_key' => (string) $company->google_analytics_key,
|
'google_analytics_key' => (string) $company->google_analytics_key,
|
||||||
@ -158,7 +158,7 @@ class CompanyTransformer extends EntityTransformer
|
|||||||
'is_large' => (bool) $this->isLarge($company),
|
'is_large' => (bool) $this->isLarge($company),
|
||||||
'is_disabled' => (bool) $company->is_disabled,
|
'is_disabled' => (bool) $company->is_disabled,
|
||||||
'enable_shop_api' => (bool) $company->enable_shop_api,
|
'enable_shop_api' => (bool) $company->enable_shop_api,
|
||||||
'mark_expenses_invoiceable'=> (bool) $company->mark_expenses_invoiceable,
|
'mark_expenses_invoiceable' => (bool) $company->mark_expenses_invoiceable,
|
||||||
'mark_expenses_paid' => (bool) $company->mark_expenses_paid,
|
'mark_expenses_paid' => (bool) $company->mark_expenses_paid,
|
||||||
'invoice_expense_documents' => (bool) $company->invoice_expense_documents,
|
'invoice_expense_documents' => (bool) $company->invoice_expense_documents,
|
||||||
'invoice_task_timelog' => (bool) $company->invoice_task_timelog,
|
'invoice_task_timelog' => (bool) $company->invoice_task_timelog,
|
||||||
@ -168,10 +168,10 @@ class CompanyTransformer extends EntityTransformer
|
|||||||
'use_credits_payment' => 'always', // @deprecate 1-2-2021
|
'use_credits_payment' => 'always', // @deprecate 1-2-2021
|
||||||
'default_task_is_date_based' => (bool) $company->default_task_is_date_based,
|
'default_task_is_date_based' => (bool) $company->default_task_is_date_based,
|
||||||
'enable_product_discount' => (bool) $company->enable_product_discount,
|
'enable_product_discount' => (bool) $company->enable_product_discount,
|
||||||
'calculate_expense_tax_by_amount' =>(bool) $company->calculate_expense_tax_by_amount,
|
'calculate_expense_tax_by_amount' => (bool) $company->calculate_expense_tax_by_amount,
|
||||||
'hide_empty_columns_on_pdf' => false, // @deprecate 1-2-2021
|
'hide_empty_columns_on_pdf' => false, // @deprecate 1-2-2021
|
||||||
'expense_inclusive_taxes' => (bool) $company->expense_inclusive_taxes,
|
'expense_inclusive_taxes' => (bool) $company->expense_inclusive_taxes,
|
||||||
'expense_amount_is_pretax' =>(bool) true, //@deprecate 1-2-2021
|
'expense_amount_is_pretax' => (bool) true, //@deprecate 1-2-2021
|
||||||
'oauth_password_required' => (bool) $company->oauth_password_required,
|
'oauth_password_required' => (bool) $company->oauth_password_required,
|
||||||
'session_timeout' => (int) $company->session_timeout,
|
'session_timeout' => (int) $company->session_timeout,
|
||||||
'default_password_timeout' => (int) $company->default_password_timeout,
|
'default_password_timeout' => (int) $company->default_password_timeout,
|
||||||
@ -204,6 +204,7 @@ class CompanyTransformer extends EntityTransformer
|
|||||||
'invoice_task_project_header' => (bool) $company->invoice_task_project_header,
|
'invoice_task_project_header' => (bool) $company->invoice_task_project_header,
|
||||||
'invoice_task_item_description' => (bool) $company->invoice_task_item_description,
|
'invoice_task_item_description' => (bool) $company->invoice_task_item_description,
|
||||||
'origin_tax_data' => $company->origin_tax_data ?: new \stdClass,
|
'origin_tax_data' => $company->origin_tax_data ?: new \stdClass,
|
||||||
|
'expense_mailbox' => $company->expense_mailbox,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,7 +238,9 @@ return [
|
|||||||
],
|
],
|
||||||
'webhook' => [
|
'webhook' => [
|
||||||
'mailbox_template' => env('INBOUND_EXPENSE_WEBHOOK_MAILBOXTEMPLATE', null),
|
'mailbox_template' => env('INBOUND_EXPENSE_WEBHOOK_MAILBOXTEMPLATE', null),
|
||||||
'mailbox_template_enterprise' => env('INBOUND_EXPENSE_WEBHOOK_MAILBOXTEMPLATE_ENTERPRISE', '{{input}}@expense.invoicing.co'),
|
'mailbox_schema' => env('INBOUND_EXPENSE_WEBHOOK_MAILBOX_SCHEMA', null),
|
||||||
|
'mailbox_schema_hascompanykey' => env('INBOUND_EXPENSE_WEBHOOK_MAILBOX_SCHEMA_HASCOMPANYKEY', false),
|
||||||
|
'mailbox_schema_enterprise' => env('INBOUND_EXPENSE_WEBHOOK_MAILBOX_SCHEMA_ENTERPRISE', '.*@expense\.invoicing\.co$'),
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
@ -2534,6 +2534,8 @@ $lang = array(
|
|||||||
'local_storage_required' => 'Error: local storage is not available.',
|
'local_storage_required' => 'Error: local storage is not available.',
|
||||||
'your_password_reset_link' => 'Your Password Reset Link',
|
'your_password_reset_link' => 'Your Password Reset Link',
|
||||||
'subdomain_taken' => 'The subdomain is already in use',
|
'subdomain_taken' => 'The subdomain is already in use',
|
||||||
|
'expense_mailbox_taken' => 'The mailbox is already in use',
|
||||||
|
'expense_mailbox_invalid' => 'The mailbox does not match the required schema',
|
||||||
'client_login' => 'Client Login',
|
'client_login' => 'Client Login',
|
||||||
'converted_amount' => 'Converted Amount',
|
'converted_amount' => 'Converted Amount',
|
||||||
'default' => 'Default',
|
'default' => 'Default',
|
||||||
@ -3857,308 +3859,308 @@ $lang = array(
|
|||||||
'registration_url' => 'Registration URL',
|
'registration_url' => 'Registration URL',
|
||||||
'show_product_cost' => 'Show Product Cost',
|
'show_product_cost' => 'Show Product Cost',
|
||||||
'complete' => 'Complete',
|
'complete' => 'Complete',
|
||||||
'next' => 'Next',
|
'next' => 'Next',
|
||||||
'next_step' => 'Next step',
|
'next_step' => 'Next step',
|
||||||
'notification_credit_sent_subject' => 'Credit :invoice was sent to :client',
|
'notification_credit_sent_subject' => 'Credit :invoice was sent to :client',
|
||||||
'notification_credit_viewed_subject' => 'Credit :invoice was viewed by :client',
|
'notification_credit_viewed_subject' => 'Credit :invoice was viewed by :client',
|
||||||
'notification_credit_sent' => 'The following client :client was emailed Credit :invoice for :amount.',
|
'notification_credit_sent' => 'The following client :client was emailed Credit :invoice for :amount.',
|
||||||
'notification_credit_viewed' => 'The following client :client viewed Credit :credit for :amount.',
|
'notification_credit_viewed' => 'The following client :client viewed Credit :credit for :amount.',
|
||||||
'reset_password_text' => 'Enter your email to reset your password.',
|
'reset_password_text' => 'Enter your email to reset your password.',
|
||||||
'password_reset' => 'Password reset',
|
'password_reset' => 'Password reset',
|
||||||
'account_login_text' => 'Welcome! Glad to see you.',
|
'account_login_text' => 'Welcome! Glad to see you.',
|
||||||
'request_cancellation' => 'Request cancellation',
|
'request_cancellation' => 'Request cancellation',
|
||||||
'delete_payment_method' => 'Delete Payment Method',
|
'delete_payment_method' => 'Delete Payment Method',
|
||||||
'about_to_delete_payment_method' => 'You are about to delete the payment method.',
|
'about_to_delete_payment_method' => 'You are about to delete the payment method.',
|
||||||
'action_cant_be_reversed' => 'Action can\'t be reversed',
|
'action_cant_be_reversed' => 'Action can\'t be reversed',
|
||||||
'profile_updated_successfully' => 'The profile has been updated successfully.',
|
'profile_updated_successfully' => 'The profile has been updated successfully.',
|
||||||
'currency_ethiopian_birr' => 'Ethiopian Birr',
|
'currency_ethiopian_birr' => 'Ethiopian Birr',
|
||||||
'client_information_text' => 'Use a permanent address where you can receive mail.',
|
'client_information_text' => 'Use a permanent address where you can receive mail.',
|
||||||
'status_id' => 'Invoice Status',
|
'status_id' => 'Invoice Status',
|
||||||
'email_already_register' => 'This email is already linked to an account',
|
'email_already_register' => 'This email is already linked to an account',
|
||||||
'locations' => 'Locations',
|
'locations' => 'Locations',
|
||||||
'freq_indefinitely' => 'Indefinitely',
|
'freq_indefinitely' => 'Indefinitely',
|
||||||
'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_files' => 'Download Files',
|
||||||
'download_timeframe' => 'Use this link to download your files, the link will expire in 1 hour.',
|
'download_timeframe' => 'Use this link to download your files, the link will expire in 1 hour.',
|
||||||
'new_signup' => 'New Signup',
|
'new_signup' => 'New Signup',
|
||||||
'new_signup_text' => 'A new account has been created by :user - :email - from IP address: :ip',
|
'new_signup_text' => 'A new account has been created by :user - :email - from IP address: :ip',
|
||||||
'notification_payment_paid_subject' => 'Payment was made by :client',
|
'notification_payment_paid_subject' => 'Payment was made by :client',
|
||||||
'notification_partial_payment_paid_subject' => 'Partial payment was made by :client',
|
'notification_partial_payment_paid_subject' => 'Partial payment was made by :client',
|
||||||
'notification_payment_paid' => 'A payment of :amount was made by client :client towards :invoice',
|
'notification_payment_paid' => 'A payment of :amount was made by client :client towards :invoice',
|
||||||
'notification_partial_payment_paid' => 'A partial payment of :amount was made by client :client towards :invoice',
|
'notification_partial_payment_paid' => 'A partial payment of :amount was made by client :client towards :invoice',
|
||||||
'notification_bot' => 'Notification Bot',
|
'notification_bot' => 'Notification Bot',
|
||||||
'invoice_number_placeholder' => 'Invoice # :invoice',
|
'invoice_number_placeholder' => 'Invoice # :invoice',
|
||||||
'entity_number_placeholder' => ':entity # :entity_number',
|
'entity_number_placeholder' => ':entity # :entity_number',
|
||||||
'email_link_not_working' => 'If the button above isn\'t working for you, please click on the link',
|
'email_link_not_working' => 'If the button above isn\'t working for you, please click on the link',
|
||||||
'display_log' => 'Display Log',
|
'display_log' => 'Display Log',
|
||||||
'send_fail_logs_to_our_server' => 'Report errors in realtime',
|
'send_fail_logs_to_our_server' => 'Report errors in realtime',
|
||||||
'setup' => 'Setup',
|
'setup' => 'Setup',
|
||||||
'quick_overview_statistics' => 'Quick overview & statistics',
|
'quick_overview_statistics' => 'Quick overview & statistics',
|
||||||
'update_your_personal_info' => 'Update your personal information',
|
'update_your_personal_info' => 'Update your personal information',
|
||||||
'name_website_logo' => 'Name, website & logo',
|
'name_website_logo' => 'Name, website & logo',
|
||||||
'make_sure_use_full_link' => 'Make sure you use full link to your site',
|
'make_sure_use_full_link' => 'Make sure you use full link to your site',
|
||||||
'personal_address' => 'Personal address',
|
'personal_address' => 'Personal address',
|
||||||
'enter_your_personal_address' => 'Enter your personal address',
|
'enter_your_personal_address' => 'Enter your personal address',
|
||||||
'enter_your_shipping_address' => 'Enter your shipping address',
|
'enter_your_shipping_address' => 'Enter your shipping address',
|
||||||
'list_of_invoices' => 'List of invoices',
|
'list_of_invoices' => 'List of invoices',
|
||||||
'with_selected' => 'With selected',
|
'with_selected' => 'With selected',
|
||||||
'invoice_still_unpaid' => 'This invoice is still not paid. Click the button to complete the payment',
|
'invoice_still_unpaid' => 'This invoice is still not paid. Click the button to complete the payment',
|
||||||
'list_of_recurring_invoices' => 'List of recurring invoices',
|
'list_of_recurring_invoices' => 'List of recurring invoices',
|
||||||
'details_of_recurring_invoice' => 'Here are some details about recurring invoice',
|
'details_of_recurring_invoice' => 'Here are some details about recurring invoice',
|
||||||
'cancellation' => 'Cancellation',
|
'cancellation' => 'Cancellation',
|
||||||
'about_cancellation' => 'In case you want to stop the recurring invoice, please click to request the cancellation.',
|
'about_cancellation' => 'In case you want to stop the recurring invoice, please click to request the cancellation.',
|
||||||
'cancellation_warning' => 'Warning! You are requesting a cancellation of this service. Your service may be cancelled with no further notification to you.',
|
'cancellation_warning' => 'Warning! You are requesting a cancellation of this service. Your service may be cancelled with no further notification to you.',
|
||||||
'cancellation_pending' => 'Cancellation pending, we\'ll be in touch!',
|
'cancellation_pending' => 'Cancellation pending, we\'ll be in touch!',
|
||||||
'list_of_payments' => 'List of payments',
|
'list_of_payments' => 'List of payments',
|
||||||
'payment_details' => 'Details of the payment',
|
'payment_details' => 'Details of the payment',
|
||||||
'list_of_payment_invoices' => 'List of invoices affected by the payment',
|
'list_of_payment_invoices' => 'List of invoices affected by the payment',
|
||||||
'list_of_payment_methods' => 'List of payment methods',
|
'list_of_payment_methods' => 'List of payment methods',
|
||||||
'payment_method_details' => 'Details of payment method',
|
'payment_method_details' => 'Details of payment method',
|
||||||
'permanently_remove_payment_method' => 'Permanently remove this payment method.',
|
'permanently_remove_payment_method' => 'Permanently remove this payment method.',
|
||||||
'warning_action_cannot_be_reversed' => 'Warning! This action can not be reversed!',
|
'warning_action_cannot_be_reversed' => 'Warning! This action can not be reversed!',
|
||||||
'confirmation' => 'Confirmation',
|
'confirmation' => 'Confirmation',
|
||||||
'list_of_quotes' => 'Quotes',
|
'list_of_quotes' => 'Quotes',
|
||||||
'waiting_for_approval' => 'Waiting for approval',
|
'waiting_for_approval' => 'Waiting for approval',
|
||||||
'quote_still_not_approved' => 'This quote is still not approved',
|
'quote_still_not_approved' => 'This quote is still not approved',
|
||||||
'list_of_credits' => 'Credits',
|
'list_of_credits' => 'Credits',
|
||||||
'required_extensions' => 'Required extensions',
|
'required_extensions' => 'Required extensions',
|
||||||
'php_version' => 'PHP version',
|
'php_version' => 'PHP version',
|
||||||
'writable_env_file' => 'Writable .env file',
|
'writable_env_file' => 'Writable .env file',
|
||||||
'env_not_writable' => '.env file is not writable by the current user.',
|
'env_not_writable' => '.env file is not writable by the current user.',
|
||||||
'minumum_php_version' => 'Minimum PHP version',
|
'minumum_php_version' => 'Minimum PHP version',
|
||||||
'satisfy_requirements' => 'Make sure all requirements are satisfied.',
|
'satisfy_requirements' => 'Make sure all requirements are satisfied.',
|
||||||
'oops_issues' => 'Oops, something does not look right!',
|
'oops_issues' => 'Oops, something does not look right!',
|
||||||
'open_in_new_tab' => 'Open in new tab',
|
'open_in_new_tab' => 'Open in new tab',
|
||||||
'complete_your_payment' => 'Complete payment',
|
'complete_your_payment' => 'Complete payment',
|
||||||
'authorize_for_future_use' => 'Authorize payment method for future use',
|
'authorize_for_future_use' => 'Authorize payment method for future use',
|
||||||
'page' => 'Page',
|
'page' => 'Page',
|
||||||
'per_page' => 'Per page',
|
'per_page' => 'Per page',
|
||||||
'of' => 'Of',
|
'of' => 'Of',
|
||||||
'view_credit' => 'View Credit',
|
'view_credit' => 'View Credit',
|
||||||
'to_view_entity_password' => 'To view the :entity you need to enter password.',
|
'to_view_entity_password' => 'To view the :entity you need to enter password.',
|
||||||
'showing_x_of' => 'Showing :first to :last out of :total results',
|
'showing_x_of' => 'Showing :first to :last out of :total results',
|
||||||
'no_results' => 'No results found.',
|
'no_results' => 'No results found.',
|
||||||
'payment_failed_subject' => 'Payment failed for Client :client',
|
'payment_failed_subject' => 'Payment failed for Client :client',
|
||||||
'payment_failed_body' => 'A payment made by client :client failed with message :message',
|
'payment_failed_body' => 'A payment made by client :client failed with message :message',
|
||||||
'register' => 'Register',
|
'register' => 'Register',
|
||||||
'register_label' => 'Create your account in seconds',
|
'register_label' => 'Create your account in seconds',
|
||||||
'password_confirmation' => 'Confirm your password',
|
'password_confirmation' => 'Confirm your password',
|
||||||
'verification' => 'Verification',
|
'verification' => 'Verification',
|
||||||
'complete_your_bank_account_verification' => 'Before using a bank account it must be verified.',
|
'complete_your_bank_account_verification' => 'Before using a bank account it must be verified.',
|
||||||
'checkout_com' => 'Checkout.com',
|
'checkout_com' => 'Checkout.com',
|
||||||
'footer_label' => 'Copyright © :year :company.',
|
'footer_label' => 'Copyright © :year :company.',
|
||||||
'credit_card_invalid' => 'Provided credit card number is not valid.',
|
'credit_card_invalid' => 'Provided credit card number is not valid.',
|
||||||
'month_invalid' => 'Provided month is not valid.',
|
'month_invalid' => 'Provided month is not valid.',
|
||||||
'year_invalid' => 'Provided year is not valid.',
|
'year_invalid' => 'Provided year is not valid.',
|
||||||
'https_required' => 'HTTPS is required, form will fail',
|
'https_required' => 'HTTPS is required, form will fail',
|
||||||
'if_you_need_help' => 'If you need help you can post to our',
|
'if_you_need_help' => 'If you need help you can post to our',
|
||||||
'update_password_on_confirm' => 'After updating password, your account will be confirmed.',
|
'update_password_on_confirm' => 'After updating password, your account will be confirmed.',
|
||||||
'bank_account_not_linked' => 'To pay with a bank account, first you have to add it as payment method.',
|
'bank_account_not_linked' => 'To pay with a bank account, first you have to add it as payment method.',
|
||||||
'application_settings_label' => 'Let\'s store basic information about your Invoice Ninja!',
|
'application_settings_label' => 'Let\'s store basic information about your Invoice Ninja!',
|
||||||
'recommended_in_production' => 'Highly recommended in production',
|
'recommended_in_production' => 'Highly recommended in production',
|
||||||
'enable_only_for_development' => 'Enable only for development',
|
'enable_only_for_development' => 'Enable only for development',
|
||||||
'test_pdf' => 'Test PDF',
|
'test_pdf' => 'Test PDF',
|
||||||
'checkout_authorize_label' => 'Checkout.com can be can saved as payment method for future use, once you complete your first transaction. Don\'t forget to check "Store credit card details" during payment process.',
|
'checkout_authorize_label' => 'Checkout.com can be can saved as payment method for future use, once you complete your first transaction. Don\'t forget to check "Store credit card details" during payment process.',
|
||||||
'sofort_authorize_label' => 'Bank account (SOFORT) can be can saved as payment method for future use, once you complete your first transaction. Don\'t forget to check "Store payment details" during payment process.',
|
'sofort_authorize_label' => 'Bank account (SOFORT) can be can saved as payment method for future use, once you complete your first transaction. Don\'t forget to check "Store payment details" during payment process.',
|
||||||
'node_status' => 'Node status',
|
'node_status' => 'Node status',
|
||||||
'npm_status' => 'NPM status',
|
'npm_status' => 'NPM status',
|
||||||
'node_status_not_found' => 'I could not find Node anywhere. Is it installed?',
|
'node_status_not_found' => 'I could not find Node anywhere. Is it installed?',
|
||||||
'npm_status_not_found' => 'I could not find NPM anywhere. Is it installed?',
|
'npm_status_not_found' => 'I could not find NPM anywhere. Is it installed?',
|
||||||
'locked_invoice' => 'This invoice is locked and unable to be modified',
|
'locked_invoice' => 'This invoice is locked and unable to be modified',
|
||||||
'downloads' => 'Downloads',
|
'downloads' => 'Downloads',
|
||||||
'resource' => 'Resource',
|
'resource' => 'Resource',
|
||||||
'document_details' => 'Details about the document',
|
'document_details' => 'Details about the document',
|
||||||
'hash' => 'Hash',
|
'hash' => 'Hash',
|
||||||
'resources' => 'Resources',
|
'resources' => 'Resources',
|
||||||
'allowed_file_types' => 'Allowed file types:',
|
'allowed_file_types' => 'Allowed file types:',
|
||||||
'common_codes' => 'Common codes and their meanings',
|
'common_codes' => 'Common codes and their meanings',
|
||||||
'payment_error_code_20087' => '20087: Bad Track Data (invalid CVV and/or expiry date)',
|
'payment_error_code_20087' => '20087: Bad Track Data (invalid CVV and/or expiry date)',
|
||||||
'download_selected' => 'Download selected',
|
'download_selected' => 'Download selected',
|
||||||
'to_pay_invoices' => 'To pay invoices, you have to',
|
'to_pay_invoices' => 'To pay invoices, you have to',
|
||||||
'add_payment_method_first' => 'add payment method',
|
'add_payment_method_first' => 'add payment method',
|
||||||
'no_items_selected' => 'No items selected.',
|
'no_items_selected' => 'No items selected.',
|
||||||
'payment_due' => 'Payment due',
|
'payment_due' => 'Payment due',
|
||||||
'account_balance' => 'Account Balance',
|
'account_balance' => 'Account Balance',
|
||||||
'thanks' => 'Thanks',
|
'thanks' => 'Thanks',
|
||||||
'minimum_required_payment' => 'Minimum required payment is :amount',
|
'minimum_required_payment' => 'Minimum required payment is :amount',
|
||||||
'under_payments_disabled' => 'Company doesn\'t support underpayments.',
|
'under_payments_disabled' => 'Company doesn\'t support underpayments.',
|
||||||
'over_payments_disabled' => 'Company doesn\'t support overpayments.',
|
'over_payments_disabled' => 'Company doesn\'t support overpayments.',
|
||||||
'saved_at' => 'Saved at :time',
|
'saved_at' => 'Saved at :time',
|
||||||
'credit_payment' => 'Credit applied to Invoice :invoice_number',
|
'credit_payment' => 'Credit applied to Invoice :invoice_number',
|
||||||
'credit_subject' => 'New credit :number from :account',
|
'credit_subject' => 'New credit :number from :account',
|
||||||
'credit_message' => 'To view your credit for :amount, click the link below.',
|
'credit_message' => 'To view your credit for :amount, click the link below.',
|
||||||
'payment_type_Crypto' => 'Cryptocurrency',
|
'payment_type_Crypto' => 'Cryptocurrency',
|
||||||
'payment_type_Credit' => 'Credit',
|
'payment_type_Credit' => 'Credit',
|
||||||
'store_for_future_use' => 'Store for future use',
|
'store_for_future_use' => 'Store for future use',
|
||||||
'pay_with_credit' => 'Pay with credit',
|
'pay_with_credit' => 'Pay with credit',
|
||||||
'payment_method_saving_failed' => 'Payment method can\'t be saved for future use.',
|
'payment_method_saving_failed' => 'Payment method can\'t be saved for future use.',
|
||||||
'pay_with' => 'Pay with',
|
'pay_with' => 'Pay with',
|
||||||
'n/a' => 'N/A',
|
'n/a' => 'N/A',
|
||||||
'by_clicking_next_you_accept_terms' => 'By clicking "Next step" you accept terms.',
|
'by_clicking_next_you_accept_terms' => 'By clicking "Next step" you accept terms.',
|
||||||
'not_specified' => 'Not specified',
|
'not_specified' => 'Not specified',
|
||||||
'before_proceeding_with_payment_warning' => 'Before proceeding with payment, you have to fill following fields',
|
'before_proceeding_with_payment_warning' => 'Before proceeding with payment, you have to fill following fields',
|
||||||
'after_completing_go_back_to_previous_page' => 'After completing, go back to previous page.',
|
'after_completing_go_back_to_previous_page' => 'After completing, go back to previous page.',
|
||||||
'pay' => 'Pay',
|
'pay' => 'Pay',
|
||||||
'instructions' => 'Instructions',
|
'instructions' => 'Instructions',
|
||||||
'notification_invoice_reminder1_sent_subject' => 'Reminder 1 for Invoice :invoice was sent to :client',
|
'notification_invoice_reminder1_sent_subject' => 'Reminder 1 for Invoice :invoice was sent to :client',
|
||||||
'notification_invoice_reminder2_sent_subject' => 'Reminder 2 for Invoice :invoice was sent to :client',
|
'notification_invoice_reminder2_sent_subject' => 'Reminder 2 for Invoice :invoice was sent to :client',
|
||||||
'notification_invoice_reminder3_sent_subject' => 'Reminder 3 for Invoice :invoice was sent to :client',
|
'notification_invoice_reminder3_sent_subject' => 'Reminder 3 for Invoice :invoice was sent to :client',
|
||||||
'notification_invoice_custom_sent_subject' => 'Custom reminder for Invoice :invoice was sent to :client',
|
'notification_invoice_custom_sent_subject' => 'Custom reminder for Invoice :invoice was sent to :client',
|
||||||
'notification_invoice_reminder_endless_sent_subject' => 'Endless reminder for Invoice :invoice was sent to :client',
|
'notification_invoice_reminder_endless_sent_subject' => 'Endless reminder for Invoice :invoice was sent to :client',
|
||||||
'assigned_user' => 'Assigned User',
|
'assigned_user' => 'Assigned User',
|
||||||
'setup_steps_notice' => 'To proceed to next step, make sure you test each section.',
|
'setup_steps_notice' => 'To proceed to next step, make sure you test each section.',
|
||||||
'setup_phantomjs_note' => 'Note about Phantom JS. Read more.',
|
'setup_phantomjs_note' => 'Note about Phantom JS. Read more.',
|
||||||
'minimum_payment' => 'Minimum Payment',
|
'minimum_payment' => 'Minimum Payment',
|
||||||
'no_action_provided' => 'No action provided. If you believe this is wrong, please contact the support.',
|
'no_action_provided' => 'No action provided. If you believe this is wrong, please contact the support.',
|
||||||
'no_payable_invoices_selected' => 'No payable invoices selected. Make sure you are not trying to pay draft invoice or invoice with zero balance due.',
|
'no_payable_invoices_selected' => 'No payable invoices selected. Make sure you are not trying to pay draft invoice or invoice with zero balance due.',
|
||||||
'required_payment_information' => 'Required payment details',
|
'required_payment_information' => 'Required payment details',
|
||||||
'required_payment_information_more' => 'To complete a payment we need more details about you.',
|
'required_payment_information_more' => 'To complete a payment we need more details about you.',
|
||||||
'required_client_info_save_label' => 'We will save this, so you don\'t have to enter it next time.',
|
'required_client_info_save_label' => 'We will save this, so you don\'t have to enter it next time.',
|
||||||
'notification_credit_bounced' => 'We were unable to deliver Credit :invoice to :contact. \n :error',
|
'notification_credit_bounced' => 'We were unable to deliver Credit :invoice to :contact. \n :error',
|
||||||
'notification_credit_bounced_subject' => 'Unable to deliver Credit :invoice',
|
'notification_credit_bounced_subject' => 'Unable to deliver Credit :invoice',
|
||||||
'save_payment_method_details' => 'Save payment method details',
|
'save_payment_method_details' => 'Save payment method details',
|
||||||
'new_card' => 'New card',
|
'new_card' => 'New card',
|
||||||
'new_bank_account' => 'New bank account',
|
'new_bank_account' => 'New bank account',
|
||||||
'company_limit_reached' => 'Limit of :limit companies per account.',
|
'company_limit_reached' => 'Limit of :limit companies per account.',
|
||||||
'credits_applied_validation' => 'Total credits applied cannot be MORE than total of invoices',
|
'credits_applied_validation' => 'Total credits applied cannot be MORE than total of invoices',
|
||||||
'credit_number_taken' => 'Credit number already taken',
|
'credit_number_taken' => 'Credit number already taken',
|
||||||
'credit_not_found' => 'Credit not found',
|
'credit_not_found' => 'Credit not found',
|
||||||
'invoices_dont_match_client' => 'Selected invoices are not from a single client',
|
'invoices_dont_match_client' => 'Selected invoices are not from a single client',
|
||||||
'duplicate_credits_submitted' => 'Duplicate credits submitted.',
|
'duplicate_credits_submitted' => 'Duplicate credits submitted.',
|
||||||
'duplicate_invoices_submitted' => 'Duplicate invoices submitted.',
|
'duplicate_invoices_submitted' => 'Duplicate invoices submitted.',
|
||||||
'credit_with_no_invoice' => 'You must have an invoice set when using a credit in a payment',
|
'credit_with_no_invoice' => 'You must have an invoice set when using a credit in a payment',
|
||||||
'client_id_required' => 'Client id is required',
|
'client_id_required' => 'Client id is required',
|
||||||
'expense_number_taken' => 'Expense number already taken',
|
'expense_number_taken' => 'Expense number already taken',
|
||||||
'invoice_number_taken' => 'Invoice number already taken',
|
'invoice_number_taken' => 'Invoice number already taken',
|
||||||
'payment_id_required' => 'Payment `id` required.',
|
'payment_id_required' => 'Payment `id` required.',
|
||||||
'unable_to_retrieve_payment' => 'Unable to retrieve specified payment',
|
'unable_to_retrieve_payment' => 'Unable to retrieve specified payment',
|
||||||
'invoice_not_related_to_payment' => 'Invoice id :invoice is not related to this payment',
|
'invoice_not_related_to_payment' => 'Invoice id :invoice is not related to this payment',
|
||||||
'credit_not_related_to_payment' => 'Credit id :credit is not related to this payment',
|
'credit_not_related_to_payment' => 'Credit id :credit is not related to this payment',
|
||||||
'max_refundable_invoice' => 'Attempting to refund more than allowed for invoice id :invoice, maximum refundable amount is :amount',
|
'max_refundable_invoice' => 'Attempting to refund more than allowed for invoice id :invoice, maximum refundable amount is :amount',
|
||||||
'refund_without_invoices' => 'Attempting to refund a payment with invoices attached, please specify valid invoice/s to be refunded.',
|
'refund_without_invoices' => 'Attempting to refund a payment with invoices attached, please specify valid invoice/s to be refunded.',
|
||||||
'refund_without_credits' => 'Attempting to refund a payment with credits attached, please specify valid credits/s to be refunded.',
|
'refund_without_credits' => 'Attempting to refund a payment with credits attached, please specify valid credits/s to be refunded.',
|
||||||
'max_refundable_credit' => 'Attempting to refund more than allowed for credit :credit, maximum refundable amount is :amount',
|
'max_refundable_credit' => 'Attempting to refund more than allowed for credit :credit, maximum refundable amount is :amount',
|
||||||
'project_client_do_not_match' => 'Project client does not match entity client',
|
'project_client_do_not_match' => 'Project client does not match entity client',
|
||||||
'quote_number_taken' => 'Quote number already taken',
|
'quote_number_taken' => 'Quote number already taken',
|
||||||
'recurring_invoice_number_taken' => 'Recurring Invoice number :number already taken',
|
'recurring_invoice_number_taken' => 'Recurring Invoice number :number already taken',
|
||||||
'user_not_associated_with_account' => 'User not associated with this account',
|
'user_not_associated_with_account' => 'User not associated with this account',
|
||||||
'amounts_do_not_balance' => 'Amounts do not balance correctly.',
|
'amounts_do_not_balance' => 'Amounts do not balance correctly.',
|
||||||
'insufficient_applied_amount_remaining' => 'Insufficient applied amount remaining to cover payment.',
|
'insufficient_applied_amount_remaining' => 'Insufficient applied amount remaining to cover payment.',
|
||||||
'insufficient_credit_balance' => 'Insufficient balance on credit.',
|
'insufficient_credit_balance' => 'Insufficient balance on credit.',
|
||||||
'one_or_more_invoices_paid' => 'One or more of these invoices have been paid',
|
'one_or_more_invoices_paid' => 'One or more of these invoices have been paid',
|
||||||
'invoice_cannot_be_refunded' => 'Invoice id :number cannot be refunded',
|
'invoice_cannot_be_refunded' => 'Invoice id :number cannot be refunded',
|
||||||
'attempted_refund_failed' => 'Attempting to refund :amount only :refundable_amount available for refund',
|
'attempted_refund_failed' => 'Attempting to refund :amount only :refundable_amount available for refund',
|
||||||
'user_not_associated_with_this_account' => 'This user is unable to be attached to this company. Perhaps they have already registered a user on another account?',
|
'user_not_associated_with_this_account' => 'This user is unable to be attached to this company. Perhaps they have already registered a user on another account?',
|
||||||
'migration_completed' => 'Migration completed',
|
'migration_completed' => 'Migration completed',
|
||||||
'migration_completed_description' => 'Your migration has completed, please review your data after logging in.',
|
'migration_completed_description' => 'Your migration has completed, please review your data after logging in.',
|
||||||
'api_404' => '404 | Nothing to see here!',
|
'api_404' => '404 | Nothing to see here!',
|
||||||
'large_account_update_parameter' => 'Cannot load a large account without a updated_at parameter',
|
'large_account_update_parameter' => 'Cannot load a large account without a updated_at parameter',
|
||||||
'no_backup_exists' => 'No backup exists for this activity',
|
'no_backup_exists' => 'No backup exists for this activity',
|
||||||
'company_user_not_found' => 'Company User record not found',
|
'company_user_not_found' => 'Company User record not found',
|
||||||
'no_credits_found' => 'No credits found.',
|
'no_credits_found' => 'No credits found.',
|
||||||
'action_unavailable' => 'The requested action :action is not available.',
|
'action_unavailable' => 'The requested action :action is not available.',
|
||||||
'no_documents_found' => 'No Documents Found',
|
'no_documents_found' => 'No Documents Found',
|
||||||
'no_group_settings_found' => 'No group settings found',
|
'no_group_settings_found' => 'No group settings found',
|
||||||
'access_denied' => 'Insufficient privileges to access/modify this resource',
|
'access_denied' => 'Insufficient privileges to access/modify this resource',
|
||||||
'invoice_cannot_be_marked_paid' => 'Invoice cannot be marked as paid',
|
'invoice_cannot_be_marked_paid' => 'Invoice cannot be marked as paid',
|
||||||
'invoice_license_or_environment' => 'Invalid license, or invalid environment :environment',
|
'invoice_license_or_environment' => 'Invalid license, or invalid environment :environment',
|
||||||
'route_not_available' => 'Route not available',
|
'route_not_available' => 'Route not available',
|
||||||
'invalid_design_object' => 'Invalid custom design object',
|
'invalid_design_object' => 'Invalid custom design object',
|
||||||
'quote_not_found' => 'Quote/s not found',
|
'quote_not_found' => 'Quote/s not found',
|
||||||
'quote_unapprovable' => 'Unable to approve this quote as it has expired.',
|
'quote_unapprovable' => 'Unable to approve this quote as it has expired.',
|
||||||
'scheduler_has_run' => 'Scheduler has run',
|
'scheduler_has_run' => 'Scheduler has run',
|
||||||
'scheduler_has_never_run' => 'Scheduler has never run',
|
'scheduler_has_never_run' => 'Scheduler has never run',
|
||||||
'self_update_not_available' => 'Self update not available on this system.',
|
'self_update_not_available' => 'Self update not available on this system.',
|
||||||
'user_detached' => 'User detached from company',
|
'user_detached' => 'User detached from company',
|
||||||
'create_webhook_failure' => 'Failed to create Webhook',
|
'create_webhook_failure' => 'Failed to create Webhook',
|
||||||
'payment_message_extended' => 'Thank you for your payment of :amount for :invoice',
|
'payment_message_extended' => 'Thank you for your payment of :amount for :invoice',
|
||||||
'online_payments_minimum_note' => 'Note: Online payments are supported only if amount is bigger than $1 or currency equivalent.',
|
'online_payments_minimum_note' => 'Note: Online payments are supported only if amount is bigger than $1 or currency equivalent.',
|
||||||
'payment_token_not_found' => 'Payment token not found, please try again. If an issue still persist, try with another payment method',
|
'payment_token_not_found' => 'Payment token not found, please try again. If an issue still persist, try with another payment method',
|
||||||
'vendor_address1' => 'Vendor Street',
|
'vendor_address1' => 'Vendor Street',
|
||||||
'vendor_address2' => 'Vendor Apt/Suite',
|
'vendor_address2' => 'Vendor Apt/Suite',
|
||||||
'partially_unapplied' => 'Partially Unapplied',
|
'partially_unapplied' => 'Partially Unapplied',
|
||||||
'select_a_gmail_user' => 'Please select a user authenticated with Gmail',
|
'select_a_gmail_user' => 'Please select a user authenticated with Gmail',
|
||||||
'list_long_press' => 'List Long Press',
|
'list_long_press' => 'List Long Press',
|
||||||
'show_actions' => 'Show Actions',
|
'show_actions' => 'Show Actions',
|
||||||
'start_multiselect' => 'Start Multiselect',
|
'start_multiselect' => 'Start Multiselect',
|
||||||
'email_sent_to_confirm_email' => 'An email has been sent to confirm the email address',
|
'email_sent_to_confirm_email' => 'An email has been sent to confirm the email address',
|
||||||
'converted_paid_to_date' => 'Converted Paid to Date',
|
'converted_paid_to_date' => 'Converted Paid to Date',
|
||||||
'converted_credit_balance' => 'Converted Credit Balance',
|
'converted_credit_balance' => 'Converted Credit Balance',
|
||||||
'converted_total' => 'Converted Total',
|
'converted_total' => 'Converted Total',
|
||||||
'reply_to_name' => 'Reply-To Name',
|
'reply_to_name' => 'Reply-To Name',
|
||||||
'payment_status_-2' => 'Partially Unapplied',
|
'payment_status_-2' => 'Partially Unapplied',
|
||||||
'color_theme' => 'Color Theme',
|
'color_theme' => 'Color Theme',
|
||||||
'start_migration' => 'Start Migration',
|
'start_migration' => 'Start Migration',
|
||||||
'recurring_cancellation_request' => 'Request for recurring invoice cancellation from :contact',
|
'recurring_cancellation_request' => 'Request for recurring invoice cancellation from :contact',
|
||||||
'recurring_cancellation_request_body' => ':contact from Client :client requested to cancel Recurring Invoice :invoice',
|
'recurring_cancellation_request_body' => ':contact from Client :client requested to cancel Recurring Invoice :invoice',
|
||||||
'hello' => 'Hello',
|
'hello' => 'Hello',
|
||||||
'group_documents' => 'Group documents',
|
'group_documents' => 'Group documents',
|
||||||
'quote_approval_confirmation_label' => 'Are you sure you want to approve this quote?',
|
'quote_approval_confirmation_label' => 'Are you sure you want to approve this quote?',
|
||||||
'migration_select_company_label' => 'Select companies to migrate',
|
'migration_select_company_label' => 'Select companies to migrate',
|
||||||
'force_migration' => 'Force migration',
|
'force_migration' => 'Force migration',
|
||||||
'require_password_with_social_login' => 'Require Password with Social Login',
|
'require_password_with_social_login' => 'Require Password with Social Login',
|
||||||
'stay_logged_in' => 'Stay Logged In',
|
'stay_logged_in' => 'Stay Logged In',
|
||||||
'session_about_to_expire' => 'Warning: Your session is about to expire',
|
'session_about_to_expire' => 'Warning: Your session is about to expire',
|
||||||
'count_hours' => ':count Hours',
|
'count_hours' => ':count Hours',
|
||||||
'count_day' => '1 Day',
|
'count_day' => '1 Day',
|
||||||
'count_days' => ':count Days',
|
'count_days' => ':count Days',
|
||||||
'web_session_timeout' => 'Web Session Timeout',
|
'web_session_timeout' => 'Web Session Timeout',
|
||||||
'security_settings' => 'Security Settings',
|
'security_settings' => 'Security Settings',
|
||||||
'resend_email' => 'Resend Email',
|
'resend_email' => 'Resend Email',
|
||||||
'confirm_your_email_address' => 'Please confirm your email address',
|
'confirm_your_email_address' => 'Please confirm your email address',
|
||||||
'freshbooks' => 'FreshBooks',
|
'freshbooks' => 'FreshBooks',
|
||||||
'invoice2go' => 'Invoice2go',
|
'invoice2go' => 'Invoice2go',
|
||||||
'invoicely' => 'Invoicely',
|
'invoicely' => 'Invoicely',
|
||||||
'waveaccounting' => 'Wave Accounting',
|
'waveaccounting' => 'Wave Accounting',
|
||||||
'zoho' => 'Zoho',
|
'zoho' => 'Zoho',
|
||||||
'accounting' => 'Accounting',
|
'accounting' => 'Accounting',
|
||||||
'required_files_missing' => 'Please provide all CSVs.',
|
'required_files_missing' => 'Please provide all CSVs.',
|
||||||
'migration_auth_label' => 'Let\'s continue by authenticating.',
|
'migration_auth_label' => 'Let\'s continue by authenticating.',
|
||||||
'api_secret' => 'API secret',
|
'api_secret' => 'API secret',
|
||||||
'migration_api_secret_notice' => 'You can find API_SECRET in the .env file or Invoice Ninja v5. If property is missing, leave field blank.',
|
'migration_api_secret_notice' => 'You can find API_SECRET in the .env file or Invoice Ninja v5. If property is missing, leave field blank.',
|
||||||
'billing_coupon_notice' => 'Your discount will be applied on the checkout.',
|
'billing_coupon_notice' => 'Your discount will be applied on the checkout.',
|
||||||
'use_last_email' => 'Use last email',
|
'use_last_email' => 'Use last email',
|
||||||
'activate_company' => 'Activate Company',
|
'activate_company' => 'Activate Company',
|
||||||
'activate_company_help' => 'Enable emails, recurring invoices and notifications',
|
'activate_company_help' => 'Enable emails, recurring invoices and notifications',
|
||||||
'an_error_occurred_try_again' => 'An error occurred, please try again',
|
'an_error_occurred_try_again' => 'An error occurred, please try again',
|
||||||
'please_first_set_a_password' => 'Please first set a password',
|
'please_first_set_a_password' => 'Please first set a password',
|
||||||
'changing_phone_disables_two_factor' => 'Warning: Changing your phone number will disable 2FA',
|
'changing_phone_disables_two_factor' => 'Warning: Changing your phone number will disable 2FA',
|
||||||
'help_translate' => 'Help Translate',
|
'help_translate' => 'Help Translate',
|
||||||
'please_select_a_country' => 'Please select a country',
|
'please_select_a_country' => 'Please select a country',
|
||||||
'disabled_two_factor' => 'Successfully disabled 2FA',
|
'disabled_two_factor' => 'Successfully disabled 2FA',
|
||||||
'connected_google' => 'Successfully connected account',
|
'connected_google' => 'Successfully connected account',
|
||||||
'disconnected_google' => 'Successfully disconnected account',
|
'disconnected_google' => 'Successfully disconnected account',
|
||||||
'delivered' => 'Delivered',
|
'delivered' => 'Delivered',
|
||||||
'spam' => 'Spam',
|
'spam' => 'Spam',
|
||||||
'view_docs' => 'View Docs',
|
'view_docs' => 'View Docs',
|
||||||
'enter_phone_to_enable_two_factor' => 'Please provide a mobile phone number to enable two factor authentication',
|
'enter_phone_to_enable_two_factor' => 'Please provide a mobile phone number to enable two factor authentication',
|
||||||
'send_sms' => 'Send SMS',
|
'send_sms' => 'Send SMS',
|
||||||
'sms_code' => 'SMS Code',
|
'sms_code' => 'SMS Code',
|
||||||
'connect_google' => 'Connect Google',
|
'connect_google' => 'Connect Google',
|
||||||
'disconnect_google' => 'Disconnect Google',
|
'disconnect_google' => 'Disconnect Google',
|
||||||
'disable_two_factor' => 'Disable Two Factor',
|
'disable_two_factor' => 'Disable Two Factor',
|
||||||
'invoice_task_datelog' => 'Invoice Task Datelog',
|
'invoice_task_datelog' => 'Invoice Task Datelog',
|
||||||
'invoice_task_datelog_help' => 'Add date details to the invoice line items',
|
'invoice_task_datelog_help' => 'Add date details to the invoice line items',
|
||||||
'promo_code' => 'Promo code',
|
'promo_code' => 'Promo code',
|
||||||
'recurring_invoice_issued_to' => 'Recurring invoice issued to',
|
'recurring_invoice_issued_to' => 'Recurring invoice issued to',
|
||||||
'subscription' => 'Subscription',
|
'subscription' => 'Subscription',
|
||||||
'new_subscription' => 'New Subscription',
|
'new_subscription' => 'New Subscription',
|
||||||
'deleted_subscription' => 'Successfully deleted subscription',
|
'deleted_subscription' => 'Successfully deleted subscription',
|
||||||
'removed_subscription' => 'Successfully removed subscription',
|
'removed_subscription' => 'Successfully removed subscription',
|
||||||
'restored_subscription' => 'Successfully restored subscription',
|
'restored_subscription' => 'Successfully restored subscription',
|
||||||
'search_subscription' => 'Search 1 Subscription',
|
'search_subscription' => 'Search 1 Subscription',
|
||||||
'search_subscriptions' => 'Search :count Subscriptions',
|
'search_subscriptions' => 'Search :count Subscriptions',
|
||||||
'subdomain_is_not_available' => 'Subdomain is not available',
|
'subdomain_is_not_available' => 'Subdomain is not available',
|
||||||
'connect_gmail' => 'Connect Gmail',
|
'connect_gmail' => 'Connect Gmail',
|
||||||
'disconnect_gmail' => 'Disconnect Gmail',
|
'disconnect_gmail' => 'Disconnect Gmail',
|
||||||
'connected_gmail' => 'Successfully connected Gmail',
|
'connected_gmail' => 'Successfully connected Gmail',
|
||||||
'disconnected_gmail' => 'Successfully disconnected Gmail',
|
'disconnected_gmail' => 'Successfully disconnected Gmail',
|
||||||
'update_fail_help' => 'Changes to the codebase may be blocking the update, you can run this command to discard the changes:',
|
'update_fail_help' => 'Changes to the codebase may be blocking the update, you can run this command to discard the changes:',
|
||||||
'client_id_number' => 'Client ID Number',
|
'client_id_number' => 'Client ID Number',
|
||||||
'count_minutes' => ':count Minutes',
|
'count_minutes' => ':count Minutes',
|
||||||
'password_timeout' => 'Password Timeout',
|
'password_timeout' => 'Password Timeout',
|
||||||
'shared_invoice_credit_counter' => 'Share Invoice/Credit Counter',
|
'shared_invoice_credit_counter' => 'Share Invoice/Credit Counter',
|
||||||
'activity_80' => ':user created subscription :subscription',
|
'activity_80' => ':user created subscription :subscription',
|
||||||
'activity_81' => ':user updated subscription :subscription',
|
'activity_81' => ':user updated subscription :subscription',
|
||||||
'activity_82' => ':user archived subscription :subscription',
|
'activity_82' => ':user archived subscription :subscription',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user