mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 01:54:29 -04:00
Merge branch 'v5-develop' into v5-stable
This commit is contained in:
commit
ebee366092
@ -57,7 +57,6 @@ DELETE_PDF_DAYS=60
|
||||
DELETE_BACKUP_DAYS=60
|
||||
|
||||
COMPOSER_AUTH='{"github-oauth": {"github.com": "${{ secrets.GITHUB_TOKEN }}"}}'
|
||||
SENTRY_LARAVEL_DSN=https://39389664f3f14969b4c43dadda00a40b@sentry2.invoicing.co/5
|
||||
|
||||
GOOGLE_PLAY_PACKAGE_NAME=
|
||||
APPSTORE_PASSWORD=
|
||||
|
@ -1 +1 @@
|
||||
5.5.33
|
||||
5.5.34
|
@ -1048,6 +1048,29 @@ class CheckData extends Command
|
||||
|
||||
$this->logMessage("Fixing - {$ninja_portal_url}");
|
||||
}
|
||||
else{
|
||||
|
||||
$c = Client::on('db-ninja-01')->where("company_id", config('ninja.ninja_default_company_id'))->where('custom_value2', $cu->account->key)->first();
|
||||
|
||||
if($c)
|
||||
{
|
||||
|
||||
$cc = $c->contacts()->first();
|
||||
|
||||
if($cc)
|
||||
{
|
||||
$ninja_portal_url = "https://invoiceninja.invoicing.co/client/ninja/{$cc->contact_key}/{$cu->account->key}";
|
||||
|
||||
$cu->ninja_portal_url = $ninja_portal_url;
|
||||
$cu->save();
|
||||
|
||||
$this->logMessage("Fixing - {$ninja_portal_url}");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
@ -56,10 +56,10 @@ class Kernel extends ConsoleKernel
|
||||
$schedule->job(new QueueSize)->everyFiveMinutes()->withoutOverlapping();
|
||||
|
||||
/* Checks for large companies and marked them as is_large */
|
||||
$schedule->job(new CompanySizeCheck)->daily()->withoutOverlapping();
|
||||
$schedule->job(new CompanySizeCheck)->dailyAt('23:20')->withoutOverlapping();
|
||||
|
||||
/* Pulls in the latest exchange rates */
|
||||
$schedule->job(new UpdateExchangeRates)->daily()->withoutOverlapping();
|
||||
$schedule->job(new UpdateExchangeRates)->dailyAt('23:30')->withoutOverlapping();
|
||||
|
||||
/* Runs cleanup code for subscriptions */
|
||||
$schedule->job(new SubscriptionCron)->daily()->withoutOverlapping();
|
||||
|
@ -136,6 +136,6 @@ class DesignFilters extends QueryFilters
|
||||
public function entityFilter()
|
||||
{
|
||||
//return $this->builder->whereCompanyId(auth()->user()->company()->id);
|
||||
return $this->builder->whereCompanyId(auth()->user()->company()->id)->orWhere('company_id', null);
|
||||
return $this->builder->where('company_id', auth()->user()->company()->id)->orWhere('company_id', null)->orderBy('id','asc');
|
||||
}
|
||||
}
|
||||
|
@ -141,7 +141,7 @@ class SwissQrGenerator
|
||||
// Optionally, add some human-readable information about what the bill is for.
|
||||
$qrBill->setAdditionalInformation(
|
||||
QrBill\DataGroup\Element\AdditionalInformation::create(
|
||||
$this->invoice->public_notes ?: ''
|
||||
$this->invoice->public_notes ?: ctrans('texts.invoice_number_placeholder', ['invoice' => $invoice_number])
|
||||
)
|
||||
);
|
||||
|
||||
@ -149,7 +149,7 @@ class SwissQrGenerator
|
||||
// Now get the QR code image and save it as a file.
|
||||
try {
|
||||
|
||||
$output = new QrBill\PaymentPart\Output\HtmlOutput\HtmlOutput($qrBill, 'en');
|
||||
$output = new QrBill\PaymentPart\Output\HtmlOutput\HtmlOutput($qrBill, $this->client->locale() ?: 'en');
|
||||
|
||||
$html = $output
|
||||
->setPrintable(false)
|
||||
|
@ -108,6 +108,8 @@ class ActivityController extends BaseController
|
||||
'credit' => $activity->credit ? $activity->credit : '',
|
||||
'task' => $activity->task ? $activity->task : '',
|
||||
'vendor' => $activity->vendor ? $activity->vendor : '',
|
||||
'vendor_contact' => $activity->vendor_contact ? $activity->vendor_contact : '',
|
||||
'purchase_order' => $activity->purchase_order ? $activity->purchase_order : '',
|
||||
];
|
||||
|
||||
return array_merge($arr, $activity->toArray());
|
||||
|
@ -592,7 +592,10 @@ class LoginController extends BaseController
|
||||
|
||||
$google = new Google();
|
||||
|
||||
$user = $google->getTokenResponse(request()->input('id_token'));
|
||||
if(request()->has('id_token'))
|
||||
$user = $google->getTokenResponse(request()->input('id_token'));
|
||||
else
|
||||
return response()->json(['message' => 'Illegal request'], 403);
|
||||
|
||||
if (is_array($user)) {
|
||||
$query = [
|
||||
|
@ -459,7 +459,8 @@ class BaseController extends Controller
|
||||
);
|
||||
|
||||
if ($query instanceof Builder) {
|
||||
$limit = request()->input('per_page', 20);
|
||||
//27-10-2022 - enforce unsigned integer
|
||||
$limit = $this->resolveQueryLimit();
|
||||
|
||||
$paginator = $query->paginate($limit);
|
||||
$query = $paginator->getCollection();
|
||||
@ -472,6 +473,14 @@ class BaseController extends Controller
|
||||
return $this->response($this->manager->createData($resource)->toArray());
|
||||
}
|
||||
|
||||
private function resolveQueryLimit()
|
||||
{
|
||||
if(request()->has('per_page'))
|
||||
return abs((int)request()->input('per_page', 20));
|
||||
|
||||
return 20;
|
||||
}
|
||||
|
||||
protected function miniLoadResponse($query)
|
||||
{
|
||||
$user = auth()->user();
|
||||
@ -524,7 +533,7 @@ class BaseController extends Controller
|
||||
);
|
||||
|
||||
if ($query instanceof Builder) {
|
||||
$limit = request()->input('per_page', 20);
|
||||
$limit = $this->resolveQueryLimit();
|
||||
|
||||
$paginator = $query->paginate($limit);
|
||||
$query = $paginator->getCollection();
|
||||
@ -782,7 +791,7 @@ class BaseController extends Controller
|
||||
);
|
||||
|
||||
if ($query instanceof Builder) {
|
||||
$limit = request()->input('per_page', 20);
|
||||
$limit = $this->resolveQueryLimit();
|
||||
|
||||
$paginator = $query->paginate($limit);
|
||||
$query = $paginator->getCollection();
|
||||
@ -831,7 +840,7 @@ class BaseController extends Controller
|
||||
}
|
||||
|
||||
if ($query instanceof Builder) {
|
||||
$limit = request()->input('per_page', 20);
|
||||
$limit = $this->resolveQueryLimit();
|
||||
$paginator = $query->paginate($limit);
|
||||
$query = $paginator->getCollection();
|
||||
$resource = new Collection($query, $transformer, $this->entity_type);
|
||||
|
@ -237,7 +237,7 @@ class InvoiceController extends BaseController
|
||||
'metadata' => [],
|
||||
];
|
||||
|
||||
TransactionLog::dispatch(TransactionEvent::INVOICE_UPDATED, $transaction, $invoice->company->db);
|
||||
// TransactionLog::dispatch(TransactionEvent::INVOICE_UPDATED, $transaction, $invoice->company->db);
|
||||
|
||||
return $this->itemResponse($invoice);
|
||||
}
|
||||
@ -433,7 +433,7 @@ class InvoiceController extends BaseController
|
||||
'metadata' => [],
|
||||
];
|
||||
|
||||
TransactionLog::dispatch(TransactionEvent::INVOICE_UPDATED, $transaction, $invoice->company->db);
|
||||
// TransactionLog::dispatch(TransactionEvent::INVOICE_UPDATED, $transaction, $invoice->company->db);
|
||||
|
||||
return $this->itemResponse($invoice);
|
||||
}
|
||||
|
@ -11,9 +11,12 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Requests\Twilio\Confirm2faRequest;
|
||||
use App\Http\Requests\Twilio\ConfirmSmsRequest;
|
||||
use App\Http\Requests\Twilio\Generate2faRequest;
|
||||
use App\Http\Requests\Twilio\GenerateSmsRequest;
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
use Illuminate\Http\Response;
|
||||
use Twilio\Rest\Client;
|
||||
@ -100,6 +103,87 @@ class TwilioController extends BaseController
|
||||
|
||||
return response()->json(['message' => 'SMS not verified'], 400);
|
||||
|
||||
}
|
||||
|
||||
public function generate2faResetCode(Generate2faRequest $request)
|
||||
{
|
||||
$user = User::where('email', $request->email)->first();
|
||||
|
||||
if(!$user)
|
||||
return response()->json(['message' => 'Unable to retrieve user.'], 400);
|
||||
|
||||
$sid = config('ninja.twilio_account_sid');
|
||||
$token = config('ninja.twilio_auth_token');
|
||||
|
||||
$twilio = new Client($sid, $token);
|
||||
|
||||
|
||||
try {
|
||||
$verification = $twilio->verify
|
||||
->v2
|
||||
->services(config('ninja.twilio_verify_sid'))
|
||||
->verifications
|
||||
->create($user->phone, "sms");
|
||||
}
|
||||
catch(\Exception $e) {
|
||||
|
||||
return response()->json(['message' => 'Invalid phone number on file, we are unable to reset. Please contact support.'], 400);
|
||||
|
||||
}
|
||||
|
||||
$user->sms_verification_code = $verification->sid;
|
||||
$user->save();
|
||||
|
||||
return response()->json(['message' => 'Code sent.'], 200);
|
||||
}
|
||||
|
||||
public function confirm2faResetCode(Confirm2faRequest $request)
|
||||
{
|
||||
$user = User::where('email', $request->email)->first();
|
||||
|
||||
if(!$user)
|
||||
return response()->json(['message' => 'Unable to retrieve user.'], 400);
|
||||
|
||||
$sid = config('ninja.twilio_account_sid');
|
||||
$token = config('ninja.twilio_auth_token');
|
||||
|
||||
$twilio = new Client($sid, $token);
|
||||
|
||||
$verification_check = $twilio->verify
|
||||
->v2
|
||||
->services(config('ninja.twilio_verify_sid'))
|
||||
->verificationChecks
|
||||
->create([
|
||||
"to" => $user->phone,
|
||||
"code" => $request->code
|
||||
]);
|
||||
|
||||
|
||||
if($verification_check->status == 'approved'){
|
||||
|
||||
$user->google_2fa_secret = '';
|
||||
$user->sms_verification_code = '';
|
||||
$user->save();
|
||||
|
||||
return response()->json(['message' => 'SMS verified, 2FA disabled.'], 200);
|
||||
}
|
||||
|
||||
return response()->json(['message' => 'SMS not verified.'], 400);
|
||||
|
||||
}
|
||||
|
||||
public function validatePhoneNumber()
|
||||
{
|
||||
|
||||
$sid = config('ninja.twilio_account_sid');
|
||||
$token = config('ninja.twilio_auth_token');
|
||||
|
||||
$twilio = new Client($sid, $token);
|
||||
|
||||
$phone_number = $twilio->lookups->v1->phoneNumbers("0417918829")
|
||||
->fetch(["countryCode" => "AU"]);
|
||||
|
||||
print($phone_number);
|
||||
|
||||
}
|
||||
|
||||
|
@ -389,15 +389,18 @@ class UserController extends BaseController
|
||||
$new_user = $user->fresh();
|
||||
|
||||
/* When changing email address we store the former email in case we need to rollback */
|
||||
/* 27-10-2022 we need to wipe the oauth data at this point*/
|
||||
if ($old_user_email != $new_email) {
|
||||
$user->last_confirmed_email_address = $old_user_email;
|
||||
$user->email_verified_at = null;
|
||||
$user->oauth_user_id = null;
|
||||
$user->oauth_provider_id = null;
|
||||
$user->oauth_user_refresh_token = null;
|
||||
$user->oauth_user_token = null;
|
||||
$user->save();
|
||||
UserEmailChanged::dispatch($new_user, json_decode($old_user), auth()->user()->company());
|
||||
}
|
||||
|
||||
// $user->company_users()->update(["permissions_updated_at" => now()]);
|
||||
|
||||
event(new UserWasUpdated($user, auth()->user(), auth()->user()->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
|
||||
return $this->itemResponse($user);
|
||||
|
@ -14,6 +14,7 @@ namespace App\Http\Controllers\VendorPortal;
|
||||
use App\Events\Credit\CreditWasViewed;
|
||||
use App\Events\Invoice\InvoiceWasViewed;
|
||||
use App\Events\Misc\InvitationWasViewed;
|
||||
use App\Events\PurchaseOrder\PurchaseOrderWasViewed;
|
||||
use App\Events\Quote\QuoteWasViewed;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Jobs\Entity\CreateRawPdf;
|
||||
@ -83,7 +84,8 @@ class InvitationController extends Controller
|
||||
|
||||
$invitation->markViewed();
|
||||
event(new InvitationWasViewed($invitation->purchase_order, $invitation, $invitation->company, Ninja::eventVars()));
|
||||
|
||||
event(new PurchaseOrderWasViewed($invitation, $invitation->company, Ninja::eventVars()));
|
||||
|
||||
}
|
||||
else{
|
||||
|
||||
|
50
app/Http/Requests/Twilio/Confirm2faRequest.php
Normal file
50
app/Http/Requests/Twilio/Confirm2faRequest.php
Normal file
@ -0,0 +1,50 @@
|
||||
<?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\Http\Requests\Twilio;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use App\Libraries\MultiDB;
|
||||
|
||||
|
||||
class Confirm2faRequest extends Request
|
||||
{
|
||||
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize() : bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function rules()
|
||||
{
|
||||
|
||||
return [
|
||||
'code' => 'required',
|
||||
'email' => 'required|exists:users,email',
|
||||
];
|
||||
}
|
||||
|
||||
public function prepareForValidation()
|
||||
{
|
||||
$input = $this->all();
|
||||
|
||||
if(array_key_exists('email', $input))
|
||||
MultiDB::userFindAndSetDb($input['email']);
|
||||
|
||||
$this->replace($input);
|
||||
}
|
||||
|
||||
}
|
51
app/Http/Requests/Twilio/Generate2faRequest.php
Normal file
51
app/Http/Requests/Twilio/Generate2faRequest.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?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\Http\Requests\Twilio;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use App\Libraries\MultiDB;
|
||||
|
||||
|
||||
class Generate2faRequest extends Request
|
||||
{
|
||||
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize() : bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public function rules()
|
||||
{
|
||||
|
||||
return [
|
||||
'email' => 'required|exists:users,email',
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
public function prepareForValidation()
|
||||
{
|
||||
$input = $this->all();
|
||||
|
||||
if(array_key_exists('email', $input))
|
||||
MultiDB::userFindAndSetDb($input['email']);
|
||||
|
||||
$this->replace($input);
|
||||
}
|
||||
|
||||
}
|
@ -185,6 +185,8 @@ class MatchBankTransactions implements ShouldQueue
|
||||
$expense->transaction_reference = $this->bt->description;
|
||||
$expense->transaction_id = $this->bt->id;
|
||||
$expense->vendor_id = array_key_exists('vendor_id', $input) ? $input['vendor_id'] : null;
|
||||
$expense->invoice_documents = $this->company->invoice_expense_documents;
|
||||
$expense->should_be_invoiced = $this->company->mark_expenses_invoiceable;
|
||||
$expense->save();
|
||||
|
||||
$this->bt->expense_id = $expense->id;
|
||||
|
@ -25,7 +25,7 @@ class AutoBill implements ShouldQueue
|
||||
|
||||
public $tries = 1;
|
||||
|
||||
public Invoice $invoice;
|
||||
public int $invoice_id;
|
||||
|
||||
public string $db;
|
||||
|
||||
@ -34,9 +34,9 @@ class AutoBill implements ShouldQueue
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Invoice $invoice, ?string $db)
|
||||
public function __construct(int $invoice_id, ?string $db)
|
||||
{
|
||||
$this->invoice = $invoice;
|
||||
$this->invoice_id = $invoice_id;
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
@ -54,11 +54,13 @@ class AutoBill implements ShouldQueue
|
||||
}
|
||||
|
||||
try {
|
||||
nlog("autobill {$this->invoice->id}");
|
||||
nlog("autobill {$this->invoice_id}");
|
||||
|
||||
$invoice = Invoice::withTrashed()->find($this->invoice_id);
|
||||
|
||||
$this->invoice->service()->autoBill();
|
||||
$invoice->service()->autoBill();
|
||||
} catch (\Exception $e) {
|
||||
nlog("Failed to capture payment for {$this->invoice->company_id} - {$this->invoice->number} ->".$e->getMessage());
|
||||
nlog("Failed to capture payment for {$this->invoice_id} ->".$e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -58,13 +58,12 @@ class AutoBillCron
|
||||
->whereHas('company', function ($query) {
|
||||
$query->where('is_disabled', 0);
|
||||
})
|
||||
->orderBy('id', 'DESC')
|
||||
->with('company');
|
||||
->orderBy('id', 'DESC');
|
||||
|
||||
nlog($auto_bill_partial_invoices->count().' partial invoices to auto bill');
|
||||
|
||||
$auto_bill_partial_invoices->cursor()->each(function ($invoice) {
|
||||
AutoBill::dispatch($invoice, false);
|
||||
AutoBill::dispatch($invoice->id, false);
|
||||
});
|
||||
|
||||
$auto_bill_invoices = Invoice::whereDate('due_date', '<=', now())
|
||||
@ -76,13 +75,12 @@ class AutoBillCron
|
||||
->whereHas('company', function ($query) {
|
||||
$query->where('is_disabled', 0);
|
||||
})
|
||||
->orderBy('id', 'DESC')
|
||||
->with('company');
|
||||
->orderBy('id', 'DESC');
|
||||
|
||||
nlog($auto_bill_invoices->count().' full invoices to auto bill');
|
||||
|
||||
$auto_bill_invoices->cursor()->each(function ($invoice) {
|
||||
AutoBill::dispatch($invoice, false);
|
||||
AutoBill::dispatch($invoice->id, false);
|
||||
});
|
||||
} else {
|
||||
//multiDB environment, need to
|
||||
@ -98,13 +96,12 @@ class AutoBillCron
|
||||
->whereHas('company', function ($query) {
|
||||
$query->where('is_disabled', 0);
|
||||
})
|
||||
->orderBy('id', 'DESC')
|
||||
->with('company');
|
||||
->orderBy('id', 'DESC');
|
||||
|
||||
nlog($auto_bill_partial_invoices->count()." partial invoices to auto bill db = {$db}");
|
||||
|
||||
$auto_bill_partial_invoices->cursor()->each(function ($invoice) use ($db) {
|
||||
AutoBill::dispatch($invoice, $db);
|
||||
AutoBill::dispatch($invoice->id, $db);
|
||||
});
|
||||
|
||||
$auto_bill_invoices = Invoice::whereDate('due_date', '<=', now())
|
||||
@ -116,14 +113,13 @@ class AutoBillCron
|
||||
->whereHas('company', function ($query) {
|
||||
$query->where('is_disabled', 0);
|
||||
})
|
||||
->orderBy('id', 'DESC')
|
||||
->with('company');
|
||||
->orderBy('id', 'DESC');
|
||||
|
||||
nlog($auto_bill_invoices->count()." full invoices to auto bill db = {$db}");
|
||||
|
||||
$auto_bill_invoices->cursor()->each(function ($invoice) use ($db) {
|
||||
nlog($this->counter);
|
||||
AutoBill::dispatch($invoice, $db);
|
||||
AutoBill::dispatch($invoice->id, $db);
|
||||
$this->counter++;
|
||||
});
|
||||
}
|
||||
|
@ -122,12 +122,13 @@ class NinjaMailerJob implements ShouldQueue
|
||||
->to($this->nmo->to_user->email)
|
||||
->send($this->nmo->mailable);
|
||||
|
||||
LightLogs::create(new EmailSuccess($this->nmo->company->company_key))
|
||||
->batch();
|
||||
|
||||
/* Count the amount of emails sent across all the users accounts */
|
||||
Cache::increment($this->company->account->key);
|
||||
|
||||
LightLogs::create(new EmailSuccess($this->nmo->company->company_key))
|
||||
->send();
|
||||
|
||||
|
||||
} catch (\Exception | \RuntimeException | \Google\Service\Exception $e) {
|
||||
|
||||
nlog("error failed with {$e->getMessage()}");
|
||||
@ -394,7 +395,7 @@ class NinjaMailerJob implements ShouldQueue
|
||||
$job_failure->string_metric6 = substr($errors, 0, 150);
|
||||
|
||||
LightLogs::create($job_failure)
|
||||
->queue();
|
||||
->send();
|
||||
}
|
||||
|
||||
public function failed($exception = null)
|
||||
|
@ -63,8 +63,15 @@ class AdjustEmailQuota implements ShouldQueue
|
||||
|
||||
$email_count = Cache::get($account->key);
|
||||
|
||||
if($email_count > 0)
|
||||
LightLogs::create(new EmailCount($email_count, $account->key))->batch();
|
||||
if($email_count > 0){
|
||||
|
||||
try{
|
||||
LightLogs::create(new EmailCount($email_count, $account->key))->send();
|
||||
}
|
||||
catch(\Exception $e){
|
||||
nlog($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
Cache::forget($account->key);
|
||||
Cache::forget("throttle_notified:{$account->key}");
|
||||
|
@ -43,6 +43,6 @@ class QueueSize implements ShouldQueue
|
||||
public function handle()
|
||||
{
|
||||
LightLogs::create(new QueueSizeAnalytic(Queue::size()))
|
||||
->queue();
|
||||
->send();
|
||||
}
|
||||
}
|
||||
|
@ -142,7 +142,7 @@ class ProcessPostmarkWebhook implements ShouldQueue
|
||||
$this->invitation->opened_date = now();
|
||||
$this->invitation->save();
|
||||
|
||||
SystemLogger::dispatch($this->request,
|
||||
SystemLogger::dispatchSync($this->request,
|
||||
SystemLog::CATEGORY_MAIL,
|
||||
SystemLog::EVENT_MAIL_OPENED,
|
||||
SystemLog::TYPE_WEBHOOK_RESPONSE,
|
||||
@ -171,7 +171,7 @@ class ProcessPostmarkWebhook implements ShouldQueue
|
||||
$this->invitation->email_status = 'delivered';
|
||||
$this->invitation->save();
|
||||
|
||||
SystemLogger::dispatch($this->request,
|
||||
SystemLogger::dispatchSync($this->request,
|
||||
SystemLog::CATEGORY_MAIL,
|
||||
SystemLog::EVENT_MAIL_DELIVERY,
|
||||
SystemLog::TYPE_WEBHOOK_RESPONSE,
|
||||
@ -217,9 +217,9 @@ class ProcessPostmarkWebhook implements ShouldQueue
|
||||
$this->request['MessageID']
|
||||
);
|
||||
|
||||
LightLogs::create($bounce)->batch();
|
||||
LightLogs::create($bounce)->send();
|
||||
|
||||
SystemLogger::dispatch($this->request, SystemLog::CATEGORY_MAIL, SystemLog::EVENT_MAIL_BOUNCED, SystemLog::TYPE_WEBHOOK_RESPONSE, $this->invitation->contact->client, $this->invitation->company);
|
||||
SystemLogger::dispatchSync($this->request, SystemLog::CATEGORY_MAIL, SystemLog::EVENT_MAIL_BOUNCED, SystemLog::TYPE_WEBHOOK_RESPONSE, $this->invitation->contact->client, $this->invitation->company);
|
||||
|
||||
// if(config('ninja.notification.slack'))
|
||||
// $this->invitation->company->notification(new EmailBounceNotification($this->invitation->company->account))->ninja();
|
||||
@ -263,9 +263,9 @@ class ProcessPostmarkWebhook implements ShouldQueue
|
||||
$this->request['MessageID']
|
||||
);
|
||||
|
||||
LightLogs::create($spam)->batch();
|
||||
LightLogs::create($spam)->send();
|
||||
|
||||
SystemLogger::dispatch($this->request, SystemLog::CATEGORY_MAIL, SystemLog::EVENT_MAIL_SPAM_COMPLAINT, SystemLog::TYPE_WEBHOOK_RESPONSE, $this->invitation->contact->client, $this->invitation->company);
|
||||
SystemLogger::dispatchSync($this->request, SystemLog::CATEGORY_MAIL, SystemLog::EVENT_MAIL_SPAM_COMPLAINT, SystemLog::TYPE_WEBHOOK_RESPONSE, $this->invitation->contact->client, $this->invitation->company);
|
||||
|
||||
if(config('ninja.notification.slack'))
|
||||
$this->invitation->company->notification(new EmailSpamNotification($this->invitation->company->account))->ninja();
|
||||
|
@ -130,7 +130,7 @@ class SendRecurring implements ShouldQueue
|
||||
$invoice->invitations->each(function ($invitation) use ($invoice) {
|
||||
if ($invitation->contact && ! $invitation->contact->trashed() && strlen($invitation->contact->email) >= 1 && $invoice->client->getSetting('auto_email_invoice')) {
|
||||
try {
|
||||
EmailEntity::dispatch($invitation, $invoice->company)->delay(rand(10,20));
|
||||
EmailEntity::dispatch($invitation, $invoice->company)->delay(rand(1,2));
|
||||
} catch (\Exception $e) {
|
||||
nlog($e->getMessage());
|
||||
}
|
||||
@ -143,13 +143,13 @@ class SendRecurring implements ShouldQueue
|
||||
if ($invoice->client->getSetting('auto_bill_date') == 'on_send_date' && $invoice->auto_bill_enabled) {
|
||||
nlog("attempting to autobill {$invoice->number}");
|
||||
// $invoice->service()->autoBill();
|
||||
AutoBill::dispatch($invoice, $this->db)->delay(rand(30,40));
|
||||
AutoBill::dispatch($invoice->id, $this->db)->delay(rand(1,2));
|
||||
|
||||
} 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())) {
|
||||
nlog("attempting to autobill {$invoice->number}");
|
||||
// $invoice->service()->autoBill();
|
||||
AutoBill::dispatch($invoice, $this->db)->delay(rand(30,40));
|
||||
AutoBill::dispatch($invoice->id, $this->db)->delay(rand(1,2));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -181,7 +181,7 @@ class SendRecurring implements ShouldQueue
|
||||
$job_failure->string_metric6 = $exception->getMessage();
|
||||
|
||||
LightLogs::create($job_failure)
|
||||
->queue();
|
||||
->send();
|
||||
|
||||
nlog(print_r($exception->getMessage(), 1));
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ class ReminderJob implements ShouldQueue
|
||||
(Ninja::isSelfHost() || $invoice->company->account->isPaidHostedClient())) {
|
||||
|
||||
$invoice->invitations->each(function ($invitation) use ($invoice, $reminder_template) {
|
||||
EmailEntity::dispatch($invitation, $invitation->company, $reminder_template);
|
||||
EmailEntity::dispatchSync($invitation, $invitation->company, $reminder_template);
|
||||
nlog("Firing reminder email for invoice {$invoice->number} - {$reminder_template}");
|
||||
});
|
||||
|
||||
@ -216,7 +216,7 @@ class ReminderJob implements ShouldQueue
|
||||
'metadata' => ['setLateFee'],
|
||||
];
|
||||
|
||||
TransactionLog::dispatch(TransactionEvent::CLIENT_STATUS, $transaction, $invoice->company->db);
|
||||
// TransactionLog::dispatch(TransactionEvent::CLIENT_STATUS, $transaction, $invoice->company->db);
|
||||
|
||||
return $invoice;
|
||||
}
|
||||
|
@ -38,19 +38,23 @@ class CreateInvoicePdf implements ShouldQueue
|
||||
|
||||
if (isset($event->invoice)) {
|
||||
$event->invoice->invitations->each(function ($invitation) {
|
||||
CreateEntityPdf::dispatch($invitation->load('invoice', 'contact.client.company'));
|
||||
// CreateEntityPdf::dispatch($invitation->load('invoice', 'contact.client.company'));
|
||||
(new CreateEntityPdf($invitation->load('invoice', 'contact.client.company')))->handle();
|
||||
});
|
||||
}
|
||||
|
||||
if (isset($event->quote)) {
|
||||
$event->quote->invitations->each(function ($invitation) {
|
||||
CreateEntityPdf::dispatch($invitation->load('quote', 'contact.client.company'));
|
||||
// CreateEntityPdf::dispatch($invitation->load('quote', 'contact.client.company'));
|
||||
(new CreateEntityPdf($invitation->load('quote', 'contact.client.company')))->handle();
|
||||
});
|
||||
}
|
||||
|
||||
if (isset($event->credit)) {
|
||||
$event->credit->invitations->each(function ($invitation) {
|
||||
CreateEntityPdf::dispatch($invitation->load('credit', 'contact.client.company'));
|
||||
// CreateEntityPdf::dispatch($invitation->load('credit', 'contact.client.company'));
|
||||
(new CreateEntityPdf($invitation->load('credit', 'contact.client.company')))->handle();
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -17,8 +17,10 @@ use App\Jobs\Mail\NinjaMailerObject;
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Mail\Admin\EntityViewedObject;
|
||||
use App\Notifications\Admin\EntityViewedNotification;
|
||||
use App\Utils\Ninja;
|
||||
use App\Utils\Traits\Notifications\UserNotifies;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use Illuminate\Support\Facades\Notification;
|
||||
|
||||
class InvitationViewedListener implements ShouldQueue
|
||||
@ -44,6 +46,11 @@ class InvitationViewedListener implements ShouldQueue
|
||||
{
|
||||
MultiDB::setDb($event->company->db);
|
||||
|
||||
App::forgetInstance('translator');
|
||||
$t = app('translator');
|
||||
$t->replace(Ninja::transformTranslations($event->company->settings));
|
||||
App::setLocale($event->company->getLocale());
|
||||
|
||||
$entity_name = lcfirst(class_basename($event->entity));
|
||||
$invitation = $event->invitation;
|
||||
|
||||
|
@ -329,4 +329,18 @@ class PaymentEmailEngine extends BaseEmailEngine
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function generateLabelsAndValues()
|
||||
{
|
||||
$data = [];
|
||||
|
||||
$values = $this->makePaymentVariables();
|
||||
|
||||
foreach ($values as $key => $value) {
|
||||
$data['values'][$key] = $value['value'];
|
||||
$data['labels'][$key.'_label'] = $value['label'];
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
@ -305,6 +305,16 @@ class Activity extends StaticModel
|
||||
return $this->belongsTo(Expense::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function purchase_order()
|
||||
{
|
||||
return $this->belongsTo(PurchaseOrder::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function vendor_contact()
|
||||
{
|
||||
return $this->belongsTo(VendorContact::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function task()
|
||||
{
|
||||
return $this->belongsTo(Task::class)->withTrashed();
|
||||
|
@ -333,7 +333,7 @@ class BaseDriver extends AbstractPaymentDriver
|
||||
'metadata' => [],
|
||||
];
|
||||
|
||||
TransactionLog::dispatch(TransactionEvent::INVOICE_FEE_APPLIED, $transaction, $invoice->company->db);
|
||||
// TransactionLog::dispatch(TransactionEvent::INVOICE_FEE_APPLIED, $transaction, $invoice->company->db);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -209,7 +209,7 @@ class PaymentRepository extends BaseRepository {
|
||||
'metadata' => [],
|
||||
];
|
||||
|
||||
TransactionLog::dispatch(TransactionEvent::PAYMENT_MADE, $transaction, $payment->company->db);
|
||||
// TransactionLog::dispatch(TransactionEvent::PAYMENT_MADE, $transaction, $payment->company->db);
|
||||
|
||||
return $payment->refresh();
|
||||
}
|
||||
|
@ -113,7 +113,7 @@ class ApplyPayment extends AbstractService
|
||||
'metadata' => [],
|
||||
];
|
||||
|
||||
TransactionLog::dispatch(TransactionEvent::INVOICE_PAYMENT_APPLIED, $transaction, $this->invoice->company->db);
|
||||
// TransactionLog::dispatch(TransactionEvent::INVOICE_PAYMENT_APPLIED, $transaction, $this->invoice->company->db);
|
||||
|
||||
return $this->invoice;
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ class HandleCancellation extends AbstractService
|
||||
|
||||
//adjust client balance
|
||||
$this->invoice->client->service()->updateBalance($adjustment)->save();
|
||||
$this->invoice->fresh();
|
||||
// $this->invoice->fresh();
|
||||
|
||||
$this->invoice->service()->workFlow()->save();
|
||||
|
||||
@ -65,7 +65,7 @@ class HandleCancellation extends AbstractService
|
||||
'metadata' => [],
|
||||
];
|
||||
|
||||
TransactionLog::dispatch(TransactionEvent::INVOICE_CANCELLED, $transaction, $this->invoice->company->db);
|
||||
// TransactionLog::dispatch(TransactionEvent::INVOICE_CANCELLED, $transaction, $this->invoice->company->db);
|
||||
|
||||
return $this->invoice;
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
namespace App\Services\Invoice;
|
||||
|
||||
use App\Models\Invoice;
|
||||
use App\Models\Paymentable;
|
||||
use App\Services\AbstractService;
|
||||
use App\Utils\Ninja;
|
||||
use App\Utils\Traits\GeneratesCounter;
|
||||
@ -74,10 +75,14 @@ class HandleRestore extends AbstractService
|
||||
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]);
|
||||
|
||||
Paymentable::query()
|
||||
->withTrashed()
|
||||
->where('payment_id', $payment->id)
|
||||
->where('paymentable_type', '=', 'invoices')
|
||||
->where('paymentable_id', $this->invoice->id)
|
||||
->update(['deleted_at' => false]);
|
||||
|
||||
});
|
||||
|
||||
return $this;
|
||||
|
@ -147,7 +147,7 @@ class HandleReversal extends AbstractService
|
||||
'metadata' => [],
|
||||
];
|
||||
|
||||
TransactionLog::dispatch(TransactionEvent::INVOICE_REVERSED, $transaction, $this->invoice->company->db);
|
||||
// TransactionLog::dispatch(TransactionEvent::INVOICE_REVERSED, $transaction, $this->invoice->company->db);
|
||||
|
||||
return $this->invoice;
|
||||
//create a ledger row for this with the resulting Credit ( also include an explanation in the notes section )
|
||||
|
@ -56,7 +56,7 @@ class MarkInvoiceDeleted extends AbstractService
|
||||
'metadata' => ['total_payments' => $this->total_payments, 'balance_adjustment' => $this->balance_adjustment, 'adjustment_amount' => $this->adjustment_amount],
|
||||
];
|
||||
|
||||
TransactionLog::dispatch(TransactionEvent::INVOICE_DELETED, $transaction, $this->invoice->company->db);
|
||||
// TransactionLog::dispatch(TransactionEvent::INVOICE_DELETED, $transaction, $this->invoice->company->db);
|
||||
|
||||
return $this->invoice;
|
||||
}
|
||||
|
@ -141,7 +141,7 @@ class MarkPaid extends AbstractService
|
||||
'metadata' => [],
|
||||
];
|
||||
|
||||
TransactionLog::dispatch(TransactionEvent::INVOICE_MARK_PAID, $transaction, $this->invoice->company->db);
|
||||
// TransactionLog::dispatch(TransactionEvent::INVOICE_MARK_PAID, $transaction, $this->invoice->company->db);
|
||||
|
||||
return $this->invoice;
|
||||
}
|
||||
|
@ -132,7 +132,7 @@ class DeletePayment
|
||||
'metadata' => [],
|
||||
];
|
||||
|
||||
TransactionLog::dispatch(TransactionEvent::PAYMENT_DELETED, $transaction, $paymentable_invoice->company->db);
|
||||
// TransactionLog::dispatch(TransactionEvent::PAYMENT_DELETED, $transaction, $paymentable_invoice->company->db);
|
||||
});
|
||||
}
|
||||
|
||||
@ -151,7 +151,7 @@ class DeletePayment
|
||||
'metadata' => [],
|
||||
];
|
||||
|
||||
TransactionLog::dispatch(TransactionEvent::CLIENT_STATUS, $transaction, $this->payment->company->db);
|
||||
// TransactionLog::dispatch(TransactionEvent::CLIENT_STATUS, $transaction, $this->payment->company->db);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ class RefundPayment
|
||||
'metadata' => [],
|
||||
];
|
||||
|
||||
TransactionLog::dispatch(TransactionEvent::PAYMENT_REFUND, $transaction, $this->payment->company->db);
|
||||
// TransactionLog::dispatch(TransactionEvent::PAYMENT_REFUND, $transaction, $this->payment->company->db);
|
||||
|
||||
$notes = ctrans('texts.refunded') . " : {$this->total_refund} - " . ctrans('texts.gateway_refund') . " : ";
|
||||
$notes .= $this->refund_data['gateway_refund'] !== false ? ctrans('texts.yes') : ctrans('texts.no');
|
||||
@ -296,7 +296,7 @@ class RefundPayment
|
||||
'metadata' => [],
|
||||
];
|
||||
|
||||
TransactionLog::dispatch(TransactionEvent::PAYMENT_REFUND, $transaction, $invoice->company->db);
|
||||
// TransactionLog::dispatch(TransactionEvent::PAYMENT_REFUND, $transaction, $invoice->company->db);
|
||||
|
||||
if ($invoice->is_deleted) {
|
||||
$invoice->delete();
|
||||
@ -319,7 +319,7 @@ class RefundPayment
|
||||
'metadata' => [],
|
||||
];
|
||||
|
||||
TransactionLog::dispatch(TransactionEvent::PAYMENT_REFUND, $transaction, $client->company->db);
|
||||
// TransactionLog::dispatch(TransactionEvent::PAYMENT_REFUND, $transaction, $client->company->db);
|
||||
} else {
|
||||
//if we are refunding and no payments have been tagged, then we need to decrement the client->paid_to_date by the total refund amount.
|
||||
|
||||
@ -339,7 +339,7 @@ class RefundPayment
|
||||
'metadata' => [],
|
||||
];
|
||||
|
||||
TransactionLog::dispatch(TransactionEvent::PAYMENT_REFUND, $transaction, $client->company->db);
|
||||
// TransactionLog::dispatch(TransactionEvent::PAYMENT_REFUND, $transaction, $client->company->db);
|
||||
}
|
||||
|
||||
return $this;
|
||||
|
@ -119,7 +119,7 @@ class UpdateInvoicePayment
|
||||
'metadata' => [],
|
||||
];
|
||||
|
||||
TransactionLog::dispatch(TransactionEvent::GATEWAY_PAYMENT_MADE, $transaction, $invoice->company->db);
|
||||
// TransactionLog::dispatch(TransactionEvent::GATEWAY_PAYMENT_MADE, $transaction, $invoice->company->db);
|
||||
|
||||
|
||||
});
|
||||
|
@ -15,8 +15,14 @@ use App\Models\Activity;
|
||||
use App\Models\Backup;
|
||||
use App\Models\ClientContact;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\PurchaseOrder;
|
||||
use App\Models\Task;
|
||||
use App\Models\User;
|
||||
use App\Models\Vendor;
|
||||
use App\Models\VendorContact;
|
||||
use App\Transformers\PurchaseOrderTransformer;
|
||||
use App\Transformers\VendorContactTransformer;
|
||||
use App\Transformers\VendorTransformer;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
|
||||
class ActivityTransformer extends EntityTransformer
|
||||
@ -40,6 +46,9 @@ class ActivityTransformer extends EntityTransformer
|
||||
'payment',
|
||||
'expense',
|
||||
'task',
|
||||
'purchase_order',
|
||||
'vendor',
|
||||
'vendor_contact',
|
||||
];
|
||||
|
||||
/**
|
||||
@ -56,6 +65,7 @@ class ActivityTransformer extends EntityTransformer
|
||||
'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) : '',
|
||||
'purchase_order_id' => $activity->purchase_order_id ? (string) $this->encodePrimaryKey($activity->purchase_order_id) : '',
|
||||
'vendor_id' => $activity->vendor_id ? (string) $this->encodePrimaryKey($activity->vendor_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) : '',
|
||||
'user_id' => (string) $this->encodePrimaryKey($activity->user_id),
|
||||
@ -90,6 +100,13 @@ class ActivityTransformer extends EntityTransformer
|
||||
return $this->includeItem($activity->client, $transformer, Client::class);
|
||||
}
|
||||
|
||||
public function includeVendor(Activity $activity)
|
||||
{
|
||||
$transformer = new VendorTransformer($this->serializer);
|
||||
|
||||
return $this->includeItem($activity->vendor, $transformer, Vendor::class);
|
||||
}
|
||||
|
||||
public function includeContact(Activity $activity)
|
||||
{
|
||||
$transformer = new ClientContactTransformer($this->serializer);
|
||||
@ -97,6 +114,13 @@ class ActivityTransformer extends EntityTransformer
|
||||
return $this->includeItem($activity->contact, $transformer, ClientContact::class);
|
||||
}
|
||||
|
||||
public function includeVendorContact(Activity $activity)
|
||||
{
|
||||
$transformer = new VendorContactTransformer($this->serializer);
|
||||
|
||||
return $this->includeItem($activity->vendor_contact, $transformer, VendorContact::class);
|
||||
}
|
||||
|
||||
public function includeRecurringInvoice(Activity $activity)
|
||||
{
|
||||
$transformer = new RecurringInvoiceTransformer($this->serializer);
|
||||
@ -104,6 +128,14 @@ class ActivityTransformer extends EntityTransformer
|
||||
return $this->includeItem($activity->recurring_invoice, $transformer, RecurringInvoice::class);
|
||||
}
|
||||
|
||||
public function includePurchaseOrder(Activity $activity)
|
||||
{
|
||||
$transformer = new PurchaseOrderTransformer($this->serializer);
|
||||
|
||||
return $this->includeItem($activity->purchase_order(), $transformer, PurchaseOrder::class);
|
||||
}
|
||||
|
||||
|
||||
public function includeQuote(Activity $activity)
|
||||
{
|
||||
$transformer = new RecurringInvoiceTransformer($this->serializer);
|
||||
|
@ -13,6 +13,7 @@ namespace App\Utils;
|
||||
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Mail\TestMailServer;
|
||||
use App\Models\Company;
|
||||
use Exception;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
@ -82,9 +83,34 @@ class SystemHealth
|
||||
'queue' => (string) config('queue.default'),
|
||||
'trailing_slash' => (bool) self::checkUrlState(),
|
||||
'file_permissions' => (string) self::checkFileSystem(),
|
||||
'exchange_rate_api_not_configured' => (bool)self::checkCurrencySanity(),
|
||||
];
|
||||
}
|
||||
|
||||
private static function checkCurrencySanity()
|
||||
{
|
||||
|
||||
if(strlen(config('ninja.currency_converter_api_key')) == 0){
|
||||
|
||||
$cs = DB::table('clients')
|
||||
->select('settings->currency_id as id')
|
||||
->get();
|
||||
|
||||
|
||||
$currency_count = $cs->unique('id')->filter(function ($value){
|
||||
return !is_null($value->id);
|
||||
})->count();
|
||||
|
||||
|
||||
if($currency_count > 1)
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
private static function checkQueueSize()
|
||||
{
|
||||
$count = 0;
|
||||
|
@ -13,10 +13,12 @@
|
||||
namespace App\Utils;
|
||||
|
||||
use App\DataMapper\EmailTemplateDefaults;
|
||||
use App\Mail\Engine\PaymentEmailEngine;
|
||||
use App\Models\Client;
|
||||
use App\Models\ClientContact;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\InvoiceInvitation;
|
||||
use App\Models\Payment;
|
||||
use App\Models\PurchaseOrder;
|
||||
use App\Models\PurchaseOrderInvitation;
|
||||
use App\Models\Quote;
|
||||
@ -188,6 +190,8 @@ class TemplateEngine
|
||||
{
|
||||
if (in_array($this->entity, ['purchaseOrder', 'purchase_order']))
|
||||
$this->labels_and_values = (new VendorHtmlEngine($this->entity_obj->invitations->first()))->generateLabelsAndValues();
|
||||
elseif($this->entity == 'payment')
|
||||
$this->labels_and_values = (new PaymentEmailEngine($this->entity_obj, $this->entity_obj->client->contacts->first()))->generateLabelsAndValues();
|
||||
else
|
||||
$this->labels_and_values = (new HtmlEngine($this->entity_obj->invitations->first()))->generateLabelsAndValues();
|
||||
|
||||
@ -267,6 +271,8 @@ class TemplateEngine
|
||||
{
|
||||
if (!$this->entity && $this->template && str_contains($this->template, 'purchase_order'))
|
||||
$this->entity = 'purchaseOrder';
|
||||
elseif(str_contains($this->template, 'payment'))
|
||||
$this->entity = 'payment';
|
||||
|
||||
DB::connection(config('database.default'))->beginTransaction();
|
||||
|
||||
@ -285,6 +291,40 @@ class TemplateEngine
|
||||
'send_email' => true,
|
||||
]);
|
||||
|
||||
if ($this->entity == 'payment') {
|
||||
|
||||
|
||||
$this->entity_obj = Payment::factory()->create([
|
||||
'user_id' => auth()->user()->id,
|
||||
'company_id' => auth()->user()->company()->id,
|
||||
'client_id' => $client->id,
|
||||
'amount' => 10,
|
||||
'applied' => 10,
|
||||
'refunded' => 5,
|
||||
]);
|
||||
|
||||
$invoice = Invoice::factory()->create([
|
||||
'user_id' => auth()->user()->id,
|
||||
'company_id' => auth()->user()->company()->id,
|
||||
'client_id' => $client->id,
|
||||
'amount' => 10,
|
||||
'balance' => 10,
|
||||
'number' => rand(1,10000)
|
||||
]);
|
||||
|
||||
$invitation = InvoiceInvitation::factory()->create([
|
||||
'user_id' => auth()->user()->id,
|
||||
'company_id' => auth()->user()->company()->id,
|
||||
'invoice_id' => $invoice->id,
|
||||
'client_contact_id' => $contact->id,
|
||||
]);
|
||||
|
||||
$this->entity_obj->invoices()->attach($invoice->id, [
|
||||
'amount' => 10,
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
if (!$this->entity || $this->entity == 'invoice') {
|
||||
$this->entity_obj = Invoice::factory()->create([
|
||||
'user_id' => auth()->user()->id,
|
||||
@ -315,8 +355,6 @@ class TemplateEngine
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if ($this->entity == 'purchaseOrder') {
|
||||
|
||||
$vendor = Vendor::factory()->create([
|
||||
|
@ -74,7 +74,7 @@
|
||||
"omnipay/paypal": "^3.0",
|
||||
"payfast/payfast-php-sdk": "^1.1",
|
||||
"pragmarx/google2fa": "^8.0",
|
||||
"predis/predis": "^1.1",
|
||||
"turbo124/predis": "^1.1",
|
||||
"razorpay/razorpay": "2.*",
|
||||
"sentry/sentry-laravel": "^2",
|
||||
"setasign/fpdf": "^1.8",
|
||||
|
1052
composer.lock
generated
1052
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@ -14,8 +14,8 @@ return [
|
||||
'require_https' => env('REQUIRE_HTTPS', true),
|
||||
'app_url' => rtrim(env('APP_URL', ''), '/'),
|
||||
'app_domain' => env('APP_DOMAIN', 'invoicing.co'),
|
||||
'app_version' => '5.5.33',
|
||||
'app_tag' => '5.5.33',
|
||||
'app_version' => '5.5.34',
|
||||
'app_tag' => '5.5.34',
|
||||
'minimum_client_version' => '5.0.16',
|
||||
'terms_version' => '1.0.1',
|
||||
'api_secret' => env('API_SECRET', ''),
|
||||
@ -38,7 +38,7 @@ return [
|
||||
'trusted_proxies' => env('TRUSTED_PROXIES', false),
|
||||
'is_docker' => env('IS_DOCKER', false),
|
||||
'local_download' => env('LOCAL_DOWNLOAD', false),
|
||||
'sentry_dsn' => env('SENTRY_LARAVEL_DSN', 'https://39389664f3f14969b4c43dadda00a40b@sentry2.invoicing.co/5'),
|
||||
'sentry_dsn' => env('SENTRY_LARAVEL_DSN', null),
|
||||
'environment' => env('NINJA_ENVIRONMENT', 'selfhost'), // 'hosted', 'development', 'selfhost', 'reseller'
|
||||
'preconfigured_install' => env('PRECONFIGURED_INSTALL', false),
|
||||
'update_secret' => env('UPDATE_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('users', function (Blueprint $table) {
|
||||
$table->string('sms_verification_code', 191)->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
//
|
||||
}
|
||||
};
|
4
public/flutter_service_worker.js
vendored
4
public/flutter_service_worker.js
vendored
@ -11,9 +11,9 @@ const RESOURCES = {
|
||||
"favicon.png": "dca91c54388f52eded692718d5a98b8b",
|
||||
"favicon.ico": "51636d3a390451561744c42188ccd628",
|
||||
"flutter.js": "f85e6fb278b0fd20c349186fb46ae36d",
|
||||
"/": "6e1815518c0c0c9e98dee5de3d0d94fe",
|
||||
"/": "cb6f2c73612e3d57c56452ef7c10795a",
|
||||
"manifest.json": "ef43d90e57aa7682d7e2cfba2f484a40",
|
||||
"main.dart.js": "b8307c0fe25db9fbd88e3d9519e05edf",
|
||||
"main.dart.js": "69afcf35930517b4949ed2f4d551307a",
|
||||
"assets/AssetManifest.json": "759f9ef9973f7e26c2a51450b55bb9fa",
|
||||
"assets/FontManifest.json": "087fb858dc3cbfbf6baf6a30004922f1",
|
||||
"assets/NOTICES": "1a34e70168d56fad075adfb4bdbb20eb",
|
||||
|
32687
public/main.dart.js
vendored
32687
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
32441
public/main.foss.dart.js
vendored
32441
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
74
public/main.profile.dart.js
vendored
74
public/main.profile.dart.js
vendored
@ -58156,7 +58156,7 @@
|
||||
},
|
||||
_$HealthCheckPHPResponseSerializer: function _$HealthCheckPHPResponseSerializer() {
|
||||
},
|
||||
_$HealthCheckResponse: function _$HealthCheckResponse(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13) {
|
||||
_$HealthCheckResponse: function _$HealthCheckResponse(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14) {
|
||||
var _ = this;
|
||||
_.systemHealth = t0;
|
||||
_.phpVersion = t1;
|
||||
@ -58171,12 +58171,13 @@
|
||||
_.pendingJobs = t10;
|
||||
_.pdfEngine = t11;
|
||||
_.trailingSlash = t12;
|
||||
_.queue = t13;
|
||||
_.exchangeRateApiNotConfigured = t13;
|
||||
_.queue = t14;
|
||||
_._health_check_model$__hashCode = null;
|
||||
},
|
||||
HealthCheckResponseBuilder: function HealthCheckResponseBuilder() {
|
||||
var _ = this;
|
||||
_._health_check_model$_queue = _._trailingSlash = _._pdfEngine = _._pendingJobs = _._emailDriver = _._execEnabled = _._filePermissions = _._openBasedir = _._phantomEnabled = _._cacheEnabled = _._dbCheck = _._envWritable = _._phpVersion = _._systemHealth = _._health_check_model$_$v = null;
|
||||
_._health_check_model$_queue = _._exchangeRateApiNotConfigured = _._trailingSlash = _._pdfEngine = _._pendingJobs = _._emailDriver = _._execEnabled = _._filePermissions = _._openBasedir = _._phantomEnabled = _._cacheEnabled = _._dbCheck = _._envWritable = _._phpVersion = _._systemHealth = _._health_check_model$_$v = null;
|
||||
},
|
||||
_$HealthCheckPHPResponse: function _$HealthCheckPHPResponse(t0, t1, t2, t3, t4) {
|
||||
var _ = this;
|
||||
@ -119612,7 +119613,7 @@
|
||||
t5 = state;
|
||||
t6 = t5.userCompanyStates;
|
||||
t5 = t5.uiState.selectedCompanyIndex;
|
||||
A.print("## Confirm password: " + alwaysRequire + ", " + t2 + ", " + t3 + ", " + (t4.length === 0) + ", " + t6._list[t5].userCompany.company.oauthPasswordRequired);
|
||||
A.print("## Confirm password: " + alwaysRequire + ", " + t2 + ", " + t3 + ", " + t4 + ", " + t6._list[t5].userCompany.company.oauthPasswordRequired);
|
||||
if (alwaysRequire && !user.hasPassword) {
|
||||
t1.toString;
|
||||
t2 = $.$get$LocalizationsProvider__localizedValues();
|
||||
@ -326941,7 +326942,7 @@
|
||||
A.HealthCheckPHPResponse.prototype = {};
|
||||
A._$HealthCheckResponseSerializer.prototype = {
|
||||
serialize$3$specifiedType(serializers, object, specifiedType) {
|
||||
return A._setArrayType(["system_health", serializers.serialize$2$specifiedType(object.systemHealth, B.FullType_MtR), "php_version", serializers.serialize$2$specifiedType(object.phpVersion, B.FullType_uRN), "env_writable", serializers.serialize$2$specifiedType(object.envWritable, B.FullType_MtR), "simple_db_check", serializers.serialize$2$specifiedType(object.dbCheck, B.FullType_MtR), "cache_enabled", serializers.serialize$2$specifiedType(object.cacheEnabled, B.FullType_MtR), "phantom_enabled", serializers.serialize$2$specifiedType(object.phantomEnabled, B.FullType_MtR), "open_basedir", serializers.serialize$2$specifiedType(object.openBasedir, B.FullType_MtR), "file_permissions", serializers.serialize$2$specifiedType(object.filePermissions, B.FullType_h8g), "exec", serializers.serialize$2$specifiedType(object.execEnabled, B.FullType_MtR), "mail_mailer", serializers.serialize$2$specifiedType(object.emailDriver, B.FullType_h8g), "jobs_pending", serializers.serialize$2$specifiedType(object.pendingJobs, B.FullType_kjq), "pdf_engine", serializers.serialize$2$specifiedType(object.pdfEngine, B.FullType_h8g), "trailing_slash", serializers.serialize$2$specifiedType(object.trailingSlash, B.FullType_MtR), "queue", serializers.serialize$2$specifiedType(object.queue, B.FullType_h8g)], type$.JSArray_legacy_Object);
|
||||
return A._setArrayType(["system_health", serializers.serialize$2$specifiedType(object.systemHealth, B.FullType_MtR), "php_version", serializers.serialize$2$specifiedType(object.phpVersion, B.FullType_uRN), "env_writable", serializers.serialize$2$specifiedType(object.envWritable, B.FullType_MtR), "simple_db_check", serializers.serialize$2$specifiedType(object.dbCheck, B.FullType_MtR), "cache_enabled", serializers.serialize$2$specifiedType(object.cacheEnabled, B.FullType_MtR), "phantom_enabled", serializers.serialize$2$specifiedType(object.phantomEnabled, B.FullType_MtR), "open_basedir", serializers.serialize$2$specifiedType(object.openBasedir, B.FullType_MtR), "file_permissions", serializers.serialize$2$specifiedType(object.filePermissions, B.FullType_h8g), "exec", serializers.serialize$2$specifiedType(object.execEnabled, B.FullType_MtR), "mail_mailer", serializers.serialize$2$specifiedType(object.emailDriver, B.FullType_h8g), "jobs_pending", serializers.serialize$2$specifiedType(object.pendingJobs, B.FullType_kjq), "pdf_engine", serializers.serialize$2$specifiedType(object.pdfEngine, B.FullType_h8g), "trailing_slash", serializers.serialize$2$specifiedType(object.trailingSlash, B.FullType_MtR), "exchange_rate_api_not_configured", serializers.serialize$2$specifiedType(object.exchangeRateApiNotConfigured, B.FullType_MtR), "queue", serializers.serialize$2$specifiedType(object.queue, B.FullType_h8g)], type$.JSArray_legacy_Object);
|
||||
},
|
||||
serialize$2(serializers, object) {
|
||||
return this.serialize$3$specifiedType(serializers, object, B.FullType_null_List_empty_false);
|
||||
@ -327020,6 +327021,10 @@
|
||||
t2 = A._asBoolS(serializers.deserialize$2$specifiedType(value, B.FullType_MtR));
|
||||
result.get$_health_check_model$_$this()._trailingSlash = t2;
|
||||
break;
|
||||
case "exchange_rate_api_not_configured":
|
||||
t2 = A._asBoolS(serializers.deserialize$2$specifiedType(value, B.FullType_MtR));
|
||||
result.get$_health_check_model$_$this()._exchangeRateApiNotConfigured = t2;
|
||||
break;
|
||||
case "queue":
|
||||
t2 = A._asStringS(serializers.deserialize$2$specifiedType(value, B.FullType_h8g));
|
||||
result.get$_health_check_model$_$this()._health_check_model$_queue = t2;
|
||||
@ -327100,14 +327105,14 @@
|
||||
return false;
|
||||
if (other === _this)
|
||||
return true;
|
||||
return other instanceof A.HealthCheckResponse && _this.systemHealth === other.systemHealth && _this.phpVersion.$eq(0, other.phpVersion) && _this.envWritable === other.envWritable && _this.dbCheck === other.dbCheck && _this.cacheEnabled === other.cacheEnabled && _this.phantomEnabled === other.phantomEnabled && _this.openBasedir === other.openBasedir && _this.filePermissions === other.filePermissions && _this.execEnabled === other.execEnabled && _this.emailDriver === other.emailDriver && _this.pendingJobs === other.pendingJobs && _this.pdfEngine === other.pdfEngine && _this.trailingSlash === other.trailingSlash && _this.queue === other.queue;
|
||||
return other instanceof A.HealthCheckResponse && _this.systemHealth === other.systemHealth && _this.phpVersion.$eq(0, other.phpVersion) && _this.envWritable === other.envWritable && _this.dbCheck === other.dbCheck && _this.cacheEnabled === other.cacheEnabled && _this.phantomEnabled === other.phantomEnabled && _this.openBasedir === other.openBasedir && _this.filePermissions === other.filePermissions && _this.execEnabled === other.execEnabled && _this.emailDriver === other.emailDriver && _this.pendingJobs === other.pendingJobs && _this.pdfEngine === other.pdfEngine && _this.trailingSlash === other.trailingSlash && _this.exchangeRateApiNotConfigured === other.exchangeRateApiNotConfigured && _this.queue === other.queue;
|
||||
},
|
||||
get$hashCode(_) {
|
||||
var _this = this,
|
||||
t1 = _this._health_check_model$__hashCode;
|
||||
if (t1 == null) {
|
||||
t1 = _this.phpVersion;
|
||||
t1 = _this._health_check_model$__hashCode = A.$jf(A.$jc(A.$jc(A.$jc(A.$jc(A.$jc(A.$jc(A.$jc(A.$jc(A.$jc(A.$jc(A.$jc(A.$jc(A.$jc(A.$jc(0, B.JSBool_methods.get$hashCode(_this.systemHealth)), t1.get$hashCode(t1)), B.JSBool_methods.get$hashCode(_this.envWritable)), B.JSBool_methods.get$hashCode(_this.dbCheck)), B.JSBool_methods.get$hashCode(_this.cacheEnabled)), B.JSBool_methods.get$hashCode(_this.phantomEnabled)), B.JSBool_methods.get$hashCode(_this.openBasedir)), B.JSString_methods.get$hashCode(_this.filePermissions)), B.JSBool_methods.get$hashCode(_this.execEnabled)), B.JSString_methods.get$hashCode(_this.emailDriver)), B.JSInt_methods.get$hashCode(_this.pendingJobs)), B.JSString_methods.get$hashCode(_this.pdfEngine)), B.JSBool_methods.get$hashCode(_this.trailingSlash)), B.JSString_methods.get$hashCode(_this.queue)));
|
||||
t1 = _this._health_check_model$__hashCode = A.$jf(A.$jc(A.$jc(A.$jc(A.$jc(A.$jc(A.$jc(A.$jc(A.$jc(A.$jc(A.$jc(A.$jc(A.$jc(A.$jc(A.$jc(A.$jc(0, B.JSBool_methods.get$hashCode(_this.systemHealth)), t1.get$hashCode(t1)), B.JSBool_methods.get$hashCode(_this.envWritable)), B.JSBool_methods.get$hashCode(_this.dbCheck)), B.JSBool_methods.get$hashCode(_this.cacheEnabled)), B.JSBool_methods.get$hashCode(_this.phantomEnabled)), B.JSBool_methods.get$hashCode(_this.openBasedir)), B.JSString_methods.get$hashCode(_this.filePermissions)), B.JSBool_methods.get$hashCode(_this.execEnabled)), B.JSString_methods.get$hashCode(_this.emailDriver)), B.JSInt_methods.get$hashCode(_this.pendingJobs)), B.JSString_methods.get$hashCode(_this.pdfEngine)), B.JSBool_methods.get$hashCode(_this.trailingSlash)), B.JSBool_methods.get$hashCode(_this.exchangeRateApiNotConfigured)), B.JSString_methods.get$hashCode(_this.queue)));
|
||||
}
|
||||
return t1;
|
||||
},
|
||||
@ -327128,6 +327133,7 @@
|
||||
t2.add$2(t1, "pendingJobs", _this.pendingJobs);
|
||||
t2.add$2(t1, "pdfEngine", _this.pdfEngine);
|
||||
t2.add$2(t1, "trailingSlash", _this.trailingSlash);
|
||||
t2.add$2(t1, "exchangeRateApiNotConfigured", _this.exchangeRateApiNotConfigured);
|
||||
t2.add$2(t1, "queue", _this.queue);
|
||||
return t2.toString$0(t1);
|
||||
}
|
||||
@ -327167,13 +327173,14 @@
|
||||
_this._pendingJobs = $$v.pendingJobs;
|
||||
_this._pdfEngine = $$v.pdfEngine;
|
||||
_this._trailingSlash = $$v.trailingSlash;
|
||||
_this._exchangeRateApiNotConfigured = $$v.exchangeRateApiNotConfigured;
|
||||
_this._health_check_model$_queue = $$v.queue;
|
||||
_this._health_check_model$_$v = null;
|
||||
}
|
||||
return _this;
|
||||
},
|
||||
build$0() {
|
||||
var _$failedField, e, _$result0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, exception, _this = this,
|
||||
var _$failedField, e, _$result0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, exception, _this = this,
|
||||
_s19_ = "HealthCheckResponse",
|
||||
_$result = null;
|
||||
try {
|
||||
@ -327216,10 +327223,13 @@
|
||||
t13 = _this.get$_health_check_model$_$this()._trailingSlash;
|
||||
if (t13 == null)
|
||||
A.throwExpression(A.BuiltValueNullFieldError$(_s19_, "trailingSlash"));
|
||||
t14 = _this.get$_health_check_model$_$this()._health_check_model$_queue;
|
||||
t14 = _this.get$_health_check_model$_$this()._exchangeRateApiNotConfigured;
|
||||
if (t14 == null)
|
||||
A.throwExpression(A.BuiltValueNullFieldError$(_s19_, "exchangeRateApiNotConfigured"));
|
||||
t15 = _this.get$_health_check_model$_$this()._health_check_model$_queue;
|
||||
if (t15 == null)
|
||||
A.throwExpression(A.BuiltValueNullFieldError$(_s19_, "queue"));
|
||||
_$result0 = new A._$HealthCheckResponse(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14);
|
||||
_$result0 = new A._$HealthCheckResponse(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15);
|
||||
}
|
||||
_$result = _$result0;
|
||||
} catch (exception) {
|
||||
@ -347194,7 +347204,11 @@
|
||||
return B.JSArray_methods.get$first(t1.split(","));
|
||||
},
|
||||
get$listDisplayName() {
|
||||
return this.description;
|
||||
var t1 = this.description;
|
||||
if (t1.length !== 0)
|
||||
return t1;
|
||||
else
|
||||
return A.S(this.date);
|
||||
},
|
||||
get$listDisplayAmount() {
|
||||
return this.amount;
|
||||
@ -416947,6 +416961,8 @@
|
||||
t9.push(new A._HealthListTile("SnapPDF not enabled", true, true, "Use SnapPDF to generate PDF files locally", "https://invoiceninja.github.io/docs/self-host-troubleshooting/#pdf-conversion-issues", _null));
|
||||
if (_this._response.trailingSlash)
|
||||
t9.push(new A._HealthListTile("APP_URL has trailing slash", true, true, "Remove the slash in the .env file", _null, _null));
|
||||
if (_this._response.exchangeRateApiNotConfigured)
|
||||
t9.push(new A._HealthListTile("Exchange Rate API Not Enabled", true, true, "Add an Open Exchange key to the .env file", "https://invoiceninja.github.io/docs/self-host-installation/#currency-conversion", _null));
|
||||
t1 = A.Column$(t9, B.CrossAxisAlignment_2, _null, B.MainAxisAlignment_0, B.MainAxisSize_0, B.VerticalDirection_1);
|
||||
}
|
||||
if (_this._response == null)
|
||||
@ -416974,7 +416990,9 @@
|
||||
};
|
||||
A._HealthCheckDialogState_runCheck_closure0.prototype = {
|
||||
call$1(response) {
|
||||
var t1 = this.$this;
|
||||
var t1;
|
||||
A.print("## response: " + A.S(response));
|
||||
t1 = this.$this;
|
||||
t1.setState$1(new A._HealthCheckDialogState_runCheck__closure(t1, response));
|
||||
},
|
||||
$signature: 6
|
||||
@ -420580,7 +420598,7 @@
|
||||
if (t7.$eq(0, B.TextInputType_1_null_null))
|
||||
t11 = B.TextInputAction_12;
|
||||
else
|
||||
t11 = enterShouldSubmit ? B.TextInputAction_2 : B.TextInputAction_6;
|
||||
t11 = B.TextInputAction_2;
|
||||
t12 = _this._widget;
|
||||
t13 = t12.inputFormatters;
|
||||
t14 = t12.enabled;
|
||||
@ -423743,49 +423761,49 @@
|
||||
if (prefState.isFilterVisible)
|
||||
switch (t1.length === 0 ? _null : B.JSArray_methods.get$last(t1).get$entityType()) {
|
||||
case B.EntityType_client:
|
||||
leftFilterChild = _this.editingFilterEntity && !uiState.get$isEditing() ? new A.ClientEditScreen(_null) : new A.ClientViewScreen(true, false, _null);
|
||||
leftFilterChild = new A.ClientViewScreen(true, false, _null);
|
||||
break;
|
||||
case B.EntityType_invoice:
|
||||
leftFilterChild = _this.editingFilterEntity && !uiState.get$isEditing() ? new A.InvoiceViewScreen(false, _null) : new A.InvoiceViewScreen(true, _null);
|
||||
leftFilterChild = new A.InvoiceViewScreen(true, _null);
|
||||
break;
|
||||
case B.EntityType_quote:
|
||||
leftFilterChild = _this.editingFilterEntity && !uiState.get$isEditing() ? new A.QuoteViewScreen(false, _null) : new A.QuoteViewScreen(true, _null);
|
||||
leftFilterChild = new A.QuoteViewScreen(true, _null);
|
||||
break;
|
||||
case B.EntityType_credit:
|
||||
leftFilterChild = _this.editingFilterEntity && !uiState.get$isEditing() ? new A.CreditViewScreen(false, _null) : new A.CreditViewScreen(true, _null);
|
||||
leftFilterChild = new A.CreditViewScreen(true, _null);
|
||||
break;
|
||||
case B.EntityType_purchaseOrder:
|
||||
leftFilterChild = _this.editingFilterEntity && !uiState.get$isEditing() ? new A.PurchaseOrderViewScreen(false, _null) : new A.PurchaseOrderViewScreen(true, _null);
|
||||
leftFilterChild = new A.PurchaseOrderViewScreen(true, _null);
|
||||
break;
|
||||
case B.EntityType_payment:
|
||||
leftFilterChild = _this.editingFilterEntity && !uiState.get$isEditing() ? new A.PaymentEditScreen(_null) : new A.PaymentViewScreen(true, _null);
|
||||
leftFilterChild = new A.PaymentViewScreen(true, _null);
|
||||
break;
|
||||
case B.EntityType_user:
|
||||
leftFilterChild = _this.editingFilterEntity && !uiState.get$isEditing() ? new A.UserEditScreen(_null) : new A.UserViewScreen(true, _null);
|
||||
leftFilterChild = new A.UserViewScreen(true, _null);
|
||||
break;
|
||||
case B.EntityType_group:
|
||||
leftFilterChild = _this.editingFilterEntity && !uiState.get$isEditing() ? new A.GroupEditScreen(_null) : new A.GroupViewScreen(true, _null);
|
||||
leftFilterChild = new A.GroupViewScreen(true, _null);
|
||||
break;
|
||||
case B.EntityType_subscription:
|
||||
leftFilterChild = _this.editingFilterEntity && !uiState.get$isEditing() ? new A.SubscriptionEditScreen(_null) : new A.SubscriptionViewScreen(true, _null);
|
||||
leftFilterChild = new A.SubscriptionViewScreen(true, _null);
|
||||
break;
|
||||
case B.EntityType_companyGateway:
|
||||
leftFilterChild = _this.editingFilterEntity && !uiState.get$isEditing() ? new A.CompanyGatewayEditScreen(_null) : new A.CompanyGatewayViewScreen(true, _null);
|
||||
leftFilterChild = new A.CompanyGatewayViewScreen(true, _null);
|
||||
break;
|
||||
case B.EntityType_recurringInvoice:
|
||||
leftFilterChild = _this.editingFilterEntity && !uiState.get$isEditing() ? new A.RecurringInvoiceEditScreen(_null) : new A.RecurringInvoiceViewScreen(true, _null);
|
||||
leftFilterChild = new A.RecurringInvoiceViewScreen(true, _null);
|
||||
break;
|
||||
case B.EntityType_expenseCategory:
|
||||
leftFilterChild = _this.editingFilterEntity && !uiState.get$isEditing() ? new A.ExpenseCategoryEditScreen(_null) : new A.ExpenseCategoryViewScreen(true, _null);
|
||||
leftFilterChild = new A.ExpenseCategoryViewScreen(true, _null);
|
||||
break;
|
||||
case B.EntityType_taskStatus:
|
||||
leftFilterChild = _this.editingFilterEntity && !uiState.get$isEditing() ? new A.TaskStatusEditScreen(_null) : new A.TaskStatusViewScreen(true, _null);
|
||||
leftFilterChild = new A.TaskStatusViewScreen(true, _null);
|
||||
break;
|
||||
case B.EntityType_vendor:
|
||||
leftFilterChild = _this.editingFilterEntity && !uiState.get$isEditing() ? new A.VendorEditScreen(_null) : new A.VendorViewScreen(true, false, _null);
|
||||
leftFilterChild = new A.VendorViewScreen(true, false, _null);
|
||||
break;
|
||||
case B.EntityType_project:
|
||||
leftFilterChild = _this.editingFilterEntity && !uiState.get$isEditing() ? new A.ProjectEditScreen(_null) : new A.ProjectViewScreen(true, _null);
|
||||
leftFilterChild = new A.ProjectViewScreen(true, _null);
|
||||
break;
|
||||
case B.EntityType_design:
|
||||
leftFilterChild = new A.DesignViewScreen(true, _null);
|
||||
|
@ -33,6 +33,13 @@
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#qr-bill {
|
||||
width:100% !important;
|
||||
box-sizing: border-box;
|
||||
border-collapse: collapse;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.header-container {
|
||||
display: grid;
|
||||
|
@ -298,7 +298,6 @@ Route::group(['middleware' => ['throttle:300,1', 'api_db', 'token_auth', 'locale
|
||||
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');
|
||||
|
||||
@ -344,6 +343,9 @@ Route::group(['middleware' => ['throttle:300,1', 'api_db', 'token_auth', 'locale
|
||||
|
||||
});
|
||||
|
||||
Route::post('api/v1/sms_reset', [TwilioController::class, 'generate2faResetCode'])->name('sms_reset.generate')->middleware('throttle:10,1');
|
||||
Route::post('api/v1/sms_reset/confirm', [TwilioController::class, 'confirm2faResetCode'])->name('sms_reset.confirm')->middleware('throttle:20,1');
|
||||
|
||||
Route::match(['get', 'post'], 'payment_webhook/{company_key}/{company_gateway_id}', PaymentWebhookController::class)
|
||||
->middleware('throttle:1000,1')
|
||||
->name('payment_webhook');
|
||||
|
@ -12,6 +12,8 @@
|
||||
|
||||
namespace Tests\Feature\Bank;
|
||||
|
||||
use App\Factory\BankIntegrationFactory;
|
||||
use App\Factory\BankTransactionFactory;
|
||||
use App\Models\BankTransaction;
|
||||
use App\Models\Invoice;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
@ -54,10 +56,31 @@ class BankTransactionTest extends TestCase
|
||||
|
||||
public function testMatchBankTransactionValidationShouldPass()
|
||||
{
|
||||
|
||||
if (config('ninja.testvars.travis') !== false) {
|
||||
$this->markTestSkipped('Skip test for Github Actions');
|
||||
}
|
||||
|
||||
$data = [];
|
||||
|
||||
$bi = BankIntegrationFactory::create($this->company->id, $this->user->id, $this->account->id);
|
||||
$bi->save();
|
||||
|
||||
$bt = BankTransactionFactory::create($this->company->id, $this->user->id);
|
||||
$bt->bank_integration_id = $bi->id;
|
||||
$bt->description = 'Fuel';
|
||||
$bt->amount = 10;
|
||||
$bt->currency_code = $this->client->currency()->code;
|
||||
$bt->date = now()->format('Y-m-d');
|
||||
$bt->transaction_id = 1234567890;
|
||||
$bt->category_id = 10000003;
|
||||
$bt->base_type = 'DEBIT';
|
||||
$bt->save();
|
||||
|
||||
$data = [];
|
||||
|
||||
$data['transactions'][] = [
|
||||
'id' => $this->bank_transaction->hashed_id,
|
||||
'id' => $bt->hashed_id,
|
||||
];
|
||||
|
||||
$response = $this->withHeaders([
|
||||
|
@ -37,7 +37,7 @@ class YodleeApiTest extends TestCase
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
if(!config('ninja.yodlee.client_id'))
|
||||
// if(!config('ninja.yodlee.client_id'))
|
||||
$this->markTestSkipped('Skip test no Yodlee API credentials found');
|
||||
|
||||
$this->makeTestData();
|
||||
@ -160,55 +160,58 @@ class YodleeApiTest extends TestCase
|
||||
|
||||
}
|
||||
|
||||
public function testFunctionalMatching()
|
||||
{
|
||||
// public function testFunctionalMatching()
|
||||
// {
|
||||
|
||||
$yodlee = new Yodlee('sbMem62e1e69547bfb1');
|
||||
// $yodlee = new Yodlee('sbMem62e1e69547bfb1');
|
||||
|
||||
$accounts = $yodlee->getAccounts();
|
||||
// $accounts = $yodlee->getAccounts();
|
||||
|
||||
foreach($accounts as $account)
|
||||
{
|
||||
// foreach($accounts as $account)
|
||||
// {
|
||||
|
||||
if(!BankIntegration::where('bank_account_id', $account['id'])->where('company_id', $this->company->id)->exists())
|
||||
{
|
||||
$bank_integration = new BankIntegration();
|
||||
$bank_integration->company_id = $this->company->id;
|
||||
$bank_integration->account_id = $this->company->account_id;
|
||||
$bank_integration->user_id = $this->user->id;
|
||||
$bank_integration->bank_account_id = $account['id'];
|
||||
$bank_integration->bank_account_type = $account['account_type'];
|
||||
$bank_integration->bank_account_name = $account['account_name'];
|
||||
$bank_integration->bank_account_status = $account['account_status'];
|
||||
$bank_integration->bank_account_number = $account['account_number'];
|
||||
$bank_integration->provider_id = $account['provider_id'];
|
||||
$bank_integration->provider_name = $account['provider_name'];
|
||||
$bank_integration->nickname = $account['nickname'];
|
||||
$bank_integration->balance = $account['current_balance'];
|
||||
$bank_integration->currency = $account['account_currency'];
|
||||
// if(!BankIntegration::where('bank_account_id', $account['id'])->where('company_id', $this->company->id)->exists())
|
||||
// {
|
||||
// $bank_integration = new BankIntegration();
|
||||
// $bank_integration->company_id = $this->company->id;
|
||||
// $bank_integration->account_id = $this->company->account_id;
|
||||
// $bank_integration->user_id = $this->user->id;
|
||||
// $bank_integration->bank_account_id = $account['id'];
|
||||
// $bank_integration->bank_account_type = $account['account_type'];
|
||||
// $bank_integration->bank_account_name = $account['account_name'];
|
||||
// $bank_integration->bank_account_status = $account['account_status'];
|
||||
// $bank_integration->bank_account_number = $account['account_number'];
|
||||
// $bank_integration->provider_id = $account['provider_id'];
|
||||
// $bank_integration->provider_name = $account['provider_name'];
|
||||
// $bank_integration->nickname = $account['nickname'];
|
||||
// $bank_integration->balance = $account['current_balance'];
|
||||
// $bank_integration->currency = $account['account_currency'];
|
||||
|
||||
$bank_integration->save();
|
||||
// $bank_integration->save();
|
||||
|
||||
ProcessBankTransactions::dispatchSync('sbMem62e1e69547bfb1', $bank_integration);
|
||||
// ProcessBankTransactions::dispatchSync('sbMem62e1e69547bfb1', $bank_integration);
|
||||
|
||||
}
|
||||
}
|
||||
// }
|
||||
// }
|
||||
|
||||
$this->assertGreaterThan(0, BankIntegration::count());
|
||||
$this->assertGreaterThan(0, BankTransaction::count());
|
||||
// $this->assertGreaterThan(0, BankIntegration::count());
|
||||
// $this->assertGreaterThan(0, BankTransaction::count());
|
||||
|
||||
$this->invoice->number = "XXXXXX8501";
|
||||
$this->invoice->save();
|
||||
// $this->invoice->company_id = $this->company->id;
|
||||
// $this->invoice->number = "XXXXXX8501";
|
||||
// $this->invoice->save();
|
||||
|
||||
BankService::dispatchSync($this->company->id, $this->company->db);
|
||||
// BankService::dispatchSync($this->company->id, $this->company->db);
|
||||
|
||||
$bt = BankTransaction::where('invoice_ids', $this->invoice->hashed_id)->first();
|
||||
// $bt = BankTransaction::where('invoice_ids', $this->invoice->hashed_id)->first();
|
||||
|
||||
$this->assertNotNull($bt);
|
||||
// nlog(BankTransaction::where('company_id', $this->company->id)->pluck('invoice_ids'));
|
||||
|
||||
$this->assertEquals(BankTransaction::STATUS_MATCHED, $bt->status_id);
|
||||
// $this->assertNotNull($bt);
|
||||
|
||||
}
|
||||
// $this->assertEquals(BankTransaction::STATUS_MATCHED, $bt->status_id);
|
||||
|
||||
// }
|
||||
|
||||
|
||||
public function testDataMatching()
|
||||
|
Loading…
x
Reference in New Issue
Block a user