mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
commit
9734d3b8bc
9
.github/workflows/phpunit.yml
vendored
9
.github/workflows/phpunit.yml
vendored
@ -12,8 +12,8 @@ jobs:
|
|||||||
runs-on: ${{ matrix.operating-system }}
|
runs-on: ${{ matrix.operating-system }}
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
operating-system: ['ubuntu-18.04', 'ubuntu-20.04']
|
operating-system: ['ubuntu-18.04', 'ubuntu-20.04', 'ubuntu-22.04']
|
||||||
php-versions: ['7.4','8.0','8.1']
|
php-versions: ['8.1']
|
||||||
phpunit-versions: ['latest']
|
phpunit-versions: ['latest']
|
||||||
|
|
||||||
env:
|
env:
|
||||||
@ -103,11 +103,8 @@ jobs:
|
|||||||
- name: Run Testsuite
|
- name: Run Testsuite
|
||||||
run: |
|
run: |
|
||||||
cat .env
|
cat .env
|
||||||
|
vendor/bin/snappdf download
|
||||||
vendor/bin/phpunit --testdox
|
vendor/bin/phpunit --testdox
|
||||||
env:
|
env:
|
||||||
DB_PORT: ${{ job.services.mysql.ports[3306] }}
|
DB_PORT: ${{ job.services.mysql.ports[3306] }}
|
||||||
PHP_CS_FIXER_IGNORE_ENV: true
|
PHP_CS_FIXER_IGNORE_ENV: true
|
||||||
|
|
||||||
- name: Run php-cs-fixer
|
|
||||||
run: |
|
|
||||||
PHP_CS_FIXER_IGNORE_ENV=1 vendor/bin/php-cs-fixer fix
|
|
||||||
|
@ -1 +1 @@
|
|||||||
5.5.8
|
5.5.14
|
@ -166,7 +166,7 @@ class SendRemindersCron extends Command
|
|||||||
|
|
||||||
$invoice_item = new InvoiceItem;
|
$invoice_item = new InvoiceItem;
|
||||||
$invoice_item->type_id = '5';
|
$invoice_item->type_id = '5';
|
||||||
$invoice_item->product_key = trans('texts.fee');
|
$invoice_item->product_key = ctrans('texts.fee');
|
||||||
$invoice_item->notes = ctrans('texts.late_fee_added', ['date' => $this->translateDate(now()->startOfDay(), $invoice->client->date_format(), $invoice->client->locale())]);
|
$invoice_item->notes = ctrans('texts.late_fee_added', ['date' => $this->translateDate(now()->startOfDay(), $invoice->client->date_format(), $invoice->client->locale())]);
|
||||||
$invoice_item->quantity = 1;
|
$invoice_item->quantity = 1;
|
||||||
$invoice_item->cost = $fee;
|
$invoice_item->cost = $fee;
|
||||||
|
40
app/Factory/CloneQuoteToProjectFactory.php
Normal file
40
app/Factory/CloneQuoteToProjectFactory.php
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Project Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2022. Project Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Factory;
|
||||||
|
|
||||||
|
use App\Models\Project;
|
||||||
|
use App\Models\Quote;
|
||||||
|
|
||||||
|
class CloneQuoteToProjectFactory
|
||||||
|
{
|
||||||
|
public static function create(Quote $quote, $user_id) : ?Project
|
||||||
|
{
|
||||||
|
$project = new Project();
|
||||||
|
|
||||||
|
$project->company_id = $quote->company_id;
|
||||||
|
$project->user_id = $user_id;
|
||||||
|
$project->client_id = $quote->client_id;
|
||||||
|
|
||||||
|
$project->public_notes = $quote->public_notes;
|
||||||
|
$project->private_notes = $quote->private_notes;
|
||||||
|
$project->budgeted_hours = 0;
|
||||||
|
$project->task_rate = 0;
|
||||||
|
$project->name = ctrans('texts.quote_number_short') . " " . $quote->number;
|
||||||
|
$project->custom_value1 = '';
|
||||||
|
$project->custom_value2 = '';
|
||||||
|
$project->custom_value3 = '';
|
||||||
|
$project->custom_value4 = '';
|
||||||
|
$project->is_deleted = 0;
|
||||||
|
|
||||||
|
return $project;
|
||||||
|
}
|
||||||
|
}
|
@ -587,21 +587,21 @@ class CreditController extends BaseController
|
|||||||
$this->credit_repository->archive($credit);
|
$this->credit_repository->archive($credit);
|
||||||
|
|
||||||
if (! $bulk) {
|
if (! $bulk) {
|
||||||
return $this->listResponse($credit);
|
return $this->itemResponse($credit);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'restore':
|
case 'restore':
|
||||||
$this->credit_repository->restore($credit);
|
$this->credit_repository->restore($credit);
|
||||||
|
|
||||||
if (! $bulk) {
|
if (! $bulk) {
|
||||||
return $this->listResponse($credit);
|
return $this->itemResponse($credit);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'delete':
|
case 'delete':
|
||||||
$this->credit_repository->delete($credit);
|
$this->credit_repository->delete($credit);
|
||||||
|
|
||||||
if (! $bulk) {
|
if (! $bulk) {
|
||||||
return $this->listResponse($credit);
|
return $this->itemResponse($credit);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'email':
|
case 'email':
|
||||||
|
@ -722,14 +722,14 @@ class InvoiceController extends BaseController
|
|||||||
$this->invoice_repo->restore($invoice);
|
$this->invoice_repo->restore($invoice);
|
||||||
|
|
||||||
if (! $bulk) {
|
if (! $bulk) {
|
||||||
return $this->listResponse($invoice);
|
return $this->itemResponse($invoice);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'archive':
|
case 'archive':
|
||||||
$this->invoice_repo->archive($invoice);
|
$this->invoice_repo->archive($invoice);
|
||||||
|
|
||||||
if (! $bulk) {
|
if (! $bulk) {
|
||||||
return $this->listResponse($invoice);
|
return $this->itemResponse($invoice);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'delete':
|
case 'delete':
|
||||||
@ -737,7 +737,7 @@ class InvoiceController extends BaseController
|
|||||||
$this->invoice_repo->delete($invoice);
|
$this->invoice_repo->delete($invoice);
|
||||||
|
|
||||||
if (! $bulk) {
|
if (! $bulk) {
|
||||||
return $this->listResponse($invoice);
|
return $this->itemResponse($invoice);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'cancel':
|
case 'cancel':
|
||||||
|
@ -623,14 +623,14 @@ class PurchaseOrderController extends BaseController
|
|||||||
$this->purchase_order_repository->restore($purchase_order);
|
$this->purchase_order_repository->restore($purchase_order);
|
||||||
|
|
||||||
if (! $bulk) {
|
if (! $bulk) {
|
||||||
return $this->listResponse($purchase_order);
|
return $this->itemResponse($purchase_order);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'archive':
|
case 'archive':
|
||||||
$this->purchase_order_repository->archive($purchase_order);
|
$this->purchase_order_repository->archive($purchase_order);
|
||||||
|
|
||||||
if (! $bulk) {
|
if (! $bulk) {
|
||||||
return $this->listResponse($purchase_order);
|
return $this->itemResponse($purchase_order);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'delete':
|
case 'delete':
|
||||||
@ -638,7 +638,7 @@ class PurchaseOrderController extends BaseController
|
|||||||
$this->purchase_order_repository->delete($purchase_order);
|
$this->purchase_order_repository->delete($purchase_order);
|
||||||
|
|
||||||
if (! $bulk) {
|
if (! $bulk) {
|
||||||
return $this->listResponse($purchase_order);
|
return $this->itemResponse($purchase_order);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -684,7 +684,7 @@ class PurchaseOrderController extends BaseController
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (! $bulk) {
|
if (! $bulk) {
|
||||||
return $this->listResponse($purchase_order);
|
return $this->itemResponse($purchase_order);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ use App\Events\Quote\QuoteWasCreated;
|
|||||||
use App\Events\Quote\QuoteWasUpdated;
|
use App\Events\Quote\QuoteWasUpdated;
|
||||||
use App\Factory\CloneQuoteFactory;
|
use App\Factory\CloneQuoteFactory;
|
||||||
use App\Factory\CloneQuoteToInvoiceFactory;
|
use App\Factory\CloneQuoteToInvoiceFactory;
|
||||||
|
use App\Factory\CloneQuoteToProjectFactory;
|
||||||
use App\Factory\QuoteFactory;
|
use App\Factory\QuoteFactory;
|
||||||
use App\Filters\QuoteFilters;
|
use App\Filters\QuoteFilters;
|
||||||
use App\Http\Requests\Quote\ActionQuoteRequest;
|
use App\Http\Requests\Quote\ActionQuoteRequest;
|
||||||
@ -31,12 +32,15 @@ use App\Jobs\Quote\ZipQuotes;
|
|||||||
use App\Models\Account;
|
use App\Models\Account;
|
||||||
use App\Models\Client;
|
use App\Models\Client;
|
||||||
use App\Models\Invoice;
|
use App\Models\Invoice;
|
||||||
|
use App\Models\Project;
|
||||||
use App\Models\Quote;
|
use App\Models\Quote;
|
||||||
use App\Repositories\QuoteRepository;
|
use App\Repositories\QuoteRepository;
|
||||||
use App\Transformers\InvoiceTransformer;
|
use App\Transformers\InvoiceTransformer;
|
||||||
|
use App\Transformers\ProjectTransformer;
|
||||||
use App\Transformers\QuoteTransformer;
|
use App\Transformers\QuoteTransformer;
|
||||||
use App\Utils\Ninja;
|
use App\Utils\Ninja;
|
||||||
use App\Utils\TempFile;
|
use App\Utils\TempFile;
|
||||||
|
use App\Utils\Traits\GeneratesCounter;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
use App\Utils\Traits\SavesDocuments;
|
use App\Utils\Traits\SavesDocuments;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
@ -50,6 +54,7 @@ class QuoteController extends BaseController
|
|||||||
{
|
{
|
||||||
use MakesHash;
|
use MakesHash;
|
||||||
use SavesDocuments;
|
use SavesDocuments;
|
||||||
|
use GeneratesCounter;
|
||||||
|
|
||||||
protected $entity_type = Quote::class;
|
protected $entity_type = Quote::class;
|
||||||
|
|
||||||
@ -556,6 +561,28 @@ class QuoteController extends BaseController
|
|||||||
return $this->listResponse(Quote::withTrashed()->whereIn('id', $this->transformKeys($ids))->company());
|
return $this->listResponse(Quote::withTrashed()->whereIn('id', $this->transformKeys($ids))->company());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if($action == 'convert_to_project')
|
||||||
|
{
|
||||||
|
|
||||||
|
$quotes->each(function ($quote, $key) use ($action) {
|
||||||
|
if (auth()->user()->can('edit', $quote))
|
||||||
|
{
|
||||||
|
$project = CloneQuoteToProjectFactory::create($quote, auth()->user()->id);
|
||||||
|
|
||||||
|
if (empty($project->number)) {
|
||||||
|
$project->number = $this->getNextProjectNumber($project);
|
||||||
|
|
||||||
|
}
|
||||||
|
$project->save();
|
||||||
|
$quote->project_id = $project->id;
|
||||||
|
$quote->save();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return $this->listResponse(Quote::withTrashed()->whereIn('id', $this->transformKeys($ids))->company());
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Send the other actions to the switch
|
* Send the other actions to the switch
|
||||||
*/
|
*/
|
||||||
@ -661,6 +688,7 @@ class QuoteController extends BaseController
|
|||||||
return $this->itemResponse($quote->service()->convertToInvoice());
|
return $this->itemResponse($quote->service()->convertToInvoice());
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'clone_to_invoice':
|
case 'clone_to_invoice':
|
||||||
|
|
||||||
$this->entity_type = Invoice::class;
|
$this->entity_type = Invoice::class;
|
||||||
@ -700,7 +728,7 @@ class QuoteController extends BaseController
|
|||||||
$this->quote_repo->restore($quote);
|
$this->quote_repo->restore($quote);
|
||||||
|
|
||||||
if (! $bulk) {
|
if (! $bulk) {
|
||||||
return $this->listResponse($quote);
|
return $this->itemResponse($quote);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -708,7 +736,7 @@ class QuoteController extends BaseController
|
|||||||
$this->quote_repo->archive($quote);
|
$this->quote_repo->archive($quote);
|
||||||
|
|
||||||
if (! $bulk) {
|
if (! $bulk) {
|
||||||
return $this->listResponse($quote);
|
return $this->itemResponse($quote);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -716,7 +744,7 @@ class QuoteController extends BaseController
|
|||||||
$this->quote_repo->delete($quote);
|
$this->quote_repo->delete($quote);
|
||||||
|
|
||||||
if (! $bulk) {
|
if (! $bulk) {
|
||||||
return $this->listResponse($quote);
|
return $this->itemResponse($quote);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -511,21 +511,21 @@ class RecurringExpenseController extends BaseController
|
|||||||
$this->recurring_expense_repo->archive($recurring_expense);
|
$this->recurring_expense_repo->archive($recurring_expense);
|
||||||
|
|
||||||
if (! $bulk) {
|
if (! $bulk) {
|
||||||
return $this->listResponse($recurring_expense);
|
return $this->itemResponse($recurring_expense);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'restore':
|
case 'restore':
|
||||||
$this->recurring_expense_repo->restore($recurring_expense);
|
$this->recurring_expense_repo->restore($recurring_expense);
|
||||||
|
|
||||||
if (! $bulk) {
|
if (! $bulk) {
|
||||||
return $this->listResponse($recurring_expense);
|
return $this->itemResponse($recurring_expense);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'delete':
|
case 'delete':
|
||||||
$this->recurring_expense_repo->delete($recurring_expense);
|
$this->recurring_expense_repo->delete($recurring_expense);
|
||||||
|
|
||||||
if (! $bulk) {
|
if (! $bulk) {
|
||||||
return $this->listResponse($recurring_expense);
|
return $this->itemResponse($recurring_expense);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'email':
|
case 'email':
|
||||||
|
@ -662,21 +662,21 @@ class RecurringInvoiceController extends BaseController
|
|||||||
$this->recurring_invoice_repo->archive($recurring_invoice);
|
$this->recurring_invoice_repo->archive($recurring_invoice);
|
||||||
|
|
||||||
if (! $bulk) {
|
if (! $bulk) {
|
||||||
return $this->listResponse($recurring_invoice);
|
return $this->itemResponse($recurring_invoice);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'restore':
|
case 'restore':
|
||||||
$this->recurring_invoice_repo->restore($recurring_invoice);
|
$this->recurring_invoice_repo->restore($recurring_invoice);
|
||||||
|
|
||||||
if (! $bulk) {
|
if (! $bulk) {
|
||||||
return $this->listResponse($recurring_invoice);
|
return $this->itemResponse($recurring_invoice);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'delete':
|
case 'delete':
|
||||||
$this->recurring_invoice_repo->delete($recurring_invoice);
|
$this->recurring_invoice_repo->delete($recurring_invoice);
|
||||||
|
|
||||||
if (! $bulk) {
|
if (! $bulk) {
|
||||||
return $this->listResponse($recurring_invoice);
|
return $this->itemResponse($recurring_invoice);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'email':
|
case 'email':
|
||||||
|
@ -17,6 +17,7 @@ use App\Utils\Traits\MakesHash;
|
|||||||
use App\Utils\Traits\UserSessionAttributes;
|
use App\Utils\Traits\UserSessionAttributes;
|
||||||
use Illuminate\Http\RedirectResponse;
|
use Illuminate\Http\RedirectResponse;
|
||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class VerifiesUserEmail.
|
* Class VerifiesUserEmail.
|
||||||
@ -33,14 +34,12 @@ trait VerifiesUserEmail
|
|||||||
{
|
{
|
||||||
$user = User::where('confirmation_code', request()->confirmation_code)->first();
|
$user = User::where('confirmation_code', request()->confirmation_code)->first();
|
||||||
|
|
||||||
// if ($user = User::whereRaw("BINARY `confirmation_code`= ?", request()->input('confirmation_code'))->first()) {
|
|
||||||
|
|
||||||
if (! $user) {
|
if (! $user) {
|
||||||
return $this->render('auth.confirmed', ['root' => 'themes', 'message' => ctrans('texts.wrong_confirmation')]);
|
return $this->render('auth.confirmed', ['root' => 'themes', 'message' => ctrans('texts.wrong_confirmation')]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$user->email_verified_at = now();
|
$user->email_verified_at = now();
|
||||||
$user->confirmation_code = null;
|
// $user->confirmation_code = null; //this prevented the form from showing validation errors.
|
||||||
$user->save();
|
$user->save();
|
||||||
|
|
||||||
if (isset($user->oauth_user_id)) {
|
if (isset($user->oauth_user_id)) {
|
||||||
@ -64,10 +63,18 @@ trait VerifiesUserEmail
|
|||||||
{
|
{
|
||||||
$user = User::where('id', $this->decodePrimaryKey(request()->user_id))->firstOrFail();
|
$user = User::where('id', $this->decodePrimaryKey(request()->user_id))->firstOrFail();
|
||||||
|
|
||||||
request()->validate([
|
$validator = Validator::make(request()->all(), [
|
||||||
'password' => ['required', 'min:6'],
|
//'password' => ['required', 'min:6'],
|
||||||
|
'password' => 'min:6|required_with:password_confirmation|same:password_confirmation',
|
||||||
|
'password_confirmation' => 'min:6'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return back()
|
||||||
|
->withErrors($validator)
|
||||||
|
->withInput();
|
||||||
|
}
|
||||||
|
|
||||||
$user->password = Hash::make(request()->password);
|
$user->password = Hash::make(request()->password);
|
||||||
|
|
||||||
$user->email_verified_at = now();
|
$user->email_verified_at = now();
|
||||||
|
@ -98,6 +98,8 @@ class BillingPortalPurchase extends Component
|
|||||||
*/
|
*/
|
||||||
public $payment_method_id;
|
public $payment_method_id;
|
||||||
|
|
||||||
|
private $user_coupon;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of steps that frontend form follows.
|
* List of steps that frontend form follows.
|
||||||
*
|
*
|
||||||
@ -263,6 +265,9 @@ class BillingPortalPurchase extends Component
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// nlog($this->subscription->group_settings->settings);
|
||||||
|
// nlog($this->subscription->group_settings->settings->currency_id);
|
||||||
|
|
||||||
if(array_key_exists('currency_id', $this->request_data)) {
|
if(array_key_exists('currency_id', $this->request_data)) {
|
||||||
|
|
||||||
$currency = Cache::get('currencies')->filter(function ($item){
|
$currency = Cache::get('currencies')->filter(function ($item){
|
||||||
@ -272,6 +277,16 @@ class BillingPortalPurchase extends Component
|
|||||||
if($currency)
|
if($currency)
|
||||||
$data['settings']->currency_id = $currency->id;
|
$data['settings']->currency_id = $currency->id;
|
||||||
|
|
||||||
|
}
|
||||||
|
elseif($this->subscription->group_settings && property_exists($this->subscription->group_settings->settings, 'currency_id')) {
|
||||||
|
|
||||||
|
$currency = Cache::get('currencies')->filter(function ($item){
|
||||||
|
return $item->id == $this->subscription->group_settings->settings->currency_id;
|
||||||
|
})->first();
|
||||||
|
|
||||||
|
if($currency)
|
||||||
|
$data['settings']->currency_id = $currency->id;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (array_key_exists('locale', $this->request_data)) {
|
if (array_key_exists('locale', $this->request_data)) {
|
||||||
@ -436,32 +451,45 @@ class BillingPortalPurchase extends Component
|
|||||||
*/
|
*/
|
||||||
public function updateQuantity(string $option): int
|
public function updateQuantity(string $option): int
|
||||||
{
|
{
|
||||||
|
$this->handleCoupon();
|
||||||
|
|
||||||
if ($this->quantity == 1 && $option == 'decrement') {
|
if ($this->quantity == 1 && $option == 'decrement') {
|
||||||
|
$this->price = $this->price * 1;
|
||||||
return $this->quantity;
|
return $this->quantity;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->quantity >= $this->subscription->max_seats_limit && $option == 'increment') {
|
if ($this->quantity > $this->subscription->max_seats_limit && $option == 'increment') {
|
||||||
|
$this->price = $this->price * $this->subscription->max_seats_limit;
|
||||||
return $this->quantity;
|
return $this->quantity;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($option == 'increment') {
|
if ($option == 'increment') {
|
||||||
$this->quantity++;
|
$this->quantity++;
|
||||||
$this->price = $this->subscription->promo_price * $this->quantity;
|
$this->price = $this->price * $this->quantity;
|
||||||
return $this->quantity;
|
return $this->quantity;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->quantity--;
|
$this->quantity--;
|
||||||
$this->price = $this->subscription->promo_price * $this->quantity;
|
$this->price = $this->price * $this->quantity;
|
||||||
|
|
||||||
return $this->quantity;
|
return $this->quantity;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function handleCoupon()
|
public function handleCoupon()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if($this->steps['discount_applied']){
|
||||||
|
$this->price = $this->subscription->promo_price;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->coupon == $this->subscription->promo_code) {
|
if ($this->coupon == $this->subscription->promo_code) {
|
||||||
$this->price = $this->subscription->promo_price;
|
$this->price = $this->subscription->promo_price;
|
||||||
|
$this->quantity = 1;
|
||||||
$this->steps['discount_applied'] = true;
|
$this->steps['discount_applied'] = true;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
$this->price = $this->subscription->price;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function passwordlessLogin()
|
public function passwordlessLogin()
|
||||||
|
@ -20,7 +20,6 @@ use Livewire\WithPagination;
|
|||||||
|
|
||||||
class QuotesTable extends Component
|
class QuotesTable extends Component
|
||||||
{
|
{
|
||||||
use WithSorting;
|
|
||||||
use WithPagination;
|
use WithPagination;
|
||||||
|
|
||||||
public $per_page = 10;
|
public $per_page = 10;
|
||||||
@ -29,6 +28,19 @@ class QuotesTable extends Component
|
|||||||
|
|
||||||
public $company;
|
public $company;
|
||||||
|
|
||||||
|
public $sort_field = 'status_id'; // Default sortBy. Feel free to change or pull from client/company settings.
|
||||||
|
|
||||||
|
public $sort_asc = true;
|
||||||
|
|
||||||
|
public function sortBy($field)
|
||||||
|
{
|
||||||
|
$this->sort_field === $field
|
||||||
|
? $this->sort_asc = ! $this->sort_asc
|
||||||
|
: $this->sort_asc = true;
|
||||||
|
|
||||||
|
$this->sort_field = $field;
|
||||||
|
}
|
||||||
|
|
||||||
public function mount()
|
public function mount()
|
||||||
{
|
{
|
||||||
MultiDB::setDb($this->company->db);
|
MultiDB::setDb($this->company->db);
|
||||||
@ -36,6 +48,7 @@ class QuotesTable extends Component
|
|||||||
|
|
||||||
public function render()
|
public function render()
|
||||||
{
|
{
|
||||||
|
|
||||||
$query = Quote::query()
|
$query = Quote::query()
|
||||||
->with('client.gateway_tokens', 'company', 'client.contacts')
|
->with('client.gateway_tokens', 'company', 'client.contacts')
|
||||||
->orderBy($this->sort_field, $this->sort_asc ? 'asc' : 'desc');
|
->orderBy($this->sort_field, $this->sort_asc ? 'asc' : 'desc');
|
||||||
@ -44,7 +57,6 @@ class QuotesTable extends Component
|
|||||||
|
|
||||||
/* Special filter for expired*/
|
/* Special filter for expired*/
|
||||||
if (in_array('-1', $this->status)) {
|
if (in_array('-1', $this->status)) {
|
||||||
// $query->whereDate('due_date', '<=', now()->startOfDay());
|
|
||||||
|
|
||||||
$query->where(function ($query) {
|
$query->where(function ($query) {
|
||||||
$query->whereDate('due_date', '<=', now()->startOfDay())
|
$query->whereDate('due_date', '<=', now()->startOfDay())
|
||||||
@ -69,10 +81,6 @@ class QuotesTable extends Component
|
|||||||
->where('company_id', $this->company->id)
|
->where('company_id', $this->company->id)
|
||||||
->where('client_id', auth()->guard('contact')->user()->client->id)
|
->where('client_id', auth()->guard('contact')->user()->client->id)
|
||||||
->where('status_id', '<>', Quote::STATUS_DRAFT)
|
->where('status_id', '<>', Quote::STATUS_DRAFT)
|
||||||
// ->where(function ($query){
|
|
||||||
// $query->whereDate('due_date', '>=', now())
|
|
||||||
// ->orWhereNull('due_date');
|
|
||||||
// })
|
|
||||||
->where('is_deleted', 0)
|
->where('is_deleted', 0)
|
||||||
->withTrashed()
|
->withTrashed()
|
||||||
->paginate($this->per_page);
|
->paginate($this->per_page);
|
||||||
|
@ -14,6 +14,7 @@ namespace App\Http\Requests\Expense;
|
|||||||
use App\Http\Requests\Request;
|
use App\Http\Requests\Request;
|
||||||
use App\Http\ValidationRules\Expense\UniqueExpenseNumberRule;
|
use App\Http\ValidationRules\Expense\UniqueExpenseNumberRule;
|
||||||
use App\Models\Expense;
|
use App\Models\Expense;
|
||||||
|
use App\Models\Project;
|
||||||
use App\Models\PurchaseOrder;
|
use App\Models\PurchaseOrder;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
use Illuminate\Validation\Rule;
|
use Illuminate\Validation\Rule;
|
||||||
@ -65,13 +66,29 @@ class StoreExpenseRequest extends Request
|
|||||||
$input['color'] = '';
|
$input['color'] = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Ensure the project is related */
|
||||||
|
if (array_key_exists('project_id', $input) && isset($input['project_id'])) {
|
||||||
|
$project = Project::withTrashed()->find($input['project_id'])->company()->first();
|
||||||
|
|
||||||
|
if($project){
|
||||||
|
$input['client_id'] = $project->client_id;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unset($input['project_id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
$this->replace($input);
|
$this->replace($input);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function messages()
|
public function messages()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'unique' => ctrans('validation.unique', ['attribute' => 'email']),
|
// 'unique' => ctrans('validation.unique', ['attribute' => 'number']),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
namespace App\Http\Requests\Expense;
|
namespace App\Http\Requests\Expense;
|
||||||
|
|
||||||
use App\Http\Requests\Request;
|
use App\Http\Requests\Request;
|
||||||
|
use App\Models\Project;
|
||||||
use App\Utils\Traits\ChecksEntityStatus;
|
use App\Utils\Traits\ChecksEntityStatus;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
use Illuminate\Validation\Rule;
|
use Illuminate\Validation\Rule;
|
||||||
@ -35,9 +36,6 @@ class UpdateExpenseRequest extends Request
|
|||||||
{
|
{
|
||||||
/* Ensure we have a client name, and that all emails are unique*/
|
/* Ensure we have a client name, and that all emails are unique*/
|
||||||
$rules = [];
|
$rules = [];
|
||||||
// $rules['country_id'] = 'integer|nullable';
|
|
||||||
|
|
||||||
// $rules['contacts.*.email'] = 'nullable|distinct';
|
|
||||||
|
|
||||||
if (isset($this->number)) {
|
if (isset($this->number)) {
|
||||||
$rules['number'] = Rule::unique('expenses')->where('company_id', auth()->user()->company()->id)->ignore($this->expense->id);
|
$rules['number'] = Rule::unique('expenses')->where('company_id', auth()->user()->company()->id)->ignore($this->expense->id);
|
||||||
@ -46,16 +44,6 @@ class UpdateExpenseRequest extends Request
|
|||||||
return $this->globalRules($rules);
|
return $this->globalRules($rules);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function messages()
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'unique' => ctrans('validation.unique', ['attribute' => 'email']),
|
|
||||||
'email' => ctrans('validation.email', ['attribute' => 'email']),
|
|
||||||
'name.required' => ctrans('validation.required', ['attribute' => 'name']),
|
|
||||||
'required' => ctrans('validation.required', ['attribute' => 'email']),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function prepareForValidation()
|
public function prepareForValidation()
|
||||||
{
|
{
|
||||||
$input = $this->all();
|
$input = $this->all();
|
||||||
@ -74,6 +62,20 @@ class UpdateExpenseRequest extends Request
|
|||||||
$input['currency_id'] = (string) auth()->user()->company()->settings->currency_id;
|
$input['currency_id'] = (string) auth()->user()->company()->settings->currency_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Ensure the project is related */
|
||||||
|
if (array_key_exists('project_id', $input) && isset($input['project_id'])) {
|
||||||
|
$project = Project::withTrashed()->find($input['project_id'])->company()->first();
|
||||||
|
|
||||||
|
if($project){
|
||||||
|
$input['client_id'] = $project->client_id;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unset($input['project_id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
$this->replace($input);
|
$this->replace($input);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,15 +47,4 @@ class LoginRequest extends Request
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
// public function prepareForValidation()
|
|
||||||
// {
|
|
||||||
// $input = $this->all();
|
|
||||||
|
|
||||||
// // if(base64_decode(base64_encode($input['password'])) === $input['password'])
|
|
||||||
// // $input['password'] = base64_decode($input['password']);
|
|
||||||
|
|
||||||
// // nlog($input['password']);
|
|
||||||
|
|
||||||
// $this->replace($input);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
namespace App\Http\Requests\Task;
|
namespace App\Http\Requests\Task;
|
||||||
|
|
||||||
use App\Http\Requests\Request;
|
use App\Http\Requests\Request;
|
||||||
|
use App\Models\Project;
|
||||||
use App\Models\Task;
|
use App\Models\Task;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
use Illuminate\Validation\Rule;
|
use Illuminate\Validation\Rule;
|
||||||
@ -38,19 +39,49 @@ class StoreTaskRequest extends Request
|
|||||||
$rules['number'] = Rule::unique('tasks')->where('company_id', auth()->user()->company()->id);
|
$rules['number'] = Rule::unique('tasks')->where('company_id', auth()->user()->company()->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(isset($this->client_id))
|
||||||
|
$rules['client_id'] = 'bail|required|exists:clients,id,company_id,'.auth()->user()->company()->id.',is_deleted,0';
|
||||||
|
|
||||||
|
if(isset($this->project_id))
|
||||||
|
$rules['project_id'] = 'bail|required|exists:projects,id,company_id,'.auth()->user()->company()->id.',is_deleted,0';
|
||||||
|
|
||||||
|
$rules['timelog'] = ['bail','array',function ($attribute, $values, $fail) {
|
||||||
|
|
||||||
|
foreach($values as $k)
|
||||||
|
{
|
||||||
|
if(!is_int($k[0]) || !is_int($k[1]))
|
||||||
|
$fail('The '.$attribute.' - '.print_r($k,1).' is invalid. Unix timestamps only.');
|
||||||
|
}
|
||||||
|
|
||||||
|
}];
|
||||||
|
|
||||||
|
|
||||||
return $this->globalRules($rules);
|
return $this->globalRules($rules);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function prepareForValidation()
|
public function prepareForValidation()
|
||||||
{
|
{
|
||||||
$input = $this->all();
|
$input = $this->all();
|
||||||
|
|
||||||
$input = $this->decodePrimaryKeys($this->all());
|
$input = $this->decodePrimaryKeys($this->all());
|
||||||
|
|
||||||
if (array_key_exists('status_id', $input) && is_string($input['status_id'])) {
|
if (array_key_exists('status_id', $input) && is_string($input['status_id'])) {
|
||||||
$input['status_id'] = $this->decodePrimaryKey($input['status_id']);
|
$input['status_id'] = $this->decodePrimaryKey($input['status_id']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Ensure the project is related */
|
||||||
|
if (array_key_exists('project_id', $input) && isset($input['project_id'])) {
|
||||||
|
$project = Project::withTrashed()->find($input['project_id'])->company()->first();
|
||||||
|
|
||||||
|
if($project){
|
||||||
|
$input['client_id'] = $project->client_id;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unset($input['project_id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
$this->replace($input);
|
$this->replace($input);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
namespace App\Http\Requests\Task;
|
namespace App\Http\Requests\Task;
|
||||||
|
|
||||||
use App\Http\Requests\Request;
|
use App\Http\Requests\Request;
|
||||||
|
use App\Models\Project;
|
||||||
use App\Utils\Traits\ChecksEntityStatus;
|
use App\Utils\Traits\ChecksEntityStatus;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
use Illuminate\Validation\Rule;
|
use Illuminate\Validation\Rule;
|
||||||
@ -39,6 +40,22 @@ class UpdateTaskRequest extends Request
|
|||||||
$rules['number'] = Rule::unique('tasks')->where('company_id', auth()->user()->company()->id)->ignore($this->task->id);
|
$rules['number'] = Rule::unique('tasks')->where('company_id', auth()->user()->company()->id)->ignore($this->task->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(isset($this->client_id))
|
||||||
|
$rules['client_id'] = 'bail|required|exists:clients,id,company_id,'.auth()->user()->company()->id.',is_deleted,0';
|
||||||
|
|
||||||
|
if(isset($this->project_id))
|
||||||
|
$rules['project_id'] = 'bail|required|exists:projects,id,company_id,'.auth()->user()->company()->id.',is_deleted,0';
|
||||||
|
|
||||||
|
$rules['timelog'] = ['bail','array',function ($attribute, $values, $fail) {
|
||||||
|
|
||||||
|
foreach($values as $k)
|
||||||
|
{
|
||||||
|
if(!is_int($k[0]) || !is_int($k[1]))
|
||||||
|
$fail('The '.$attribute.' - '.print_r($k,1).' is invalid. Unix timestamps only.');
|
||||||
|
}
|
||||||
|
|
||||||
|
}];
|
||||||
|
|
||||||
return $this->globalRules($rules);
|
return $this->globalRules($rules);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,6 +67,20 @@ class UpdateTaskRequest extends Request
|
|||||||
$input['status_id'] = $this->decodePrimaryKey($input['status_id']);
|
$input['status_id'] = $this->decodePrimaryKey($input['status_id']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Ensure the project is related */
|
||||||
|
if (array_key_exists('project_id', $input) && isset($input['project_id'])) {
|
||||||
|
$project = Project::withTrashed()->find($input['project_id'])->company()->first();
|
||||||
|
|
||||||
|
if($project){
|
||||||
|
$input['client_id'] = $project->client_id;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unset($input['project_id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (array_key_exists('color', $input) && is_null($input['color'])) {
|
if (array_key_exists('color', $input) && is_null($input['color'])) {
|
||||||
$input['color'] = '';
|
$input['color'] = '';
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,8 @@ class BlackListRule implements Rule
|
|||||||
'vusra.com',
|
'vusra.com',
|
||||||
'fourthgenet.com',
|
'fourthgenet.com',
|
||||||
'arxxwalls.com',
|
'arxxwalls.com',
|
||||||
'superhostforumla.com'
|
'superhostforumla.com',
|
||||||
|
'wnpop.com',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -65,6 +65,7 @@ class BaseTransformer
|
|||||||
|
|
||||||
public function getClient($client_name, $client_email)
|
public function getClient($client_name, $client_email)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (! empty($client_name)) {
|
if (! empty($client_name)) {
|
||||||
$client_id_search = $this->company
|
$client_id_search = $this->company
|
||||||
->clients()
|
->clients()
|
||||||
|
@ -38,13 +38,15 @@ class ClientTransformer extends BaseTransformer
|
|||||||
$settings->payment_terms = $data['Payment Terms'];
|
$settings->payment_terms = $data['Payment Terms'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$client_id_proxy = array_key_exists('Customer ID', $data) ? 'Customer ID' : 'Primary Contact ID';
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'company_id' => $this->company->id,
|
'company_id' => $this->company->id,
|
||||||
'name' => $this->getString($data, 'Company Name'),
|
'name' => $this->getString($data, 'Display Name'),
|
||||||
'phone' => $this->getString($data, 'Phone'),
|
'phone' => $this->getString($data, 'Phone'),
|
||||||
'private_notes' => $this->getString($data, 'Notes'),
|
'private_notes' => $this->getString($data, 'Notes'),
|
||||||
'website' => $this->getString($data, 'Website'),
|
'website' => $this->getString($data, 'Website'),
|
||||||
'id_number' => $this->getString($data, 'Customer ID'),
|
'id_number' => $this->getString($data, $client_id_proxy),
|
||||||
'address1' => $this->getString($data, 'Billing Address'),
|
'address1' => $this->getString($data, 'Billing Address'),
|
||||||
'address2' => $this->getString($data, 'Billing Street2'),
|
'address2' => $this->getString($data, 'Billing Street2'),
|
||||||
'city' => $this->getString($data, 'Billing City'),
|
'city' => $this->getString($data, 'Billing City'),
|
||||||
|
@ -40,7 +40,7 @@ class InvoiceTransformer extends BaseTransformer
|
|||||||
|
|
||||||
$transformed = [
|
$transformed = [
|
||||||
'company_id' => $this->company->id,
|
'company_id' => $this->company->id,
|
||||||
'client_id' => $this->getClient($this->getString($invoice_data, 'Customer ID'), null),
|
'client_id' => $this->getClient($this->getString($invoice_data, 'Customer ID'), $this->getString($invoice_data, 'Primary Contact EmailID')),
|
||||||
'number' => $this->getString($invoice_data, 'Invoice Number'),
|
'number' => $this->getString($invoice_data, 'Invoice Number'),
|
||||||
'date' => isset($invoice_data['Invoice Date']) ? date('Y-m-d', strtotime($invoice_data['Invoice Date'])) : null,
|
'date' => isset($invoice_data['Invoice Date']) ? date('Y-m-d', strtotime($invoice_data['Invoice Date'])) : null,
|
||||||
'due_date' => isset($invoice_data['Due Date']) ? date('Y-m-d', strtotime($invoice_data['Due Date'])) : null,
|
'due_date' => isset($invoice_data['Due Date']) ? date('Y-m-d', strtotime($invoice_data['Due Date'])) : null,
|
||||||
@ -51,14 +51,19 @@ class InvoiceTransformer extends BaseTransformer
|
|||||||
'balance' => $this->getFloat($invoice_data, 'Balance'),
|
'balance' => $this->getFloat($invoice_data, 'Balance'),
|
||||||
'status_id' => $invoiceStatusMap[$status =
|
'status_id' => $invoiceStatusMap[$status =
|
||||||
strtolower($this->getString($invoice_data, 'Invoice Status'))] ?? Invoice::STATUS_SENT,
|
strtolower($this->getString($invoice_data, 'Invoice Status'))] ?? Invoice::STATUS_SENT,
|
||||||
|
'terms' => $this->getString($invoice_data, 'Terms & Conditions'),
|
||||||
|
|
||||||
// 'viewed' => $status === 'viewed',
|
// 'viewed' => $status === 'viewed',
|
||||||
];
|
];
|
||||||
|
|
||||||
$line_items = [];
|
$line_items = [];
|
||||||
foreach ($line_items_data as $record) {
|
foreach ($line_items_data as $record) {
|
||||||
|
|
||||||
|
$item_notes_key = array_key_exists('Item Description', $record) ? 'Item Description' : 'Item Desc';
|
||||||
|
|
||||||
$line_items[] = [
|
$line_items[] = [
|
||||||
'product_key' => $this->getString($record, 'Item Name'),
|
'product_key' => $this->getString($record, 'Item Name'),
|
||||||
'notes' => $this->getString($record, 'Item Description'),
|
'notes' => $this->getString($record, $item_notes_key),
|
||||||
'cost' => round($this->getFloat($record, 'Item Price'), 2),
|
'cost' => round($this->getFloat($record, 'Item Price'), 2),
|
||||||
'quantity' => $this->getFloat($record, 'Quantity'),
|
'quantity' => $this->getFloat($record, 'Quantity'),
|
||||||
'discount' => $this->getString($record, 'Discount Amount'),
|
'discount' => $this->getString($record, 'Discount Amount'),
|
||||||
|
@ -152,6 +152,12 @@ class BaseTransformer
|
|||||||
return Number::parseFloat($number);
|
return Number::parseFloat($number);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getFloatWithSamePrecision($data, $field)
|
||||||
|
{
|
||||||
|
$precision = (int) strpos(strrev($data[$field]), ".");
|
||||||
|
|
||||||
|
return round($data[$field], $precision);
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* @param $name
|
* @param $name
|
||||||
*
|
*
|
||||||
|
@ -39,11 +39,11 @@ class InvoiceTransformer extends BaseTransformer
|
|||||||
'is_sent' => $this->getString($data, 'invoice.is_sent'),
|
'is_sent' => $this->getString($data, 'invoice.is_sent'),
|
||||||
'private_notes' => $this->getString($data, 'invoice.private_notes'),
|
'private_notes' => $this->getString($data, 'invoice.private_notes'),
|
||||||
'tax_name1' => $this->getString($data, 'invoice.tax_name1'),
|
'tax_name1' => $this->getString($data, 'invoice.tax_name1'),
|
||||||
'tax_rate1' => $this->getFloat($data, 'invoice.tax_rate1'),
|
'tax_rate1' => $this->getFloatWithSamePrecision($data, 'invoice.tax_rate1'),
|
||||||
'tax_name2' => $this->getString($data, 'invoice.tax_name2'),
|
'tax_name2' => $this->getString($data, 'invoice.tax_name2'),
|
||||||
'tax_rate2' => $this->getFloat($data, 'invoice.tax_rate2'),
|
'tax_rate2' => $this->getFloatWithSamePrecision($data, 'invoice.tax_rate2'),
|
||||||
'tax_name3' => $this->getString($data, 'invoice.tax_name3'),
|
'tax_name3' => $this->getString($data, 'invoice.tax_name3'),
|
||||||
'tax_rate3' => $this->getFloat($data, 'invoice.tax_rate3'),
|
'tax_rate3' => $this->getFloatWithSamePrecision($data, 'invoice.tax_rate3'),
|
||||||
'custom_value1' => $this->getString($data, 'invoice.custom_value1'),
|
'custom_value1' => $this->getString($data, 'invoice.custom_value1'),
|
||||||
'custom_value2' => $this->getString($data, 'invoice.custom_value2'),
|
'custom_value2' => $this->getString($data, 'invoice.custom_value2'),
|
||||||
'custom_value3' => $this->getString($data, 'invoice.custom_value3'),
|
'custom_value3' => $this->getString($data, 'invoice.custom_value3'),
|
||||||
|
@ -40,7 +40,8 @@ class RecurringInvoicesCron
|
|||||||
public function handle() : void
|
public function handle() : void
|
||||||
{
|
{
|
||||||
/* Get all invoices where the send date is less than NOW + 30 minutes() */
|
/* Get all invoices where the send date is less than NOW + 30 minutes() */
|
||||||
nlog('Sending recurring invoices '.Carbon::now()->format('Y-m-d h:i:s'));
|
$start = Carbon::now()->format('Y-m-d h:i:s');
|
||||||
|
nlog('Sending recurring invoices '.$start);
|
||||||
|
|
||||||
if (! config('ninja.db.multi_db_enabled')) {
|
if (! config('ninja.db.multi_db_enabled')) {
|
||||||
$recurring_invoices = RecurringInvoice::where('next_send_date', '<=', now()->toDateTimeString())
|
$recurring_invoices = RecurringInvoice::where('next_send_date', '<=', now()->toDateTimeString())
|
||||||
@ -119,5 +120,8 @@ class RecurringInvoicesCron
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nlog("Recurring invoice send duration " . $start . " - " . Carbon::now()->format('Y-m-d h:i:s'));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,18 @@ class NinjaMailerJob implements ShouldQueue
|
|||||||
$this->nmo->mailable->replyTo($this->company->owner()->email, $this->company->owner()->present()->name());
|
$this->nmo->mailable->replyTo($this->company->owner()->email, $this->company->owner()->present()->name());
|
||||||
}
|
}
|
||||||
|
|
||||||
// $this->nmo->mailable->tag($this->company->company_key);
|
$this->nmo->mailable->tag($this->company->company_key);
|
||||||
|
|
||||||
|
if($this->nmo->invitation)
|
||||||
|
{
|
||||||
|
|
||||||
|
$this->nmo
|
||||||
|
->mailable
|
||||||
|
->withSymfonyMessage(function ($message) {
|
||||||
|
$message->getHeaders()->addTextHeader('x-invitation', $this->nmo->invitation->key);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
//send email
|
//send email
|
||||||
try {
|
try {
|
||||||
@ -313,6 +324,10 @@ class NinjaMailerJob implements ShouldQueue
|
|||||||
if($this->company->is_disabled && !$this->override)
|
if($this->company->is_disabled && !$this->override)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
/* To handle spam users we drop all emails from flagged accounts */
|
||||||
|
if(Ninja::isHosted() && $this->company->account && $this->company->account->is_flagged)
|
||||||
|
return true;
|
||||||
|
|
||||||
/* On the hosted platform we set default contacts a @example.com email address - we shouldn't send emails to these types of addresses */
|
/* On the hosted platform we set default contacts a @example.com email address - we shouldn't send emails to these types of addresses */
|
||||||
if(Ninja::isHosted() && $this->nmo->to_user && strpos($this->nmo->to_user->email, '@example.com') !== false)
|
if(Ninja::isHosted() && $this->nmo->to_user && strpos($this->nmo->to_user->email, '@example.com') !== false)
|
||||||
return true;
|
return true;
|
||||||
@ -325,10 +340,6 @@ class NinjaMailerJob implements ShouldQueue
|
|||||||
if(Ninja::isHosted() && $this->company->account && $this->company->account->emailQuotaExceeded())
|
if(Ninja::isHosted() && $this->company->account && $this->company->account->emailQuotaExceeded())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
/* To handle spam users we drop all emails from flagged accounts */
|
|
||||||
if(Ninja::isHosted() && $this->company->account && $this->company->account->is_flagged)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
/* If the account is verified, we allow emails to flow */
|
/* If the account is verified, we allow emails to flow */
|
||||||
if(Ninja::isHosted() && $this->company->account && $this->company->account->is_verified_account) {
|
if(Ninja::isHosted() && $this->company->account && $this->company->account->is_verified_account) {
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ class PaymentFailedMailer implements ShouldQueue
|
|||||||
|
|
||||||
public ?PaymentHash $payment_hash;
|
public ?PaymentHash $payment_hash;
|
||||||
|
|
||||||
public string $error;
|
public $error;
|
||||||
|
|
||||||
public Company $company;
|
public Company $company;
|
||||||
|
|
||||||
@ -55,7 +55,7 @@ class PaymentFailedMailer implements ShouldQueue
|
|||||||
* @param $company
|
* @param $company
|
||||||
* @param $amount
|
* @param $amount
|
||||||
*/
|
*/
|
||||||
public function __construct(?PaymentHash $payment_hash, Company $company, Client $client, string $error)
|
public function __construct(?PaymentHash $payment_hash, Company $company, Client $client, $error)
|
||||||
{
|
{
|
||||||
$this->payment_hash = $payment_hash;
|
$this->payment_hash = $payment_hash;
|
||||||
$this->client = $client;
|
$this->client = $client;
|
||||||
@ -70,6 +70,10 @@ class PaymentFailedMailer implements ShouldQueue
|
|||||||
*/
|
*/
|
||||||
public function handle()
|
public function handle()
|
||||||
{
|
{
|
||||||
|
if(!is_string($this->error)){
|
||||||
|
$this->error = "Payment failed, no reason given.";
|
||||||
|
}
|
||||||
|
|
||||||
//Set DB
|
//Set DB
|
||||||
MultiDB::setDb($this->company->db);
|
MultiDB::setDb($this->company->db);
|
||||||
App::setLocale($this->client->locale());
|
App::setLocale($this->client->locale());
|
||||||
|
@ -26,6 +26,7 @@ use App\Models\Company;
|
|||||||
use App\Models\CreditInvitation;
|
use App\Models\CreditInvitation;
|
||||||
use App\Models\InvoiceInvitation;
|
use App\Models\InvoiceInvitation;
|
||||||
use App\Models\Payment;
|
use App\Models\Payment;
|
||||||
|
use App\Models\PurchaseOrderInvitation;
|
||||||
use App\Models\QuoteInvitation;
|
use App\Models\QuoteInvitation;
|
||||||
use App\Models\RecurringInvoiceInvitation;
|
use App\Models\RecurringInvoiceInvitation;
|
||||||
use App\Models\SystemLog;
|
use App\Models\SystemLog;
|
||||||
@ -283,6 +284,8 @@ class ProcessPostmarkWebhook implements ShouldQueue
|
|||||||
return $invitation;
|
return $invitation;
|
||||||
elseif($invitation = CreditInvitation::where('message_id', $message_id)->first())
|
elseif($invitation = CreditInvitation::where('message_id', $message_id)->first())
|
||||||
return $invitation;
|
return $invitation;
|
||||||
|
elseif($invitation = PurchaseOrderInvitation::where('message_id', $message_id)->first())
|
||||||
|
return $invitation;
|
||||||
else
|
else
|
||||||
return $invitation;
|
return $invitation;
|
||||||
}
|
}
|
||||||
|
@ -127,7 +127,7 @@ class SendRecurring implements ShouldQueue
|
|||||||
$invoice->invitations->each(function ($invitation) use ($invoice) {
|
$invoice->invitations->each(function ($invitation) use ($invoice) {
|
||||||
if ($invitation->contact && ! $invitation->contact->trashed() && strlen($invitation->contact->email) >= 1 && $invoice->client->getSetting('auto_email_invoice')) {
|
if ($invitation->contact && ! $invitation->contact->trashed() && strlen($invitation->contact->email) >= 1 && $invoice->client->getSetting('auto_email_invoice')) {
|
||||||
try {
|
try {
|
||||||
EmailEntity::dispatch($invitation, $invoice->company)->delay(10);
|
EmailEntity::dispatch($invitation, $invoice->company)->delay(rand(10,20));
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
nlog($e->getMessage());
|
nlog($e->getMessage());
|
||||||
}
|
}
|
||||||
@ -140,13 +140,13 @@ class SendRecurring implements ShouldQueue
|
|||||||
if ($invoice->client->getSetting('auto_bill_date') == 'on_send_date' && $invoice->auto_bill_enabled) {
|
if ($invoice->client->getSetting('auto_bill_date') == 'on_send_date' && $invoice->auto_bill_enabled) {
|
||||||
nlog("attempting to autobill {$invoice->number}");
|
nlog("attempting to autobill {$invoice->number}");
|
||||||
// $invoice->service()->autoBill();
|
// $invoice->service()->autoBill();
|
||||||
AutoBill::dispatch($invoice, $this->db)->delay(20);
|
AutoBill::dispatch($invoice, $this->db)->delay(rand(30,40));
|
||||||
|
|
||||||
} elseif ($invoice->client->getSetting('auto_bill_date') == 'on_due_date' && $invoice->auto_bill_enabled) {
|
} elseif ($invoice->client->getSetting('auto_bill_date') == 'on_due_date' && $invoice->auto_bill_enabled) {
|
||||||
if ($invoice->due_date && Carbon::parse($invoice->due_date)->startOfDay()->lte(now()->startOfDay())) {
|
if ($invoice->due_date && Carbon::parse($invoice->due_date)->startOfDay()->lte(now()->startOfDay())) {
|
||||||
nlog("attempting to autobill {$invoice->number}");
|
nlog("attempting to autobill {$invoice->number}");
|
||||||
// $invoice->service()->autoBill();
|
// $invoice->service()->autoBill();
|
||||||
AutoBill::dispatch($invoice, $this->db)->delay(20);
|
AutoBill::dispatch($invoice, $this->db)->delay(rand(30,40));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,6 +75,7 @@ class ReminderJob implements ShouldQueue
|
|||||||
->with('invitations')->cursor()->each(function ($invoice) {
|
->with('invitations')->cursor()->each(function ($invoice) {
|
||||||
if ($invoice->isPayable()) {
|
if ($invoice->isPayable()) {
|
||||||
$reminder_template = $invoice->calculateTemplate('invoice');
|
$reminder_template = $invoice->calculateTemplate('invoice');
|
||||||
|
nlog("reminder template = {$reminder_template}");
|
||||||
$invoice->service()->touchReminder($reminder_template)->save();
|
$invoice->service()->touchReminder($reminder_template)->save();
|
||||||
$invoice = $this->calcLateFee($invoice, $reminder_template);
|
$invoice = $this->calcLateFee($invoice, $reminder_template);
|
||||||
|
|
||||||
@ -93,6 +94,7 @@ class ReminderJob implements ShouldQueue
|
|||||||
$invoice->client->getSetting($enabled_reminder) &&
|
$invoice->client->getSetting($enabled_reminder) &&
|
||||||
$invoice->client->getSetting('send_reminders') &&
|
$invoice->client->getSetting('send_reminders') &&
|
||||||
(Ninja::isSelfHost() || $invoice->company->account->isPaidHostedClient())) {
|
(Ninja::isSelfHost() || $invoice->company->account->isPaidHostedClient())) {
|
||||||
|
|
||||||
$invoice->invitations->each(function ($invitation) use ($invoice, $reminder_template) {
|
$invoice->invitations->each(function ($invitation) use ($invoice, $reminder_template) {
|
||||||
EmailEntity::dispatch($invitation, $invitation->company, $reminder_template);
|
EmailEntity::dispatch($invitation, $invitation->company, $reminder_template);
|
||||||
nlog("Firing reminder email for invoice {$invoice->number}");
|
nlog("Firing reminder email for invoice {$invoice->number}");
|
||||||
|
@ -12,9 +12,16 @@
|
|||||||
namespace App\Listeners\Mail;
|
namespace App\Listeners\Mail;
|
||||||
|
|
||||||
use App\Libraries\MultiDB;
|
use App\Libraries\MultiDB;
|
||||||
|
use App\Models\CreditInvitation;
|
||||||
|
use App\Models\InvoiceInvitation;
|
||||||
|
use App\Models\PurchaseOrderInvitation;
|
||||||
|
use App\Models\QuoteInvitation;
|
||||||
|
use App\Models\RecurringInvoiceInvitation;
|
||||||
|
use App\Utils\Ninja;
|
||||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
use Illuminate\Mail\Events\MessageSent;
|
use Illuminate\Mail\Events\MessageSent;
|
||||||
use Illuminate\Support\Facades\Notification;
|
use Illuminate\Support\Facades\Notification;
|
||||||
|
use Symfony\Component\Mime\MessageConverter;
|
||||||
|
|
||||||
class MailSentListener implements ShouldQueue
|
class MailSentListener implements ShouldQueue
|
||||||
{
|
{
|
||||||
@ -35,19 +42,52 @@ class MailSentListener implements ShouldQueue
|
|||||||
*/
|
*/
|
||||||
public function handle(MessageSent $event)
|
public function handle(MessageSent $event)
|
||||||
{
|
{
|
||||||
nlog("mail listener");
|
if(!Ninja::isHosted());
|
||||||
nlog($event);
|
return;
|
||||||
// if (property_exists($event->message, 'invitation') && $event->message->invitation) {
|
|
||||||
// MultiDB::setDb($event->sent->invitation->company->db);
|
|
||||||
|
|
||||||
// if ($event->message->getHeaders()->get('x-pm-message-id')) {
|
$message_id = $event->sent->getMessageId();
|
||||||
// $postmark_id = $event->sent->getHeaders()->get('x-pm-message-id')->getValue();
|
|
||||||
|
|
||||||
// // nlog($postmark_id);
|
$message = MessageConverter::toEmail($event->sent->getOriginalMessage());
|
||||||
// $invitation = $event->sent->invitation;
|
|
||||||
// $invitation->message_id = $postmark_id;
|
$invitation_key = $message->getHeaders()->get('x-invitation')->getValue();
|
||||||
// $invitation->save();
|
|
||||||
// }
|
if($message_id && $invitation_key)
|
||||||
// }
|
{
|
||||||
|
|
||||||
|
$invitation = $this->discoverInvitation($invitation_key);
|
||||||
|
|
||||||
|
if(!$invitation)
|
||||||
|
return;
|
||||||
|
|
||||||
|
$invitation->message_id = $message_id;
|
||||||
|
$invitation->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private function discoverInvitation($key)
|
||||||
|
{
|
||||||
|
|
||||||
|
$invitation = false;
|
||||||
|
|
||||||
|
foreach (MultiDB::$dbs as $db)
|
||||||
|
{
|
||||||
|
|
||||||
|
if($invitation = InvoiceInvitation::on($db)->where('key', $key)->first())
|
||||||
|
return $invitation;
|
||||||
|
elseif($invitation = QuoteInvitation::on($db)->where('key', $key)->first())
|
||||||
|
return $invitation;
|
||||||
|
elseif($invitation = RecurringInvoiceInvitation::on($db)->where('key', $key)->first())
|
||||||
|
return $invitation;
|
||||||
|
elseif($invitation = CreditInvitation::on($db)->where('key', $key)->first())
|
||||||
|
return $invitation;
|
||||||
|
elseif($invitation = PurchaseOrderInvitation::on($db)->where('key', $key)->first())
|
||||||
|
return $invitation;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return $invitation;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -96,12 +96,9 @@ class InvoiceEmailEngine extends BaseEmailEngine
|
|||||||
|
|
||||||
if (is_array($this->template_data) && array_key_exists('subject', $this->template_data) && strlen($this->template_data['subject']) > 0) {
|
if (is_array($this->template_data) && array_key_exists('subject', $this->template_data) && strlen($this->template_data['subject']) > 0) {
|
||||||
$subject_template = $this->template_data['subject'];
|
$subject_template = $this->template_data['subject'];
|
||||||
nlog('subject = template data');
|
|
||||||
} elseif (strlen($this->client->getSetting('email_subject_'.$this->reminder_template)) > 0) {
|
} elseif (strlen($this->client->getSetting('email_subject_'.$this->reminder_template)) > 0) {
|
||||||
$subject_template = $this->client->getSetting('email_subject_'.$this->reminder_template);
|
$subject_template = $this->client->getSetting('email_subject_'.$this->reminder_template);
|
||||||
nlog('subject = settings var');
|
|
||||||
} else {
|
} else {
|
||||||
nlog('subject = default template '.'email_subject_'.$this->reminder_template);
|
|
||||||
$subject_template = EmailTemplateDefaults::getDefaultTemplate('email_subject_'.$this->reminder_template, $this->client->locale());
|
$subject_template = EmailTemplateDefaults::getDefaultTemplate('email_subject_'.$this->reminder_template, $this->client->locale());
|
||||||
// $subject_template = $this->client->getSetting('email_subject_'.$this->reminder_template);
|
// $subject_template = $this->client->getSetting('email_subject_'.$this->reminder_template);
|
||||||
}
|
}
|
||||||
|
@ -115,12 +115,12 @@ class TemplateEmail extends Mailable
|
|||||||
'company' => $company,
|
'company' => $company,
|
||||||
'whitelabel' => $this->client->user->account->isPaid() ? true : false,
|
'whitelabel' => $this->client->user->account->isPaid() ? true : false,
|
||||||
'logo' => $this->company->present()->logo($settings),
|
'logo' => $this->company->present()->logo($settings),
|
||||||
])
|
]);
|
||||||
->withSymfonyMessage(function ($message) use ($company) {
|
// ->withSymfonyMessage(function ($message) use ($company) {
|
||||||
$message->getHeaders()->addTextHeader('Tag', $company->company_key);
|
// $message->getHeaders()->addTextHeader('Tag', $company->company_key);
|
||||||
$message->invitation = $this->invitation;
|
// $message->invitation = $this->invitation;
|
||||||
})
|
//});
|
||||||
->tag($company->company_key);
|
// ->tag($company->company_key);
|
||||||
|
|
||||||
/*In the hosted platform we need to slow things down a little for Storage to catch up.*/
|
/*In the hosted platform we need to slow things down a little for Storage to catch up.*/
|
||||||
|
|
||||||
|
@ -109,12 +109,12 @@ class VendorTemplateEmail extends Mailable
|
|||||||
'company' => $this->company,
|
'company' => $this->company,
|
||||||
'whitelabel' => $this->vendor->user->account->isPaid() ? true : false,
|
'whitelabel' => $this->vendor->user->account->isPaid() ? true : false,
|
||||||
'logo' => $this->company->present()->logo($settings),
|
'logo' => $this->company->present()->logo($settings),
|
||||||
])
|
]);
|
||||||
->withSymfonyMessage(function ($message) {
|
//->withSymfonyMessage(function ($message) {
|
||||||
$message->getHeaders()->addTextHeader('Tag', $this->company->company_key);
|
// $message->getHeaders()->addTextHeader('Tag', $this->company->company_key);
|
||||||
$message->invitation = $this->invitation;
|
// $message->invitation = $this->invitation;
|
||||||
})
|
//});
|
||||||
->tag($this->company->company_key);
|
// ->tag($this->company->company_key);
|
||||||
|
|
||||||
if(Ninja::isHosted() && $this->invitation){
|
if(Ninja::isHosted() && $this->invitation){
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ class Account extends BaseModel
|
|||||||
use PresentableTrait;
|
use PresentableTrait;
|
||||||
use MakesHash;
|
use MakesHash;
|
||||||
|
|
||||||
private $free_plan_email_quota = 50;
|
private $free_plan_email_quota = 20;
|
||||||
|
|
||||||
private $paid_plan_email_quota = 500;
|
private $paid_plan_email_quota = 500;
|
||||||
/**
|
/**
|
||||||
@ -390,11 +390,11 @@ class Account extends BaseModel
|
|||||||
|
|
||||||
if($this->isPaid()){
|
if($this->isPaid()){
|
||||||
$limit = $this->paid_plan_email_quota;
|
$limit = $this->paid_plan_email_quota;
|
||||||
$limit += Carbon::createFromTimestamp($this->created_at)->diffInMonths() * 100;
|
$limit += Carbon::createFromTimestamp($this->created_at)->diffInMonths() * 50;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
$limit = $this->free_plan_email_quota;
|
$limit = $this->free_plan_email_quota;
|
||||||
$limit += Carbon::createFromTimestamp($this->created_at)->diffInMonths() * 50;
|
$limit += Carbon::createFromTimestamp($this->created_at)->diffInMonths() * 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
return min($limit, 5000);
|
return min($limit, 5000);
|
||||||
|
@ -236,6 +236,11 @@ class Client extends BaseModel implements HasLocalePreference
|
|||||||
return $this->hasMany(Task::class)->withTrashed();
|
return $this->hasMany(Task::class)->withTrashed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function payments()
|
||||||
|
{
|
||||||
|
return $this->hasMany(Payment::class)->withTrashed();
|
||||||
|
}
|
||||||
|
|
||||||
public function recurring_invoices()
|
public function recurring_invoices()
|
||||||
{
|
{
|
||||||
return $this->hasMany(RecurringInvoice::class)->withTrashed();
|
return $this->hasMany(RecurringInvoice::class)->withTrashed();
|
||||||
@ -370,6 +375,8 @@ class Client extends BaseModel implements HasLocalePreference
|
|||||||
return $this->settings->{$setting};
|
return $this->settings->{$setting};
|
||||||
} elseif (is_bool($this->settings->{$setting})) {
|
} elseif (is_bool($this->settings->{$setting})) {
|
||||||
return $this->settings->{$setting};
|
return $this->settings->{$setting};
|
||||||
|
} elseif (is_int($this->settings->{$setting})) { //10-08-2022 integer client values are not being passed back! This resolves it.
|
||||||
|
return $this->settings->{$setting};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -625,11 +632,6 @@ class Client extends BaseModel implements HasLocalePreference
|
|||||||
return $defaults;
|
return $defaults;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function payments()
|
|
||||||
{
|
|
||||||
return $this->hasMany(Payment::class)->withTrashed();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function timezone_offset()
|
public function timezone_offset()
|
||||||
{
|
{
|
||||||
$offset = 0;
|
$offset = 0;
|
||||||
|
@ -405,15 +405,21 @@ class Company extends BaseModel
|
|||||||
{
|
{
|
||||||
$languages = Cache::get('languages');
|
$languages = Cache::get('languages');
|
||||||
|
|
||||||
|
//build cache and reinit
|
||||||
if (! $languages) {
|
if (! $languages) {
|
||||||
$this->buildCache(true);
|
$this->buildCache(true);
|
||||||
|
$languages = Cache::get('languages');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//if the cache is still dead, get from DB
|
||||||
|
if(!$languages && property_exists($this->settings, 'language_id'))
|
||||||
|
return Language::find($this->settings->language_id);
|
||||||
|
|
||||||
return $languages->filter(function ($item) {
|
return $languages->filter(function ($item) {
|
||||||
return $item->id == $this->settings->language_id;
|
return $item->id == $this->settings->language_id;
|
||||||
})->first();
|
})->first();
|
||||||
|
|
||||||
// return Language::find($this->settings->language_id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getLocale()
|
public function getLocale()
|
||||||
|
@ -73,6 +73,7 @@ class CompanyGateway extends BaseModel
|
|||||||
// const TYPE_WEPAY = 309;
|
// const TYPE_WEPAY = 309;
|
||||||
// const TYPE_PAYFAST = 310;
|
// const TYPE_PAYFAST = 310;
|
||||||
// const TYPE_PAYTRACE = 311;
|
// const TYPE_PAYTRACE = 311;
|
||||||
|
// const TYPE_FORTE = 314;
|
||||||
|
|
||||||
public $gateway_consts = [
|
public $gateway_consts = [
|
||||||
'38f2c48af60c7dd69e04248cbb24c36e' => 300,
|
'38f2c48af60c7dd69e04248cbb24c36e' => 300,
|
||||||
@ -85,6 +86,7 @@ class CompanyGateway extends BaseModel
|
|||||||
'8fdeed552015b3c7b44ed6c8ebd9e992' => 309,
|
'8fdeed552015b3c7b44ed6c8ebd9e992' => 309,
|
||||||
'd6814fc83f45d2935e7777071e629ef9' => 310,
|
'd6814fc83f45d2935e7777071e629ef9' => 310,
|
||||||
'bbd736b3254b0aabed6ad7fda1298c88' => 311,
|
'bbd736b3254b0aabed6ad7fda1298c88' => 311,
|
||||||
|
'kivcvjexxvdiyqtj3mju5d6yhpeht2xs' => 314,
|
||||||
'65faab2ab6e3223dbe848b1686490baz' => 320,
|
'65faab2ab6e3223dbe848b1686490baz' => 320,
|
||||||
'b9886f9257f0c6ee7c302f1c74475f6c' => 321,
|
'b9886f9257f0c6ee7c302f1c74475f6c' => 321,
|
||||||
'hxd6gwg3ekb9tb3v9lptgx1mqyg69zu9' => 322,
|
'hxd6gwg3ekb9tb3v9lptgx1mqyg69zu9' => 322,
|
||||||
@ -308,7 +310,7 @@ class CompanyGateway extends BaseModel
|
|||||||
if(strlen($fees_and_limits->fee_percent) >=1)
|
if(strlen($fees_and_limits->fee_percent) >=1)
|
||||||
$label .= $fees_and_limits->fee_percent . '%';
|
$label .= $fees_and_limits->fee_percent . '%';
|
||||||
|
|
||||||
if(strlen($fees_and_limits->fee_amount) >=1){
|
if(strlen($fees_and_limits->fee_amount) >=1 && $fees_and_limits->fee_amount > 0){
|
||||||
|
|
||||||
if(strlen($label) > 1) {
|
if(strlen($label) > 1) {
|
||||||
|
|
||||||
@ -411,8 +413,9 @@ class CompanyGateway extends BaseModel
|
|||||||
|
|
||||||
public function resolveRouteBinding($value, $field = null)
|
public function resolveRouteBinding($value, $field = null)
|
||||||
{
|
{
|
||||||
|
|
||||||
return $this
|
return $this
|
||||||
->where('id', $this->decodePrimaryKey($value))->firstOrFail();
|
->where('id', $this->decodePrimaryKey($value))->withTrashed()->firstOrFail();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -559,6 +559,10 @@ class RecurringInvoice extends BaseModel
|
|||||||
return $this->calculateDateFromTerms($date);
|
return $this->calculateDateFromTerms($date);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'on_receipt':
|
||||||
|
return Carbon::Parse($date)->copy();
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return $this->setDayOfMonth($date, $this->due_date_days);
|
return $this->setDayOfMonth($date, $this->due_date_days);
|
||||||
break;
|
break;
|
||||||
|
@ -83,6 +83,11 @@ class Subscription extends BaseModel
|
|||||||
return $this->belongsTo(User::class)->withTrashed();
|
return $this->belongsTo(User::class)->withTrashed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function group_settings()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(GroupSetting::class, 'group_id', 'id');
|
||||||
|
}
|
||||||
|
|
||||||
public function nextDateByInterval($date, $frequency_id)
|
public function nextDateByInterval($date, $frequency_id)
|
||||||
{
|
{
|
||||||
switch ($frequency_id) {
|
switch ($frequency_id) {
|
||||||
|
@ -101,6 +101,8 @@ class SystemLog extends Model
|
|||||||
|
|
||||||
const TYPE_EWAY = 313;
|
const TYPE_EWAY = 313;
|
||||||
|
|
||||||
|
const TYPE_FORTE = 314;
|
||||||
|
|
||||||
const TYPE_SQUARE = 320;
|
const TYPE_SQUARE = 320;
|
||||||
|
|
||||||
const TYPE_GOCARDLESS = 321;
|
const TYPE_GOCARDLESS = 321;
|
||||||
@ -250,7 +252,9 @@ class SystemLog extends Model
|
|||||||
case self::TYPE_WEPAY:
|
case self::TYPE_WEPAY:
|
||||||
return 'WePay';
|
return 'WePay';
|
||||||
case self::TYPE_PAYFAST:
|
case self::TYPE_PAYFAST:
|
||||||
return 'Payfast';
|
return "Payfast";
|
||||||
|
case self::TYPE_FORTE:
|
||||||
|
return "Forte";
|
||||||
default:
|
default:
|
||||||
return 'undefined';
|
return 'undefined';
|
||||||
}
|
}
|
||||||
|
@ -181,4 +181,10 @@ class Vendor extends BaseModel
|
|||||||
{
|
{
|
||||||
return $this->belongsTo(Country::class);
|
return $this->belongsTo(Country::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function date_format()
|
||||||
|
{
|
||||||
|
return $this->company->date_format();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
89
app/Notifications/Ninja/UserQualityNotification.php
Normal file
89
app/Notifications/Ninja/UserQualityNotification.php
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Notifications\Ninja;
|
||||||
|
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Bus\Queueable;
|
||||||
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
|
use Illuminate\Foundation\Bus\Dispatchable;
|
||||||
|
use Illuminate\Notifications\Messages\MailMessage;
|
||||||
|
use Illuminate\Notifications\Messages\SlackMessage;
|
||||||
|
use Illuminate\Notifications\Notification;
|
||||||
|
use Illuminate\Queue\InteractsWithQueue;
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
|
||||||
|
class UserQualityNotification extends Notification
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new notification instance.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
protected User $user;
|
||||||
|
|
||||||
|
protected string $account_key;
|
||||||
|
|
||||||
|
public function __construct(User $user, string $account_key)
|
||||||
|
{
|
||||||
|
$this->user = $user;
|
||||||
|
$this->account_key = $account_key;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the notification's delivery channels.
|
||||||
|
*
|
||||||
|
* @param mixed $notifiable
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function via($notifiable)
|
||||||
|
{
|
||||||
|
return ['slack'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the mail representation of the notification.
|
||||||
|
*
|
||||||
|
* @param mixed $notifiable
|
||||||
|
* @return MailMessage
|
||||||
|
*/
|
||||||
|
public function toMail($notifiable)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the array representation of the notification.
|
||||||
|
*
|
||||||
|
* @param mixed $notifiable
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function toArray($notifiable)
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
//
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toSlack($notifiable)
|
||||||
|
{
|
||||||
|
|
||||||
|
$content = "User Quality notification {$this->user->present()->name()} \n";
|
||||||
|
$content .= "Account: {$this->account_key }\n";
|
||||||
|
|
||||||
|
return (new SlackMessage)
|
||||||
|
->success()
|
||||||
|
->from(ctrans('texts.notification_bot'))
|
||||||
|
->image('https://app.invoiceninja.com/favicon.png')
|
||||||
|
->content($content);
|
||||||
|
}
|
||||||
|
}
|
@ -23,7 +23,10 @@ class UserObserver
|
|||||||
*/
|
*/
|
||||||
public function created(User $user)
|
public function created(User $user)
|
||||||
{
|
{
|
||||||
//
|
|
||||||
|
if(class_exists(\Modules\Admin\Jobs\Account\UserQuality::class))
|
||||||
|
\Modules\Admin\Jobs\Account\UserQuality::dispatch($user, $user->account->key);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -34,6 +37,10 @@ class UserObserver
|
|||||||
*/
|
*/
|
||||||
public function updated(User $user)
|
public function updated(User $user)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if(class_exists(\Modules\Admin\Jobs\Account\UserQuality::class))
|
||||||
|
\Modules\Admin\Jobs\Account\UserQuality::dispatch($user, $user->account->key);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -431,6 +431,10 @@ class BaseDriver extends AbstractPaymentDriver
|
|||||||
|
|
||||||
public function sendFailureMail($error)
|
public function sendFailureMail($error)
|
||||||
{
|
{
|
||||||
|
if(is_object($error)){
|
||||||
|
$error = 'Payment Aborted';
|
||||||
|
}
|
||||||
|
|
||||||
if (! is_null($this->payment_hash)) {
|
if (! is_null($this->payment_hash)) {
|
||||||
$this->unWindGatewayFees($this->payment_hash);
|
$this->unWindGatewayFees($this->payment_hash);
|
||||||
}
|
}
|
||||||
|
@ -126,6 +126,17 @@ class BraintreePaymentDriver extends BaseDriver
|
|||||||
|
|
||||||
return $result->customer;
|
return $result->customer;
|
||||||
}
|
}
|
||||||
|
//12-08-2022 catch when the customer is not created.
|
||||||
|
$data = [
|
||||||
|
'transaction_reference' => null,
|
||||||
|
'transaction_response' => $result,
|
||||||
|
'success' => false,
|
||||||
|
'description' => 'Could not create customer',
|
||||||
|
'code' => 500,
|
||||||
|
];
|
||||||
|
|
||||||
|
SystemLogger::dispatch(['server_response' => $result, 'data' => $data], SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_FAILURE, SystemLog::TYPE_BRAINTREE, $this->client, $this->client->company);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function refund(Payment $payment, $amount, $return_client_response = false)
|
public function refund(Payment $payment, $amount, $return_client_response = false)
|
||||||
|
@ -44,6 +44,7 @@ use Checkout\Payments\PaymentRequest as PaymentsPaymentRequest;
|
|||||||
use Checkout\Payments\RefundRequest;
|
use Checkout\Payments\RefundRequest;
|
||||||
use Checkout\Payments\Source\RequestIdSource;
|
use Checkout\Payments\Source\RequestIdSource;
|
||||||
use Exception;
|
use Exception;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
class CheckoutComPaymentDriver extends BaseDriver
|
class CheckoutComPaymentDriver extends BaseDriver
|
||||||
{
|
{
|
||||||
@ -407,9 +408,16 @@ class CheckoutComPaymentDriver extends BaseDriver
|
|||||||
|
|
||||||
public function process3dsConfirmation(Checkout3dsRequest $request)
|
public function process3dsConfirmation(Checkout3dsRequest $request)
|
||||||
{
|
{
|
||||||
|
|
||||||
$this->init();
|
$this->init();
|
||||||
$this->setPaymentHash($request->getPaymentHash());
|
$this->setPaymentHash($request->getPaymentHash());
|
||||||
|
|
||||||
|
//11-08-2022 check the user is autenticated
|
||||||
|
if (!Auth::guard('contact')->check()) {
|
||||||
|
$client = $request->getClient();
|
||||||
|
auth()->guard('contact')->loginUsingId($client->contacts()->first()->id, true);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$payment = $this->gateway->getPaymentsClient()->getPaymentDetails(
|
$payment = $this->gateway->getPaymentsClient()->getPaymentDetails(
|
||||||
$request->query('cko-session-id')
|
$request->query('cko-session-id')
|
||||||
|
@ -20,6 +20,8 @@ use App\Http\Requests\Request;
|
|||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
use Illuminate\Support\Facades\Validator;
|
use Illuminate\Support\Facades\Validator;
|
||||||
use App\PaymentDrivers\FortePaymentDriver;
|
use App\PaymentDrivers\FortePaymentDriver;
|
||||||
|
use App\Jobs\Util\SystemLogger;
|
||||||
|
use App\Models\SystemLog;
|
||||||
|
|
||||||
class ACH
|
class ACH
|
||||||
{
|
{
|
||||||
@ -130,12 +132,35 @@ class ACH
|
|||||||
throw $th;
|
throw $th;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$message = [
|
||||||
|
'server_message' => $response->response->response_desc,
|
||||||
|
'server_response' => $response,
|
||||||
|
'data' => $payment_hash->data,
|
||||||
|
];
|
||||||
|
|
||||||
if ($httpcode>299) {
|
if ($httpcode>299) {
|
||||||
|
SystemLogger::dispatch(
|
||||||
|
$message,
|
||||||
|
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
||||||
|
SystemLog::EVENT_GATEWAY_FAILURE,
|
||||||
|
SystemLog::TYPE_FORTE,
|
||||||
|
$this->forte->client,
|
||||||
|
$this->forte->client->company,
|
||||||
|
);
|
||||||
$error = Validator::make([], []);
|
$error = Validator::make([], []);
|
||||||
$error->getMessageBag()->add('gateway_error', $response->response->response_desc);
|
$error->getMessageBag()->add('gateway_error', $response->response->response_desc);
|
||||||
return redirect('client/invoices')->withErrors($error);
|
return redirect('client/invoices')->withErrors($error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SystemLogger::dispatch(
|
||||||
|
$message,
|
||||||
|
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
||||||
|
SystemLog::EVENT_GATEWAY_SUCCESS,
|
||||||
|
SystemLog::TYPE_FORTE,
|
||||||
|
$this->forte->client,
|
||||||
|
$this->forte->client->company,
|
||||||
|
);
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
'payment_method' => $request->payment_method_id,
|
'payment_method' => $request->payment_method_id,
|
||||||
'payment_type' => PaymentType::ACH,
|
'payment_type' => PaymentType::ACH,
|
||||||
|
@ -21,6 +21,8 @@ use Illuminate\Support\Facades\Session;
|
|||||||
use Illuminate\Support\Facades\Validator;
|
use Illuminate\Support\Facades\Validator;
|
||||||
use App\PaymentDrivers\FortePaymentDriver;
|
use App\PaymentDrivers\FortePaymentDriver;
|
||||||
use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest;
|
use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest;
|
||||||
|
use App\Jobs\Util\SystemLogger;
|
||||||
|
use App\Models\SystemLog;
|
||||||
|
|
||||||
class CreditCard
|
class CreditCard
|
||||||
{
|
{
|
||||||
@ -141,12 +143,36 @@ class CreditCard
|
|||||||
} catch (\Throwable $th) {
|
} catch (\Throwable $th) {
|
||||||
throw $th;
|
throw $th;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$message = [
|
||||||
|
'server_message' => $response->response->response_desc,
|
||||||
|
'server_response' => $response,
|
||||||
|
'data' => $payment_hash->data,
|
||||||
|
];
|
||||||
|
|
||||||
if ($httpcode>299) {
|
if ($httpcode>299) {
|
||||||
|
SystemLogger::dispatch(
|
||||||
|
$message,
|
||||||
|
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
||||||
|
SystemLog::EVENT_GATEWAY_FAILURE,
|
||||||
|
SystemLog::TYPE_FORTE,
|
||||||
|
$this->forte->client,
|
||||||
|
$this->forte->client->company,
|
||||||
|
);
|
||||||
$error = Validator::make([], []);
|
$error = Validator::make([], []);
|
||||||
$error->getMessageBag()->add('gateway_error', $response->response->response_desc);
|
$error->getMessageBag()->add('gateway_error', $response->response->response_desc);
|
||||||
return redirect('client/invoices')->withErrors($error);
|
return redirect('client/invoices')->withErrors($error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SystemLogger::dispatch(
|
||||||
|
$message,
|
||||||
|
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
||||||
|
SystemLog::EVENT_GATEWAY_SUCCESS,
|
||||||
|
SystemLog::TYPE_FORTE,
|
||||||
|
$this->forte->client,
|
||||||
|
$this->forte->client->company,
|
||||||
|
);
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
'payment_method' => $request->payment_method_id,
|
'payment_method' => $request->payment_method_id,
|
||||||
'payment_type' => PaymentType::parseCardType(strtolower($request->card_brand)) ?: PaymentType::CREDIT_CARD_OTHER,
|
'payment_type' => PaymentType::parseCardType(strtolower($request->card_brand)) ?: PaymentType::CREDIT_CARD_OTHER,
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
namespace App\PaymentDrivers;
|
namespace App\PaymentDrivers;
|
||||||
|
|
||||||
|
use App\Models\Payment;
|
||||||
|
use App\Jobs\Util\SystemLogger;
|
||||||
use App\Models\SystemLog;
|
use App\Models\SystemLog;
|
||||||
use App\Models\GatewayType;
|
use App\Models\GatewayType;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
@ -49,7 +51,7 @@ class FortePaymentDriver extends BaseDriver
|
|||||||
return $types;
|
return $types;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SYSTEM_LOG_TYPE = SystemLog::TYPE_STRIPE; //define a constant for your gateway ie TYPE_YOUR_CUSTOM_GATEWAY - set the const in the SystemLog model
|
const SYSTEM_LOG_TYPE = SystemLog::TYPE_FORTE; //define a constant for your gateway ie TYPE_YOUR_CUSTOM_GATEWAY - set the const in the SystemLog model
|
||||||
|
|
||||||
public function setPaymentMethod($payment_method_id)
|
public function setPaymentMethod($payment_method_id)
|
||||||
{
|
{
|
||||||
@ -60,31 +62,130 @@ class FortePaymentDriver extends BaseDriver
|
|||||||
|
|
||||||
public function authorizeView(array $data)
|
public function authorizeView(array $data)
|
||||||
{
|
{
|
||||||
return $this->payment_method->authorizeView($data); //this is your custom implementation from here
|
return $this->payment_method->authorizeView($data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function authorizeResponse($request)
|
public function authorizeResponse($request)
|
||||||
{
|
{
|
||||||
return $this->payment_method->authorizeResponse($request); //this is your custom implementation from here
|
return $this->payment_method->authorizeResponse($request);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function processPaymentView(array $data)
|
public function processPaymentView(array $data)
|
||||||
{
|
{
|
||||||
return $this->payment_method->paymentView($data); //this is your custom implementation from here
|
return $this->payment_method->paymentView($data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function processPaymentResponse($request)
|
public function processPaymentResponse($request)
|
||||||
{
|
{
|
||||||
return $this->payment_method->paymentResponse($request); //this is your custom implementation from here
|
return $this->payment_method->paymentResponse($request);
|
||||||
}
|
}
|
||||||
|
|
||||||
// public function refund(Payment $payment, $amount, $return_client_response = false)
|
public function refund(Payment $payment, $amount, $return_client_response = false)
|
||||||
// {
|
{
|
||||||
// return $this->payment_method->yourRefundImplementationHere(); //this is your custom implementation from here
|
$forte_base_uri = "https://sandbox.forte.net/api/v3/";
|
||||||
// }
|
if($this->company_gateway->getConfigField('testMode') == false){
|
||||||
|
$forte_base_uri = "https://api.forte.net/v3/";
|
||||||
|
}
|
||||||
|
$forte_api_access_id = $this->company_gateway->getConfigField('apiAccessId');
|
||||||
|
$forte_secure_key = $this->company_gateway->getConfigField('secureKey');
|
||||||
|
$forte_auth_organization_id = $this->company_gateway->getConfigField('authOrganizationId');
|
||||||
|
$forte_organization_id = $this->company_gateway->getConfigField('organizationId');
|
||||||
|
$forte_location_id = $this->company_gateway->getConfigField('locationId');
|
||||||
|
|
||||||
|
try {
|
||||||
|
$curl = curl_init();
|
||||||
|
|
||||||
|
curl_setopt_array($curl, array(
|
||||||
|
CURLOPT_URL => $forte_base_uri.'organizations/'.$forte_organization_id.'/locations/'.$forte_location_id.'/transactions',
|
||||||
|
CURLOPT_RETURNTRANSFER => true,
|
||||||
|
CURLOPT_ENCODING => '',
|
||||||
|
CURLOPT_MAXREDIRS => 10,
|
||||||
|
CURLOPT_TIMEOUT => 0,
|
||||||
|
CURLOPT_FOLLOWLOCATION => true,
|
||||||
|
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
||||||
|
CURLOPT_CUSTOMREQUEST => 'POST',
|
||||||
|
CURLOPT_POSTFIELDS =>'{
|
||||||
|
"action":"reverse",
|
||||||
|
"authorization_amount":'.$amount.',
|
||||||
|
"original_transaction_id":"'.$payment->transaction_reference.'",
|
||||||
|
"authorization_code": "9ZQ754"
|
||||||
|
}',
|
||||||
|
CURLOPT_HTTPHEADER => array(
|
||||||
|
'Content-Type: application/json',
|
||||||
|
'X-Forte-Auth-Organization-Id: '.$forte_organization_id,
|
||||||
|
'Authorization: Basic '.base64_encode($forte_api_access_id.':'.$forte_secure_key)
|
||||||
|
),
|
||||||
|
));
|
||||||
|
|
||||||
|
$response = curl_exec($curl);
|
||||||
|
$httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
|
||||||
|
|
||||||
|
curl_close($curl);
|
||||||
|
|
||||||
|
$response=json_decode($response);
|
||||||
|
|
||||||
|
} catch (\Throwable $th) {
|
||||||
|
$message = [
|
||||||
|
'action' => 'error',
|
||||||
|
'data' => $th,
|
||||||
|
];
|
||||||
|
|
||||||
|
SystemLogger::dispatch(
|
||||||
|
$message,
|
||||||
|
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
||||||
|
SystemLog::EVENT_GATEWAY_FAILURE,
|
||||||
|
SystemLog::TYPE_FORTE,
|
||||||
|
$this->client,
|
||||||
|
$this->client->company,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$message = [
|
||||||
|
'action' => 'refund',
|
||||||
|
'server_message' => $response->response->response_desc,
|
||||||
|
'server_response' => $response,
|
||||||
|
'data' => $payment->paymentables,
|
||||||
|
];
|
||||||
|
|
||||||
|
if ($httpcode>299) {
|
||||||
|
SystemLogger::dispatch(
|
||||||
|
$message,
|
||||||
|
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
||||||
|
SystemLog::EVENT_GATEWAY_FAILURE,
|
||||||
|
SystemLog::TYPE_FORTE,
|
||||||
|
$this->client,
|
||||||
|
$this->client->company,
|
||||||
|
);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'transaction_reference' => $payment->transaction_reference,
|
||||||
|
'transaction_response' => $response,
|
||||||
|
'success' => false,
|
||||||
|
'description' => $payment->paymentables,
|
||||||
|
'code' => 422,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
SystemLogger::dispatch(
|
||||||
|
$message,
|
||||||
|
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
||||||
|
SystemLog::EVENT_GATEWAY_SUCCESS,
|
||||||
|
SystemLog::TYPE_FORTE,
|
||||||
|
$this->client,
|
||||||
|
$this->client->company,
|
||||||
|
);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'transaction_reference' => $payment->transaction_reference,
|
||||||
|
'transaction_response' => $response,
|
||||||
|
'success' => $response->response->response_code == 'A01' ? true : false,
|
||||||
|
'description' => $payment->paymentables,
|
||||||
|
'code' => $httpcode,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
// public function tokenBilling(ClientGatewayToken $cgt, PaymentHash $payment_hash)
|
// public function tokenBilling(ClientGatewayToken $cgt, PaymentHash $payment_hash)
|
||||||
// {
|
// {
|
||||||
// return $this->payment_method->yourTokenBillingImplmentation(); //this is your custom implementation from here
|
// return $this->payment_method->yourTokenBillingImplmentation();
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
@ -62,12 +62,12 @@ class DirectDebit implements MethodInterface
|
|||||||
'session_token' => $session_token,
|
'session_token' => $session_token,
|
||||||
]),
|
]),
|
||||||
'prefilled_customer' => [
|
'prefilled_customer' => [
|
||||||
'given_name' => auth()->guard('contact')->user()->first_name,
|
'given_name' => auth()->guard('contact')->user()->first_name ?: '',
|
||||||
'family_name' => auth()->guard('contact')->user()->last_name,
|
'family_name' => auth()->guard('contact')->user()->last_name ?: '',
|
||||||
'email' => auth()->guard('contact')->user()->email,
|
'email' => auth()->guard('contact')->user()->email ?: '',
|
||||||
'address_line1' => auth()->guard('contact')->user()->client->address1,
|
'address_line1' => auth()->guard('contact')->user()->client->address1 ?: '',
|
||||||
'city' => auth()->guard('contact')->user()->client->city,
|
'city' => auth()->guard('contact')->user()->client->city ?: '',
|
||||||
'postal_code' => auth()->guard('contact')->user()->client->postal_code,
|
'postal_code' => auth()->guard('contact')->user()->client->postal_code ?: '',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
|
@ -47,14 +47,6 @@ class CreditCard
|
|||||||
return render('gateways.paytrace.authorize', $data);
|
return render('gateways.paytrace.authorize', $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// +"success": true
|
|
||||||
// +"response_code": 160
|
|
||||||
// +"status_message": "The customer profile for PLS5U60OoLUfQXzcmtJYNefPA0gTthzT/11 was successfully created."
|
|
||||||
// +"customer_id": "PLS5U60OoLUfQXzcmtJYNefPA0gTthzT"
|
|
||||||
|
|
||||||
//if(!$response->success)
|
|
||||||
//handle failure
|
|
||||||
|
|
||||||
public function authorizeResponse($request)
|
public function authorizeResponse($request)
|
||||||
{
|
{
|
||||||
$data = $request->all();
|
$data = $request->all();
|
||||||
@ -64,27 +56,6 @@ class CreditCard
|
|||||||
return redirect()->route('client.payment_methods.index');
|
return redirect()->route('client.payment_methods.index');
|
||||||
}
|
}
|
||||||
|
|
||||||
// "_token" => "Vl1xHflBYQt9YFSaNCPTJKlY5x3rwcFE9kvkw71I"
|
|
||||||
// "company_gateway_id" => "1"
|
|
||||||
// "HPF_Token" => "e484a92c-90ed-4468-ac4d-da66824c75de"
|
|
||||||
// "enc_key" => "zqz6HMHCXALWdX5hyBqrIbSwU7TBZ0FTjjLB3Cp0FQY="
|
|
||||||
// "amount" => "Amount"
|
|
||||||
// "q" => "/client/payment_methods"
|
|
||||||
// "method" => "1"
|
|
||||||
// ]
|
|
||||||
|
|
||||||
// "customer_id":"customer789",
|
|
||||||
// "hpf_token":"e369847e-3027-4174-9161-fa0d4e98d318",
|
|
||||||
// "enc_key":"lI785yOBMet4Rt9o4NLXEyV84WBU3tdStExcsfoaOoo=",
|
|
||||||
// "integrator_id":"xxxxxxxxxx",
|
|
||||||
// "billing_address":{
|
|
||||||
// "name":"Mark Smith",
|
|
||||||
// "street_address":"8320 E. West St.",
|
|
||||||
// "city":"Spokane",
|
|
||||||
// "state":"WA",
|
|
||||||
// "zip":"85284"
|
|
||||||
// }
|
|
||||||
|
|
||||||
private function createCustomer($data)
|
private function createCustomer($data)
|
||||||
{
|
{
|
||||||
$post_data = [
|
$post_data = [
|
||||||
@ -156,7 +127,7 @@ class CreditCard
|
|||||||
'zip' => $this->paytrace->client->postal_code,
|
'zip' => $this->paytrace->client->postal_code,
|
||||||
];
|
];
|
||||||
|
|
||||||
nlog($data);
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function paymentView($data)
|
public function paymentView($data)
|
||||||
|
@ -89,15 +89,11 @@ class PaytracePaymentDriver extends BaseDriver
|
|||||||
|
|
||||||
public function refund(Payment $payment, $amount, $return_client_response = false)
|
public function refund(Payment $payment, $amount, $return_client_response = false)
|
||||||
{
|
{
|
||||||
// $cgt = ClientGatewayToken::where('company_gateway_id', $payment->company_gateway_id)
|
|
||||||
// ->where('gateway_type_id', $payment->gateway_type_id)
|
|
||||||
// ->first();
|
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
'amount' => $amount,
|
'amount' => $amount,
|
||||||
//'customer_id' => $cgt->token,
|
|
||||||
'transaction_id' => $payment->transaction_reference,
|
'transaction_id' => $payment->transaction_reference,
|
||||||
'integrator_id' => '959195xd1CuC',
|
'integrator_id' => $this->company_gateway->getConfigField('integratorId'),
|
||||||
];
|
];
|
||||||
|
|
||||||
$response = $this->gatewayRequest('/v1/transactions/refund/for_transaction', $data);
|
$response = $this->gatewayRequest('/v1/transactions/refund/for_transaction', $data);
|
||||||
|
@ -195,8 +195,6 @@ class SquarePaymentDriver extends BaseDriver
|
|||||||
{
|
{
|
||||||
$fields = [];
|
$fields = [];
|
||||||
|
|
||||||
$fields[] = ['name' => 'client_postal_code', 'label' => ctrans('texts.postal_code'), 'type' => 'text', 'validation' => 'required'];
|
|
||||||
|
|
||||||
if ($this->company_gateway->require_client_name) {
|
if ($this->company_gateway->require_client_name) {
|
||||||
$fields[] = ['name' => 'client_name', 'label' => ctrans('texts.client_name'), 'type' => 'text', 'validation' => 'required'];
|
$fields[] = ['name' => 'client_name', 'label' => ctrans('texts.client_name'), 'type' => 'text', 'validation' => 'required'];
|
||||||
}
|
}
|
||||||
@ -217,6 +215,7 @@ class SquarePaymentDriver extends BaseDriver
|
|||||||
if ($this->company_gateway->require_billing_address) {
|
if ($this->company_gateway->require_billing_address) {
|
||||||
$fields[] = ['name' => 'client_address_line_1', 'label' => ctrans('texts.address1'), 'type' => 'text', 'validation' => 'required'];
|
$fields[] = ['name' => 'client_address_line_1', 'label' => ctrans('texts.address1'), 'type' => 'text', 'validation' => 'required'];
|
||||||
// $fields[] = ['name' => 'client_address_line_2', 'label' => ctrans('texts.address2'), 'type' => 'text', 'validation' => 'nullable'];
|
// $fields[] = ['name' => 'client_address_line_2', 'label' => ctrans('texts.address2'), 'type' => 'text', 'validation' => 'nullable'];
|
||||||
|
$fields[] = ['name' => 'client_postal_code', 'label' => ctrans('texts.postal_code'), 'type' => 'text', 'validation' => 'required'];
|
||||||
$fields[] = ['name' => 'client_city', 'label' => ctrans('texts.city'), 'type' => 'text', 'validation' => 'required'];
|
$fields[] = ['name' => 'client_city', 'label' => ctrans('texts.city'), 'type' => 'text', 'validation' => 'required'];
|
||||||
$fields[] = ['name' => 'client_state', 'label' => ctrans('texts.state'), 'type' => 'text', 'validation' => 'required'];
|
$fields[] = ['name' => 'client_state', 'label' => ctrans('texts.state'), 'type' => 'text', 'validation' => 'required'];
|
||||||
$fields[] = ['name' => 'client_country_id', 'label' => ctrans('texts.country'), 'type' => 'text', 'validation' => 'required'];
|
$fields[] = ['name' => 'client_country_id', 'label' => ctrans('texts.country'), 'type' => 'text', 'validation' => 'required'];
|
||||||
|
@ -167,6 +167,17 @@ class CreditCard
|
|||||||
$this->stripe->client->company,
|
$this->stripe->client->company,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//If the user has come from a subscription double check here if we need to redirect.
|
||||||
|
//08-08-2022
|
||||||
|
if($payment->invoices()->whereHas('subscription')->exists()){
|
||||||
|
$subscription = $payment->invoices()->first()->subscription;
|
||||||
|
|
||||||
|
if($subscription && array_key_exists('return_url', $subscription->webhook_configuration) && strlen($subscription->webhook_configuration['return_url']) >=1)
|
||||||
|
return redirect($subscription->webhook_configuration['return_url']);
|
||||||
|
|
||||||
|
}
|
||||||
|
//08-08-2022
|
||||||
|
|
||||||
return redirect()->route('client.payments.show', ['payment' => $this->stripe->encodePrimaryKey($payment->id)]);
|
return redirect()->route('client.payments.show', ['payment' => $this->stripe->encodePrimaryKey($payment->id)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,9 +271,9 @@ class EventServiceProvider extends ServiceProvider
|
|||||||
],
|
],
|
||||||
MessageSending::class => [
|
MessageSending::class => [
|
||||||
],
|
],
|
||||||
// MessageSent::class => [
|
MessageSent::class => [
|
||||||
// MailSentListener::class,
|
MailSentListener::class,
|
||||||
// ],
|
],
|
||||||
UserWasCreated::class => [
|
UserWasCreated::class => [
|
||||||
CreatedUserActivity::class,
|
CreatedUserActivity::class,
|
||||||
SendVerificationNotification::class,
|
SendVerificationNotification::class,
|
||||||
|
@ -15,6 +15,7 @@ use App\Models\Invoice;
|
|||||||
use App\Services\AbstractService;
|
use App\Services\AbstractService;
|
||||||
use App\Utils\Ninja;
|
use App\Utils\Ninja;
|
||||||
use App\Utils\Traits\GeneratesCounter;
|
use App\Utils\Traits\GeneratesCounter;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
class HandleRestore extends AbstractService
|
class HandleRestore extends AbstractService
|
||||||
{
|
{
|
||||||
@ -24,6 +25,10 @@ class HandleRestore extends AbstractService
|
|||||||
|
|
||||||
private $payment_total = 0;
|
private $payment_total = 0;
|
||||||
|
|
||||||
|
private $total_payments = 0;
|
||||||
|
|
||||||
|
private $adjustment_amount = 0;
|
||||||
|
|
||||||
public function __construct(Invoice $invoice)
|
public function __construct(Invoice $invoice)
|
||||||
{
|
{
|
||||||
$this->invoice = $invoice;
|
$this->invoice = $invoice;
|
||||||
@ -47,16 +52,90 @@ class HandleRestore extends AbstractService
|
|||||||
//adjust ledger balance
|
//adjust ledger balance
|
||||||
$this->invoice->ledger()->updateInvoiceBalance($this->invoice->balance, "Restored invoice {$this->invoice->number}")->save();
|
$this->invoice->ledger()->updateInvoiceBalance($this->invoice->balance, "Restored invoice {$this->invoice->number}")->save();
|
||||||
|
|
||||||
$this->invoice->client->service()->updateBalance($this->invoice->balance)->save();
|
$this->invoice->client
|
||||||
|
->service()
|
||||||
|
->updateBalance($this->invoice->balance)
|
||||||
|
->updatePaidToDate($this->invoice->paid_to_date)
|
||||||
|
->save();
|
||||||
|
|
||||||
$this->windBackInvoiceNumber();
|
$this->windBackInvoiceNumber();
|
||||||
|
|
||||||
$this->invoice->is_deleted = false;
|
$this->invoice->is_deleted = false;
|
||||||
$this->invoice->save();
|
$this->invoice->save();
|
||||||
|
|
||||||
|
$this->restorePaymentables()
|
||||||
|
->setAdjustmentAmount()
|
||||||
|
->adjustPayments();
|
||||||
|
|
||||||
return $this->invoice;
|
return $this->invoice;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Touches all paymentables as deleted */
|
||||||
|
private function restorePaymentables()
|
||||||
|
{
|
||||||
|
$this->invoice->payments->each(function ($payment) {
|
||||||
|
$payment->paymentables()
|
||||||
|
->where('paymentable_type', '=', 'invoices')
|
||||||
|
->where('paymentable_id', $this->invoice->id)
|
||||||
|
->update(['deleted_at' => false]);
|
||||||
|
});
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private function setAdjustmentAmount()
|
||||||
|
{
|
||||||
|
foreach ($this->invoice->payments as $payment) {
|
||||||
|
$this->adjustment_amount += $payment->paymentables
|
||||||
|
->where('paymentable_type', '=', 'invoices')
|
||||||
|
->where('paymentable_id', $this->invoice->id)
|
||||||
|
->sum(DB::raw('amount'));
|
||||||
|
|
||||||
|
$this->adjustment_amount += $payment->paymentables
|
||||||
|
->where('paymentable_type', '=', 'invoices')
|
||||||
|
->where('paymentable_id', $this->invoice->id)
|
||||||
|
->sum(DB::raw('refunded'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->total_payments = $this->invoice->payments->sum('amount') - $this->invoice->payments->sum('refunded');
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function adjustPayments()
|
||||||
|
{
|
||||||
|
//if total payments = adjustment amount - that means we need to delete the payments as well.
|
||||||
|
|
||||||
|
if ($this->adjustment_amount == $this->total_payments) {
|
||||||
|
$this->invoice->payments()->update(['payments.deleted_at' => null, 'payments.is_deleted' => false]);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
//adjust payments down by the amount applied to the invoice payment.
|
||||||
|
|
||||||
|
$this->invoice->payments->each(function ($payment) {
|
||||||
|
$payment_adjustment = $payment->paymentables
|
||||||
|
->where('paymentable_type', '=', 'invoices')
|
||||||
|
->where('paymentable_id', $this->invoice->id)
|
||||||
|
->sum(DB::raw('amount'));
|
||||||
|
|
||||||
|
$payment_adjustment -= $payment->paymentables
|
||||||
|
->where('paymentable_type', '=', 'invoices')
|
||||||
|
->where('paymentable_id', $this->invoice->id)
|
||||||
|
->sum(DB::raw('refunded'));
|
||||||
|
|
||||||
|
$payment->amount += $payment_adjustment;
|
||||||
|
$payment->applied += $payment_adjustment;
|
||||||
|
$payment->is_deleted = false;
|
||||||
|
$payment->restore();
|
||||||
|
$payment->save();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private function windBackInvoiceNumber()
|
private function windBackInvoiceNumber()
|
||||||
{
|
{
|
||||||
$findme = '_'.ctrans('texts.deleted');
|
$findme = '_'.ctrans('texts.deleted');
|
||||||
|
@ -50,10 +50,8 @@ class Design extends BaseDesign
|
|||||||
/** Construct options */
|
/** Construct options */
|
||||||
public $options;
|
public $options;
|
||||||
|
|
||||||
/** @var Invoice[] */
|
|
||||||
public $invoices;
|
public $invoices;
|
||||||
|
|
||||||
/** @var Payment[] */
|
|
||||||
public $payments;
|
public $payments;
|
||||||
|
|
||||||
public $settings_object;
|
public $settings_object;
|
||||||
@ -396,7 +394,7 @@ class Design extends BaseDesign
|
|||||||
public function productTable(): array
|
public function productTable(): array
|
||||||
{
|
{
|
||||||
$product_items = collect($this->entity->line_items)->filter(function ($item) {
|
$product_items = collect($this->entity->line_items)->filter(function ($item) {
|
||||||
return $item->type_id == 1 || $item->type_id == 6;
|
return $item->type_id == 1 || $item->type_id == 6 || $item->type_id == 5;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (count($product_items) == 0) {
|
if (count($product_items) == 0) {
|
||||||
|
@ -80,7 +80,6 @@ class ConvertQuote
|
|||||||
/**
|
/**
|
||||||
* Only create the invitations that are defined on the quote.
|
* Only create the invitations that are defined on the quote.
|
||||||
*
|
*
|
||||||
* @return Invoice $invoice
|
|
||||||
*/
|
*/
|
||||||
private function createConversionInvitations($invoice, $quote)
|
private function createConversionInvitations($invoice, $quote)
|
||||||
{
|
{
|
||||||
|
@ -129,7 +129,8 @@ class QuoteService
|
|||||||
/**
|
/**
|
||||||
* Sometimes we need to refresh the
|
* Sometimes we need to refresh the
|
||||||
* PDF when it is updated etc.
|
* PDF when it is updated etc.
|
||||||
* @return InvoiceService
|
*
|
||||||
|
* @return QuoteService
|
||||||
*/
|
*/
|
||||||
public function touchPdf($force = false)
|
public function touchPdf($force = false)
|
||||||
{
|
{
|
||||||
|
@ -840,7 +840,6 @@ class SubscriptionService
|
|||||||
* Get the single charge products for the
|
* Get the single charge products for the
|
||||||
* subscription
|
* subscription
|
||||||
*
|
*
|
||||||
* @return ?Product Collection
|
|
||||||
*/
|
*/
|
||||||
public function products()
|
public function products()
|
||||||
{
|
{
|
||||||
@ -859,7 +858,6 @@ class SubscriptionService
|
|||||||
* Get the recurring products for the
|
* Get the recurring products for the
|
||||||
* subscription
|
* subscription
|
||||||
*
|
*
|
||||||
* @return ?Product Collection
|
|
||||||
*/
|
*/
|
||||||
public function recurring_products()
|
public function recurring_products()
|
||||||
{
|
{
|
||||||
|
@ -55,6 +55,8 @@ class ActivityTransformer extends EntityTransformer
|
|||||||
'client_id' => $activity->client_id ? (string) $this->encodePrimaryKey($activity->client_id) : '',
|
'client_id' => $activity->client_id ? (string) $this->encodePrimaryKey($activity->client_id) : '',
|
||||||
'recurring_invoice_id' => $activity->recurring_invoice_id ? (string) $this->encodePrimaryKey($activity->recurring_invoice_id) : '',
|
'recurring_invoice_id' => $activity->recurring_invoice_id ? (string) $this->encodePrimaryKey($activity->recurring_invoice_id) : '',
|
||||||
'recurring_expense_id' => $activity->recurring_expense_id ? (string) $this->encodePrimaryKey($activity->recurring_expense_id) : '',
|
'recurring_expense_id' => $activity->recurring_expense_id ? (string) $this->encodePrimaryKey($activity->recurring_expense_id) : '',
|
||||||
|
'purchase_order_id' => $activity->purchase_order_id ? (string) $this->encodePrimaryKey($activity->purchase_order_id) : '',
|
||||||
|
'vendor_contact_id' => $activity->vendor_contact_id ? (string) $this->encodePrimaryKey($activity->vendor_contact_id) : '',
|
||||||
'company_id' => $activity->company_id ? (string) $this->encodePrimaryKey($activity->company_id) : '',
|
'company_id' => $activity->company_id ? (string) $this->encodePrimaryKey($activity->company_id) : '',
|
||||||
'user_id' => (string) $this->encodePrimaryKey($activity->user_id),
|
'user_id' => (string) $this->encodePrimaryKey($activity->user_id),
|
||||||
'invoice_id' => $activity->invoice_id ? (string) $this->encodePrimaryKey($activity->invoice_id) : '',
|
'invoice_id' => $activity->invoice_id ? (string) $this->encodePrimaryKey($activity->invoice_id) : '',
|
||||||
|
@ -42,8 +42,8 @@ class CompanyUserTransformer extends EntityTransformer
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
'permissions' => $company_user->permissions ?: '',
|
'permissions' => $company_user->permissions ?: '',
|
||||||
'notifications' => (object) $company_user->notifications ?: $blank_obj,
|
'notifications' => $company_user->notifications ? (object) $company_user->notifications : $blank_obj,
|
||||||
'settings' => (object) $company_user->settings ?: $blank_obj,
|
'settings' => $company_user->settings ? (object) $company_user->settings : $blank_obj,
|
||||||
'is_owner' => (bool) $company_user->is_owner,
|
'is_owner' => (bool) $company_user->is_owner,
|
||||||
'is_admin' => (bool) $company_user->is_admin,
|
'is_admin' => (bool) $company_user->is_admin,
|
||||||
'is_locked' => (bool) $company_user->is_locked,
|
'is_locked' => (bool) $company_user->is_locked,
|
||||||
|
@ -80,7 +80,6 @@ class CreditTransformer extends EntityTransformer
|
|||||||
'amount' => (float) $credit->amount,
|
'amount' => (float) $credit->amount,
|
||||||
'balance' => (float) $credit->balance,
|
'balance' => (float) $credit->balance,
|
||||||
'client_id' => (string) $this->encodePrimaryKey($credit->client_id),
|
'client_id' => (string) $this->encodePrimaryKey($credit->client_id),
|
||||||
'vendor_id' => (string) $this->encodePrimaryKey($credit->vendor_id),
|
|
||||||
'status_id' => (string) ($credit->status_id ?: 1),
|
'status_id' => (string) ($credit->status_id ?: 1),
|
||||||
'design_id' => (string) $this->encodePrimaryKey($credit->design_id),
|
'design_id' => (string) $this->encodePrimaryKey($credit->design_id),
|
||||||
'created_at' => (int) $credit->created_at,
|
'created_at' => (int) $credit->created_at,
|
||||||
|
@ -137,7 +137,6 @@ class RecurringInvoiceTransformer extends EntityTransformer
|
|||||||
'due_date_days' => (string) $invoice->due_date_days ?: '',
|
'due_date_days' => (string) $invoice->due_date_days ?: '',
|
||||||
'paid_to_date' => (float) $invoice->paid_to_date,
|
'paid_to_date' => (float) $invoice->paid_to_date,
|
||||||
'subscription_id' => (string) $this->encodePrimaryKey($invoice->subscription_id),
|
'subscription_id' => (string) $this->encodePrimaryKey($invoice->subscription_id),
|
||||||
'recurring_dates' => (array) [],
|
|
||||||
];
|
];
|
||||||
|
|
||||||
if (request()->has('show_dates') && request()->query('show_dates') == 'true') {
|
if (request()->has('show_dates') && request()->query('show_dates') == 'true') {
|
||||||
|
@ -414,6 +414,7 @@ class HtmlEngine
|
|||||||
|
|
||||||
$data['$portal_button'] = ['value' => '<a class="button" href="'.$this->contact->getLoginLink().'?client_hash='.$this->client->client_hash.'">'.ctrans('texts.view_client_portal').'</a>', 'label' => ctrans('view_client_portal')];
|
$data['$portal_button'] = ['value' => '<a class="button" href="'.$this->contact->getLoginLink().'?client_hash='.$this->client->client_hash.'">'.ctrans('texts.view_client_portal').'</a>', 'label' => ctrans('view_client_portal')];
|
||||||
$data['$contact.portal_button'] = &$data['$portal_button'];
|
$data['$contact.portal_button'] = &$data['$portal_button'];
|
||||||
|
$data['$portalButton'] = &$data['$portal_button'];
|
||||||
|
|
||||||
$data['$contact.custom1'] = ['value' => isset($this->contact) ? $this->contact->custom_value1 : ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'contact1')];
|
$data['$contact.custom1'] = ['value' => isset($this->contact) ? $this->contact->custom_value1 : ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'contact1')];
|
||||||
$data['$contact.custom2'] = ['value' => isset($this->contact) ? $this->contact->custom_value2 : ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'contact2')];
|
$data['$contact.custom2'] = ['value' => isset($this->contact) ? $this->contact->custom_value2 : ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'contact2')];
|
||||||
@ -543,7 +544,6 @@ class HtmlEngine
|
|||||||
/*Payment Aliases*/
|
/*Payment Aliases*/
|
||||||
$data['$paymentLink'] = &$data['$payment_link'];
|
$data['$paymentLink'] = &$data['$payment_link'];
|
||||||
$data['$payment_url'] = &$data['$payment_link'];
|
$data['$payment_url'] = &$data['$payment_link'];
|
||||||
$data['$portalButton'] = &$data['$portal_button'];
|
|
||||||
|
|
||||||
$data['$dir'] = ['value' => in_array(optional($this->client->language())->locale, ['ar', 'he']) ? 'rtl' : 'ltr', 'label' => ''];
|
$data['$dir'] = ['value' => in_array(optional($this->client->language())->locale, ['ar', 'he']) ? 'rtl' : 'ltr', 'label' => ''];
|
||||||
$data['$dir_text_align'] = ['value' => in_array(optional($this->client->language())->locale, ['ar', 'he']) ? 'right' : 'left', 'label' => ''];
|
$data['$dir_text_align'] = ['value' => in_array(optional($this->client->language())->locale, ['ar', 'he']) ? 'right' : 'left', 'label' => ''];
|
||||||
|
@ -282,9 +282,9 @@ trait MakesInvoiceValues
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($table_type == '$task' && $item->type_id != 2) {
|
if ($table_type == '$task' && $item->type_id != 2) {
|
||||||
if ($item->type_id != 4 && $item->type_id != 5) {
|
// if ($item->type_id != 4 && $item->type_id != 5) {
|
||||||
continue;
|
continue;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
$helpers = new Helpers();
|
$helpers = new Helpers();
|
||||||
|
@ -21,6 +21,7 @@ trait MakesReminders
|
|||||||
{
|
{
|
||||||
public function inReminderWindow($schedule_reminder, $num_days_reminder)
|
public function inReminderWindow($schedule_reminder, $num_days_reminder)
|
||||||
{
|
{
|
||||||
|
|
||||||
switch ($schedule_reminder) {
|
switch ($schedule_reminder) {
|
||||||
case 'after_invoice_date':
|
case 'after_invoice_date':
|
||||||
return Carbon::parse($this->date)->addDays($num_days_reminder)->startOfDay()->eq(Carbon::now()->startOfDay());
|
return Carbon::parse($this->date)->addDays($num_days_reminder)->startOfDay()->eq(Carbon::now()->startOfDay());
|
||||||
|
@ -217,10 +217,10 @@ class VendorHtmlEngine
|
|||||||
$data['$entity.public_notes'] = &$data['$public_notes'];
|
$data['$entity.public_notes'] = &$data['$public_notes'];
|
||||||
$data['$notes'] = &$data['$public_notes'];
|
$data['$notes'] = &$data['$public_notes'];
|
||||||
|
|
||||||
$data['$purchase_order.custom1'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'purchase_order1', $this->entity->custom_value1, $this->company) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'purchase_order1')];
|
$data['$purchase_order.custom1'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'invoice1', $this->entity->custom_value1, $this->company) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'invoice1')];
|
||||||
$data['$purchase_order.custom2'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'purchase_order2', $this->entity->custom_value2, $this->company) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'purchase_order2')];
|
$data['$purchase_order.custom2'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'invoice2', $this->entity->custom_value2, $this->company) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'invoice2')];
|
||||||
$data['$purchase_order.custom3'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'purchase_order3', $this->entity->custom_value3, $this->company) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'purchase_order3')];
|
$data['$purchase_order.custom3'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'invoice3', $this->entity->custom_value3, $this->company) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'invoice3')];
|
||||||
$data['$purchase_order.custom4'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'purchase_order4', $this->entity->custom_value4, $this->company) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'purchase_order4')];
|
$data['$purchase_order.custom4'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'invoice4', $this->entity->custom_value4, $this->company) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'invoice4')];
|
||||||
|
|
||||||
$data['$vendor1'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'vendor1', $this->vendor->custom_value1, $this->company) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'vendor1')];
|
$data['$vendor1'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'vendor1', $this->vendor->custom_value1, $this->company) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'vendor1')];
|
||||||
$data['$vendor2'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'vendor2', $this->vendor->custom_value2, $this->company) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'vendor2')];
|
$data['$vendor2'] = ['value' => $this->helpers->formatCustomFieldValue($this->company->custom_fields, 'vendor2', $this->vendor->custom_value2, $this->company) ?: ' ', 'label' => $this->helpers->makeCustomField($this->company->custom_fields, 'vendor2')];
|
||||||
|
@ -133,10 +133,8 @@
|
|||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"post-install-cmd": [
|
"post-install-cmd": [
|
||||||
"if [ \"${IS_DOCKER:-false}\" != \"true\" ]; then vendor/bin/snappdf download; fi"
|
|
||||||
],
|
],
|
||||||
"post-update-cmd": [
|
"post-update-cmd": [
|
||||||
"vendor/bin/snappdf download",
|
|
||||||
"@php artisan vendor:publish --tag=laravel-assets --ansi --force"
|
"@php artisan vendor:publish --tag=laravel-assets --ansi --force"
|
||||||
],
|
],
|
||||||
"post-root-package-install": [
|
"post-root-package-install": [
|
||||||
|
90
composer.lock
generated
90
composer.lock
generated
@ -378,16 +378,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "aws/aws-sdk-php",
|
"name": "aws/aws-sdk-php",
|
||||||
"version": "3.232.2",
|
"version": "3.232.3",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/aws/aws-sdk-php.git",
|
"url": "https://github.com/aws/aws-sdk-php.git",
|
||||||
"reference": "390ceb3372ffb9f834694e2bd76a36a78ed7d2ee"
|
"reference": "96fae7f4b2ab11a3eb3fceacef7cb4b12e46b27c"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/390ceb3372ffb9f834694e2bd76a36a78ed7d2ee",
|
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/96fae7f4b2ab11a3eb3fceacef7cb4b12e46b27c",
|
||||||
"reference": "390ceb3372ffb9f834694e2bd76a36a78ed7d2ee",
|
"reference": "96fae7f4b2ab11a3eb3fceacef7cb4b12e46b27c",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -464,9 +464,9 @@
|
|||||||
"support": {
|
"support": {
|
||||||
"forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80",
|
"forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80",
|
||||||
"issues": "https://github.com/aws/aws-sdk-php/issues",
|
"issues": "https://github.com/aws/aws-sdk-php/issues",
|
||||||
"source": "https://github.com/aws/aws-sdk-php/tree/3.232.2"
|
"source": "https://github.com/aws/aws-sdk-php/tree/3.232.3"
|
||||||
},
|
},
|
||||||
"time": "2022-08-04T18:17:49+00:00"
|
"time": "2022-08-08T18:19:49+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "bacon/bacon-qr-code",
|
"name": "bacon/bacon-qr-code",
|
||||||
@ -1165,16 +1165,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "doctrine/dbal",
|
"name": "doctrine/dbal",
|
||||||
"version": "3.3.7",
|
"version": "3.4.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/doctrine/dbal.git",
|
"url": "https://github.com/doctrine/dbal.git",
|
||||||
"reference": "9f79d4650430b582f4598fe0954ef4d52fbc0a8a"
|
"reference": "118a360e9437e88d49024f36283c8bcbd76105f5"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/doctrine/dbal/zipball/9f79d4650430b582f4598fe0954ef4d52fbc0a8a",
|
"url": "https://api.github.com/repos/doctrine/dbal/zipball/118a360e9437e88d49024f36283c8bcbd76105f5",
|
||||||
"reference": "9f79d4650430b582f4598fe0954ef4d52fbc0a8a",
|
"reference": "118a360e9437e88d49024f36283c8bcbd76105f5",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -1182,21 +1182,21 @@
|
|||||||
"doctrine/cache": "^1.11|^2.0",
|
"doctrine/cache": "^1.11|^2.0",
|
||||||
"doctrine/deprecations": "^0.5.3|^1",
|
"doctrine/deprecations": "^0.5.3|^1",
|
||||||
"doctrine/event-manager": "^1.0",
|
"doctrine/event-manager": "^1.0",
|
||||||
"php": "^7.3 || ^8.0",
|
"php": "^7.4 || ^8.0",
|
||||||
"psr/cache": "^1|^2|^3",
|
"psr/cache": "^1|^2|^3",
|
||||||
"psr/log": "^1|^2|^3"
|
"psr/log": "^1|^2|^3"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"doctrine/coding-standard": "9.0.0",
|
"doctrine/coding-standard": "9.0.0",
|
||||||
"jetbrains/phpstorm-stubs": "2022.1",
|
"jetbrains/phpstorm-stubs": "2022.1",
|
||||||
"phpstan/phpstan": "1.7.13",
|
"phpstan/phpstan": "1.8.2",
|
||||||
"phpstan/phpstan-strict-rules": "^1.2",
|
"phpstan/phpstan-strict-rules": "^1.3",
|
||||||
"phpunit/phpunit": "9.5.20",
|
"phpunit/phpunit": "9.5.21",
|
||||||
"psalm/plugin-phpunit": "0.16.1",
|
"psalm/plugin-phpunit": "0.17.0",
|
||||||
"squizlabs/php_codesniffer": "3.7.0",
|
"squizlabs/php_codesniffer": "3.7.1",
|
||||||
"symfony/cache": "^5.2|^6.0",
|
"symfony/cache": "^5.4|^6.0",
|
||||||
"symfony/console": "^2.7|^3.0|^4.0|^5.0|^6.0",
|
"symfony/console": "^4.4|^5.4|^6.0",
|
||||||
"vimeo/psalm": "4.23.0"
|
"vimeo/psalm": "4.24.0"
|
||||||
},
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
"symfony/console": "For helpful console commands such as SQL execution and import of files."
|
"symfony/console": "For helpful console commands such as SQL execution and import of files."
|
||||||
@ -1256,7 +1256,7 @@
|
|||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/doctrine/dbal/issues",
|
"issues": "https://github.com/doctrine/dbal/issues",
|
||||||
"source": "https://github.com/doctrine/dbal/tree/3.3.7"
|
"source": "https://github.com/doctrine/dbal/tree/3.4.0"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@ -1272,7 +1272,7 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2022-06-13T21:43:03+00:00"
|
"time": "2022-08-06T20:35:57+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "doctrine/deprecations",
|
"name": "doctrine/deprecations",
|
||||||
@ -2162,16 +2162,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "google/apiclient-services",
|
"name": "google/apiclient-services",
|
||||||
"version": "v0.260.0",
|
"version": "v0.261.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/googleapis/google-api-php-client-services.git",
|
"url": "https://github.com/googleapis/google-api-php-client-services.git",
|
||||||
"reference": "8c519ddfd2458fda02dc10d10b142973e578516a"
|
"reference": "c91c5a694e3b8bca37136b830072a23f2c1250fa"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/8c519ddfd2458fda02dc10d10b142973e578516a",
|
"url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/c91c5a694e3b8bca37136b830072a23f2c1250fa",
|
||||||
"reference": "8c519ddfd2458fda02dc10d10b142973e578516a",
|
"reference": "c91c5a694e3b8bca37136b830072a23f2c1250fa",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -2200,9 +2200,9 @@
|
|||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/googleapis/google-api-php-client-services/issues",
|
"issues": "https://github.com/googleapis/google-api-php-client-services/issues",
|
||||||
"source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.260.0"
|
"source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.261.0"
|
||||||
},
|
},
|
||||||
"time": "2022-07-31T00:58:12+00:00"
|
"time": "2022-08-08T01:28:12+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "google/auth",
|
"name": "google/auth",
|
||||||
@ -4801,16 +4801,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "livewire/livewire",
|
"name": "livewire/livewire",
|
||||||
"version": "v2.10.6",
|
"version": "v2.10.7",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/livewire/livewire.git",
|
"url": "https://github.com/livewire/livewire.git",
|
||||||
"reference": "020ad095cf1239138b097d22b584e2701ec3edfb"
|
"reference": "fa0441bf82f1674beecb3a8ad8a4ae428736ed18"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/livewire/livewire/zipball/020ad095cf1239138b097d22b584e2701ec3edfb",
|
"url": "https://api.github.com/repos/livewire/livewire/zipball/fa0441bf82f1674beecb3a8ad8a4ae428736ed18",
|
||||||
"reference": "020ad095cf1239138b097d22b584e2701ec3edfb",
|
"reference": "fa0441bf82f1674beecb3a8ad8a4ae428736ed18",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -4862,7 +4862,7 @@
|
|||||||
"description": "A front-end framework for Laravel.",
|
"description": "A front-end framework for Laravel.",
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/livewire/livewire/issues",
|
"issues": "https://github.com/livewire/livewire/issues",
|
||||||
"source": "https://github.com/livewire/livewire/tree/v2.10.6"
|
"source": "https://github.com/livewire/livewire/tree/v2.10.7"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@ -4870,7 +4870,7 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2022-06-19T02:54:20+00:00"
|
"time": "2022-08-08T13:52:53+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "microsoft/microsoft-graph",
|
"name": "microsoft/microsoft-graph",
|
||||||
@ -5404,16 +5404,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "nesbot/carbon",
|
"name": "nesbot/carbon",
|
||||||
"version": "2.60.0",
|
"version": "2.61.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/briannesbitt/Carbon.git",
|
"url": "https://github.com/briannesbitt/Carbon.git",
|
||||||
"reference": "00a259ae02b003c563158b54fb6743252b638ea6"
|
"reference": "bdf4f4fe3a3eac4de84dbec0738082a862c68ba6"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/00a259ae02b003c563158b54fb6743252b638ea6",
|
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/bdf4f4fe3a3eac4de84dbec0738082a862c68ba6",
|
||||||
"reference": "00a259ae02b003c563158b54fb6743252b638ea6",
|
"reference": "bdf4f4fe3a3eac4de84dbec0738082a862c68ba6",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -5502,7 +5502,7 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2022-07-27T15:57:48+00:00"
|
"time": "2022-08-06T12:41:24+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "nette/schema",
|
"name": "nette/schema",
|
||||||
@ -16041,16 +16041,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "spatie/flare-client-php",
|
"name": "spatie/flare-client-php",
|
||||||
"version": "1.2.0",
|
"version": "1.3.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/spatie/flare-client-php.git",
|
"url": "https://github.com/spatie/flare-client-php.git",
|
||||||
"reference": "86a380f5b1ce839af04a08f1c8f2697184cdf23f"
|
"reference": "b1b974348750925b717fa8c8b97a0db0d1aa40ca"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/spatie/flare-client-php/zipball/86a380f5b1ce839af04a08f1c8f2697184cdf23f",
|
"url": "https://api.github.com/repos/spatie/flare-client-php/zipball/b1b974348750925b717fa8c8b97a0db0d1aa40ca",
|
||||||
"reference": "86a380f5b1ce839af04a08f1c8f2697184cdf23f",
|
"reference": "b1b974348750925b717fa8c8b97a0db0d1aa40ca",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -16098,7 +16098,7 @@
|
|||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/spatie/flare-client-php/issues",
|
"issues": "https://github.com/spatie/flare-client-php/issues",
|
||||||
"source": "https://github.com/spatie/flare-client-php/tree/1.2.0"
|
"source": "https://github.com/spatie/flare-client-php/tree/1.3.0"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@ -16106,7 +16106,7 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2022-05-16T12:13:39+00:00"
|
"time": "2022-08-08T10:10:20+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "spatie/ignition",
|
"name": "spatie/ignition",
|
||||||
@ -16707,5 +16707,5 @@
|
|||||||
"platform-dev": {
|
"platform-dev": {
|
||||||
"php": "^7.4|^8.0"
|
"php": "^7.4|^8.0"
|
||||||
},
|
},
|
||||||
"plugin-api-version": "2.1.0"
|
"plugin-api-version": "2.3.0"
|
||||||
}
|
}
|
||||||
|
@ -14,8 +14,8 @@ return [
|
|||||||
'require_https' => env('REQUIRE_HTTPS', true),
|
'require_https' => env('REQUIRE_HTTPS', true),
|
||||||
'app_url' => rtrim(env('APP_URL', ''), '/'),
|
'app_url' => rtrim(env('APP_URL', ''), '/'),
|
||||||
'app_domain' => env('APP_DOMAIN', 'invoicing.co'),
|
'app_domain' => env('APP_DOMAIN', 'invoicing.co'),
|
||||||
'app_version' => '5.5.8',
|
'app_version' => '5.5.14',
|
||||||
'app_tag' => '5.5.8',
|
'app_tag' => '5.5.14',
|
||||||
'minimum_client_version' => '5.0.16',
|
'minimum_client_version' => '5.0.16',
|
||||||
'terms_version' => '1.0.1',
|
'terms_version' => '1.0.1',
|
||||||
'api_secret' => env('API_SECRET', ''),
|
'api_secret' => env('API_SECRET', ''),
|
||||||
|
@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('licenses', function (Blueprint $table) {
|
||||||
|
$table->unsignedBigInteger('recurring_invoice_id')->nullable();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
};
|
@ -200,7 +200,7 @@ $LANG = array(
|
|||||||
'removed_logo' => 'Successfully removed logo',
|
'removed_logo' => 'Successfully removed logo',
|
||||||
'sent_message' => 'Successfully sent message',
|
'sent_message' => 'Successfully sent message',
|
||||||
'invoice_error' => 'Please make sure to select a client and correct any errors',
|
'invoice_error' => 'Please make sure to select a client and correct any errors',
|
||||||
'limit_clients' => 'Sorry, this will exceed the limit of :count clients',
|
'limit_clients' => 'Sorry, this will exceed the limit of :count clients. Please upgrade to a paid plan.',
|
||||||
'payment_error' => 'There was an error processing your payment. Please try again later.',
|
'payment_error' => 'There was an error processing your payment. Please try again later.',
|
||||||
'registration_required' => 'Please sign up to email an invoice',
|
'registration_required' => 'Please sign up to email an invoice',
|
||||||
'confirmation_required' => 'Please confirm your email address, :link to resend the confirmation email.',
|
'confirmation_required' => 'Please confirm your email address, :link to resend the confirmation email.',
|
||||||
@ -4730,6 +4730,43 @@ $LANG = array(
|
|||||||
'converted_to_expenses' => 'Successfully converted to expenses',
|
'converted_to_expenses' => 'Successfully converted to expenses',
|
||||||
'entity_removed' => 'This document has been removed, please contact the vendor for further information',
|
'entity_removed' => 'This document has been removed, please contact the vendor for further information',
|
||||||
'entity_removed_title' => 'Document no longer available',
|
'entity_removed_title' => 'Document no longer available',
|
||||||
|
'field' => 'Field',
|
||||||
|
'period' => 'Period',
|
||||||
|
'fields_per_row' => 'Fields Per Row',
|
||||||
|
'total_active_invoices' => 'Active Invoices',
|
||||||
|
'total_outstanding_invoices' => 'Outstanding Invoices',
|
||||||
|
'total_completed_payments' => 'Completed Payments',
|
||||||
|
'total_refunded_payments' => 'Refunded Payments',
|
||||||
|
'total_active_quotes' => 'Active Quotes',
|
||||||
|
'total_approved_quotes' => 'Approved Quotes',
|
||||||
|
'total_unapproved_quotes' => 'Unapproved Quotes',
|
||||||
|
'total_logged_tasks' => 'Logged Tasks',
|
||||||
|
'total_invoiced_tasks' => 'Invoiced Tasks',
|
||||||
|
'total_paid_tasks' => 'Paid Tasks',
|
||||||
|
'total_logged_expenses' => 'Logged Expenses',
|
||||||
|
'total_pending_expenses' => 'Pending Expenses',
|
||||||
|
'total_invoiced_expenses' => 'Invoiced Expenses',
|
||||||
|
'total_invoice_paid_expenses' => 'Invoice Paid Expenses',
|
||||||
|
'vendor_portal' => 'Vendor Portal',
|
||||||
|
'send_code' => 'Send Code',
|
||||||
|
'save_to_upload_documents' => 'Save the record to upload documents',
|
||||||
|
'expense_tax_rates' => 'Expense Tax Rates',
|
||||||
|
'invoice_item_tax_rates' => 'Invoice Item Tax Rates',
|
||||||
|
'verified_phone_number' => 'Successfully verified phone number',
|
||||||
|
'code_was_sent' => 'A code has been sent via SMS',
|
||||||
|
'resend' => 'Resend',
|
||||||
|
'verify' => 'Verify',
|
||||||
|
'enter_phone_number' => 'Please provide a phone number',
|
||||||
|
'invalid_phone_number' => 'Invalid phone number',
|
||||||
|
'verify_phone_number' => 'Verify Phone Number',
|
||||||
|
'verify_phone_number_help' => 'Please verify your phone number to send emails',
|
||||||
|
'merged_clients' => 'Successfully merged clients',
|
||||||
|
'merge_into' => 'Merge Into',
|
||||||
|
'php81_required' => 'Note: v5.5 requires PHP 8.1',
|
||||||
|
'bulk_email_purchase_orders' => 'Email Purchase Orders',
|
||||||
|
'bulk_email_invoices' => 'Email Invoices',
|
||||||
|
'bulk_email_quotes' => 'Email Quotes',
|
||||||
|
'bulk_email_credits' => 'Email Credits',
|
||||||
);
|
);
|
||||||
|
|
||||||
return $LANG;
|
return $LANG;
|
||||||
|
@ -200,7 +200,7 @@ $LANG = array(
|
|||||||
'removed_logo' => 'Logotipo removido com sucesso',
|
'removed_logo' => 'Logotipo removido com sucesso',
|
||||||
'sent_message' => 'Mensagem enviada com sucesso',
|
'sent_message' => 'Mensagem enviada com sucesso',
|
||||||
'invoice_error' => 'Assegure-se de selecionar um cliente e corrigir quaisquer erros',
|
'invoice_error' => 'Assegure-se de selecionar um cliente e corrigir quaisquer erros',
|
||||||
'limit_clients' => 'Desculpe, isto irá exceder o limite de :count clientes',
|
'limit_clients' => 'Sorry, this will exceed the limit of :count clients. Please upgrade to a paid plan.',
|
||||||
'payment_error' => 'Ocorreu um erro ao processar seu pagamento. Por favor tente novamente mais tarde.',
|
'payment_error' => 'Ocorreu um erro ao processar seu pagamento. Por favor tente novamente mais tarde.',
|
||||||
'registration_required' => 'Favor cadastre-se para enviar uma fatura por email',
|
'registration_required' => 'Favor cadastre-se para enviar uma fatura por email',
|
||||||
'confirmation_required' => 'Por favor confirme seu endereço de email, :link para re-enviar o email de confirmação.',
|
'confirmation_required' => 'Por favor confirme seu endereço de email, :link para re-enviar o email de confirmação.',
|
||||||
@ -2241,7 +2241,7 @@ Quando tiver as quantias, volte a esta página de formas de pagamento e clique "
|
|||||||
'navigation_variables' => 'Variáveis de Navegação',
|
'navigation_variables' => 'Variáveis de Navegação',
|
||||||
'custom_variables' => 'Variáveis Personalizadas',
|
'custom_variables' => 'Variáveis Personalizadas',
|
||||||
'invalid_file' => 'Tipo de arquivo inválido',
|
'invalid_file' => 'Tipo de arquivo inválido',
|
||||||
'add_documents_to_invoice' => 'Adicionar documentos à fatura',
|
'add_documents_to_invoice' => 'Add Documents to Invoice',
|
||||||
'mark_expense_paid' => 'Marcar como pago',
|
'mark_expense_paid' => 'Marcar como pago',
|
||||||
'white_label_license_error' => 'Falha ao validar a licença, verifique storage/logs/laravel-error.log para mais detalhes.',
|
'white_label_license_error' => 'Falha ao validar a licença, verifique storage/logs/laravel-error.log para mais detalhes.',
|
||||||
'plan_price' => 'Preço do Plano',
|
'plan_price' => 'Preço do Plano',
|
||||||
@ -4628,6 +4628,102 @@ Quando tiver as quantias, volte a esta página de formas de pagamento e clique "
|
|||||||
'notification_purchase_order_accepted_subject' => 'Purchase Order :purchase_order was accepted by :vendor',
|
'notification_purchase_order_accepted_subject' => 'Purchase Order :purchase_order was accepted by :vendor',
|
||||||
'notification_purchase_order_accepted' => 'The following vendor :vendor accepted Purchase Order :purchase_order for :amount.',
|
'notification_purchase_order_accepted' => 'The following vendor :vendor accepted Purchase Order :purchase_order for :amount.',
|
||||||
'amount_received' => 'Amount received',
|
'amount_received' => 'Amount received',
|
||||||
|
'purchase_order_already_expensed' => 'Already converted to an expense.',
|
||||||
|
'convert_to_expense' => 'Convert to Expense',
|
||||||
|
'add_to_inventory' => 'Add to Inventory',
|
||||||
|
'added_purchase_order_to_inventory' => 'Successfully added purchase order to inventory',
|
||||||
|
'added_purchase_orders_to_inventory' => 'Successfully added purchase orders to inventory',
|
||||||
|
'client_document_upload' => 'Client Document Upload',
|
||||||
|
'vendor_document_upload' => 'Vendor Document Upload',
|
||||||
|
'vendor_document_upload_help' => 'Enable vendors to upload documents',
|
||||||
|
'are_you_enjoying_the_app' => 'Are you enjoying the app?',
|
||||||
|
'yes_its_great' => 'Yes, it"s great!',
|
||||||
|
'not_so_much' => 'Not so much',
|
||||||
|
'would_you_rate_it' => 'Great to hear! Would you like to rate it?',
|
||||||
|
'would_you_tell_us_more' => 'Sorry to hear it! Would you like to tell us more?',
|
||||||
|
'sure_happy_to' => 'Sure, happy to',
|
||||||
|
'no_not_now' => 'No, not now',
|
||||||
|
'add' => 'Add',
|
||||||
|
'last_sent_template' => 'Last Sent Template',
|
||||||
|
'enable_flexible_search' => 'Enable Flexible Search',
|
||||||
|
'enable_flexible_search_help' => 'Match non-contiguous characters, ie. "ct" matches "cat"',
|
||||||
|
'vendor_details' => 'Vendor Details',
|
||||||
|
'purchase_order_details' => 'Purchase Order Details',
|
||||||
|
'qr_iban' => 'QR IBAN',
|
||||||
|
'besr_id' => 'BESR ID',
|
||||||
|
'clone_to_purchase_order' => 'Clone to PO',
|
||||||
|
'vendor_email_not_set' => 'Vendor does not have an email address set',
|
||||||
|
'bulk_send_email' => 'Send Email',
|
||||||
|
'marked_purchase_order_as_sent' => 'Successfully marked purchase order as sent',
|
||||||
|
'marked_purchase_orders_as_sent' => 'Successfully marked purchase orders as sent',
|
||||||
|
'accepted_purchase_order' => 'Successfully accepted purchase order',
|
||||||
|
'accepted_purchase_orders' => 'Successfully accepted purchase orders',
|
||||||
|
'cancelled_purchase_order' => 'Successfully cancelled purchase order',
|
||||||
|
'cancelled_purchase_orders' => 'Successfully cancelled purchase orders',
|
||||||
|
'please_select_a_vendor' => 'Please select a vendor',
|
||||||
|
'purchase_order_total' => 'Purchase Order Total',
|
||||||
|
'email_purchase_order' => 'Email Purchase Order',
|
||||||
|
'bulk_email_purchase_order' => 'Email Purchase Order',
|
||||||
|
'disconnected_email' => 'Successfully disconnected email',
|
||||||
|
'connect_email' => 'Connect Email',
|
||||||
|
'disconnect_email' => 'Disconnect Email',
|
||||||
|
'use_web_app_to_connect_microsoft' => 'Please use the web app to connect to Microsoft',
|
||||||
|
'email_provider' => 'Email Provider',
|
||||||
|
'connect_microsoft' => 'Connect Microsoft',
|
||||||
|
'disconnect_microsoft' => 'Disconnect Microsoft',
|
||||||
|
'connected_microsoft' => 'Successfully connected Microsoft',
|
||||||
|
'disconnected_microsoft' => 'Successfully disconnected Microsoft',
|
||||||
|
'microsoft_sign_in' => 'Login with Microsoft',
|
||||||
|
'microsoft_sign_up' => 'Sign up with Microsoft',
|
||||||
|
'emailed_purchase_order' => 'Successfully queued purchase order to be sent',
|
||||||
|
'emailed_purchase_orders' => 'Successfully queued purchase orders to be sent',
|
||||||
|
'enable_react_app' => 'Change to the React web app',
|
||||||
|
'purchase_order_design' => 'Purchase Order Design',
|
||||||
|
'purchase_order_terms' => 'Purchase Order Terms',
|
||||||
|
'purchase_order_footer' => 'Purchase Order Footer',
|
||||||
|
'require_purchase_order_signature' => 'Purchase Order Signature',
|
||||||
|
'require_purchase_order_signature_help' => 'Require vendor to provide their signature.',
|
||||||
|
'new_purchase_order' => 'New Purchase Order',
|
||||||
|
'edit_purchase_order' => 'Edit Purchase Order',
|
||||||
|
'created_purchase_order' => 'Successfully created purchase order',
|
||||||
|
'updated_purchase_order' => 'Successfully updated purchase order',
|
||||||
|
'archived_purchase_order' => 'Successfully archived purchase order',
|
||||||
|
'deleted_purchase_order' => 'Successfully deleted purchase order',
|
||||||
|
'removed_purchase_order' => 'Successfully removed purchase order',
|
||||||
|
'restored_purchase_order' => 'Successfully restored purchase order',
|
||||||
|
'search_purchase_order' => 'Search Purchase Order',
|
||||||
|
'search_purchase_orders' => 'Search Purchase Orders',
|
||||||
|
'login_url' => 'Login URL',
|
||||||
|
'enable_applying_payments' => 'Enable Applying Payments',
|
||||||
|
'enable_applying_payments_help' => 'Support separately creating and applying payments',
|
||||||
|
'stock_quantity' => 'Stock Quantity',
|
||||||
|
'notification_threshold' => 'Notification Threshold',
|
||||||
|
'track_inventory' => 'Track Inventory',
|
||||||
|
'track_inventory_help' => 'Display a product stock field and update when invoices are sent',
|
||||||
|
'stock_notifications' => 'Stock Notifications',
|
||||||
|
'stock_notifications_help' => 'Send an email when the stock reaches the threshold',
|
||||||
|
'vat' => 'VAT',
|
||||||
|
'view_map' => 'View Map',
|
||||||
|
'set_default_design' => 'Set Default Design',
|
||||||
|
'add_gateway_help_message' => 'Add a payment gateway (ie. Stripe, WePay or PayPal) to accept online payments',
|
||||||
|
'purchase_order_issued_to' => 'Purchase Order issued to',
|
||||||
|
'archive_task_status' => 'Archive Task Status',
|
||||||
|
'delete_task_status' => 'Delete Task Status',
|
||||||
|
'restore_task_status' => 'Restore Task Status',
|
||||||
|
'lang_Hebrew' => 'Hebrew',
|
||||||
|
'price_change_accepted' => 'Price change accepted',
|
||||||
|
'price_change_failed' => 'Price change failed with code',
|
||||||
|
'restore_purchases' => 'Restore Purchases',
|
||||||
|
'activate' => 'Activate',
|
||||||
|
'connect_apple' => 'Connect Apple',
|
||||||
|
'disconnect_apple' => 'Disconnect Apple',
|
||||||
|
'disconnected_apple' => 'Successfully disconnected Apple',
|
||||||
|
'send_now' => 'Send Now',
|
||||||
|
'received' => 'Received',
|
||||||
|
'converted_to_expense' => 'Successfully converted to expense',
|
||||||
|
'converted_to_expenses' => 'Successfully converted to expenses',
|
||||||
|
'entity_removed' => 'This document has been removed, please contact the vendor for further information',
|
||||||
|
'entity_removed_title' => 'Document no longer available',
|
||||||
);
|
);
|
||||||
|
|
||||||
return $LANG;
|
return $LANG;
|
||||||
|
1076
lang/pt_PT/texts.php
1076
lang/pt_PT/texts.php
File diff suppressed because it is too large
Load Diff
10
psalm.xml
10
psalm.xml
@ -57,6 +57,16 @@
|
|||||||
<directory name="app" />
|
<directory name="app" />
|
||||||
</errorLevel>
|
</errorLevel>
|
||||||
</UndefinedMagicPropertyFetch>
|
</UndefinedMagicPropertyFetch>
|
||||||
|
<TooManyArguments>
|
||||||
|
<errorLevel type="suppress">
|
||||||
|
<directory name="app" />
|
||||||
|
</errorLevel>
|
||||||
|
</TooManyArguments>
|
||||||
|
<RedundantCast>
|
||||||
|
<errorLevel type="suppress">
|
||||||
|
<directory name="app" />
|
||||||
|
</errorLevel>
|
||||||
|
</RedundantCast>
|
||||||
<InvalidNullableReturnType>
|
<InvalidNullableReturnType>
|
||||||
<errorLevel type="suppress">
|
<errorLevel type="suppress">
|
||||||
<directory name="app" />
|
<directory name="app" />
|
||||||
|
@ -8225,6 +8225,31 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
flutter_staggered_grid_view
|
||||||
|
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2018 Romain Rastel
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
flutter_styled_toast
|
flutter_styled_toast
|
||||||
webdriver
|
webdriver
|
||||||
|
568
public/flutter_service_worker.js
vendored
568
public/flutter_service_worker.js
vendored
@ -3,304 +3,304 @@ const MANIFEST = 'flutter-app-manifest';
|
|||||||
const TEMP = 'flutter-temp-cache';
|
const TEMP = 'flutter-temp-cache';
|
||||||
const CACHE_NAME = 'flutter-app-cache';
|
const CACHE_NAME = 'flutter-app-cache';
|
||||||
const RESOURCES = {
|
const RESOURCES = {
|
||||||
|
"canvaskit/canvaskit.js": "c2b4e5f3d7a3d82aed024e7249a78487",
|
||||||
"canvaskit/profiling/canvaskit.js": "ae2949af4efc61d28a4a80fffa1db900",
|
"canvaskit/profiling/canvaskit.js": "ae2949af4efc61d28a4a80fffa1db900",
|
||||||
"canvaskit/profiling/canvaskit.wasm": "95e736ab31147d1b2c7b25f11d4c32cd",
|
"canvaskit/profiling/canvaskit.wasm": "95e736ab31147d1b2c7b25f11d4c32cd",
|
||||||
"canvaskit/canvaskit.js": "c2b4e5f3d7a3d82aed024e7249a78487",
|
|
||||||
"canvaskit/canvaskit.wasm": "4b83d89d9fecbea8ca46f2f760c5a9ba",
|
"canvaskit/canvaskit.wasm": "4b83d89d9fecbea8ca46f2f760c5a9ba",
|
||||||
"/": "784b9b59de6c49b2fa8bc36999656d6a",
|
"main.dart.js": "809c193905ea4c80a7c0b2b0e484e1db",
|
||||||
"favicon.png": "dca91c54388f52eded692718d5a98b8b",
|
|
||||||
"main.dart.js": "819a7e0f760429027b88f15315928b59",
|
|
||||||
"manifest.json": "ef43d90e57aa7682d7e2cfba2f484a40",
|
|
||||||
"version.json": "c0a4deee2c1337ed484674fb0099de5c",
|
|
||||||
"flutter.js": "eb2682e33f25cd8f1fc59011497c35f8",
|
|
||||||
"icons/Icon-512.png": "0f9aff01367f0a0c69773d25ca16ef35",
|
|
||||||
"icons/Icon-192.png": "bb1cf5f6982006952211c7c8404ffbed",
|
|
||||||
"favicon.ico": "51636d3a390451561744c42188ccd628",
|
"favicon.ico": "51636d3a390451561744c42188ccd628",
|
||||||
"assets/FontManifest.json": "087fb858dc3cbfbf6baf6a30004922f1",
|
"assets/AssetManifest.json": "759f9ef9973f7e26c2a51450b55bb9fa",
|
||||||
"assets/NOTICES": "ac722c5f2b53ebcb315197c83737fe42",
|
|
||||||
"assets/fonts/MaterialIcons-Regular.otf": "95db9098c58fd6db106f1116bae85a0b",
|
|
||||||
"assets/assets/images/icon.png": "090f69e23311a4b6d851b3880ae52541",
|
|
||||||
"assets/assets/images/payment_types/mastercard.png": "6f6cdc29ee2e22e06b1ac029cb52ef71",
|
|
||||||
"assets/assets/images/payment_types/other.png": "d936e11fa3884b8c9f1bd5c914be8629",
|
|
||||||
"assets/assets/images/payment_types/ach.png": "7433f0aff779dc98a649b7a2daf777cf",
|
|
||||||
"assets/assets/images/payment_types/carteblanche.png": "d936e11fa3884b8c9f1bd5c914be8629",
|
|
||||||
"assets/assets/images/payment_types/solo.png": "2030c3ccaccf5d5e87916a62f5b084d6",
|
|
||||||
"assets/assets/images/payment_types/amex.png": "c49a4247984b3732a4af50a3390aa978",
|
|
||||||
"assets/assets/images/payment_types/switch.png": "4fa11c45327f5fdc20205821b2cfd9cc",
|
|
||||||
"assets/assets/images/payment_types/unionpay.png": "7002f52004e0ab8cc0b7450b0208ccb2",
|
|
||||||
"assets/assets/images/payment_types/dinerscard.png": "06d85186ba858c18ab7c9caa42c92024",
|
|
||||||
"assets/assets/images/payment_types/discover.png": "6c0a386a00307f87db7bea366cca35f5",
|
|
||||||
"assets/assets/images/payment_types/laser.png": "b4e6e93dd35517ac429301119ff05868",
|
|
||||||
"assets/assets/images/payment_types/visa.png": "3ddc4a4d25c946e8ad7e6998f30fd4e3",
|
|
||||||
"assets/assets/images/payment_types/paypal.png": "8e06c094c1871376dfea1da8088c29d1",
|
|
||||||
"assets/assets/images/payment_types/jcb.png": "07e0942d16c5592118b72e74f2f7198c",
|
|
||||||
"assets/assets/images/payment_types/maestro.png": "e533b92bfb50339fdbfa79e3dfe81f08",
|
|
||||||
"assets/assets/images/logo_light.png": "e5f46d5a78e226e7a9553d4ca6f69219",
|
|
||||||
"assets/assets/images/logo_dark.png": "a233ed1d4d0f7414bf97a9a10f11fb0a",
|
|
||||||
"assets/assets/images/google_logo.png": "0f118259ce403274f407f5e982e681c3",
|
|
||||||
"assets/assets/google_fonts/Roboto-Regular.ttf": "8a36205bd9b83e03af0591a004bc97f4",
|
"assets/assets/google_fonts/Roboto-Regular.ttf": "8a36205bd9b83e03af0591a004bc97f4",
|
||||||
"assets/packages/intl_phone_field/assets/flags/et.png": "57edff61c7fddf2761a19948acef1498",
|
"assets/assets/images/google_logo.png": "0f118259ce403274f407f5e982e681c3",
|
||||||
"assets/packages/intl_phone_field/assets/flags/sy.png": "24186a0f4ce804a16c91592db5a16a3a",
|
"assets/assets/images/logo_light.png": "e5f46d5a78e226e7a9553d4ca6f69219",
|
||||||
"assets/packages/intl_phone_field/assets/flags/eg.png": "311d780e8e3dd43f87e6070f6feb74c7",
|
"assets/assets/images/icon.png": "090f69e23311a4b6d851b3880ae52541",
|
||||||
"assets/packages/intl_phone_field/assets/flags/cy.png": "7b36f4af86257a3f15f5a5a16f4a2fcd",
|
"assets/assets/images/logo_dark.png": "a233ed1d4d0f7414bf97a9a10f11fb0a",
|
||||||
"assets/packages/intl_phone_field/assets/flags/pm.png": "134bee9f9d794dc5c0922d1b9bdbb710",
|
"assets/assets/images/payment_types/ach.png": "7433f0aff779dc98a649b7a2daf777cf",
|
||||||
"assets/packages/intl_phone_field/assets/flags/es.png": "654965f9722f6706586476fb2f5d30dd",
|
"assets/assets/images/payment_types/amex.png": "c49a4247984b3732a4af50a3390aa978",
|
||||||
"assets/packages/intl_phone_field/assets/flags/hu.png": "281582a753e643b46bdd894047db08bb",
|
"assets/assets/images/payment_types/jcb.png": "07e0942d16c5592118b72e74f2f7198c",
|
||||||
"assets/packages/intl_phone_field/assets/flags/cf.png": "263583ffdf7a888ce4fba8487d1da0b2",
|
"assets/assets/images/payment_types/dinerscard.png": "06d85186ba858c18ab7c9caa42c92024",
|
||||||
"assets/packages/intl_phone_field/assets/flags/fo.png": "2c7d9233582e83a86927e634897a2a90",
|
"assets/assets/images/payment_types/other.png": "d936e11fa3884b8c9f1bd5c914be8629",
|
||||||
"assets/packages/intl_phone_field/assets/flags/fi.png": "3ccd69a842e55183415b7ea2c04b15c8",
|
"assets/assets/images/payment_types/carteblanche.png": "d936e11fa3884b8c9f1bd5c914be8629",
|
||||||
"assets/packages/intl_phone_field/assets/flags/ec.png": "c1ae60d080be91f3be31e92e0a2d9555",
|
"assets/assets/images/payment_types/mastercard.png": "6f6cdc29ee2e22e06b1ac029cb52ef71",
|
||||||
"assets/packages/intl_phone_field/assets/flags/ly.png": "8d65057351859065d64b4c118ff9e30e",
|
"assets/assets/images/payment_types/switch.png": "4fa11c45327f5fdc20205821b2cfd9cc",
|
||||||
"assets/packages/intl_phone_field/assets/flags/pl.png": "f20e9ef473a9ed24176f5ad74dd0d50a",
|
"assets/assets/images/payment_types/maestro.png": "e533b92bfb50339fdbfa79e3dfe81f08",
|
||||||
"assets/packages/intl_phone_field/assets/flags/vn.png": "32ff65ccbf31a707a195be2a5141a89b",
|
"assets/assets/images/payment_types/visa.png": "3ddc4a4d25c946e8ad7e6998f30fd4e3",
|
||||||
"assets/packages/intl_phone_field/assets/flags/mh.png": "18dda388ef5c1cf37cae5e7d5fef39bc",
|
"assets/assets/images/payment_types/discover.png": "6c0a386a00307f87db7bea366cca35f5",
|
||||||
"assets/packages/intl_phone_field/assets/flags/me.png": "590284bc85810635ace30a173e615ca4",
|
"assets/assets/images/payment_types/unionpay.png": "7002f52004e0ab8cc0b7450b0208ccb2",
|
||||||
"assets/packages/intl_phone_field/assets/flags/sd.png": "65ce270762dfc87475ea99bd18f79025",
|
"assets/assets/images/payment_types/laser.png": "b4e6e93dd35517ac429301119ff05868",
|
||||||
|
"assets/assets/images/payment_types/solo.png": "2030c3ccaccf5d5e87916a62f5b084d6",
|
||||||
|
"assets/assets/images/payment_types/paypal.png": "8e06c094c1871376dfea1da8088c29d1",
|
||||||
|
"assets/fonts/MaterialIcons-Regular.otf": "95db9098c58fd6db106f1116bae85a0b",
|
||||||
|
"assets/packages/material_design_icons_flutter/lib/fonts/materialdesignicons-webfont.ttf": "b62641afc9ab487008e996a5c5865e56",
|
||||||
"assets/packages/intl_phone_field/assets/flags/au.png": "72be14316f0af3903cdca7a726c0c589",
|
"assets/packages/intl_phone_field/assets/flags/au.png": "72be14316f0af3903cdca7a726c0c589",
|
||||||
"assets/packages/intl_phone_field/assets/flags/mg.png": "0ef6271ad284ebc0069ff0aeb5a3ad1e",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ht.png": "630f7f8567d87409a32955107ad11a86",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/gm.png": "7148d3715527544c2e7d8d6f4a445bb6",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/sl.png": "61b9d992c8a6a83abc4d432069617811",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/gb-eng.png": "0d9f2a6775fd52b79e1d78eb1dda10cf",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/nz.png": "65c811e96eb6c9da65538f899c110895",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/cm.png": "42d52fa71e8b4dbb182ff431749e8d0d",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/tg.png": "7f91f02b26b74899ff882868bd611714",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/bl.png": "dae94f5465d3390fdc5929e4f74d3f5f",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/dm.png": "8886b222ed9ccd00f67e8bcf86dadcc2",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/at.png": "570c070177a5ea0fe03e20107ebf5283",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/cu.png": "f41715bd51f63a9aebf543788543b4c4",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ke.png": "cf5aae3699d3cacb39db9803edae172b",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/it.png": "5c8e910e6a33ec63dfcda6e8960dd19c",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/az.png": "6ffa766f6883d2d3d350cdc22a062ca3",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ad.png": "384e9845debe9aca8f8586d9bedcb7e6",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/sj.png": "33bc70259c4908b7b9adeef9436f7a9f",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/sz.png": "d1829842e45c2b2b29222c1b7e201591",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/nl.png": "3649c177693bfee9c2fcc63c191a51f1",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/nu.png": "f4169998548e312584c67873e0d9352d",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/br.png": "5093e0cd8fd3c094664cd17ea8a36fd1",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/bo.png": "3ccf6fa7f9cbc27949b8418925e4e89c",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/bh.png": "a1acd86ef0e19ea5f0297bbe1de6cfd4",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/im.png": "7c9ccb825f0fca557d795c4330cf4f50",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/gb-wls.png": "d7d7c77c72cd425d993bdc50720f4d04",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/dj.png": "078bd37d41f746c3cb2d84c1e9611c55",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/dz.png": "132ceca353a95c8214676b2e94ecd40f",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/hk.png": "4b5ec424348c98ec71a46ad3dce3931d",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/mp.png": "87351c30a529071ee9a4bb67765fea4f",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/iq.png": "bc3e6f68c5188dbf99b473e2bea066f2",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/gq.png": "4286e56f388a37f64b21eb56550c06d9",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/lk.png": "5a3a063cfff4a92fb0ba6158e610e025",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/mk.png": "835f2263974de523fa779d29c90595bf",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/pn.png": "0b0641b356af4c3e3489192ff4b0be77",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/mw.png": "ffc1f18eeedc1dfbb1080aa985ce7d05",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ie.png": "1d91912afc591dd120b47b56ea78cdbf",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/gd.png": "7a4864ccfa2a0564041c2d1f8a13a8c9",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/mo.png": "849848a26bbfc87024017418ad7a6233",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/bm.png": "b366ba84cbc8286c830f392bb9086be5",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/af.png": "ba710b50a060b5351381b55366396c30",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ax.png": "ec2062c36f09ed8fb90ac8992d010024",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/gb-nir.png": "98773db151c150cabe845183241bfe6b",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ae.png": "792efc5eb6c31d780bd34bf4bad69f3f",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/la.png": "e8cd9c3ee6e134adcbe3e986e1974e4a",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/de.png": "5d9561246523cf6183928756fd605e25",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/bv.png": "33bc70259c4908b7b9adeef9436f7a9f",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ug.png": "9a0f358b1eb19863e21ae2063fab51c0",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/om.png": "cebd9ab4b9ab071b2142e21ae2129efc",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/dk.png": "abcd01bdbcc02b4a29cbac237f29cd1d",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/id.png": "80bb82d11d5bc144a21042e77972bca9",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/st.png": "fef62c31713ff1063da2564df3f43eea",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ws.png": "f206322f3e22f175869869dbfadb6ce8",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/qa.png": "eb9b3388e554cf85aea1e739247548df",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ky.png": "38e39eba673e82c48a1f25bd103a7e97",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/hn.png": "9ecf68aed83c4a9b3f1e6275d96bfb04",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/aq.png": "0c586e7b91aa192758fdd0f03adb84d8",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/mv.png": "d9245f74e34d5c054413ace4b86b4f16",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/gu.png": "2acb614b442e55864411b6e418df6eab",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/tf.png": "b2c044b86509e7960b5ba66b094ea285",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/si.png": "24237e53b34752554915e71e346bb405",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/sm.png": "a8d6801cb7c5360e18f0a2ed146b396d",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/fk.png": "da8b0fe48829aae2c8feb4839895de63",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ga.png": "b0e5b2fa1b7106c7652a955db24c11c4",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/cw.png": "6c598eb0d331d6b238da57055ec00d33",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/gn.png": "b2287c03c88a72d968aa796a076ba056",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ps.png": "52a25a48658ca9274830ffa124a8c1db",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/gi.png": "446aa44aaa063d240adab88243b460d3",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/pk.png": "7a6a621f7062589677b3296ca16c6718",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/gb-sct.png": "75106a5e49e3e16da76cb33bdac102ab",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/bg.png": "1d24bc616e3389684ed2c9f18bcb0209",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/bf.png": "63f1c67fca7ce8b52b3418a90af6ad37",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ss.png": "b0120cb000b31bb1a5c801c3592139bc",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ru.png": "6974dcb42ad7eb3add1009ea0c6003e3",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/kr.png": "a3b7da3b76b20a70e9cd63cc2315b51b",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/tk.png": "60428ff1cdbae680e5a0b8cde4677dd5",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ne.png": "a20724c177e86d6a27143aa9c9664a6f",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/na.png": "cdc00e9267a873609b0abea944939ff7",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/gw.png": "05606b9a6393971bd87718b809e054f9",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/bt.png": "3cfe1440e952bc7266d71f7f1454fa23",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ba.png": "d415bad33b35de3f095177e8e86cbc82",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/gh.png": "b35464dca793fa33e51bf890b5f3d92b",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/cz.png": "73ecd64c6144786c4d03729b1dd9b1f3",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/an.png": "4e4b90fbca1275d1839ca5b44fc51071",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/tz.png": "56ec99c7e0f68b88a2210620d873683a",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/mq.png": "134bee9f9d794dc5c0922d1b9bdbb710",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/hm.png": "72be14316f0af3903cdca7a726c0c589",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ni.png": "e398dc23e79d9ccd702546cc25f126bf",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/no.png": "33bc70259c4908b7b9adeef9436f7a9f",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/za.png": "b28280c6c3eb4624c18b5455d4a1b1ff",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/py.png": "154d4add03b4878caf00bd3249e14f40",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/bi.png": "adda8121501f0543f1075244a1acc275",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/zm.png": "81cec35b715f227328cad8f314acd797",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/tv.png": "c57025ed7ae482210f29b9da86b0d211",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/kg.png": "c4aa6d221d9a9d332155518d6b82dbc7",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ki.png": "14db0fc29398730064503907bd696176",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/eh.png": "515a9cf2620c802e305b5412ac81aed2",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/so.png": "1ce20d052f9d057250be96f42647513b",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/um.png": "8fe7c4fed0a065fdfb9bd3125c6ecaa1",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/gs.png": "419dd57836797a3f1bf6258ea6589f9a",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ch.png": "a251702f7760b0aac141428ed60b7b66",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/li.png": "ecdf7b3fe932378b110851674335d9ab",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/bj.png": "6fdc6449f73d23ad3f07060f92db4423",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/do.png": "ed35983a9263bb5713be37d9a52caddc",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/aw.png": "a93ddf8e32d246dc47f6631f38e0ed92",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/mz.png": "1ab1ac750fbbb453d33e9f25850ac2a0",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/nf.png": "1c2069b299ce3660a2a95ec574dfde25",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ro.png": "85af99741fe20664d9a7112cfd8d9722",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/pa.png": "78e3e4fd56f0064837098fe3f22fb41b",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ye.png": "4cf73209d90e9f02ead1565c8fdf59e5",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/lu.png": "6274fd1cae3c7a425d25e4ccb0941bb8",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/bz.png": "fd2d7d27a5ddabe4eb9a10b1d3a433e4",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/sv.png": "217b691efbef7a0f48cdd53e91997f0e",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/eu.png": "c58ece3931acb87faadc5b940d4f7755",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/lt.png": "7df2cd6566725685f7feb2051f916a3e",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/be.png": "7e5e1831cdd91935b38415479a7110eb",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/gb.png": "98773db151c150cabe845183241bfe6b",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ci.png": "7f5ca3779d5ff6ce0c803a6efa0d2da7",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ag.png": "41c11d5668c93ba6e452f811defdbb24",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/mu.png": "c5228d1e94501d846b5bf203f038ae49",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/il.png": "1e06ad7783f24332405d36561024cc4c",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/mr.png": "f2a62602d43a1ee14625af165b96ce2f",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/sk.png": "2a1ee716d4b41c017ff1dbf3fd3ffc64",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/us.png": "83b065848d14d33c0d10a13e01862f34",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ir.png": "37f67c3141e9843196cb94815be7bd37",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/vg.png": "fc095e11f5b58604d6f4d3c2b43d167f",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/zw.png": "078a3267ea8eabf88b2d43fe4aed5ce5",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/to.png": "1cdd716b5b5502f85d6161dac6ee6c5b",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/gt.png": "706a0c3b5e0b589c843e2539e813839e",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/lb.png": "f80cde345f0d9bd0086531808ce5166a",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/wf.png": "6f1644b8f907d197c0ff7ed2f366ad64",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/jm.png": "074400103847c56c37425a73f9d23665",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/cx.png": "8efa3231c8a3900a78f2b51d829f8c52",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ck.png": "39f343868a8dc8ca95d27b27a5caf480",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/er.png": "8ca78e10878a2e97c1371b38c5d258a7",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ge.png": "6fbd41f07921fa415347ebf6dff5b0f7",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ao.png": "5f0a372aa3aa7150a3dafea97acfc10d",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/fr.png": "134bee9f9d794dc5c0922d1b9bdbb710",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/gf.png": "134bee9f9d794dc5c0922d1b9bdbb710",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ml.png": "0c50dfd539e87bb4313da0d4556e2d13",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/sx.png": "9c19254973d8acf81581ad95b408c7e6",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/bq.png": "3649c177693bfee9c2fcc63c191a51f1",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/hr.png": "69711b2ea009a3e7c40045b538768d4e",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/cl.png": "6735e0e2d88c119e9ed1533be5249ef1",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/kw.png": "3ca448e219d0df506fb2efd5b91be092",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/bs.png": "2b9540c4fa514f71911a48de0bd77e71",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/mf.png": "134bee9f9d794dc5c0922d1b9bdbb710",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/in.png": "1dec13ba525529cffd4c7f8a35d51121",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/cn.png": "040539c2cdb60ebd9dc8957cdc6a8ad0",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/tr.png": "27feab1a5ca390610d07e0c6bd4720d5",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/sa.png": "7c95c1a877148e2aa21a213d720ff4fd",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/tw.png": "b1101fd5f871a9ffe7c9ad191a7d3304",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/tm.png": "0980fb40ec450f70896f2c588510f933",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/mn.png": "16086e8d89c9067d29fd0f2ea7021a45",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/mc.png": "90c2ad7f144d73d4650cbea9dd621275",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/vu.png": "3f201fdfb6d669a64c35c20a801016d1",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/lv.png": "53105fea0cc9cc554e0ceaabc53a2d5d",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/bb.png": "a8473747387e4e7a8450c499529f1c93",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/mm.png": "32e5293d6029d8294c7dfc3c3835c222",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/gg.png": "eed435d25bd755aa7f9cd7004b9ed49d",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ee.png": "e242645cae28bd5291116ea211f9a566",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/pt.png": "eba93d33545c78cc67915d9be8323661",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/sh.png": "98773db151c150cabe845183241bfe6b",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ls.png": "2bca756f9313957347404557acb532b0",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/kh.png": "d48d51e8769a26930da6edfc15de97fe",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/kn.png": "f318e2fd87e5fd2cabefe9ff252bba46",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ve.png": "893391d65cbd10ca787a73578c77d3a7",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/tt.png": "a8e1fc5c65dc8bc362a9453fadf9c4b3",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/tl.png": "c80876dc80cda5ab6bb8ef078bc6b05d",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ar.png": "3bd245f8c28f70c9ef9626dae27adc65",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/pf.png": "1ae72c24380d087cbe2d0cd6c3b58821",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/rw.png": "d1aae0647a5b1ab977ae43ab894ce2c3",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/va.png": "c010bf145f695d5c8fb551bafc081f77",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/np.png": "6e099fb1e063930bdd00e8df5cef73d4",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/my.png": "f7f962e8a074387fd568c9d4024e0959",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/pe.png": "4d9249aab70a26fadabb14380b3b55d2",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/sb.png": "296ecedbd8d1c2a6422c3ba8e5cd54bd",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/as.png": "d9c1da515c6f945c2e2554592a9dfaae",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/vc.png": "da3ca14a978717467abbcdece05d3544",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/sg.png": "bc772e50b8c79f08f3c2189f5d8ce491",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/cg.png": "eca97338cc1cb5b5e91bec72af57b3d4",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/fm.png": "d571b8bc4b80980a81a5edbde788b6d2",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/pg.png": "0f7e03465a93e0b4e3e1c9d3dd5814a4",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/cr.png": "bfd8b41e63fc3cc829c72c4b2e170532",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/sr.png": "9f912879f2829a625436ccd15e643e39",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/fj.png": "1c6a86752578eb132390febf12789cd6",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/cd.png": "5b5f832ed6cd9f9240cb31229d8763dc",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/kz.png": "cb3b0095281c9d7e7fb5ce1716ef8ee5",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/rs.png": "9dff535d2d08c504be63062f39eff0b7",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ca.png": "76f2fac1d3b2cc52ba6695c2e2941632",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ua.png": "b4b10d893611470661b079cb30473871",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/mx.png": "84b12a569b209e213daccfcbdd1fc799",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ma.png": "057ea2e08587f1361b3547556adae0c2",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/cv.png": "9b1f31f9fc0795d728328dedd33eb1c0",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/sc.png": "e969fd5afb1eb5902675b6bcf49a8c2e",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/bw.png": "fac8b90d7404728c08686dc39bab4fb3",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/gr.png": "ec11281d7decbf07b81a23a72a609b59",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/is.png": "907840430252c431518005b562707831",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/gy.png": "159a260bf0217128ea7475ba5b272b6a",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/gl.png": "b79e24ee1889b7446ba3d65564b86810",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ng.png": "aedbe364bd1543832e88e64b5817e877",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/th.png": "11ce0c9f8c738fd217ea52b9bc29014b",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ai.png": "ce5e91ed1725f0499b9231b69a7fd448",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/uy.png": "da4247b21fcbd9e30dc2b3f7c5dccb64",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ms.png": "9c955a926cf7d57fccb450a97192afa7",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/md.png": "8911d3d821b95b00abbba8771e997eb3",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/uz.png": "3adad3bac322220cac8abc1c7cbaacac",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/io.png": "83d45bbbff087d47b2b39f1c20598f52",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/se.png": "25dd5434891ac1ca2ad1af59cda70f80",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/bd.png": "86a0e4bd8787dc8542137a407e0f987f",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/ph.png": "e4025d1395a8455f1ba038597a95228c",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/td.png": "009303b6188ca0e30bd50074b16f0b16",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/je.png": "288f8dca26098e83ff0455b08cceca1b",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/pr.png": "b97b2f4432c430bc340d893f36527e31",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/nc.png": "cb36e0c945b79d56def11b23c6a9c7e9",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/tn.png": "6612e9fec4bef022cbd45cbb7c02b2b6",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/re.png": "134bee9f9d794dc5c0922d1b9bdbb710",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/pw.png": "2e697cc6907a7b94c7f94f5d9b3bdccc",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/by.png": "beabf61e94fb3a4f7c7a7890488b213d",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/tc.png": "d728d6763c17c520ad6bcf3c24282a29",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/am.png": "aaa39141fbc80205bebaa0200b55a13a",
|
"assets/packages/intl_phone_field/assets/flags/am.png": "aaa39141fbc80205bebaa0200b55a13a",
|
||||||
"assets/packages/intl_phone_field/assets/flags/tj.png": "c73b793f2acd262e71b9236e64c77636",
|
"assets/packages/intl_phone_field/assets/flags/sm.png": "a8d6801cb7c5360e18f0a2ed146b396d",
|
||||||
"assets/packages/intl_phone_field/assets/flags/bn.png": "ed650de06fff61ff27ec92a872197948",
|
"assets/packages/intl_phone_field/assets/flags/gb-nir.png": "98773db151c150cabe845183241bfe6b",
|
||||||
"assets/packages/intl_phone_field/assets/flags/kp.png": "e1c8bb52f31fca22d3368d8f492d8f27",
|
"assets/packages/intl_phone_field/assets/flags/tz.png": "56ec99c7e0f68b88a2210620d873683a",
|
||||||
"assets/packages/intl_phone_field/assets/flags/mt.png": "f3119401ae0c3a9d6e2dc23803928c06",
|
"assets/packages/intl_phone_field/assets/flags/py.png": "154d4add03b4878caf00bd3249e14f40",
|
||||||
"assets/packages/intl_phone_field/assets/flags/yt.png": "134bee9f9d794dc5c0922d1b9bdbb710",
|
"assets/packages/intl_phone_field/assets/flags/cx.png": "8efa3231c8a3900a78f2b51d829f8c52",
|
||||||
"assets/packages/intl_phone_field/assets/flags/gp.png": "134bee9f9d794dc5c0922d1b9bdbb710",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/cc.png": "31a475216e12fef447382c97b42876ce",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/sn.png": "68eaa89bbc83b3f356e1ba2096b09b3c",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/km.png": "5554c8746c16d4f482986fb78ffd9b36",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/jo.png": "c01cb41f74f9db0cf07ba20f0af83011",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/al.png": "722cf9e5c7a1d9c9e4608fb44dbb427d",
|
|
||||||
"assets/packages/intl_phone_field/assets/flags/lr.png": "b92c75e18dd97349c75d6a43bd17ee94",
|
"assets/packages/intl_phone_field/assets/flags/lr.png": "b92c75e18dd97349c75d6a43bd17ee94",
|
||||||
"assets/packages/intl_phone_field/assets/flags/jp.png": "25ac778acd990bedcfdc02a9b4570045",
|
"assets/packages/intl_phone_field/assets/flags/jp.png": "25ac778acd990bedcfdc02a9b4570045",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/sc.png": "e969fd5afb1eb5902675b6bcf49a8c2e",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ba.png": "d415bad33b35de3f095177e8e86cbc82",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/sh.png": "98773db151c150cabe845183241bfe6b",
|
||||||
"assets/packages/intl_phone_field/assets/flags/co.png": "e3b1be16dcdae6cb72e9c238fdddce3c",
|
"assets/packages/intl_phone_field/assets/flags/co.png": "e3b1be16dcdae6cb72e9c238fdddce3c",
|
||||||
"assets/packages/intl_phone_field/assets/flags/nr.png": "1316f3a8a419d8be1975912c712535ea",
|
"assets/packages/intl_phone_field/assets/flags/ca.png": "76f2fac1d3b2cc52ba6695c2e2941632",
|
||||||
"assets/packages/intl_phone_field/assets/flags/xk.png": "079259fbcb1f3c78dafa944464295c16",
|
"assets/packages/intl_phone_field/assets/flags/bw.png": "fac8b90d7404728c08686dc39bab4fb3",
|
||||||
"assets/packages/intl_phone_field/assets/flags/lc.png": "8c1a03a592aa0a99fcaf2b81508a87eb",
|
"assets/packages/intl_phone_field/assets/flags/re.png": "134bee9f9d794dc5c0922d1b9bdbb710",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/cl.png": "6735e0e2d88c119e9ed1533be5249ef1",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/gy.png": "159a260bf0217128ea7475ba5b272b6a",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/vc.png": "da3ca14a978717467abbcdece05d3544",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/th.png": "11ce0c9f8c738fd217ea52b9bc29014b",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/bg.png": "1d24bc616e3389684ed2c9f18bcb0209",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/bn.png": "ed650de06fff61ff27ec92a872197948",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/bj.png": "6fdc6449f73d23ad3f07060f92db4423",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/us.png": "83b065848d14d33c0d10a13e01862f34",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/bo.png": "3ccf6fa7f9cbc27949b8418925e4e89c",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/nz.png": "65c811e96eb6c9da65538f899c110895",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/dk.png": "abcd01bdbcc02b4a29cbac237f29cd1d",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/gg.png": "eed435d25bd755aa7f9cd7004b9ed49d",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/gm.png": "7148d3715527544c2e7d8d6f4a445bb6",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/aw.png": "a93ddf8e32d246dc47f6631f38e0ed92",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/mq.png": "134bee9f9d794dc5c0922d1b9bdbb710",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/al.png": "722cf9e5c7a1d9c9e4608fb44dbb427d",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/zm.png": "81cec35b715f227328cad8f314acd797",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ae.png": "792efc5eb6c31d780bd34bf4bad69f3f",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/wf.png": "6f1644b8f907d197c0ff7ed2f366ad64",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/la.png": "e8cd9c3ee6e134adcbe3e986e1974e4a",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/pt.png": "eba93d33545c78cc67915d9be8323661",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/cu.png": "f41715bd51f63a9aebf543788543b4c4",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/bl.png": "dae94f5465d3390fdc5929e4f74d3f5f",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ls.png": "2bca756f9313957347404557acb532b0",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/er.png": "8ca78e10878a2e97c1371b38c5d258a7",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/cz.png": "73ecd64c6144786c4d03729b1dd9b1f3",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/gn.png": "b2287c03c88a72d968aa796a076ba056",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ly.png": "8d65057351859065d64b4c118ff9e30e",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/tt.png": "a8e1fc5c65dc8bc362a9453fadf9c4b3",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/no.png": "33bc70259c4908b7b9adeef9436f7a9f",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/il.png": "1e06ad7783f24332405d36561024cc4c",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ec.png": "c1ae60d080be91f3be31e92e0a2d9555",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/eh.png": "515a9cf2620c802e305b5412ac81aed2",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/tw.png": "b1101fd5f871a9ffe7c9ad191a7d3304",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/mh.png": "18dda388ef5c1cf37cae5e7d5fef39bc",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/sb.png": "296ecedbd8d1c2a6422c3ba8e5cd54bd",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ru.png": "6974dcb42ad7eb3add1009ea0c6003e3",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/kw.png": "3ca448e219d0df506fb2efd5b91be092",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/jm.png": "074400103847c56c37425a73f9d23665",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/gb-wls.png": "d7d7c77c72cd425d993bdc50720f4d04",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ci.png": "7f5ca3779d5ff6ce0c803a6efa0d2da7",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/mu.png": "c5228d1e94501d846b5bf203f038ae49",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/sd.png": "65ce270762dfc87475ea99bd18f79025",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/an.png": "4e4b90fbca1275d1839ca5b44fc51071",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/uz.png": "3adad3bac322220cac8abc1c7cbaacac",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/na.png": "cdc00e9267a873609b0abea944939ff7",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/de.png": "5d9561246523cf6183928756fd605e25",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/by.png": "beabf61e94fb3a4f7c7a7890488b213d",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/mr.png": "f2a62602d43a1ee14625af165b96ce2f",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/sg.png": "bc772e50b8c79f08f3c2189f5d8ce491",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/mz.png": "1ab1ac750fbbb453d33e9f25850ac2a0",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/vn.png": "32ff65ccbf31a707a195be2a5141a89b",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/gb.png": "98773db151c150cabe845183241bfe6b",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/nl.png": "3649c177693bfee9c2fcc63c191a51f1",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/jo.png": "c01cb41f74f9db0cf07ba20f0af83011",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/et.png": "57edff61c7fddf2761a19948acef1498",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/dj.png": "078bd37d41f746c3cb2d84c1e9611c55",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/cm.png": "42d52fa71e8b4dbb182ff431749e8d0d",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/in.png": "1dec13ba525529cffd4c7f8a35d51121",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/im.png": "7c9ccb825f0fca557d795c4330cf4f50",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/sk.png": "2a1ee716d4b41c017ff1dbf3fd3ffc64",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/np.png": "6e099fb1e063930bdd00e8df5cef73d4",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/mo.png": "849848a26bbfc87024017418ad7a6233",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ma.png": "057ea2e08587f1361b3547556adae0c2",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/mv.png": "d9245f74e34d5c054413ace4b86b4f16",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/it.png": "5c8e910e6a33ec63dfcda6e8960dd19c",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/gh.png": "b35464dca793fa33e51bf890b5f3d92b",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/sl.png": "61b9d992c8a6a83abc4d432069617811",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/om.png": "cebd9ab4b9ab071b2142e21ae2129efc",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ve.png": "893391d65cbd10ca787a73578c77d3a7",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ee.png": "e242645cae28bd5291116ea211f9a566",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/mk.png": "835f2263974de523fa779d29c90595bf",
|
||||||
"assets/packages/intl_phone_field/assets/flags/vi.png": "3f317c56f31971b3179abd4e03847036",
|
"assets/packages/intl_phone_field/assets/flags/vi.png": "3f317c56f31971b3179abd4e03847036",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/gb-sct.png": "75106a5e49e3e16da76cb33bdac102ab",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ir.png": "37f67c3141e9843196cb94815be7bd37",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/fj.png": "1c6a86752578eb132390febf12789cd6",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/sn.png": "68eaa89bbc83b3f356e1ba2096b09b3c",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ag.png": "41c11d5668c93ba6e452f811defdbb24",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/eu.png": "c58ece3931acb87faadc5b940d4f7755",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/fi.png": "3ccd69a842e55183415b7ea2c04b15c8",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/gu.png": "2acb614b442e55864411b6e418df6eab",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/za.png": "b28280c6c3eb4624c18b5455d4a1b1ff",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/li.png": "ecdf7b3fe932378b110851674335d9ab",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/sv.png": "217b691efbef7a0f48cdd53e91997f0e",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/mw.png": "ffc1f18eeedc1dfbb1080aa985ce7d05",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/af.png": "ba710b50a060b5351381b55366396c30",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/as.png": "d9c1da515c6f945c2e2554592a9dfaae",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ug.png": "9a0f358b1eb19863e21ae2063fab51c0",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/iq.png": "bc3e6f68c5188dbf99b473e2bea066f2",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/dz.png": "132ceca353a95c8214676b2e94ecd40f",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/bd.png": "86a0e4bd8787dc8542137a407e0f987f",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/se.png": "25dd5434891ac1ca2ad1af59cda70f80",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/mm.png": "32e5293d6029d8294c7dfc3c3835c222",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/cn.png": "040539c2cdb60ebd9dc8957cdc6a8ad0",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/lu.png": "6274fd1cae3c7a425d25e4ccb0941bb8",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/cd.png": "5b5f832ed6cd9f9240cb31229d8763dc",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/bq.png": "3649c177693bfee9c2fcc63c191a51f1",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/gt.png": "706a0c3b5e0b589c843e2539e813839e",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/fr.png": "134bee9f9d794dc5c0922d1b9bdbb710",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ye.png": "4cf73209d90e9f02ead1565c8fdf59e5",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/gf.png": "134bee9f9d794dc5c0922d1b9bdbb710",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ki.png": "14db0fc29398730064503907bd696176",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/pw.png": "2e697cc6907a7b94c7f94f5d9b3bdccc",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/mg.png": "0ef6271ad284ebc0069ff0aeb5a3ad1e",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ie.png": "1d91912afc591dd120b47b56ea78cdbf",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/lc.png": "8c1a03a592aa0a99fcaf2b81508a87eb",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/io.png": "83d45bbbff087d47b2b39f1c20598f52",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/pl.png": "f20e9ef473a9ed24176f5ad74dd0d50a",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/km.png": "5554c8746c16d4f482986fb78ffd9b36",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/mp.png": "87351c30a529071ee9a4bb67765fea4f",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/gr.png": "ec11281d7decbf07b81a23a72a609b59",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/pf.png": "1ae72c24380d087cbe2d0cd6c3b58821",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/sa.png": "7c95c1a877148e2aa21a213d720ff4fd",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/nf.png": "1c2069b299ce3660a2a95ec574dfde25",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/bt.png": "3cfe1440e952bc7266d71f7f1454fa23",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/rw.png": "d1aae0647a5b1ab977ae43ab894ce2c3",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/fm.png": "d571b8bc4b80980a81a5edbde788b6d2",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/td.png": "009303b6188ca0e30bd50074b16f0b16",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ar.png": "3bd245f8c28f70c9ef9626dae27adc65",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ws.png": "f206322f3e22f175869869dbfadb6ce8",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/yt.png": "134bee9f9d794dc5c0922d1b9bdbb710",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ga.png": "b0e5b2fa1b7106c7652a955db24c11c4",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/hk.png": "4b5ec424348c98ec71a46ad3dce3931d",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/uy.png": "da4247b21fcbd9e30dc2b3f7c5dccb64",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ni.png": "e398dc23e79d9ccd702546cc25f126bf",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/st.png": "fef62c31713ff1063da2564df3f43eea",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/es.png": "654965f9722f6706586476fb2f5d30dd",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/si.png": "24237e53b34752554915e71e346bb405",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/cf.png": "263583ffdf7a888ce4fba8487d1da0b2",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ml.png": "0c50dfd539e87bb4313da0d4556e2d13",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/sz.png": "d1829842e45c2b2b29222c1b7e201591",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/kz.png": "cb3b0095281c9d7e7fb5ce1716ef8ee5",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/az.png": "6ffa766f6883d2d3d350cdc22a062ca3",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/fo.png": "2c7d9233582e83a86927e634897a2a90",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ai.png": "ce5e91ed1725f0499b9231b69a7fd448",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/va.png": "c010bf145f695d5c8fb551bafc081f77",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/vg.png": "fc095e11f5b58604d6f4d3c2b43d167f",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/nc.png": "cb36e0c945b79d56def11b23c6a9c7e9",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ky.png": "38e39eba673e82c48a1f25bd103a7e97",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/do.png": "ed35983a9263bb5713be37d9a52caddc",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/bv.png": "33bc70259c4908b7b9adeef9436f7a9f",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/pn.png": "0b0641b356af4c3e3489192ff4b0be77",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/nu.png": "f4169998548e312584c67873e0d9352d",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/pe.png": "4d9249aab70a26fadabb14380b3b55d2",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/tl.png": "c80876dc80cda5ab6bb8ef078bc6b05d",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/sx.png": "9c19254973d8acf81581ad95b408c7e6",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/tf.png": "b2c044b86509e7960b5ba66b094ea285",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/bf.png": "63f1c67fca7ce8b52b3418a90af6ad37",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/zw.png": "078a3267ea8eabf88b2d43fe4aed5ce5",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/um.png": "8fe7c4fed0a065fdfb9bd3125c6ecaa1",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/gp.png": "134bee9f9d794dc5c0922d1b9bdbb710",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ng.png": "aedbe364bd1543832e88e64b5817e877",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/mx.png": "84b12a569b209e213daccfcbdd1fc799",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/aq.png": "0c586e7b91aa192758fdd0f03adb84d8",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/me.png": "590284bc85810635ace30a173e615ca4",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ht.png": "630f7f8567d87409a32955107ad11a86",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/gw.png": "05606b9a6393971bd87718b809e054f9",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/bm.png": "b366ba84cbc8286c830f392bb9086be5",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/pk.png": "7a6a621f7062589677b3296ca16c6718",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/br.png": "5093e0cd8fd3c094664cd17ea8a36fd1",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/tj.png": "c73b793f2acd262e71b9236e64c77636",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/qa.png": "eb9b3388e554cf85aea1e739247548df",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ge.png": "6fbd41f07921fa415347ebf6dff5b0f7",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/is.png": "907840430252c431518005b562707831",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/hn.png": "9ecf68aed83c4a9b3f1e6275d96bfb04",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/pg.png": "0f7e03465a93e0b4e3e1c9d3dd5814a4",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/tv.png": "c57025ed7ae482210f29b9da86b0d211",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/kn.png": "f318e2fd87e5fd2cabefe9ff252bba46",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/md.png": "8911d3d821b95b00abbba8771e997eb3",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/pm.png": "134bee9f9d794dc5c0922d1b9bdbb710",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/bh.png": "a1acd86ef0e19ea5f0297bbe1de6cfd4",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ua.png": "b4b10d893611470661b079cb30473871",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ph.png": "e4025d1395a8455f1ba038597a95228c",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/gd.png": "7a4864ccfa2a0564041c2d1f8a13a8c9",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/kh.png": "d48d51e8769a26930da6edfc15de97fe",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/tg.png": "7f91f02b26b74899ff882868bd611714",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/gs.png": "419dd57836797a3f1bf6258ea6589f9a",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/to.png": "1cdd716b5b5502f85d6161dac6ee6c5b",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/sr.png": "9f912879f2829a625436ccd15e643e39",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/cv.png": "9b1f31f9fc0795d728328dedd33eb1c0",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ps.png": "52a25a48658ca9274830ffa124a8c1db",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/tr.png": "27feab1a5ca390610d07e0c6bd4720d5",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/lt.png": "7df2cd6566725685f7feb2051f916a3e",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/hu.png": "281582a753e643b46bdd894047db08bb",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/sj.png": "33bc70259c4908b7b9adeef9436f7a9f",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/gi.png": "446aa44aaa063d240adab88243b460d3",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ck.png": "39f343868a8dc8ca95d27b27a5caf480",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ne.png": "a20724c177e86d6a27143aa9c9664a6f",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/bb.png": "a8473747387e4e7a8450c499529f1c93",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/kg.png": "c4aa6d221d9a9d332155518d6b82dbc7",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/tk.png": "60428ff1cdbae680e5a0b8cde4677dd5",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/tc.png": "d728d6763c17c520ad6bcf3c24282a29",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/vu.png": "3f201fdfb6d669a64c35c20a801016d1",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/hm.png": "72be14316f0af3903cdca7a726c0c589",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/kr.png": "a3b7da3b76b20a70e9cd63cc2315b51b",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/eg.png": "311d780e8e3dd43f87e6070f6feb74c7",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/mn.png": "16086e8d89c9067d29fd0f2ea7021a45",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ke.png": "cf5aae3699d3cacb39db9803edae172b",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/dm.png": "8886b222ed9ccd00f67e8bcf86dadcc2",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/lk.png": "5a3a063cfff4a92fb0ba6158e610e025",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/pa.png": "78e3e4fd56f0064837098fe3f22fb41b",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/nr.png": "1316f3a8a419d8be1975912c712535ea",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/tn.png": "6612e9fec4bef022cbd45cbb7c02b2b6",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/so.png": "1ce20d052f9d057250be96f42647513b",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/sy.png": "24186a0f4ce804a16c91592db5a16a3a",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/mf.png": "134bee9f9d794dc5c0922d1b9bdbb710",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ss.png": "b0120cb000b31bb1a5c801c3592139bc",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/id.png": "80bb82d11d5bc144a21042e77972bca9",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/tm.png": "0980fb40ec450f70896f2c588510f933",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/kp.png": "e1c8bb52f31fca22d3368d8f492d8f27",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/cg.png": "eca97338cc1cb5b5e91bec72af57b3d4",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/cr.png": "bfd8b41e63fc3cc829c72c4b2e170532",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/pr.png": "b97b2f4432c430bc340d893f36527e31",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/lb.png": "f80cde345f0d9bd0086531808ce5166a",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ad.png": "384e9845debe9aca8f8586d9bedcb7e6",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/lv.png": "53105fea0cc9cc554e0ceaabc53a2d5d",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/je.png": "288f8dca26098e83ff0455b08cceca1b",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/cc.png": "31a475216e12fef447382c97b42876ce",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/gb-eng.png": "0d9f2a6775fd52b79e1d78eb1dda10cf",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/hr.png": "69711b2ea009a3e7c40045b538768d4e",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/gl.png": "b79e24ee1889b7446ba3d65564b86810",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/cw.png": "6c598eb0d331d6b238da57055ec00d33",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/xk.png": "079259fbcb1f3c78dafa944464295c16",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/my.png": "f7f962e8a074387fd568c9d4024e0959",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/mt.png": "f3119401ae0c3a9d6e2dc23803928c06",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/gq.png": "4286e56f388a37f64b21eb56550c06d9",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/bs.png": "2b9540c4fa514f71911a48de0bd77e71",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ax.png": "ec2062c36f09ed8fb90ac8992d010024",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ms.png": "9c955a926cf7d57fccb450a97192afa7",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/bi.png": "adda8121501f0543f1075244a1acc275",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ao.png": "5f0a372aa3aa7150a3dafea97acfc10d",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/rs.png": "9dff535d2d08c504be63062f39eff0b7",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/mc.png": "90c2ad7f144d73d4650cbea9dd621275",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/bz.png": "fd2d7d27a5ddabe4eb9a10b1d3a433e4",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/cy.png": "7b36f4af86257a3f15f5a5a16f4a2fcd",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/fk.png": "da8b0fe48829aae2c8feb4839895de63",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/be.png": "7e5e1831cdd91935b38415479a7110eb",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ro.png": "85af99741fe20664d9a7112cfd8d9722",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/ch.png": "a251702f7760b0aac141428ed60b7b66",
|
||||||
|
"assets/packages/intl_phone_field/assets/flags/at.png": "570c070177a5ea0fe03e20107ebf5283",
|
||||||
"assets/packages/window_manager/images/ic_chrome_minimize.png": "4282cd84cb36edf2efb950ad9269ca62",
|
"assets/packages/window_manager/images/ic_chrome_minimize.png": "4282cd84cb36edf2efb950ad9269ca62",
|
||||||
"assets/packages/window_manager/images/ic_chrome_maximize.png": "af7499d7657c8b69d23b85156b60298c",
|
|
||||||
"assets/packages/window_manager/images/ic_chrome_close.png": "75f4b8ab3608a05461a31fc18d6b47c2",
|
"assets/packages/window_manager/images/ic_chrome_close.png": "75f4b8ab3608a05461a31fc18d6b47c2",
|
||||||
|
"assets/packages/window_manager/images/ic_chrome_maximize.png": "af7499d7657c8b69d23b85156b60298c",
|
||||||
"assets/packages/window_manager/images/ic_chrome_unmaximize.png": "4a90c1909cb74e8f0d35794e2f61d8bf",
|
"assets/packages/window_manager/images/ic_chrome_unmaximize.png": "4a90c1909cb74e8f0d35794e2f61d8bf",
|
||||||
"assets/packages/material_design_icons_flutter/lib/fonts/materialdesignicons-webfont.ttf": "b62641afc9ab487008e996a5c5865e56",
|
"assets/FontManifest.json": "087fb858dc3cbfbf6baf6a30004922f1",
|
||||||
"assets/AssetManifest.json": "759f9ef9973f7e26c2a51450b55bb9fa"
|
"assets/NOTICES": "254a5bf1eeb00601955e148b31cb925c",
|
||||||
|
"flutter.js": "eb2682e33f25cd8f1fc59011497c35f8",
|
||||||
|
"/": "f1ab1648b6acf56aebbd6ae07968a461",
|
||||||
|
"favicon.png": "dca91c54388f52eded692718d5a98b8b",
|
||||||
|
"version.json": "a10748384e57f928f4d2871ac7563faf",
|
||||||
|
"manifest.json": "ef43d90e57aa7682d7e2cfba2f484a40",
|
||||||
|
"icons/Icon-192.png": "bb1cf5f6982006952211c7c8404ffbed",
|
||||||
|
"icons/Icon-512.png": "0f9aff01367f0a0c69773d25ca16ef35"
|
||||||
};
|
};
|
||||||
|
|
||||||
// The application shell files that are downloaded before a service worker can
|
// The application shell files that are downloaded before a service worker can
|
||||||
|
280932
public/main.dart.js
vendored
280932
public/main.dart.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
280358
public/main.foss.dart.js
vendored
280358
public/main.foss.dart.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
22709
public/main.profile.dart.js
vendored
22709
public/main.profile.dart.js
vendored
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
|||||||
{"app_name":"invoiceninja_flutter","version":"5.0.90","build_number":"90","package_name":"invoiceninja_flutter"}
|
{"app_name":"invoiceninja_flutter","version":"5.0.91","build_number":"91","package_name":"invoiceninja_flutter"}
|
@ -21,7 +21,7 @@
|
|||||||
</script>
|
</script>
|
||||||
<script>
|
<script>
|
||||||
window.flutterConfiguration = {
|
window.flutterConfiguration = {
|
||||||
canvasKitBaseUrl: "/canvaskit/"
|
canvasKitBaseUrl: "{{config('ninja.app_url')}}/canvaskit/"
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
<label for="password" class="input-label">{{ ctrans('texts.password') }}</label>
|
<label for="password" class="input-label">{{ ctrans('texts.password') }}</label>
|
||||||
<input type="password" name="password" id="password"
|
<input type="password" name="password" id="password"
|
||||||
class="input"
|
class="input"
|
||||||
autofocus>
|
autofocus required>
|
||||||
@error('password')
|
@error('password')
|
||||||
<div class="validation validation-fail">
|
<div class="validation validation-fail">
|
||||||
{{ $message }}
|
{{ $message }}
|
||||||
@ -27,7 +27,7 @@
|
|||||||
<label for="password" class="input-label">{{ ctrans('texts.password_confirmation') }}</label>
|
<label for="password" class="input-label">{{ ctrans('texts.password_confirmation') }}</label>
|
||||||
<input type="password" name="password_confirmation" id="password_confirmation"
|
<input type="password" name="password_confirmation" id="password_confirmation"
|
||||||
class="input"
|
class="input"
|
||||||
autofocus>
|
autofocus required>
|
||||||
@error('password_confirmation')
|
@error('password_confirmation')
|
||||||
<div class="validation validation-fail">
|
<div class="validation validation-fail">
|
||||||
{{ $message }}
|
{{ $message }}
|
||||||
|
241
routes/api.php
241
routes/api.php
@ -93,119 +93,8 @@ use App\Http\Controllers\WebCronController;
|
|||||||
use App\Http\Controllers\WebhookController;
|
use App\Http\Controllers\WebhookController;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
|
|
||||||
Route::group(['middleware' => ['throttle:300,1', 'api_secret_check']], function () {
|
|
||||||
Route::post('api/v1/signup', [AccountController::class, 'store'])->name('signup.submit');
|
|
||||||
Route::post('api/v1/oauth_login', [LoginController::class, 'oauthApiLogin']);
|
|
||||||
});
|
|
||||||
|
|
||||||
Route::group(['middleware' => ['throttle:10,1','api_secret_check','email_db']], function () {
|
|
||||||
Route::post('api/v1/login', [LoginController::class, 'apiLogin'])->name('login.submit')->middleware('throttle:20,1');
|
|
||||||
Route::post('api/v1/reset_password', [ForgotPasswordController::class, 'sendResetLinkEmail']);
|
|
||||||
});
|
|
||||||
|
|
||||||
Route::group(['middleware' => ['throttle:300,1', 'api_db', 'token_auth', 'locale'], 'prefix' => 'api/v1', 'as' => 'api.'], function () {
|
Route::group(['middleware' => ['throttle:300,1', 'api_db', 'token_auth', 'locale'], 'prefix' => 'api/v1', 'as' => 'api.'], function () {
|
||||||
Route::put('accounts/{account}', [AccountController::class, 'update'])->name('account.update');
|
|
||||||
Route::post('check_subdomain', [SubdomainController::class, 'index'])->name('check_subdomain');
|
|
||||||
Route::get('ping', [PingController::class, 'index'])->name('ping');
|
|
||||||
Route::get('health_check', [PingController::class, 'health'])->name('health_check');
|
|
||||||
|
|
||||||
Route::get('activities', [ActivityController::class, 'index']);
|
|
||||||
Route::get('activities/download_entity/{activity}', [ActivityController::class, 'downloadHistoricalEntity']);
|
|
||||||
|
|
||||||
|
|
||||||
Route::post('charts/totals', [ChartController::class, 'totals'])->name('chart.totals');
|
|
||||||
Route::post('charts/chart_summary', [ChartController::class, 'chart_summary'])->name('chart.chart_summary');
|
|
||||||
|
|
||||||
Route::post('claim_license', [LicenseController::class, 'index'])->name('license.index');
|
|
||||||
|
|
||||||
Route::resource('clients', ClientController::class); // name = (clients. index / create / show / update / destroy / edit
|
|
||||||
Route::put('clients/{client}/adjust_ledger', [ClientController::class, 'adjustLedger'])->name('clients.adjust_ledger');
|
|
||||||
Route::put('clients/{client}/upload', [ClientController::class, 'upload'])->name('clients.upload');
|
|
||||||
Route::post('clients/{client}/purge', [ClientController::class, 'purge'])->name('clients.purge')->middleware('password_protected');
|
|
||||||
Route::post('clients/{client}/{mergeable_client}/merge', [ClientController::class, 'merge'])->name('clients.merge')->middleware('password_protected');
|
|
||||||
Route::post('clients/bulk', [ClientController::class, 'bulk'])->name('clients.bulk');
|
|
||||||
|
|
||||||
Route::post('filters/{entity}', [FilterController::class, 'index'])->name('filters');
|
|
||||||
|
|
||||||
Route::resource('client_gateway_tokens', ClientGatewayTokenController::class);
|
|
||||||
|
|
||||||
Route::post('connected_account', [ConnectedAccountController::class, 'index']);
|
|
||||||
Route::post('connected_account/gmail', [ConnectedAccountController::class, 'handleGmailOauth']);
|
|
||||||
|
|
||||||
Route::post('client_statement', [ClientStatementController::class, 'statement'])->name('client.statement');
|
|
||||||
|
|
||||||
Route::post('companies/purge/{company}', [MigrationController::class, 'purgeCompany'])->middleware('password_protected');
|
|
||||||
Route::post('companies/purge_save_settings/{company}', [MigrationController::class, 'purgeCompanySaveSettings'])->middleware('password_protected');
|
|
||||||
|
|
||||||
Route::resource('companies', CompanyController::class); // name = (companies. index / create / show / update / destroy / edit
|
|
||||||
|
|
||||||
Route::put('companies/{company}/upload', [CompanyController::class, 'upload']);
|
|
||||||
Route::post('companies/{company}/default', [CompanyController::class, 'default']);
|
|
||||||
|
|
||||||
Route::get('company_ledger', [CompanyLedgerController::class, 'index'])->name('company_ledger.index');
|
|
||||||
|
|
||||||
Route::resource('company_gateways', CompanyGatewayController::class);
|
|
||||||
Route::post('company_gateways/bulk', [CompanyGatewayController::class, 'bulk'])->name('company_gateways.bulk');
|
|
||||||
|
|
||||||
Route::put('company_users/{user}', [CompanyUserController::class, 'update']);
|
|
||||||
|
|
||||||
Route::resource('credits', CreditController::class); // name = (credits. index / create / show / update / destroy / edit
|
|
||||||
Route::put('credits/{credit}/upload', [CreditController::class, 'upload'])->name('credits.upload');
|
|
||||||
Route::get('credits/{credit}/{action}', [CreditController::class, 'action'])->name('credits.action');
|
|
||||||
Route::post('credits/bulk', [CreditController::class, 'bulk'])->name('credits.bulk');
|
|
||||||
|
|
||||||
Route::resource('designs', DesignController::class); // name = (payments. index / create / show / update / destroy / edit
|
|
||||||
Route::post('designs/bulk', [DesignController::class, 'bulk'])->name('designs.bulk');
|
|
||||||
Route::post('designs/set/default', [DesignController::class, 'default'])->name('designs.default');
|
|
||||||
|
|
||||||
Route::resource('documents', DocumentController::class); // name = (documents. index / create / show / update / destroy / edit
|
|
||||||
Route::get('documents/{document}/download', [DocumentController::class, 'download'])->name('documents.download');
|
|
||||||
Route::post('documents/bulk', [DocumentController::class, 'bulk'])->name('documents.bulk');
|
|
||||||
|
|
||||||
Route::post('emails', [EmailController::class, 'send'])->name('email.send')->middleware('user_verified');
|
|
||||||
|
|
||||||
Route::resource('expenses', ExpenseController::class); // name = (expenses. index / create / show / update / destroy / edit
|
|
||||||
Route::put('expenses/{expense}/upload', [ExpenseController::class, 'upload']);
|
|
||||||
Route::post('expenses/bulk', [ExpenseController::class, 'bulk'])->name('expenses.bulk');
|
|
||||||
|
|
||||||
Route::post('export', [ExportController::class, 'index'])->name('export.index');
|
|
||||||
|
|
||||||
Route::resource('expense_categories', ExpenseCategoryController::class); // name = (expense_categories. index / create / show / update / destroy / edit
|
|
||||||
Route::post('expense_categories/bulk', [ExpenseCategoryController::class, 'bulk'])->name('expense_categories.bulk');
|
|
||||||
|
|
||||||
Route::resource('group_settings', GroupSettingController::class);
|
|
||||||
Route::post('group_settings/bulk', [GroupSettingController::class, 'bulk']);
|
|
||||||
Route::put('group_settings/{group_setting}/upload', [GroupSettingController::class, 'upload'])->name('group_settings.upload');
|
|
||||||
|
|
||||||
Route::post('import', [ImportController::class, 'import'])->name('import.import');
|
|
||||||
Route::post('import_json', [ImportJsonController::class, 'import'])->name('import.import_json');
|
|
||||||
Route::post('preimport', [ImportController::class, 'preimport'])->name('import.preimport');
|
|
||||||
|
|
||||||
Route::resource('invoices', InvoiceController::class); // name = (invoices. index / create / show / update / destroy / edit
|
|
||||||
Route::get('invoices/{invoice}/delivery_note', [InvoiceController::class, 'deliveryNote'])->name('invoices.delivery_note');
|
|
||||||
Route::get('invoices/{invoice}/{action}', [InvoiceController::class, 'action'])->name('invoices.action');
|
|
||||||
Route::put('invoices/{invoice}/upload', [InvoiceController::class, 'upload'])->name('invoices.upload');
|
|
||||||
Route::get('invoice/{invitation_key}/download', [InvoiceController::class, 'downloadPdf'])->name('invoices.downloadPdf');
|
|
||||||
Route::post('invoices/bulk', [InvoiceController::class, 'bulk'])->name('invoices.bulk');
|
|
||||||
Route::post('invoices/update_reminders', [InvoiceController::class, 'update_reminders'])->name('invoices.update_reminders');
|
|
||||||
|
|
||||||
Route::post('logout', [LogoutController::class, 'index'])->name('logout');
|
|
||||||
|
|
||||||
Route::post('migrate', [MigrationController::class, 'index'])->name('migrate.start');
|
|
||||||
|
|
||||||
Route::post('migration/purge/{company}', [MigrationController::class, 'purgeCompany'])->middleware('password_protected');
|
|
||||||
Route::post('migration/purge_save_settings/{company}', [MigrationController::class, 'purgeCompanySaveSettings'])->middleware('password_protected');
|
|
||||||
Route::post('migration/start', [MigrationController::class, 'startMigration']);
|
|
||||||
|
|
||||||
Route::post('one_time_token', [OneTimeTokenController::class, 'create']);
|
|
||||||
|
|
||||||
Route::resource('payments', PaymentController::class); // name = (payments. index / create / show / update / destroy / edit
|
|
||||||
Route::post('payments/refund', [PaymentController::class, 'refund'])->name('payments.refund');
|
|
||||||
Route::post('payments/bulk', [PaymentController::class, 'bulk'])->name('payments.bulk');
|
|
||||||
Route::put('payments/{payment}/upload', [PaymentController::class, 'upload']);
|
|
||||||
|
|
||||||
Route::resource('payment_terms', PaymentTermController::class); // name = (payments. index / create / show / update / destroy / edit
|
|
||||||
Route::post('payment_terms/bulk', [PaymentTermController::class, 'bulk'])->name('payment_terms.bulk');
|
|
||||||
|
|
||||||
Route::post('preview', [PreviewController::class, 'show'])->name('preview.show');
|
Route::post('preview', [PreviewController::class, 'show'])->name('preview.show');
|
||||||
Route::post('live_preview', [PreviewController::class, 'live'])->name('preview.live');
|
Route::post('live_preview', [PreviewController::class, 'live'])->name('preview.live');
|
||||||
@ -213,137 +102,7 @@ Route::group(['middleware' => ['throttle:300,1', 'api_db', 'token_auth', 'locale
|
|||||||
Route::post('preview/purchase_order', [PreviewPurchaseOrderController::class, 'show'])->name('preview_purchase_order.show');
|
Route::post('preview/purchase_order', [PreviewPurchaseOrderController::class, 'show'])->name('preview_purchase_order.show');
|
||||||
Route::post('live_preview/purchase_order', [PreviewPurchaseOrderController::class, 'live'])->name('preview_purchase_order.live');
|
Route::post('live_preview/purchase_order', [PreviewPurchaseOrderController::class, 'live'])->name('preview_purchase_order.live');
|
||||||
|
|
||||||
Route::resource('products', ProductController::class); // name = (products. index / create / show / update / destroy / edit
|
|
||||||
Route::post('products/bulk', [ProductController::class, 'bulk'])->name('products.bulk');
|
|
||||||
Route::put('products/{product}/upload', [ProductController::class, 'upload']);
|
|
||||||
|
|
||||||
Route::resource('projects', ProjectController::class); // name = (projects. index / create / show / update / destroy / edit
|
|
||||||
Route::post('projects/bulk', [ProjectController::class, 'bulk'])->name('projects.bulk');
|
|
||||||
Route::put('projects/{project}/upload', [ProjectController::class, 'upload'])->name('projects.upload');
|
|
||||||
|
|
||||||
Route::resource('quotes', QuoteController::class); // name = (quotes. index / create / show / update / destroy / edit
|
|
||||||
Route::get('quotes/{quote}/{action}', [QuoteController::class, 'action'])->name('quotes.action');
|
|
||||||
Route::post('quotes/bulk', [QuoteController::class, 'bulk'])->name('quotes.bulk');
|
|
||||||
Route::put('quotes/{quote}/upload', [QuoteController::class, 'upload']);
|
|
||||||
|
|
||||||
Route::resource('recurring_expenses', RecurringExpenseController::class);
|
|
||||||
Route::post('recurring_expenses/bulk', [RecurringExpenseController::class, 'bulk'])->name('recurring_expenses.bulk');
|
|
||||||
Route::put('recurring_expenses/{recurring_expense}/upload', [RecurringExpenseController::class, 'upload']);
|
|
||||||
|
|
||||||
|
|
||||||
Route::resource('recurring_invoices', RecurringInvoiceController::class); // name = (recurring_invoices. index / create / show / update / destroy / edit
|
|
||||||
Route::post('recurring_invoices/bulk', [RecurringInvoiceController::class, 'bulk'])->name('recurring_invoices.bulk');
|
|
||||||
Route::put('recurring_invoices/{recurring_invoice}/upload', [RecurringInvoiceController::class, 'upload']);
|
|
||||||
Route::resource('recurring_quotes', RecurringQuoteController::class); // name = (recurring_invoices. index / create / show / update / destroy / edit
|
|
||||||
Route::post('recurring_quotes/bulk', [RecurringQuoteController::class, 'bulk'])->name('recurring_quotes.bulk');
|
|
||||||
Route::put('recurring_quotes/{recurring_quote}/upload', [RecurringQuoteController::class, 'upload']);
|
|
||||||
|
|
||||||
Route::post('refresh', [LoginController::class, 'refresh'])->middleware('throttle:300,2');
|
|
||||||
|
|
||||||
Route::post('reports/clients', ClientReportController::class);
|
|
||||||
Route::post('reports/contacts', ClientContactReportController::class);
|
|
||||||
Route::post('reports/credits', CreditReportController::class);
|
|
||||||
Route::post('reports/documents', DocumentReportController::class);
|
|
||||||
Route::post('reports/expenses', ExpenseReportController::class);
|
|
||||||
Route::post('reports/invoices', InvoiceReportController::class);
|
|
||||||
Route::post('reports/invoice_items', InvoiceItemReportController::class);
|
|
||||||
Route::post('reports/quotes', QuoteReportController::class);
|
|
||||||
Route::post('reports/quote_items', QuoteItemReportController::class);
|
|
||||||
Route::post('reports/recurring_invoices', RecurringInvoiceReportController::class);
|
|
||||||
Route::post('reports/payments', PaymentReportController::class);
|
|
||||||
Route::post('reports/products', ProductReportController::class);
|
|
||||||
Route::post('reports/tasks', TaskReportController::class);
|
|
||||||
Route::post('reports/profitloss', ProfitAndLossController::class);
|
|
||||||
|
|
||||||
Route::resource('task_scheduler', TaskSchedulerController::class)->except('edit')->parameters(['task_scheduler' => 'scheduler']);
|
|
||||||
|
|
||||||
Route::get('scheduler', [SchedulerController::class, 'index']);
|
|
||||||
Route::post('support/messages/send', SendingController::class);
|
|
||||||
|
|
||||||
Route::post('self-update', [SelfUpdateController::class, 'update'])->middleware('password_protected');
|
|
||||||
Route::post('self-update/check_version', [SelfUpdateController::class, 'checkVersion']);
|
|
||||||
|
|
||||||
Route::resource('system_logs', SystemLogController::class);
|
|
||||||
|
|
||||||
Route::resource('tasks', TaskController::class); // name = (tasks. index / create / show / update / destroy / edit
|
|
||||||
Route::post('tasks/bulk', [TaskController::class, 'bulk'])->name('tasks.bulk');
|
|
||||||
Route::put('tasks/{task}/upload', [TaskController::class, 'upload']);
|
|
||||||
Route::post('tasks/sort', [TaskController::class, 'sort']);
|
|
||||||
|
|
||||||
Route::resource('task_statuses', TaskStatusController::class); // name = (task_statuses. index / create / show / update / destroy / edit
|
|
||||||
Route::post('task_statuses/bulk', [TaskStatusController::class, 'bulk'])->name('task_statuses.bulk');
|
|
||||||
|
|
||||||
Route::resource('tax_rates', TaxRateController::class); // name = (tax_rates. index / create / show / update / destroy / edit
|
|
||||||
Route::post('tax_rates/bulk', [TaxRateController::class, 'bulk'])->name('tax_rates.bulk');
|
|
||||||
|
|
||||||
Route::post('templates', [TemplateController::class, 'show'])->name('templates.show');
|
|
||||||
|
|
||||||
Route::resource('tokens', TokenController::class); // name = (tokens. index / create / show / update / destroy / edit
|
|
||||||
Route::post('tokens/bulk', [TokenController::class, 'bulk'])->name('tokens.bulk');
|
|
||||||
|
|
||||||
Route::get('settings/enable_two_factor', [TwoFactorController::class, 'setupTwoFactor']);
|
|
||||||
Route::post('settings/enable_two_factor', [TwoFactorController::class, 'enableTwoFactor']);
|
|
||||||
Route::post('settings/disable_two_factor', [TwoFactorController::class, 'disableTwoFactor']);
|
|
||||||
|
|
||||||
|
|
||||||
Route::post('verify', [TwilioController::class, 'generate'])->name('verify.generate')->middleware('throttle:100,1');
|
|
||||||
Route::post('verify/confirm', [TwilioController::class, 'confirm'])->name('verify.confirm');
|
|
||||||
|
|
||||||
Route::resource('vendors', VendorController::class); // name = (vendors. index / create / show / update / destroy / edit
|
|
||||||
Route::post('vendors/bulk', [VendorController::class, 'bulk'])->name('vendors.bulk');
|
|
||||||
Route::put('vendors/{vendor}/upload', [VendorController::class, 'upload']);
|
|
||||||
|
|
||||||
Route::resource('purchase_orders', PurchaseOrderController::class);
|
|
||||||
Route::post('purchase_orders/bulk', [PurchaseOrderController::class, 'bulk'])->name('purchase_orders.bulk');
|
|
||||||
Route::put('purchase_orders/{purchase_order}/upload', [PurchaseOrderController::class, 'upload']);
|
|
||||||
|
|
||||||
Route::get('purchase_orders/{purchase_order}/{action}', [PurchaseOrderController::class, 'action'])->name('purchase_orders.action');
|
|
||||||
|
|
||||||
Route::get('users', [UserController::class, 'index']);
|
|
||||||
Route::get('users/create', [UserController::class, 'create'])->middleware('password_protected');
|
|
||||||
Route::get('users/{user}', [UserController::class, 'show'])->middleware('password_protected');
|
|
||||||
Route::put('users/{user}', [UserController::class, 'update'])->middleware('password_protected');
|
|
||||||
Route::post('users', [UserController::class, 'store'])->middleware('password_protected');
|
|
||||||
//Route::post('users/{user}/attach_to_company', [UserController::class, 'attach')->middleware('password_protected');
|
|
||||||
Route::delete('users/{user}/detach_from_company', [UserController::class, 'detach'])->middleware('password_protected');
|
|
||||||
|
|
||||||
Route::post('users/bulk', [UserController::class, 'bulk'])->name('users.bulk')->middleware('password_protected');
|
|
||||||
Route::post('/users/{user}/invite', [UserController::class, 'invite'])->middleware('password_protected');
|
|
||||||
Route::post('/user/{user}/reconfirm', [UserController::class, 'reconfirm']);
|
|
||||||
|
|
||||||
Route::resource('webhooks', WebhookController::class);
|
|
||||||
Route::post('webhooks/bulk', [WebhookController::class, 'bulk'])->name('webhooks.bulk');
|
|
||||||
|
|
||||||
/*Subscription and Webhook routes */
|
|
||||||
// Route::post('hooks', [SubscriptionController::class, 'subscribe'])->name('hooks.subscribe');
|
|
||||||
// Route::delete('hooks/{subscription_id}', [SubscriptionController::class, 'unsubscribe'])->name('hooks.unsubscribe');
|
|
||||||
|
|
||||||
Route::post('stripe/update_payment_methods', [StripeController::class, 'update'])->middleware('password_protected')->name('stripe.update');
|
|
||||||
Route::post('stripe/import_customers', [StripeController::class, 'import'])->middleware('password_protected')->name('stripe.import');
|
|
||||||
|
|
||||||
Route::post('stripe/verify', [StripeController::class, 'verify'])->middleware('password_protected')->name('stripe.verify');
|
|
||||||
Route::post('stripe/disconnect/{company_gateway_id}', [StripeController::class, 'disconnect'])->middleware('password_protected')->name('stripe.disconnect');
|
|
||||||
|
|
||||||
Route::resource('subscriptions', SubscriptionController::class);
|
|
||||||
Route::post('subscriptions/bulk', [SubscriptionController::class, 'bulk'])->name('subscriptions.bulk');
|
|
||||||
Route::get('statics', StaticController::class);
|
|
||||||
// Route::post('apple_pay/upload_file','ApplyPayController::class, 'upload');
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Route::match(['get', 'post'], 'payment_webhook/{company_key}/{company_gateway_id}', PaymentWebhookController::class)
|
|
||||||
->middleware('throttle:1000,1')
|
|
||||||
->name('payment_webhook');
|
|
||||||
|
|
||||||
Route::match(['get', 'post'], 'payment_notification_webhook/{company_key}/{company_gateway_id}/{client}', PaymentNotificationWebhookController::class)
|
|
||||||
->middleware('throttle:1000,1')
|
|
||||||
->name('payment_notification_webhook');
|
|
||||||
|
|
||||||
Route::post('api/v1/postmark_webhook', [PostMarkController::class, 'webhook'])->middleware('throttle:1000,1');
|
|
||||||
Route::get('token_hash_router', [OneTimeTokenController::class, 'router'])->middleware('throttle:100,1');
|
|
||||||
Route::get('webcron', [WebCronController::class, 'index'])->middleware('throttle:100,1');
|
|
||||||
Route::post('api/v1/get_migration_account', [HostedMigrationController::class, 'getAccount'])->middleware('guest')->middleware('throttle:100,1');
|
|
||||||
Route::post('api/v1/confirm_forwarding', [HostedMigrationController::class, 'confirmForwarding'])->middleware('guest')->middleware('throttle:100,1');
|
|
||||||
Route::post('api/v1/process_webhook', [AppleController::class, 'process_webhook'])->middleware('throttle:1000,1');
|
|
||||||
Route::post('api/v1/confirm_purchase', [AppleController::class, 'confirm_purchase'])->middleware('throttle:1000,1');
|
|
||||||
Route::fallback([BaseController::class, 'notFound']);
|
Route::fallback([BaseController::class, 'notFound']);
|
@ -15,6 +15,7 @@ use App\Factory\InvoiceItemFactory;
|
|||||||
use App\Models\Client;
|
use App\Models\Client;
|
||||||
use App\Models\Invoice;
|
use App\Models\Invoice;
|
||||||
use App\Models\Payment;
|
use App\Models\Payment;
|
||||||
|
use App\Repositories\InvoiceRepository;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||||
use Illuminate\Routing\Middleware\ThrottleRequests;
|
use Illuminate\Routing\Middleware\ThrottleRequests;
|
||||||
@ -41,6 +42,150 @@ class DeleteInvoiceTest extends TestCase
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testDeleteAndRestoreInvoice()
|
||||||
|
{
|
||||||
|
//create an invoice for 36000 with a partial of 6000
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'name' => 'A Nice Client - About to be deleted',
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->post('/api/v1/clients', $data);
|
||||||
|
|
||||||
|
$response->assertStatus(200);
|
||||||
|
|
||||||
|
$arr = $response->json();
|
||||||
|
|
||||||
|
$client_hash_id = $arr['data']['id'];
|
||||||
|
$client = Client::find($this->decodePrimaryKey($client_hash_id));
|
||||||
|
|
||||||
|
$this->assertEquals($client->balance, 0);
|
||||||
|
$this->assertEquals($client->paid_to_date, 0);
|
||||||
|
|
||||||
|
$line_items = [];
|
||||||
|
|
||||||
|
$item = InvoiceItemFactory::create();
|
||||||
|
$item->quantity = 1;
|
||||||
|
$item->cost = 36000;
|
||||||
|
|
||||||
|
$line_items[] = (array) $item;
|
||||||
|
|
||||||
|
$invoice = [
|
||||||
|
'status_id' => 1,
|
||||||
|
'number' => '',
|
||||||
|
'discount' => 0,
|
||||||
|
'is_amount_discount' => 1,
|
||||||
|
'po_number' => '3434343',
|
||||||
|
'public_notes' => 'notes',
|
||||||
|
'is_deleted' => 0,
|
||||||
|
'partial' => 6000,
|
||||||
|
'custom_value1' => 0,
|
||||||
|
'custom_value2' => 0,
|
||||||
|
'custom_value3' => 0,
|
||||||
|
'custom_value4' => 0,
|
||||||
|
'client_id' => $client_hash_id,
|
||||||
|
'line_items' => (array) $line_items,
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->post('/api/v1/invoices/', $invoice)
|
||||||
|
->assertStatus(200);
|
||||||
|
|
||||||
|
$arr = $response->json();
|
||||||
|
|
||||||
|
$invoice_one_hashed_id = $arr['data']['id'];
|
||||||
|
|
||||||
|
$invoice = Invoice::find($this->decodePrimaryKey($invoice_one_hashed_id));
|
||||||
|
|
||||||
|
$invoice = $invoice->service()->markSent()->save();
|
||||||
|
|
||||||
|
$this->assertEquals(6000, $invoice->partial);
|
||||||
|
$this->assertEquals(36000, $invoice->amount);
|
||||||
|
|
||||||
|
|
||||||
|
// apply a payment of 6000
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'amount' => 6000,
|
||||||
|
'client_id' => $client->hashed_id,
|
||||||
|
'invoices' => [
|
||||||
|
[
|
||||||
|
'invoice_id' => $invoice->hashed_id,
|
||||||
|
'amount' => 6000,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'date' => '2019/12/12',
|
||||||
|
];
|
||||||
|
|
||||||
|
try {
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->post('/api/v1/payments?include=invoices', $data);
|
||||||
|
} catch (ValidationException $e) {
|
||||||
|
$message = json_decode($e->validator->getMessageBag(), 1);
|
||||||
|
$this->assertNotNull($message);
|
||||||
|
}
|
||||||
|
|
||||||
|
$response->assertStatus(200);
|
||||||
|
|
||||||
|
$arr = $response->json();
|
||||||
|
|
||||||
|
$payment_id = $arr['data']['id'];
|
||||||
|
|
||||||
|
$payment = Payment::withTrashed()->whereId($this->decodePrimaryKey($payment_id))->first();
|
||||||
|
|
||||||
|
$this->assertEquals(6000, $payment->amount);
|
||||||
|
$this->assertEquals(6000, $payment->applied);
|
||||||
|
|
||||||
|
$this->assertEquals(6000, $payment->client->paid_to_date);
|
||||||
|
|
||||||
|
$invoice = $invoice->fresh();
|
||||||
|
|
||||||
|
$this->assertEquals(30000, $invoice->balance);
|
||||||
|
$this->assertEquals(6000, $invoice->paid_to_date);
|
||||||
|
|
||||||
|
//delete the invoice an inspect the balances
|
||||||
|
|
||||||
|
$invoice_repo = new InvoiceRepository();
|
||||||
|
|
||||||
|
$invoice = $invoice_repo->delete($invoice);
|
||||||
|
$invoice = $invoice->fresh();
|
||||||
|
|
||||||
|
$this->assertTrue($invoice->is_deleted);
|
||||||
|
|
||||||
|
$payment = $payment->fresh();
|
||||||
|
|
||||||
|
$this->assertTrue($payment->is_deleted);
|
||||||
|
$this->assertEquals(4, $payment->status_id);
|
||||||
|
|
||||||
|
$client->fresh();
|
||||||
|
|
||||||
|
$this->assertEquals(0, $client->balance);
|
||||||
|
$this->assertEquals(0, $client->paid_to_date);
|
||||||
|
|
||||||
|
//restore the invoice. this should also rehydrate the payments and restore the correct paid to dates on the client record
|
||||||
|
|
||||||
|
$invoice_repo->restore($invoice);
|
||||||
|
$invoice = $invoice->fresh();
|
||||||
|
$client = $client->fresh();
|
||||||
|
$payment = $payment->fresh();
|
||||||
|
|
||||||
|
$this->assertEquals(30000, $invoice->balance);
|
||||||
|
$this->assertEquals(6000, $invoice->paid_to_date);
|
||||||
|
$this->assertEquals(6000, $client->paid_to_date);
|
||||||
|
$this->assertEquals(30000, $client->balance);
|
||||||
|
$this->assertEquals(6000, $payment->amount);
|
||||||
|
$this->assertFalse($payment->is_deleted);
|
||||||
|
$this->assertNull($payment->deleted_at);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public function testInvoiceDeletionAfterCancellation()
|
public function testInvoiceDeletionAfterCancellation()
|
||||||
{
|
{
|
||||||
$data = [
|
$data = [
|
||||||
|
@ -46,6 +46,18 @@ class InvoiceTest extends TestCase
|
|||||||
$this->makeTestData();
|
$this->makeTestData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function testInvoiceArchiveAction()
|
||||||
|
{
|
||||||
|
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->get('/api/v1/invoices/'.$this->invoice->hashed_id.'/archive',)
|
||||||
|
->assertStatus(200);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public function testMarkingDeletedInvoiceAsSent()
|
public function testMarkingDeletedInvoiceAsSent()
|
||||||
{
|
{
|
||||||
Client::factory()->create(['user_id' => $this->user->id, 'company_id' => $this->company->id])->each(function ($c) {
|
Client::factory()->create(['user_id' => $this->user->id, 'company_id' => $this->company->id])->each(function ($c) {
|
||||||
@ -290,4 +302,6 @@ class InvoiceTest extends TestCase
|
|||||||
])->post('/api/v1/invoices/', $data)
|
])->post('/api/v1/invoices/', $data)
|
||||||
->assertStatus(200);
|
->assertStatus(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ namespace Tests\Feature;
|
|||||||
|
|
||||||
use App\Models\Client;
|
use App\Models\Client;
|
||||||
use App\Models\ClientContact;
|
use App\Models\ClientContact;
|
||||||
|
use App\Models\Project;
|
||||||
use App\Models\Quote;
|
use App\Models\Quote;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
@ -49,6 +50,26 @@ class QuoteTest extends TestCase
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public function testQuoteConvertToProject()
|
||||||
|
{
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->post('/api/v1/quotes/bulk',['action' => 'convert_to_project', 'ids' => [$this->quote->hashed_id]]);
|
||||||
|
|
||||||
|
$response->assertStatus(200);
|
||||||
|
|
||||||
|
$res = $response->json();
|
||||||
|
|
||||||
|
$this->assertNotNull($res['data'][0]['project_id']);
|
||||||
|
|
||||||
|
$project = Project::find($this->decodePrimaryKey($res['data'][0]['project_id']));
|
||||||
|
|
||||||
|
$this->assertEquals($project->name, ctrans('texts.quote_number_short') . " " . $this->quote->number);
|
||||||
|
}
|
||||||
|
|
||||||
public function testQuoteList()
|
public function testQuoteList()
|
||||||
{
|
{
|
||||||
$response = $this->withHeaders([
|
$response = $this->withHeaders([
|
||||||
@ -139,4 +160,5 @@ class QuoteTest extends TestCase
|
|||||||
|
|
||||||
$response->assertStatus(200);
|
$response->assertStatus(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,89 @@ class ReminderTest extends TestCase
|
|||||||
$this->withoutExceptionHandling();
|
$this->withoutExceptionHandling();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function testForClientTimezoneEdges()
|
||||||
|
{
|
||||||
|
|
||||||
|
$this->invoice->next_send_date = null;
|
||||||
|
$this->invoice->date = now()->format('Y-m-d');
|
||||||
|
$this->invoice->due_date = Carbon::now()->addDays(5)->format('Y-m-d');
|
||||||
|
$this->invoice->save();
|
||||||
|
|
||||||
|
$settings = $this->company->settings;
|
||||||
|
$settings->enable_reminder1 = true;
|
||||||
|
$settings->schedule_reminder1 = 'before_due_date';
|
||||||
|
$settings->num_days_reminder1 = 4;
|
||||||
|
$settings->enable_reminder2 = true;
|
||||||
|
$settings->schedule_reminder2 = 'before_due_date';
|
||||||
|
$settings->num_days_reminder2 = 2;
|
||||||
|
$settings->enable_reminder3 = true;
|
||||||
|
$settings->schedule_reminder3 = 'after_due_date';
|
||||||
|
$settings->num_days_reminder3 = 3;
|
||||||
|
$settings->timezone_id = '15';
|
||||||
|
$settings->entity_send_time = 8;
|
||||||
|
|
||||||
|
$this->client->company->settings = $settings;
|
||||||
|
$this->client->push();
|
||||||
|
|
||||||
|
$client_settings = $settings;
|
||||||
|
$client_settings->timezone_id = '15';
|
||||||
|
$client_settings->entity_send_time = 8;
|
||||||
|
|
||||||
|
$this->invoice->client->settings = $client_settings;
|
||||||
|
$this->invoice->push();
|
||||||
|
|
||||||
|
$this->invoice = $this->invoice->service()->markSent()->save();
|
||||||
|
$this->invoice->service()->setReminder($client_settings)->save();
|
||||||
|
|
||||||
|
$next_send_date = Carbon::parse($this->invoice->next_send_date);
|
||||||
|
$calculatedReminderDate = Carbon::parse($this->invoice->due_date)->subDays(4)->addSeconds($this->invoice->client->timezone_offset());
|
||||||
|
|
||||||
|
nlog($next_send_date->format('Y-m-d h:i:s'));
|
||||||
|
nlog($calculatedReminderDate->format('Y-m-d h:i:s'));
|
||||||
|
|
||||||
|
$this->travelTo(now()->addDays(1));
|
||||||
|
|
||||||
|
$reminder_template = $this->invoice->calculateTemplate('invoice');
|
||||||
|
|
||||||
|
$this->assertEquals('reminder1', $reminder_template);
|
||||||
|
|
||||||
|
$this->assertTrue($next_send_date->eq($calculatedReminderDate));
|
||||||
|
|
||||||
|
$this->invoice->service()->touchReminder($reminder_template)->save();
|
||||||
|
|
||||||
|
$this->assertNotNull($this->invoice->last_sent_date);
|
||||||
|
$this->assertNotNull($this->invoice->reminder1_sent);
|
||||||
|
$this->assertNotNull($this->invoice->reminder_last_sent);
|
||||||
|
|
||||||
|
//calc next send date
|
||||||
|
$this->invoice->service()->setReminder()->save();
|
||||||
|
|
||||||
|
$next_send_date = Carbon::parse($this->invoice->next_send_date);
|
||||||
|
|
||||||
|
nlog($next_send_date->format('Y-m-d h:i:s'));
|
||||||
|
|
||||||
|
$calculatedReminderDate = Carbon::parse($this->invoice->due_date)->subDays(2)->addSeconds($this->invoice->client->timezone_offset());
|
||||||
|
$this->assertTrue($next_send_date->eq($calculatedReminderDate));
|
||||||
|
|
||||||
|
$this->travelTo(now()->addDays(2));
|
||||||
|
|
||||||
|
$reminder_template = $this->invoice->calculateTemplate('invoice');
|
||||||
|
|
||||||
|
$this->assertEquals('reminder2', $reminder_template);
|
||||||
|
$this->invoice->service()->touchReminder($reminder_template)->save();
|
||||||
|
$this->assertNotNull($this->invoice->reminder2_sent);
|
||||||
|
|
||||||
|
$this->invoice->service()->setReminder()->save();
|
||||||
|
|
||||||
|
$next_send_date = Carbon::parse($this->invoice->next_send_date);
|
||||||
|
$calculatedReminderDate = Carbon::parse($this->invoice->due_date)->addDays(3)->addSeconds($this->invoice->client->timezone_offset());
|
||||||
|
$this->assertTrue($next_send_date->eq($calculatedReminderDate));
|
||||||
|
|
||||||
|
nlog($next_send_date->format('Y-m-d h:i:s'));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public function testReminderQueryCatchesDate()
|
public function testReminderQueryCatchesDate()
|
||||||
{
|
{
|
||||||
$this->invoice->next_send_date = now()->format('Y-m-d');
|
$this->invoice->next_send_date = now()->format('Y-m-d');
|
||||||
@ -189,4 +272,6 @@ class ReminderTest extends TestCase
|
|||||||
|
|
||||||
$this->assertNotNull($this->invoice->next_send_date);
|
$this->assertNotNull($this->invoice->next_send_date);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,97 @@ class TaskApiTest extends TestCase
|
|||||||
Model::reguard();
|
Model::reguard();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testTimeLogValidation()
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'timelog' => $this->faker->firstName(),
|
||||||
|
];
|
||||||
|
|
||||||
|
try {
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->post('/api/v1/tasks', $data);
|
||||||
|
|
||||||
|
$arr = $response->json();
|
||||||
|
} catch (ValidationException $e) {
|
||||||
|
$response->assertStatus(302);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testTimeLogValidation1()
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'timelog' => [[1,2],[3,4]],
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->post('/api/v1/tasks', $data);
|
||||||
|
|
||||||
|
$arr = $response->json();
|
||||||
|
$response->assertStatus(200);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testTimeLogValidation2()
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'timelog' => [],
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->post('/api/v1/tasks', $data);
|
||||||
|
|
||||||
|
$arr = $response->json();
|
||||||
|
$response->assertStatus(200);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testTimeLogValidation3()
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'timelog' => [["a","b"],["c","d"]],
|
||||||
|
];
|
||||||
|
|
||||||
|
try {
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->post('/api/v1/tasks', $data);
|
||||||
|
|
||||||
|
$arr = $response->json();
|
||||||
|
} catch (ValidationException $e) {
|
||||||
|
$response->assertStatus(302);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testTimeLogValidation4()
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'timelog' => [[1,2],[3,0]],
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->post('/api/v1/tasks', $data);
|
||||||
|
|
||||||
|
$arr = $response->json();
|
||||||
|
$response->assertStatus(200);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public function testStartTask()
|
public function testStartTask()
|
||||||
{
|
{
|
||||||
$log = [
|
$log = [
|
||||||
@ -76,6 +167,7 @@ class TaskApiTest extends TestCase
|
|||||||
$data = [
|
$data = [
|
||||||
'description' => $this->faker->firstName(),
|
'description' => $this->faker->firstName(),
|
||||||
'number' => 'taskynumber',
|
'number' => 'taskynumber',
|
||||||
|
'client_id' => $this->client->id,
|
||||||
];
|
];
|
||||||
|
|
||||||
$response = $this->withHeaders([
|
$response = $this->withHeaders([
|
||||||
@ -126,6 +218,24 @@ class TaskApiTest extends TestCase
|
|||||||
$this->assertNotEmpty($arr['data']['number']);
|
$this->assertNotEmpty($arr['data']['number']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testTaskWithBadClientId()
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'client_id' => $this->faker->firstName(),
|
||||||
|
];
|
||||||
|
|
||||||
|
try {
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->post('/api/v1/tasks', $data);
|
||||||
|
$arr = $response->json();
|
||||||
|
} catch (ValidationException $e) {
|
||||||
|
$response->assertStatus(302);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public function testTaskPostWithActionStart()
|
public function testTaskPostWithActionStart()
|
||||||
{
|
{
|
||||||
$data = [
|
$data = [
|
||||||
|
@ -90,6 +90,9 @@ class GeneratesCounterTest extends TestCase
|
|||||||
$invoice_number = $this->getNextInvoiceNumber($this->client->fresh(), $this->invoice->fresh());
|
$invoice_number = $this->getNextInvoiceNumber($this->client->fresh(), $this->invoice->fresh());
|
||||||
$this->assertEquals($date_formatted.'-0001', $invoice_number);
|
$this->assertEquals($date_formatted.'-0001', $invoice_number);
|
||||||
|
|
||||||
|
$this->invoice->number = $invoice_number;
|
||||||
|
$this->invoice->save();
|
||||||
|
|
||||||
$invoice_number = $this->getNextInvoiceNumber($this->client->fresh(), $this->invoice->fresh());
|
$invoice_number = $this->getNextInvoiceNumber($this->client->fresh(), $this->invoice->fresh());
|
||||||
$this->assertEquals($date_formatted.'-0002', $invoice_number);
|
$this->assertEquals($date_formatted.'-0002', $invoice_number);
|
||||||
|
|
||||||
@ -290,10 +293,12 @@ class GeneratesCounterTest extends TestCase
|
|||||||
|
|
||||||
$invoice_number = $this->getNextClientNumber($this->client);
|
$invoice_number = $this->getNextClientNumber($this->client);
|
||||||
|
|
||||||
$this->assertEquals($invoice_number, date('Y').'-0001');
|
$this->assertEquals($invoice_number, date('Y').'-0010');
|
||||||
|
$this->client->number = $invoice_number;
|
||||||
|
$this->client->save();
|
||||||
|
|
||||||
$invoice_number = $this->getNextClientNumber($this->client);
|
$invoice_number = $this->getNextClientNumber($this->client);
|
||||||
$this->assertEquals($invoice_number, date('Y').'-0002');
|
$this->assertEquals($invoice_number, date('Y').'-0011');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testInvoicePadding()
|
public function testInvoicePadding()
|
||||||
|
@ -13,6 +13,7 @@ namespace Tests\Unit;
|
|||||||
|
|
||||||
use App\Factory\InvoiceItemFactory;
|
use App\Factory\InvoiceItemFactory;
|
||||||
use App\Helpers\Invoice\InvoiceSum;
|
use App\Helpers\Invoice\InvoiceSum;
|
||||||
|
use App\Helpers\Invoice\InvoiceSumInclusive;
|
||||||
use App\Models\Invoice;
|
use App\Models\Invoice;
|
||||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||||
use Tests\MockAccountData;
|
use Tests\MockAccountData;
|
||||||
@ -41,11 +42,47 @@ class InvoiceTest extends TestCase
|
|||||||
|
|
||||||
$this->invoice->line_items = $this->buildLineItems();
|
$this->invoice->line_items = $this->buildLineItems();
|
||||||
|
|
||||||
$this->invoice->usesinclusive_taxes = true;
|
$this->invoice->uses_inclusive_taxes = true;
|
||||||
|
|
||||||
$this->invoice_calc = new InvoiceSum($this->invoice);
|
$this->invoice_calc = new InvoiceSum($this->invoice);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testInclusiveRounding()
|
||||||
|
{
|
||||||
|
$this->invoice->line_items = [];
|
||||||
|
$this->invoice->discount = 0;
|
||||||
|
$this->invoice->uses_inclusive_taxes = true;
|
||||||
|
$this->invoice->save();
|
||||||
|
|
||||||
|
|
||||||
|
$item = InvoiceItemFactory::create();
|
||||||
|
$item->quantity = 1;
|
||||||
|
$item->cost = 50;
|
||||||
|
$item->tax_name1 = "taxy";
|
||||||
|
$item->tax_rate1 = 19;
|
||||||
|
|
||||||
|
$line_items[] = $item;
|
||||||
|
|
||||||
|
$item = InvoiceItemFactory::create();
|
||||||
|
$item->quantity = 1;
|
||||||
|
$item->cost = 50;
|
||||||
|
$item->tax_name1 = "taxy";
|
||||||
|
$item->tax_rate1 = 19;
|
||||||
|
|
||||||
|
$line_items[] = $item;
|
||||||
|
|
||||||
|
$this->invoice->line_items = $line_items;
|
||||||
|
$this->invoice->save();
|
||||||
|
|
||||||
|
$invoice_calc = new InvoiceSumInclusive($this->invoice);
|
||||||
|
|
||||||
|
$invoice_calc->build();
|
||||||
|
// $this->invoice->save();
|
||||||
|
|
||||||
|
$this->assertEquals($invoice_calc->getTotalTaxes(), 15.96);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private function buildLineItems()
|
private function buildLineItems()
|
||||||
{
|
{
|
||||||
$line_items = [];
|
$line_items = [];
|
||||||
|
@ -21,6 +21,53 @@ use Tests\TestCase;
|
|||||||
*/
|
*/
|
||||||
class NumberTest extends TestCase
|
class NumberTest extends TestCase
|
||||||
{
|
{
|
||||||
|
|
||||||
|
public function testFloatPrecision()
|
||||||
|
{
|
||||||
|
$value = 1.1;
|
||||||
|
|
||||||
|
$precision = (int) strpos(strrev($value), ".");
|
||||||
|
|
||||||
|
$result = round($value, $precision);
|
||||||
|
|
||||||
|
$this->assertEquals(1.1, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function testFloatPrecision1()
|
||||||
|
{
|
||||||
|
$value = "1.1";
|
||||||
|
|
||||||
|
$precision = (int) strpos(strrev($value), ".");
|
||||||
|
|
||||||
|
$result = round($value, $precision);
|
||||||
|
|
||||||
|
$this->assertEquals(1.1, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function testFloatPrecision2()
|
||||||
|
{
|
||||||
|
$value = 9.975;
|
||||||
|
|
||||||
|
$precision = (int) strpos(strrev($value), ".");
|
||||||
|
|
||||||
|
$result = round($value, $precision);
|
||||||
|
|
||||||
|
$this->assertEquals(9.975, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testFloatPrecision3()
|
||||||
|
{
|
||||||
|
$value = "9.975";
|
||||||
|
|
||||||
|
$precision = (int) strpos(strrev($value), ".");
|
||||||
|
|
||||||
|
$result = round($value, $precision);
|
||||||
|
|
||||||
|
$this->assertEquals(9.975, $result);
|
||||||
|
}
|
||||||
|
|
||||||
public function testRoundingThreeLow()
|
public function testRoundingThreeLow()
|
||||||
{
|
{
|
||||||
$rounded = Number::roundValue(3.144444444444, 3);
|
$rounded = Number::roundValue(3.144444444444, 3);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user