mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-05-24 02:14:21 -04:00
commit
daedfa0d39
3
.env.ci
3
.env.ci
@ -23,4 +23,5 @@ API_SECRET=superdoopersecrethere
|
||||
PHANTOMJS_PDF_GENERATION=false
|
||||
CACHE_DRIVER=redis
|
||||
QUEUE_CONNECTION=redis
|
||||
SESSION_DRIVER=redis
|
||||
SESSION_DRIVER=redis
|
||||
PDF_GENERATOR=hosted_ninja
|
@ -1 +1 @@
|
||||
5.9.4
|
||||
5.9.9
|
@ -176,6 +176,7 @@ class BackupUpdate extends Command
|
||||
try {
|
||||
$doc_bin = $document->getFile();
|
||||
} catch(\Exception $e) {
|
||||
nlog("Exception:: BackupUpdate::" . $e->getMessage());
|
||||
nlog($e->getMessage());
|
||||
}
|
||||
|
||||
@ -184,8 +185,6 @@ class BackupUpdate extends Command
|
||||
|
||||
$document->disk = $this->option('disk');
|
||||
$document->saveQuietly();
|
||||
|
||||
nlog("Documents - Moving {$document->url} to {$this->option('disk')}");
|
||||
}
|
||||
});
|
||||
|
||||
@ -199,8 +198,6 @@ class BackupUpdate extends Command
|
||||
|
||||
if ($backup_bin) {
|
||||
Storage::disk($this->option('disk'))->put($backup->filename, $backup_bin);
|
||||
|
||||
nlog("Backups - Moving {$backup->filename} to {$this->option('disk')}");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -172,18 +172,18 @@ class CheckData extends Command
|
||||
CompanyUser::query()->cursor()->each(function ($cu) {
|
||||
|
||||
if (CompanyToken::where('user_id', $cu->user_id)->where('company_id', $cu->company_id)->where('is_system', 1)->doesntExist()) {
|
||||
|
||||
|
||||
|
||||
if ($cu->company && $cu->user) {
|
||||
$this->logMessage("Creating missing company token for user # {$cu->user_id} for company id # {$cu->company_id}");
|
||||
(new CreateCompanyToken($cu->company, $cu->user, 'System'))->handle();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!$cu->user) {
|
||||
$this->logMessage("No user found for company user - removing company user");
|
||||
$cu->forceDelete();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -477,14 +477,13 @@ class CheckData extends Command
|
||||
}
|
||||
} else {
|
||||
$this->logMessage("No contact present, so cannot add invitation for {$entity_key} - {$entity->id}");
|
||||
|
||||
try{
|
||||
|
||||
try {
|
||||
$entity->service()->createInvitations()->save();
|
||||
}
|
||||
catch(\Exception $e){
|
||||
} catch(\Exception $e) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
@ -949,12 +948,12 @@ class CheckData extends Command
|
||||
|
||||
});
|
||||
|
||||
Company::whereDoesntHave('company_users', function ($query){
|
||||
$query->where('is_owner', 1);
|
||||
Company::whereDoesntHave('company_users', function ($query) {
|
||||
$query->where('is_owner', 1);
|
||||
})
|
||||
->cursor()
|
||||
->when(Ninja::isHosted())
|
||||
->each(function ($c){
|
||||
->each(function ($c) {
|
||||
|
||||
$this->logMessage("Orphan Account # {$c->account_id}");
|
||||
|
||||
@ -963,8 +962,8 @@ class CheckData extends Command
|
||||
CompanyUser::whereDoesntHave('tokens')
|
||||
->cursor()
|
||||
->when(Ninja::isHosted())
|
||||
->each(function ($cu){
|
||||
|
||||
->each(function ($cu) {
|
||||
|
||||
$this->logMessage("Missing tokens for Company User # {$cu->id}");
|
||||
|
||||
});
|
||||
|
@ -121,28 +121,6 @@ class CreateAccount extends Command
|
||||
(new CreateCompanyTaskStatuses($company, $user))->handle();
|
||||
(new VersionCheck())->handle();
|
||||
|
||||
$this->warmCache();
|
||||
}
|
||||
|
||||
private function warmCache()
|
||||
{
|
||||
/* Warm up the cache !*/
|
||||
$cached_tables = config('ninja.cached_tables');
|
||||
|
||||
foreach ($cached_tables as $name => $class) {
|
||||
if ($name == 'payment_terms') {
|
||||
$orderBy = 'num_days';
|
||||
} elseif ($name == 'fonts') {
|
||||
$orderBy = 'sort_order';
|
||||
} elseif (in_array($name, ['currencies', 'industries', 'languages', 'countries', 'banks'])) {
|
||||
$orderBy = 'name';
|
||||
} else {
|
||||
$orderBy = 'id';
|
||||
}
|
||||
$tableData = $class::orderBy($orderBy)->get();
|
||||
if ($tableData->count()) {
|
||||
Cache::forever($name, $tableData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -97,10 +97,6 @@ class CreateSingleAccount extends Command
|
||||
$this->count = 5;
|
||||
$this->gateway = $this->argument('gateway');
|
||||
|
||||
$this->info('Warming up cache');
|
||||
|
||||
$this->warmCache();
|
||||
|
||||
$this->createSmallAccount();
|
||||
|
||||
|
||||
@ -774,32 +770,6 @@ class CreateSingleAccount extends Command
|
||||
return $line_items;
|
||||
}
|
||||
|
||||
private function warmCache()
|
||||
{
|
||||
/* Warm up the cache !*/
|
||||
$cached_tables = config('ninja.cached_tables');
|
||||
|
||||
foreach ($cached_tables as $name => $class) {
|
||||
// check that the table exists in case the migration is pending
|
||||
if (! Schema::hasTable((new $class())->getTable())) {
|
||||
continue;
|
||||
}
|
||||
if ($name == 'payment_terms') {
|
||||
$orderBy = 'num_days';
|
||||
} elseif ($name == 'fonts') {
|
||||
$orderBy = 'sort_order';
|
||||
} elseif (in_array($name, ['currencies', 'industries', 'languages', 'countries', 'banks'])) {
|
||||
$orderBy = 'name';
|
||||
} else {
|
||||
$orderBy = 'id';
|
||||
}
|
||||
$tableData = $class::orderBy($orderBy)->get();
|
||||
if ($tableData->count()) {
|
||||
Cache::forever($name, $tableData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function createGateways($company, $user)
|
||||
{
|
||||
if (config('ninja.testvars.stripe') && ($this->gateway == 'all' || $this->gateway == 'stripe')) {
|
||||
@ -1016,7 +986,7 @@ class CreateSingleAccount extends Command
|
||||
$cg->fees_and_limits = $fees_and_limits;
|
||||
$cg->save();
|
||||
}
|
||||
|
||||
|
||||
if (config('ninja.testvars.eway') && ($this->gateway == 'all' || $this->gateway == 'eway')) {
|
||||
$cg = new CompanyGateway();
|
||||
$cg->company_id = $company->id;
|
||||
@ -1038,12 +1008,12 @@ class CreateSingleAccount extends Command
|
||||
$cg->save();
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (config('ninja.testvars.gocardless') && ($this->gateway == 'all' || $this->gateway == 'gocardless')) {
|
||||
|
||||
$c_settings = ClientSettings::defaults();
|
||||
$c_settings->currency_id = '2';
|
||||
|
||||
|
||||
$client = Client::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
'company_id' => $company->id,
|
||||
|
@ -86,8 +86,6 @@ class CreateTestData extends Command
|
||||
|
||||
$this->info('Warming up cache');
|
||||
|
||||
$this->warmCache();
|
||||
|
||||
$this->createSmallAccount();
|
||||
$this->createMediumAccount();
|
||||
$this->createLargeAccount();
|
||||
@ -673,31 +671,4 @@ class CreateTestData extends Command
|
||||
return $line_items;
|
||||
}
|
||||
|
||||
private function warmCache()
|
||||
{
|
||||
/* Warm up the cache !*/
|
||||
$cached_tables = config('ninja.cached_tables');
|
||||
|
||||
foreach ($cached_tables as $name => $class) {
|
||||
if (! Cache::has($name)) {
|
||||
// check that the table exists in case the migration is pending
|
||||
if (! Schema::hasTable((new $class())->getTable())) {
|
||||
continue;
|
||||
}
|
||||
if ($name == 'payment_terms') {
|
||||
$orderBy = 'num_days';
|
||||
} elseif ($name == 'fonts') {
|
||||
$orderBy = 'sort_order';
|
||||
} elseif (in_array($name, ['currencies', 'industries', 'languages', 'countries', 'banks'])) {
|
||||
$orderBy = 'name';
|
||||
} else {
|
||||
$orderBy = 'id';
|
||||
}
|
||||
$tableData = $class::orderBy($orderBy)->get();
|
||||
if ($tableData->count()) {
|
||||
Cache::forever($name, $tableData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -84,15 +84,13 @@ class DemoMode extends Command
|
||||
|
||||
$this->invoice_repo = new InvoiceRepository();
|
||||
|
||||
$cached_tables = config('ninja.cached_tables');
|
||||
|
||||
$this->info('Migrating');
|
||||
Artisan::call('migrate:fresh --force');
|
||||
|
||||
$this->info('Seeding');
|
||||
Artisan::call('db:seed --force');
|
||||
|
||||
$this->buildCache(true);
|
||||
Artisan::call('db:seed --force');
|
||||
Artisan::call('cache:clear');
|
||||
|
||||
$this->info('Seeding Random Data');
|
||||
$this->createSmallAccount();
|
||||
@ -623,31 +621,4 @@ class DemoMode extends Command
|
||||
return $line_items;
|
||||
}
|
||||
|
||||
private function warmCache()
|
||||
{
|
||||
/* Warm up the cache !*/
|
||||
$cached_tables = config('ninja.cached_tables');
|
||||
|
||||
foreach ($cached_tables as $name => $class) {
|
||||
if (! Cache::has($name)) {
|
||||
// check that the table exists in case the migration is pending
|
||||
if (! Schema::hasTable((new $class())->getTable())) {
|
||||
continue;
|
||||
}
|
||||
if ($name == 'payment_terms') {
|
||||
$orderBy = 'num_days';
|
||||
} elseif ($name == 'fonts') {
|
||||
$orderBy = 'sort_order';
|
||||
} elseif (in_array($name, ['currencies', 'industries', 'languages', 'countries', 'banks'])) {
|
||||
$orderBy = 'name';
|
||||
} else {
|
||||
$orderBy = 'id';
|
||||
}
|
||||
$tableData = $class::orderBy($orderBy)->get();
|
||||
if ($tableData->count()) {
|
||||
Cache::forever($name, $tableData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -62,7 +62,6 @@ class HostedMigrations extends Command
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$this->buildCache();
|
||||
|
||||
if (! MultiDB::userFindAndSetDb($this->option('email'))) {
|
||||
$this->info('Could not find a user with that email address');
|
||||
|
@ -75,8 +75,6 @@ class ImportMigrations extends Command
|
||||
{
|
||||
$this->faker = Factory::create();
|
||||
|
||||
$this->buildCache();
|
||||
|
||||
$path = $this->option('path') ?? public_path('storage/migrations/import');
|
||||
|
||||
$directory = new DirectoryIterator($path);
|
||||
|
@ -86,8 +86,7 @@ class PostUpdate extends Command
|
||||
|
||||
info('queue restarted');
|
||||
|
||||
$this->buildCache(true);
|
||||
|
||||
Artisan::call('cache:clear');
|
||||
VersionCheck::dispatch();
|
||||
|
||||
info('Sent for version check');
|
||||
|
@ -48,37 +48,37 @@ class ReactBuilder extends Command
|
||||
{
|
||||
if($this->option('type') == 'local') {
|
||||
|
||||
|
||||
|
||||
$includes = '';
|
||||
|
||||
$directoryIterator = false;
|
||||
$includes = '';
|
||||
|
||||
try {
|
||||
$directoryIterator = new \RecursiveDirectoryIterator(public_path('react/v'.config('ninja.app_version').'/'), \RecursiveDirectoryIterator::SKIP_DOTS);
|
||||
} catch (\Exception $e) {
|
||||
$this->error('React files not found');
|
||||
return;
|
||||
}
|
||||
$directoryIterator = false;
|
||||
|
||||
foreach (new \RecursiveIteratorIterator($directoryIterator) as $file) {
|
||||
if ($file->getExtension() == 'js') {
|
||||
if (str_contains($file->getFileName(), 'index-')) {
|
||||
$includes .= '<script type="module" crossorigin src="/react/v'.config('ninja.app_version').'/'.$file->getFileName().'"></script>'."\n";
|
||||
} else {
|
||||
$includes .= '<link rel="modulepreload" href="/react/v'.config('ninja.app_version').'/'.$file->getFileName().'">'."\n";
|
||||
try {
|
||||
$directoryIterator = new \RecursiveDirectoryIterator(public_path('react/v'.config('ninja.app_version').'/'), \RecursiveDirectoryIterator::SKIP_DOTS);
|
||||
} catch (\Exception $e) {
|
||||
$this->error('React files not found');
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (new \RecursiveIteratorIterator($directoryIterator) as $file) {
|
||||
if ($file->getExtension() == 'js') {
|
||||
if (str_contains($file->getFileName(), 'index-')) {
|
||||
$includes .= '<script type="module" crossorigin src="/react/v'.config('ninja.app_version').'/'.$file->getFileName().'"></script>'."\n";
|
||||
} else {
|
||||
$includes .= '<link rel="modulepreload" href="/react/v'.config('ninja.app_version').'/'.$file->getFileName().'">'."\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (str_contains($file->getFileName(), '.css')) {
|
||||
$includes .= '<link rel="stylesheet" href="/react/v'.config('ninja.app_version').'/'.$file->getFileName().'">'."\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (str_contains($file->getFileName(), '.css')) {
|
||||
$includes .= '<link rel="stylesheet" href="/react/v'.config('ninja.app_version').'/'.$file->getFileName().'">'."\n";
|
||||
}
|
||||
}
|
||||
|
||||
file_put_contents(resource_path('views/react/head.blade.php'), $includes);
|
||||
file_put_contents(resource_path('views/react/head.blade.php'), $includes);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ use App\Jobs\Ninja\TaskScheduler;
|
||||
use App\Jobs\Quote\QuoteCheckExpired;
|
||||
use App\Jobs\Subscription\CleanStaleInvoiceOrder;
|
||||
use App\Jobs\Util\DiskCleanup;
|
||||
use App\Jobs\Util\QuoteReminderJob;
|
||||
use App\Jobs\Util\ReminderJob;
|
||||
use App\Jobs\Util\SchedulerCheck;
|
||||
use App\Jobs\Util\UpdateExchangeRates;
|
||||
@ -55,6 +56,9 @@ class Kernel extends ConsoleKernel
|
||||
/* Send reminders */
|
||||
$schedule->job(new ReminderJob())->hourly()->withoutOverlapping()->name('reminder-job')->onOneServer();
|
||||
|
||||
/* Send quote reminders */
|
||||
$schedule->job(new QuoteReminderJob())->hourly()->withoutOverlapping()->name('quote-reminder-job')->onOneServer();
|
||||
|
||||
/* Sends recurring invoices*/
|
||||
$schedule->job(new RecurringInvoicesCron())->hourly()->withoutOverlapping()->name('recurring-invoice-job')->onOneServer();
|
||||
|
||||
|
@ -55,7 +55,7 @@ class DbQuery extends GenericMixedMetric
|
||||
public $string_metric8 = 'client_version';
|
||||
|
||||
public $string_metric9 = 'platform';
|
||||
|
||||
|
||||
/**
|
||||
* The counter
|
||||
* set to 1.
|
||||
|
61
app/DataMapper/Analytics/LoginMeta.php
Normal file
61
app/DataMapper/Analytics/LoginMeta.php
Normal file
@ -0,0 +1,61 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2024. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\DataMapper\Analytics;
|
||||
|
||||
use Turbo124\Beacon\ExampleMetric\GenericMixedMetric;
|
||||
|
||||
class LoginMeta extends GenericMixedMetric
|
||||
{
|
||||
/**
|
||||
* The type of Sample.
|
||||
*
|
||||
* Monotonically incrementing counter
|
||||
*
|
||||
* - counter
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $type = 'mixed_metric';
|
||||
|
||||
/**
|
||||
* The name of the counter.
|
||||
* @var string
|
||||
*/
|
||||
public $name = 'login.meta';
|
||||
|
||||
/**
|
||||
* The datetime of the counter measurement.
|
||||
*
|
||||
* date("Y-m-d H:i:s")
|
||||
*
|
||||
*/
|
||||
public $datetime;
|
||||
|
||||
/**
|
||||
* The Class failure name
|
||||
* set to 0.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $string_metric5 = 'email';
|
||||
public $string_metric6 = 'ip';
|
||||
public $string_metric7 = 'result';
|
||||
|
||||
public $int_metric1 = 1;
|
||||
|
||||
public function __construct($string_metric5, $string_metric6, $string_metric7)
|
||||
{
|
||||
$this->string_metric7 = $string_metric7;
|
||||
$this->string_metric6 = $string_metric6;
|
||||
$this->string_metric5 = $string_metric5;
|
||||
}
|
||||
}
|
@ -507,7 +507,25 @@ class CompanySettings extends BaseSettings
|
||||
|
||||
public int $task_round_to_nearest = 1;
|
||||
|
||||
/** quote reminders */
|
||||
public $email_quote_template_reminder1 = '';
|
||||
public $email_quote_subject_reminder1 = '';
|
||||
public $enable_quote_reminder1 = false;
|
||||
public $quote_num_days_reminder1 = 0;
|
||||
public $quote_schedule_reminder1 = ''; //before_valid_until_date,after_valid_until_date,after_quote_date
|
||||
public $quote_late_fee_amount1 = 0;
|
||||
public $quote_late_fee_percent1 = 0;
|
||||
|
||||
|
||||
|
||||
public static $casts = [
|
||||
'enable_quote_reminder1' => 'bool',
|
||||
'quote_num_days_reminder1' => 'int',
|
||||
'quote_schedule_reminder1' => 'string',
|
||||
'quote_late_fee_amount1' => 'float',
|
||||
'quote_late_fee_percent1' => 'float',
|
||||
'email_quote_template_reminder1' => 'string',
|
||||
'email_quote_subject_reminder1' => 'string',
|
||||
'task_round_up' => 'bool',
|
||||
'task_round_to_nearest' => 'int',
|
||||
'e_quote_type' => 'string',
|
||||
@ -962,6 +980,7 @@ class CompanySettings extends BaseSettings
|
||||
'$invoice.due_date',
|
||||
'$invoice.total',
|
||||
'$invoice.balance_due',
|
||||
'$invoice.project',
|
||||
],
|
||||
'quote_details' => [
|
||||
'$quote.number',
|
||||
@ -969,6 +988,7 @@ class CompanySettings extends BaseSettings
|
||||
'$quote.date',
|
||||
'$quote.valid_until',
|
||||
'$quote.total',
|
||||
'$quote.project',
|
||||
],
|
||||
'credit_details' => [
|
||||
'$credit.number',
|
||||
|
@ -115,12 +115,32 @@ class EmailTemplateDefaults
|
||||
case 'email_vendor_notification_body':
|
||||
return self::emailVendorNotificationBody();
|
||||
|
||||
case 'email_quote_template_reminder1':
|
||||
return self::emailQuoteReminder1Body();
|
||||
|
||||
case 'email_quote_subject_reminder1':
|
||||
return self::emailQuoteReminder1Subject();
|
||||
|
||||
default:
|
||||
return self::emailInvoiceTemplate();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static function emailQuoteReminder1Subject()
|
||||
{
|
||||
return ctrans('texts.quote_reminder_subject', ['quote' => '$number', 'company' => '$company.name']);
|
||||
}
|
||||
|
||||
public static function emailQuoteReminder1Body()
|
||||
{
|
||||
|
||||
$invoice_message = '<p>$client<br><br>'.self::transformText('quote_reminder_message').'</p><div class="center">$view_button</div>';
|
||||
|
||||
return $invoice_message;
|
||||
|
||||
}
|
||||
|
||||
public static function emailVendorNotificationSubject()
|
||||
{
|
||||
return self::transformText('vendor_notification_subject');
|
||||
|
@ -64,9 +64,9 @@ class InvoiceItem
|
||||
public $task_id = '';
|
||||
|
||||
public $expense_id = '';
|
||||
|
||||
|
||||
public $unit_code = 'C62';
|
||||
|
||||
|
||||
public static $casts = [
|
||||
'task_id' => 'string',
|
||||
'expense_id' => 'string',
|
||||
|
@ -15,7 +15,6 @@ use App\DataMapper\InvoiceItem;
|
||||
|
||||
class PayPalBalanceAffecting
|
||||
{
|
||||
|
||||
private array $key_map = [
|
||||
'Date' => 'date',
|
||||
'Time' => 'time',
|
||||
@ -105,8 +104,10 @@ class PayPalBalanceAffecting
|
||||
public $discount;
|
||||
public $creditTransactionalFee;
|
||||
public $originalInvoiceId;
|
||||
|
||||
public function __construct(private array $import_row){}
|
||||
|
||||
public function __construct(private array $import_row)
|
||||
{
|
||||
}
|
||||
|
||||
public function run(): self
|
||||
{
|
||||
@ -116,11 +117,11 @@ class PayPalBalanceAffecting
|
||||
|
||||
$prop = $this->key_map[$key] ?? false;
|
||||
|
||||
if($prop){
|
||||
if($prop) {
|
||||
|
||||
echo "Setting {$prop} to {$value}".PHP_EOL;
|
||||
$this->{$prop} = $value;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -130,7 +131,7 @@ class PayPalBalanceAffecting
|
||||
private function cleanUp(): self
|
||||
{
|
||||
|
||||
foreach($this->key_map as $value){
|
||||
foreach($this->key_map as $value) {
|
||||
echo "Setting {$value} to null".PHP_EOL;
|
||||
$this->{$value} = null;
|
||||
}
|
||||
@ -154,7 +155,7 @@ class PayPalBalanceAffecting
|
||||
|
||||
public function getInvoice(): array
|
||||
{
|
||||
$item = new InvoiceItem;
|
||||
$item = new InvoiceItem();
|
||||
$item->cost = $this->gross ?? 0;
|
||||
$item->product_key = $this->itemId ?? '';
|
||||
$item->notes = $this->subject ?? $this->itemDetails;
|
||||
@ -162,7 +163,7 @@ class PayPalBalanceAffecting
|
||||
|
||||
return [
|
||||
'number' => trim($this->invoiceNumber ?? $this->transactionId),
|
||||
'date' => str_replace('/','-', $this->date ?? ''),
|
||||
'date' => str_replace('/', '-', $this->date ?? ''),
|
||||
'line_items' => [$item],
|
||||
'name' => $this->name ?? '',
|
||||
'email' => $this->fromEmailAddress ?? '',
|
||||
@ -174,12 +175,10 @@ class PayPalBalanceAffecting
|
||||
{
|
||||
$name_parts = explode(" ", $this->name ?? '');
|
||||
|
||||
if(count($name_parts) == 2)
|
||||
{
|
||||
if(count($name_parts) == 2) {
|
||||
$contact['first_name'] = $name_parts[0];
|
||||
$contact['last_name'] = $name_parts[1];
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$contact['first_name'] = $this->name ?? '';
|
||||
}
|
||||
|
||||
@ -188,7 +187,7 @@ class PayPalBalanceAffecting
|
||||
|
||||
return $contact;
|
||||
}
|
||||
|
||||
|
||||
private function returnAddress(): array
|
||||
{
|
||||
return [
|
||||
@ -203,13 +202,15 @@ class PayPalBalanceAffecting
|
||||
|
||||
private function returnShippingAddress(): array
|
||||
{
|
||||
if(strlen($this->shippingAddress ?? '') <3)
|
||||
if(strlen($this->shippingAddress ?? '') < 3) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$ship_parts = explode(",", $this->shippingAddress);
|
||||
|
||||
if(count($ship_parts) != 7)
|
||||
if(count($ship_parts) != 7) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return [
|
||||
'shipping_address1' => $ship_parts[2],
|
||||
|
@ -220,6 +220,7 @@ class BaseRule implements RuleInterface
|
||||
try {
|
||||
$this->invoice->saveQuietly();
|
||||
} catch(\Exception $e) {
|
||||
nlog("Exception:: BaseRule::" . $e->getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
@ -261,7 +262,7 @@ class BaseRule implements RuleInterface
|
||||
return $this->client->state;
|
||||
}
|
||||
|
||||
return USStates::getState(strlen($this->client->postal_code) > 1 ? $this->client->postal_code : $this->client->shipping_postal_code);
|
||||
return USStates::getState(strlen($this->client->postal_code ?? '') > 1 ? $this->client->postal_code : $this->client->shipping_postal_code);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
return 'CA';
|
||||
|
@ -24,6 +24,7 @@ class TaxData
|
||||
|
||||
public function __construct(public Response $origin)
|
||||
{
|
||||
// @phpstan-ignore-next-line
|
||||
foreach($origin as $key => $value) {
|
||||
$this->{$key} = $value;
|
||||
}
|
||||
|
@ -34006,7 +34006,7 @@ class USStates
|
||||
'WA', 'WA', 'WA', 'WA', 'WA', 'WA', 'WA', 'AK', 'AK', 'AK', 'AK', 'AK'
|
||||
];
|
||||
|
||||
$prefix = substr($zip, 0, 3);
|
||||
$prefix = substr(($zip ?? ''), 0, 3);
|
||||
$index = intval($prefix);
|
||||
/* converts prefix to integer */
|
||||
return $zip_by_state[$index] == "--" ? false : $zip_by_state[$index];
|
||||
|
28
app/Events/Quote/QuoteReminderWasEmailed.php
Normal file
28
app/Events/Quote/QuoteReminderWasEmailed.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
/**
|
||||
* Quote Ninja (https://Quoteninja.com).
|
||||
*
|
||||
* @link https://github.com/Quoteninja/Quoteninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2024. Quote Ninja LLC (https://Quoteninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\Events\Quote;
|
||||
|
||||
use App\Models\Company;
|
||||
use App\Models\QuoteInvitation;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
/**
|
||||
* Class QuoteReminderWasEmailed.
|
||||
*/
|
||||
class QuoteReminderWasEmailed
|
||||
{
|
||||
use SerializesModels;
|
||||
|
||||
public function __construct(public QuoteInvitation $invitation, public Company $company, public array $event_vars, public string $template)
|
||||
{
|
||||
}
|
||||
}
|
44
app/Exceptions/DuplicatePaymentException.php
Normal file
44
app/Exceptions/DuplicatePaymentException.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2024. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\Exceptions;
|
||||
|
||||
use Exception;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class DuplicatePaymentException extends Exception
|
||||
{
|
||||
/**
|
||||
* Report the exception.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function report()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the exception into an HTTP response.
|
||||
*
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function render($request)
|
||||
{
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Duplicate request',
|
||||
], 400);
|
||||
|
||||
}
|
||||
}
|
@ -109,10 +109,11 @@ class Handler extends ExceptionHandler
|
||||
Integration::configureScope(function (Scope $scope): void {
|
||||
$name = 'hosted@invoiceninja.com';
|
||||
|
||||
if (auth()->guard('contact') && auth()->guard('contact')->user()) {
|
||||
if (auth()->guard('contact') && auth()->guard('contact')->user()) { // @phpstan-ignore-line
|
||||
$name = 'Contact = '.auth()->guard('contact')->user()->email;
|
||||
$key = auth()->guard('contact')->user()->company->account->key;
|
||||
} elseif (auth()->guard('user') && auth()->guard('user')->user()) {
|
||||
} elseif (auth()->guard('user') && auth()->guard('user')->user()) { // @phpstan-ignore-line
|
||||
|
||||
$name = 'Admin = '.auth()->guard('user')->user()->email;
|
||||
$key = auth()->user()->account->key;
|
||||
} else {
|
||||
@ -131,13 +132,14 @@ class Handler extends ExceptionHandler
|
||||
}
|
||||
} elseif (app()->bound('sentry')) {
|
||||
Integration::configureScope(function (Scope $scope): void {
|
||||
if (auth()->guard('contact') && auth()->guard('contact')->user() && auth()->guard('contact')->user()->company->account->report_errors) {
|
||||
if (auth()->guard('contact') && auth()->guard('contact')->user() && auth()->guard('contact')->user()->company->account->report_errors) {// @phpstan-ignore-line
|
||||
|
||||
$scope->setUser([
|
||||
'id' => auth()->guard('contact')->user()->company->account->key,
|
||||
'email' => 'anonymous@example.com',
|
||||
'name' => 'Anonymous User',
|
||||
]);
|
||||
} elseif (auth()->guard('user') && auth()->guard('user')->user() && auth()->user()->companyIsSet() && auth()->user()->company()->account->report_errors) {
|
||||
} elseif (auth()->guard('user') && auth()->guard('user')->user() && auth()->user()->companyIsSet() && auth()->user()->company()->account->report_errors) {// @phpstan-ignore-line
|
||||
$scope->setUser([
|
||||
'id' => auth()->user()->account->key,
|
||||
'email' => 'anonymous@example.com',
|
||||
|
@ -25,8 +25,6 @@ use League\Csv\Writer;
|
||||
|
||||
class ActivityExport extends BaseExport
|
||||
{
|
||||
private $entity_transformer;
|
||||
|
||||
public string $date_key = 'created_at';
|
||||
|
||||
private string $date_format = 'YYYY-MM-DD';
|
||||
@ -43,7 +41,7 @@ class ActivityExport extends BaseExport
|
||||
{
|
||||
$this->company = $company;
|
||||
$this->input = $input;
|
||||
$this->entity_transformer = new ActivityTransformer();
|
||||
|
||||
}
|
||||
|
||||
public function returnJson()
|
||||
@ -143,10 +141,10 @@ class ActivityExport extends BaseExport
|
||||
|
||||
}
|
||||
|
||||
private function decorateAdvancedFields(Task $task, array $entity): array
|
||||
{
|
||||
return $entity;
|
||||
}
|
||||
// private function decorateAdvancedFields(Task $task, array $entity): array
|
||||
// {
|
||||
// return $entity;
|
||||
// }
|
||||
|
||||
|
||||
public function processMetaData(array $row, $resource): array
|
||||
|
@ -838,12 +838,12 @@ class BaseExport
|
||||
return '';
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Apply Product Filters
|
||||
*
|
||||
* @param Builder $query
|
||||
*
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
public function applyProductFilters(Builder $query): Builder
|
||||
@ -863,13 +863,13 @@ class BaseExport
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add Client Filter
|
||||
*
|
||||
* @param Builder $query
|
||||
* @param mixed $clients
|
||||
*
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
protected function addClientFilter(Builder $query, $clients): Builder
|
||||
@ -886,13 +886,13 @@ class BaseExport
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add Vendor Filter
|
||||
*
|
||||
* @param Builder $query
|
||||
* @param string $vendors
|
||||
*
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
protected function addVendorFilter(Builder$query, string $vendors): Builder
|
||||
@ -910,13 +910,13 @@ class BaseExport
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* AddProjectFilter
|
||||
*
|
||||
* @param Builder $query
|
||||
* @param string $projects
|
||||
*
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
protected function addProjectFilter(Builder $query, string $projects): Builder
|
||||
@ -934,13 +934,13 @@ class BaseExport
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add Category Filter
|
||||
*
|
||||
* @param Builder $query
|
||||
* @param string $expense_categories
|
||||
*
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
protected function addCategoryFilter(Builder $query, string $expense_categories): Builder
|
||||
@ -959,24 +959,25 @@ class BaseExport
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add Payment Status Filters
|
||||
*
|
||||
* @param Builder $query
|
||||
* @param string $status
|
||||
*
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
protected function addPaymentStatusFilters(Builder $query, string $status): Builder
|
||||
{
|
||||
|
||||
/** @var array $status_parameters */
|
||||
$status_parameters = explode(',', $status);
|
||||
|
||||
if(in_array('all', $status_parameters) || count($status_parameters) == 0) {
|
||||
if((count($status_parameters) == 0) || in_array('all', $status_parameters)) {
|
||||
return $query;
|
||||
}
|
||||
|
||||
|
||||
$query->where(function ($query) use ($status_parameters) {
|
||||
$payment_filters = [];
|
||||
|
||||
@ -1016,21 +1017,22 @@ class BaseExport
|
||||
return $query;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add RecurringInvoice Status Filter
|
||||
*
|
||||
* @param Builder $query
|
||||
* @param string $status
|
||||
*
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
protected function addRecurringInvoiceStatusFilter(Builder $query, string $status): Builder
|
||||
{
|
||||
|
||||
/** @var array $status_parameters */
|
||||
$status_parameters = explode(',', $status);
|
||||
|
||||
if (in_array('all', $status_parameters) || count($status_parameters) == 0){
|
||||
if (in_array('all', $status_parameters) || count($status_parameters) == 0) {
|
||||
return $query;
|
||||
}
|
||||
|
||||
@ -1060,7 +1062,7 @@ class BaseExport
|
||||
*
|
||||
* @param Builder $query
|
||||
* @param string $status
|
||||
*
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
protected function addQuoteStatusFilter(Builder $query, string $status): Builder
|
||||
@ -1126,12 +1128,13 @@ class BaseExport
|
||||
*
|
||||
* @param Builder $query
|
||||
* @param string $status
|
||||
*
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
protected function addPurchaseOrderStatusFilter(Builder $query, string $status): Builder
|
||||
{
|
||||
|
||||
|
||||
/** @var array $status_parameters */
|
||||
$status_parameters = explode(',', $status);
|
||||
|
||||
if (in_array('all', $status_parameters) || count($status_parameters) == 0) {
|
||||
@ -1179,7 +1182,8 @@ class BaseExport
|
||||
*/
|
||||
protected function addInvoiceStatusFilter(Builder $query, string $status): Builder
|
||||
{
|
||||
|
||||
|
||||
/** @var array $status_parameters */
|
||||
$status_parameters = explode(',', $status);
|
||||
|
||||
if(in_array('all', $status_parameters) || count($status_parameters) == 0) {
|
||||
@ -1234,7 +1238,7 @@ class BaseExport
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add Date Range
|
||||
*
|
||||
@ -1578,7 +1582,7 @@ class BaseExport
|
||||
|
||||
public function queueDocuments(Builder $query)
|
||||
{
|
||||
|
||||
|
||||
if($query->getModel() instanceof Document) {
|
||||
$documents = $query->pluck('id')->toArray();
|
||||
} else {
|
||||
|
@ -127,8 +127,9 @@ class ClientExport extends BaseExport
|
||||
->withTrashed()
|
||||
->where('company_id', $this->company->id);
|
||||
|
||||
if(!$this->input['include_deleted'] ?? false)
|
||||
if(!$this->input['include_deleted'] ?? false) {
|
||||
$query->where('is_deleted', 0);
|
||||
}
|
||||
|
||||
$query = $this->addDateRange($query);
|
||||
|
||||
@ -242,16 +243,16 @@ class ClientExport extends BaseExport
|
||||
return $entity;
|
||||
}
|
||||
|
||||
private function calculateStatus($client)
|
||||
{
|
||||
if ($client->is_deleted) {
|
||||
return ctrans('texts.deleted');
|
||||
}
|
||||
// private function calculateStatus($client)
|
||||
// {
|
||||
// if ($client->is_deleted) {
|
||||
// return ctrans('texts.deleted');
|
||||
// }
|
||||
|
||||
if ($client->deleted_at) {
|
||||
return ctrans('texts.archived');
|
||||
}
|
||||
// if ($client->deleted_at) {
|
||||
// return ctrans('texts.archived');
|
||||
// }
|
||||
|
||||
return ctrans('texts.active');
|
||||
}
|
||||
// return ctrans('texts.active');
|
||||
// }
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ class ContactExport extends BaseExport
|
||||
|
||||
$query = ClientContact::query()
|
||||
->where('company_id', $this->company->id)
|
||||
->whereHas('client', function ($q){
|
||||
->whereHas('client', function ($q) {
|
||||
$q->where('is_deleted', false);
|
||||
});
|
||||
|
||||
@ -155,7 +155,7 @@ class ContactExport extends BaseExport
|
||||
}
|
||||
|
||||
if (in_array('client.user_id', $this->input['report_keys'])) {
|
||||
$entity['client.user_id'] = $client->user ? $client->user->present()->name() : '';
|
||||
$entity['client.user_id'] = $client->user ? $client->user->present()->name() : '';// @phpstan-ignore-line
|
||||
}
|
||||
|
||||
if (in_array('client.assigned_user_id', $this->input['report_keys'])) {
|
||||
|
@ -102,7 +102,7 @@ class CreditExport extends BaseExport
|
||||
$query = Credit::query()
|
||||
->withTrashed()
|
||||
->with('client')
|
||||
->whereHas('client', function ($q){
|
||||
->whereHas('client', function ($q) {
|
||||
$q->where('is_deleted', false);
|
||||
})
|
||||
->where('company_id', $this->company->id)
|
||||
|
@ -83,9 +83,9 @@ class ExpenseExport extends BaseExport
|
||||
->with('client')
|
||||
->withTrashed()
|
||||
->where('company_id', $this->company->id);
|
||||
|
||||
|
||||
if(!$this->input['include_deleted'] ?? false){
|
||||
|
||||
|
||||
if(!$this->input['include_deleted'] ?? false) {
|
||||
$query->where('is_deleted', 0);
|
||||
}
|
||||
|
||||
@ -220,17 +220,17 @@ class ExpenseExport extends BaseExport
|
||||
// $entity['expense.client'] = $expense->client ? $expense->client->present()->name() : '';
|
||||
// }
|
||||
|
||||
// if (in_array('expense.invoice_id', $this->input['report_keys'])) {
|
||||
// $entity['expense.invoice_id'] = $expense->invoice ? $expense->invoice->number : '';
|
||||
// }
|
||||
if (in_array('expense.invoice_id', $this->input['report_keys'])) {
|
||||
$entity['expense.invoice_id'] = $expense->invoice ? $expense->invoice->number : '';
|
||||
}
|
||||
|
||||
// if (in_array('expense.category', $this->input['report_keys'])) {
|
||||
// $entity['expense.category'] = $expense->category ? $expense->category->name : '';
|
||||
// }
|
||||
|
||||
// if (in_array('expense.vendor_id', $this->input['report_keys'])) {
|
||||
// $entity['expense.vendor'] = $expense->vendor ? $expense->vendor->name : '';
|
||||
// }
|
||||
if (in_array('expense.vendor_id', $this->input['report_keys'])) {
|
||||
$entity['expense.vendor'] = $expense->vendor ? $expense->vendor->name : '';
|
||||
}
|
||||
|
||||
// if (in_array('expense.payment_type_id', $this->input['report_keys'])) {
|
||||
// $entity['expense.payment_type_id'] = $expense->payment_type ? $expense->payment_type->name : '';
|
||||
|
@ -57,13 +57,13 @@ class InvoiceExport extends BaseExport
|
||||
$query = Invoice::query()
|
||||
->withTrashed()
|
||||
->with('client')
|
||||
->whereHas('client', function ($q){
|
||||
->whereHas('client', function ($q) {
|
||||
$q->where('is_deleted', false);
|
||||
})
|
||||
->where('company_id', $this->company->id);
|
||||
|
||||
|
||||
if(!$this->input['include_deleted'] ?? false){
|
||||
|
||||
if(!$this->input['include_deleted'] ?? false) {
|
||||
$query->where('is_deleted', 0);
|
||||
}
|
||||
|
||||
|
@ -70,12 +70,12 @@ class InvoiceItemExport extends BaseExport
|
||||
$query = Invoice::query()
|
||||
->withTrashed()
|
||||
->with('client')
|
||||
->whereHas('client', function ($q){
|
||||
->whereHas('client', function ($q) {
|
||||
$q->where('is_deleted', false);
|
||||
})
|
||||
->where('company_id', $this->company->id);
|
||||
|
||||
if(!$this->input['include_deleted'] ?? false){
|
||||
|
||||
if(!$this->input['include_deleted'] ?? false) {
|
||||
$query->where('is_deleted', 0);
|
||||
}
|
||||
|
||||
|
@ -56,7 +56,7 @@ class PaymentExport extends BaseExport
|
||||
|
||||
$query = Payment::query()
|
||||
->withTrashed()
|
||||
->whereHas('client', function ($q){
|
||||
->whereHas('client', function ($q) {
|
||||
$q->where('is_deleted', false);
|
||||
})
|
||||
->where('company_id', $this->company->id)
|
||||
@ -71,7 +71,7 @@ class PaymentExport extends BaseExport
|
||||
}
|
||||
|
||||
$query = $this->addPaymentStatusFilters($query, $this->input['status'] ?? '');
|
||||
|
||||
|
||||
if($this->input['document_email_attachment'] ?? false) {
|
||||
$this->queueDocuments($query);
|
||||
}
|
||||
|
@ -74,9 +74,9 @@ class ProductExport extends BaseExport
|
||||
$query = Product::query()
|
||||
->withTrashed()
|
||||
->where('company_id', $this->company->id);
|
||||
|
||||
|
||||
if(!$this->input['include_deleted'] ?? false){
|
||||
|
||||
|
||||
if(!$this->input['include_deleted'] ?? false) {
|
||||
$query->where('is_deleted', 0);
|
||||
}
|
||||
|
||||
@ -133,16 +133,16 @@ class ProductExport extends BaseExport
|
||||
// return $this->decorateAdvancedFields($product, $entity);
|
||||
}
|
||||
|
||||
private function decorateAdvancedFields(Product $product, array $entity): array
|
||||
{
|
||||
if (in_array('vendor_id', $this->input['report_keys'])) {
|
||||
$entity['vendor'] = $product->vendor()->exists() ? $product->vendor->name : '';
|
||||
}
|
||||
// private function decorateAdvancedFields(Product $product, array $entity): array
|
||||
// {
|
||||
// if (in_array('vendor_id', $this->input['report_keys'])) {
|
||||
// $entity['vendor'] = $product->vendor()->exists() ? $product->vendor->name : '';
|
||||
// }
|
||||
|
||||
// if (array_key_exists('project_id', $this->input['report_keys'])) {
|
||||
// $entity['project'] = $product->project()->exists() ? $product->project->name : '';
|
||||
// }
|
||||
// // if (array_key_exists('project_id', $this->input['report_keys'])) {
|
||||
// // $entity['project'] = $product->project()->exists() ? $product->project->name : '';
|
||||
// // }
|
||||
|
||||
return $entity;
|
||||
}
|
||||
// return $entity;
|
||||
// }
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ class ProductSalesExport extends BaseExport
|
||||
{
|
||||
public string $date_key = 'created_at';
|
||||
|
||||
/** @var Collection<\App\Models\Product> $products*/
|
||||
protected Collection $products;
|
||||
|
||||
public Writer $csv;
|
||||
@ -65,11 +66,11 @@ class ProductSalesExport extends BaseExport
|
||||
'custom_value4' => 'custom_value4',
|
||||
];
|
||||
|
||||
private array $decorate_keys = [
|
||||
'client',
|
||||
'currency',
|
||||
'date',
|
||||
];
|
||||
// private array $decorate_keys = [
|
||||
// 'client',
|
||||
// 'currency',
|
||||
// 'date',
|
||||
// ];
|
||||
|
||||
public function __construct(Company $company, array $input)
|
||||
{
|
||||
@ -80,20 +81,20 @@ class ProductSalesExport extends BaseExport
|
||||
|
||||
public function filterByProducts($query)
|
||||
{
|
||||
|
||||
|
||||
$product_keys = &$this->input['product_key'];
|
||||
|
||||
if ($product_keys && !empty($this->input['product_key'])) {
|
||||
|
||||
$keys = explode(",", $product_keys);
|
||||
$query->where(function ($q) use ($keys){
|
||||
$query->where(function ($q) use ($keys) {
|
||||
|
||||
foreach($keys as $key) {
|
||||
foreach($keys as $key) {
|
||||
$q->orWhereJsonContains('line_items', ['product_key' => $key]);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
return $query;
|
||||
@ -121,7 +122,7 @@ class ProductSalesExport extends BaseExport
|
||||
//insert the header
|
||||
$query = Invoice::query()
|
||||
->withTrashed()
|
||||
->whereHas('client', function ($q){
|
||||
->whereHas('client', function ($q) {
|
||||
$q->where('is_deleted', false);
|
||||
})
|
||||
->where('company_id', $this->company->id)
|
||||
@ -138,30 +139,29 @@ class ProductSalesExport extends BaseExport
|
||||
|
||||
$product_keys = &$this->input['product_key'];
|
||||
|
||||
if($product_keys){
|
||||
if($product_keys) {
|
||||
$product_keys = explode(",", $product_keys);
|
||||
}
|
||||
|
||||
$query->cursor()
|
||||
->each(function ($invoice) use($product_keys) {
|
||||
->each(function ($invoice) use ($product_keys) {
|
||||
foreach ($invoice->line_items as $item) {
|
||||
|
||||
if($product_keys)
|
||||
{
|
||||
if(in_array($item->product_key, $product_keys))
|
||||
$this->csv->insertOne($this->buildRow($invoice, $item));
|
||||
}
|
||||
else {
|
||||
$this->csv->insertOne($this->buildRow($invoice, $item));
|
||||
}
|
||||
|
||||
if($product_keys) {
|
||||
if(in_array($item->product_key, $product_keys)) {
|
||||
$this->csv->insertOne($this->buildRow($invoice, $item));
|
||||
}
|
||||
} else {
|
||||
$this->csv->insertOne($this->buildRow($invoice, $item));
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
$grouped = $this->sales->groupBy('product_key')->map(function ($key, $value) use($product_keys){
|
||||
$grouped = $this->sales->groupBy('product_key')->map(function ($key, $value) use ($product_keys) {
|
||||
|
||||
if($product_keys && !in_array($value, $product_keys)){
|
||||
if($product_keys && !in_array($value, $product_keys)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -185,7 +185,8 @@ class ProductSalesExport extends BaseExport
|
||||
|
||||
})->reject(function ($value) {
|
||||
return $value === false;
|
||||
});;
|
||||
});
|
||||
;
|
||||
|
||||
$this->csv->insertOne([]);
|
||||
$this->csv->insertOne([]);
|
||||
@ -327,10 +328,10 @@ class ProductSalesExport extends BaseExport
|
||||
* getProduct
|
||||
*
|
||||
* @param string $product_key
|
||||
* @return Product
|
||||
* @return ?\Illuminate\Database\Eloquent\Model
|
||||
*/
|
||||
private function getProduct(string $product_key): ?Product
|
||||
{
|
||||
return $this->products->firstWhere('product_key', $product_key);
|
||||
}
|
||||
// private function getProduct(string $product_key)
|
||||
// {
|
||||
// return $this->products->firstWhere('product_key', $product_key);
|
||||
// }
|
||||
}
|
||||
|
@ -58,12 +58,12 @@ class PurchaseOrderExport extends BaseExport
|
||||
$query = PurchaseOrder::query()
|
||||
->withTrashed()
|
||||
->with('vendor')
|
||||
->whereHas('vendor', function ($q){
|
||||
->whereHas('vendor', function ($q) {
|
||||
$q->where('is_deleted', false);
|
||||
})
|
||||
->where('company_id', $this->company->id);
|
||||
|
||||
if(!$this->input['include_deleted'] ?? false){
|
||||
|
||||
if(!$this->input['include_deleted'] ?? false) {
|
||||
$query->where('is_deleted', 0);
|
||||
}
|
||||
|
||||
@ -72,8 +72,9 @@ class PurchaseOrderExport extends BaseExport
|
||||
|
||||
$clients = &$this->input['client_id'];
|
||||
|
||||
if($clients)
|
||||
if($clients) {
|
||||
$query = $this->addClientFilter($query, $clients);
|
||||
}
|
||||
|
||||
$query = $this->addPurchaseOrderStatusFilter($query, $this->input['status'] ?? '');
|
||||
|
||||
|
@ -62,12 +62,12 @@ class PurchaseOrderItemExport extends BaseExport
|
||||
|
||||
$query = PurchaseOrder::query()
|
||||
->withTrashed()
|
||||
->whereHas('vendor', function ($q){
|
||||
->whereHas('vendor', function ($q) {
|
||||
$q->where('is_deleted', false);
|
||||
})
|
||||
->with('vendor')->where('company_id', $this->company->id);
|
||||
|
||||
if(!$this->input['include_deleted'] ?? false){
|
||||
|
||||
if(!$this->input['include_deleted'] ?? false) {
|
||||
$query->where('is_deleted', 0);
|
||||
}
|
||||
|
||||
|
@ -31,11 +31,11 @@ class QuoteExport extends BaseExport
|
||||
|
||||
private Decorator $decorator;
|
||||
|
||||
private array $decorate_keys = [
|
||||
'client',
|
||||
'currency',
|
||||
'invoice',
|
||||
];
|
||||
// private array $decorate_keys = [
|
||||
// 'client',
|
||||
// 'currency',
|
||||
// 'invoice',
|
||||
// ];
|
||||
|
||||
public function __construct(Company $company, array $input)
|
||||
{
|
||||
@ -64,12 +64,12 @@ class QuoteExport extends BaseExport
|
||||
$query = Quote::query()
|
||||
->withTrashed()
|
||||
->with('client')
|
||||
->whereHas('client', function ($q){
|
||||
->whereHas('client', function ($q) {
|
||||
$q->where('is_deleted', false);
|
||||
})
|
||||
->where('company_id', $this->company->id);
|
||||
|
||||
if(!$this->input['include_deleted'] ?? false){
|
||||
|
||||
if(!$this->input['include_deleted'] ?? false) {
|
||||
$query->where('is_deleted', 0);
|
||||
}
|
||||
|
||||
|
@ -65,12 +65,12 @@ class QuoteItemExport extends BaseExport
|
||||
|
||||
$query = Quote::query()
|
||||
->withTrashed()
|
||||
->whereHas('client', function ($q){
|
||||
->whereHas('client', function ($q) {
|
||||
$q->where('is_deleted', false);
|
||||
})
|
||||
->with('client')->where('company_id', $this->company->id);
|
||||
|
||||
if(!$this->input['include_deleted'] ?? false){
|
||||
|
||||
if(!$this->input['include_deleted'] ?? false) {
|
||||
$query->where('is_deleted', 0);
|
||||
}
|
||||
|
||||
|
@ -56,12 +56,12 @@ class RecurringInvoiceExport extends BaseExport
|
||||
$query = RecurringInvoice::query()
|
||||
->withTrashed()
|
||||
->with('client')
|
||||
->whereHas('client', function ($q){
|
||||
->whereHas('client', function ($q) {
|
||||
$q->where('is_deleted', false);
|
||||
})
|
||||
->where('company_id', $this->company->id);
|
||||
|
||||
if(!$this->input['include_deleted'] ?? false){
|
||||
|
||||
if(!$this->input['include_deleted'] ?? false) {
|
||||
$query->where('is_deleted', 0);
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@ class TaskExport extends BaseExport
|
||||
|
||||
public string $date_key = 'created_at';
|
||||
|
||||
private string $date_format = 'YYYY-MM-DD';
|
||||
private string $date_format = 'Y-m-d';
|
||||
|
||||
public Writer $csv;
|
||||
|
||||
@ -69,22 +69,24 @@ class TaskExport extends BaseExport
|
||||
$query = Task::query()
|
||||
->withTrashed()
|
||||
->where('company_id', $this->company->id);
|
||||
|
||||
if(!$this->input['include_deleted'] ?? false){
|
||||
|
||||
if(!$this->input['include_deleted'] ?? false) {
|
||||
$query->where('is_deleted', 0);
|
||||
}
|
||||
|
||||
$query = $this->addDateRange($query);
|
||||
|
||||
|
||||
$clients = &$this->input['client_id'];
|
||||
|
||||
if($clients)
|
||||
if($clients) {
|
||||
$query = $this->addClientFilter($query, $clients);
|
||||
}
|
||||
|
||||
$document_attachments = &$this->input['document_email_attachment'];
|
||||
|
||||
if($document_attachments)
|
||||
if($document_attachments) {
|
||||
$this->queueDocuments($query);
|
||||
}
|
||||
|
||||
return $query;
|
||||
|
||||
@ -178,13 +180,7 @@ class TaskExport extends BaseExport
|
||||
|
||||
$logs = json_decode($task->time_log, 1);
|
||||
|
||||
$date_format_default = 'Y-m-d';
|
||||
|
||||
$date_format = DateFormat::find($task->company->settings->date_format_id);
|
||||
|
||||
if ($date_format) {
|
||||
$date_format_default = $date_format->format;
|
||||
}
|
||||
$date_format_default = $this->date_format;
|
||||
|
||||
foreach ($logs as $key => $item) {
|
||||
if (in_array('task.start_date', $this->input['report_keys']) || in_array('start_date', $this->input['report_keys'])) {
|
||||
@ -224,7 +220,7 @@ class TaskExport extends BaseExport
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add Task Status Filter
|
||||
*
|
||||
@ -234,7 +230,7 @@ class TaskExport extends BaseExport
|
||||
*/
|
||||
protected function addTaskStatusFilter(Builder $query, string $status): Builder
|
||||
{
|
||||
|
||||
/** @var array $status_parameters */
|
||||
$status_parameters = explode(',', $status);
|
||||
|
||||
if (in_array('all', $status_parameters) || count($status_parameters) == 0) {
|
||||
|
@ -63,8 +63,8 @@ class VendorExport extends BaseExport
|
||||
$query = Vendor::query()->with('contacts')
|
||||
->withTrashed()
|
||||
->where('company_id', $this->company->id);
|
||||
|
||||
if(!$this->input['include_deleted'] ?? false){
|
||||
|
||||
if(!$this->input['include_deleted'] ?? false) {
|
||||
$query->where('is_deleted', 0);
|
||||
}
|
||||
|
||||
@ -171,16 +171,16 @@ class VendorExport extends BaseExport
|
||||
return $entity;
|
||||
}
|
||||
|
||||
private function calculateStatus($vendor)
|
||||
{
|
||||
if ($vendor->is_deleted) {
|
||||
return ctrans('texts.deleted');
|
||||
}
|
||||
// private function calculateStatus($vendor)
|
||||
// {
|
||||
// if ($vendor->is_deleted) {
|
||||
// return ctrans('texts.deleted');
|
||||
// }
|
||||
|
||||
if ($vendor->deleted_at) {
|
||||
return ctrans('texts.archived');
|
||||
}
|
||||
// if ($vendor->deleted_at) {
|
||||
// return ctrans('texts.archived');
|
||||
// }
|
||||
|
||||
return ctrans('texts.active');
|
||||
}
|
||||
// return ctrans('texts.active');
|
||||
// }
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ class ContactDecorator implements DecoratorInterface
|
||||
$contact = $entity->contacts()->first();
|
||||
} elseif($entity->client) {
|
||||
$contact = $entity->client->primary_contact->first() ?? $entity->client->contacts()->whereNotNull('email')->first();
|
||||
} elseif($entity->vendor) {
|
||||
} elseif($entity->vendor) {
|
||||
$contact = $entity->vendor->primary_contact->first() ?? $entity->vendor->contacts()->whereNotNull('email')->first();
|
||||
}
|
||||
|
||||
|
@ -23,14 +23,13 @@ class BankIntegrationFactory
|
||||
$bank_integration->company_id = $company_id;
|
||||
|
||||
$bank_integration->provider_name = '';
|
||||
$bank_integration->bank_account_id = '';
|
||||
$bank_integration->bank_account_name = '';
|
||||
$bank_integration->bank_account_number = '';
|
||||
$bank_integration->bank_account_status = '';
|
||||
$bank_integration->bank_account_type = '';
|
||||
$bank_integration->balance = 0;
|
||||
$bank_integration->currency = '';
|
||||
$bank_integration->auto_sync = 1;
|
||||
$bank_integration->auto_sync = true;
|
||||
|
||||
return $bank_integration;
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ class ClientFactory
|
||||
$client->balance = 0;
|
||||
$client->paid_to_date = 0;
|
||||
$client->country_id = null;
|
||||
$client->is_deleted = 0;
|
||||
$client->is_deleted = false;
|
||||
$client->client_hash = Str::random(40);
|
||||
$client->settings = ClientSettings::defaults();
|
||||
$client->classification = '';
|
||||
|
@ -33,7 +33,7 @@ class CloneQuoteToProjectFactory
|
||||
$project->custom_value2 = '';
|
||||
$project->custom_value3 = '';
|
||||
$project->custom_value4 = '';
|
||||
$project->is_deleted = 0;
|
||||
$project->is_deleted = false;
|
||||
|
||||
return $project;
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ class CompanyFactory
|
||||
$company->markdown_email_enabled = true;
|
||||
$company->markdown_enabled = false;
|
||||
$company->tax_data = new TaxModel();
|
||||
$company->first_month_of_year = 1;
|
||||
$company->first_month_of_year = '1';
|
||||
$company->smtp_encryption = 'tls';
|
||||
$company->smtp_host = '';
|
||||
$company->smtp_local_domain = '';
|
||||
@ -56,7 +56,7 @@ class CompanyFactory
|
||||
$company->smtp_port = '';
|
||||
$company->smtp_username = '';
|
||||
$company->smtp_verify_peer = true;
|
||||
|
||||
|
||||
return $company;
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ class CompanyGatewayFactory
|
||||
$company_gateway->require_shipping_address = false;
|
||||
$company_gateway->config = encrypt(json_encode(new \stdClass()));
|
||||
$company_gateway->always_show_required_fields = true;
|
||||
|
||||
|
||||
return $company_gateway;
|
||||
}
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ class PurchaseOrderFactory
|
||||
$purchase_order->exchange_rate = 1;
|
||||
$purchase_order->total_taxes = 0;
|
||||
$purchase_order->uses_inclusive_taxes = false;
|
||||
|
||||
|
||||
return $purchase_order;
|
||||
}
|
||||
}
|
||||
|
@ -82,11 +82,15 @@ class RecurringExpenseToExpenseFactory
|
||||
} else {
|
||||
$locale = $recurring_expense->company->locale();
|
||||
|
||||
$date_formats = Cache::get('date_formats');
|
||||
//@deprecated
|
||||
// $date_formats = Cache::get('date_formats');
|
||||
|
||||
$date_format = $date_formats->filter(function ($item) use ($recurring_expense) {
|
||||
/** @var \Illuminate\Support\Collection<\App\Models\DateFormat> */
|
||||
$date_formats = app('date_formats');
|
||||
|
||||
$date_format = $date_formats->first(function ($item) use ($recurring_expense) {
|
||||
return $item->id == $recurring_expense->company->settings->date_format_id;
|
||||
})->first()->format;
|
||||
})->format;
|
||||
}
|
||||
|
||||
Carbon::setLocale($locale);
|
||||
@ -144,7 +148,7 @@ class RecurringExpenseToExpenseFactory
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Str::contains($match, '|')) {
|
||||
// if (Str::contains($match, '|')) {
|
||||
$parts = explode('|', $match); // [ '[MONTH', 'MONTH+2]' ]
|
||||
|
||||
$left = substr($parts[0], 1); // 'MONTH'
|
||||
@ -182,7 +186,7 @@ class RecurringExpenseToExpenseFactory
|
||||
$value,
|
||||
1
|
||||
);
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
// Second case with more common calculations.
|
||||
|
@ -23,7 +23,7 @@ class SubscriptionFactory
|
||||
$billing_subscription->company_id = $company_id;
|
||||
$billing_subscription->user_id = $user_id;
|
||||
$billing_subscription->steps = collect(Purchase::defaultSteps())
|
||||
->map(fn($step) => StepService::mapClassNameToString($step))
|
||||
->map(fn ($step) => StepService::mapClassNameToString($step))
|
||||
->implode(',');
|
||||
|
||||
return $billing_subscription;
|
||||
|
@ -20,7 +20,7 @@ class TaxRateFactory
|
||||
$tax_rate = new TaxRate();
|
||||
|
||||
$tax_rate->name = '';
|
||||
$tax_rate->rate = '';
|
||||
$tax_rate->rate = 0;
|
||||
$tax_rate->company_id = $company_id;
|
||||
$tax_rate->user_id = $user_id;
|
||||
|
||||
|
@ -26,7 +26,7 @@ class VendorFactory
|
||||
$vendor->private_notes = '';
|
||||
$vendor->public_notes = '';
|
||||
$vendor->country_id = 4;
|
||||
$vendor->is_deleted = 0;
|
||||
$vendor->is_deleted = false;
|
||||
$vendor->vendor_hash = Str::random(40);
|
||||
// $vendor->classification = '';
|
||||
|
||||
|
@ -115,6 +115,29 @@ class BankTransactionFilters extends QueryFilters
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Filters the list based on Bank Accounts.
|
||||
*
|
||||
* @param string $ids Comma Separated List of bank account ids
|
||||
* @return Builder
|
||||
*/
|
||||
public function bank_integration_ids(string $ids = ''): Builder
|
||||
{
|
||||
if(strlen($ids) == 0) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
$ids = $this->transformKeys(explode(",", $ids));
|
||||
|
||||
$this->builder->where(function ($query) use ($ids) {
|
||||
$query->whereIn('bank_integration_id', $ids);
|
||||
});
|
||||
|
||||
return $this->builder;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the list based on $sort.
|
||||
*
|
||||
|
@ -160,8 +160,9 @@ class ClientFilters extends QueryFilters
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
if($sort_col[0] == 'documents')
|
||||
if($sort_col[0] == 'documents') {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
if ($sort_col[0] == 'display_name') {
|
||||
$sort_col[0] = 'name';
|
||||
|
@ -58,10 +58,11 @@ class DesignFilters extends QueryFilters
|
||||
|
||||
public function entities(string $entities = ''): Builder
|
||||
{
|
||||
|
||||
if(stripos($entities, 'statement') !== false)
|
||||
|
||||
if(stripos($entities, 'statement') !== false) {
|
||||
$entities = 'client';
|
||||
|
||||
}
|
||||
|
||||
if (strlen($entities) == 0 || str_contains($entities, ',')) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
@ -49,22 +49,22 @@ class DocumentFilters extends QueryFilters
|
||||
*/
|
||||
public function client_id(string $client_id = ''): Builder
|
||||
{
|
||||
|
||||
|
||||
return $this->builder->where(function ($query) use ($client_id) {
|
||||
$query->whereHasMorph('documentable', [
|
||||
\App\Models\Invoice::class,
|
||||
\App\Models\Quote::class,
|
||||
\App\Models\Credit::class,
|
||||
\App\Models\Expense::class,
|
||||
\App\Models\Payment::class,
|
||||
\App\Models\Invoice::class,
|
||||
\App\Models\Quote::class,
|
||||
\App\Models\Credit::class,
|
||||
\App\Models\Expense::class,
|
||||
\App\Models\Payment::class,
|
||||
\App\Models\Task::class,
|
||||
\App\Models\RecurringExpense::class,
|
||||
\App\Models\RecurringInvoice::class,
|
||||
\App\Models\Project::class,
|
||||
], function ($q2) use ($client_id) {
|
||||
$q2->where('client_id', $this->decodePrimaryKey($client_id));
|
||||
})->orWhereHasMorph('documentable', [\App\Models\Client::class], function ($q3) use ($client_id) {
|
||||
$q3->where('id', $this->decodePrimaryKey($client_id));
|
||||
$q2->where('client_id', $this->decodePrimaryKey($client_id));
|
||||
})->orWhereHasMorph('documentable', [\App\Models\Client::class], function ($q3) use ($client_id) {
|
||||
$q3->where('id', $this->decodePrimaryKey($client_id));
|
||||
});
|
||||
});
|
||||
|
||||
@ -74,8 +74,7 @@ class DocumentFilters extends QueryFilters
|
||||
{
|
||||
$types = explode(',', $types);
|
||||
|
||||
foreach ($types as $type)
|
||||
{
|
||||
foreach ($types as $type) {
|
||||
match($type) {
|
||||
'private' => $this->builder->where('is_public', 0),
|
||||
'public' => $this->builder->where('is_public', 1),
|
||||
@ -87,7 +86,7 @@ class DocumentFilters extends QueryFilters
|
||||
}
|
||||
|
||||
return $this->builder;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the list based on $sort.
|
||||
|
@ -79,7 +79,7 @@ class ExpenseFilters extends QueryFilters
|
||||
$this->builder->where(function ($query) use ($status_parameters) {
|
||||
if (in_array('logged', $status_parameters)) {
|
||||
$query->orWhere(function ($query) {
|
||||
$query->where('amount', '>', 0)
|
||||
$query->where('amount', '>=', 0)
|
||||
->whereNull('invoice_id')
|
||||
->whereNull('payment_date')
|
||||
->where('should_be_invoiced', false);
|
||||
@ -111,8 +111,8 @@ class ExpenseFilters extends QueryFilters
|
||||
});
|
||||
}
|
||||
|
||||
if(in_array('uncategorized', $status_parameters)){
|
||||
$query->orWhere(function ($query){
|
||||
if(in_array('uncategorized', $status_parameters)) {
|
||||
$query->orWhere(function ($query) {
|
||||
$query->whereNull('category_id');
|
||||
});
|
||||
}
|
||||
|
@ -228,10 +228,9 @@ class InvoiceFilters extends QueryFilters
|
||||
$date = Carbon::createFromTimestamp((int)$date);
|
||||
} else {
|
||||
|
||||
try{
|
||||
try {
|
||||
$date = Carbon::parse($date);
|
||||
}
|
||||
catch(\Exception $e){
|
||||
} catch(\Exception $e) {
|
||||
return $this->builder;
|
||||
}
|
||||
}
|
||||
@ -272,6 +271,7 @@ class InvoiceFilters extends QueryFilters
|
||||
if (count($parts) != 2) {
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
$start_date = Carbon::parse($parts[0]);
|
||||
@ -282,7 +282,6 @@ class InvoiceFilters extends QueryFilters
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -308,7 +307,6 @@ class InvoiceFilters extends QueryFilters
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
|
||||
@ -339,7 +337,7 @@ class InvoiceFilters extends QueryFilters
|
||||
// return $this->builder->orderByRaw('CAST(number AS UNSIGNED), number ' . $dir);
|
||||
// return $this->builder->orderByRaw("number REGEXP '^[A-Za-z]+$',CAST(number as SIGNED INTEGER),CAST(REPLACE(number,'-','')AS SIGNED INTEGER) ,number");
|
||||
// return $this->builder->orderByRaw('ABS(number) ' . $dir);
|
||||
return $this->builder->orderByRaw("REGEXP_REPLACE(number,'[^0-9]+','')+0 " . $dir);
|
||||
return $this->builder->orderByRaw("REGEXP_REPLACE(number,'[^0-9]+','')+0 " . $dir);
|
||||
}
|
||||
|
||||
return $this->builder->orderBy($sort_col[0], $dir);
|
||||
|
@ -204,7 +204,6 @@ class PaymentFilters extends QueryFilters
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -133,7 +133,11 @@ class RecurringInvoiceFilters extends QueryFilters
|
||||
return $this->builder->orderByRaw("REGEXP_REPLACE(number,'[^0-9]+','')+0 " . $dir);
|
||||
}
|
||||
|
||||
if($sort_col[0] == 'next_send_datetime'){
|
||||
if($sort_col[0] == 'status_id'){
|
||||
return $this->builder->orderBy('status_id', $dir)->orderBy('last_sent_date', $dir);
|
||||
}
|
||||
|
||||
if($sort_col[0] == 'next_send_datetime') {
|
||||
$sort_col[0] = 'next_send_date';
|
||||
}
|
||||
|
||||
@ -162,9 +166,10 @@ class RecurringInvoiceFilters extends QueryFilters
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
/** @var array $key_parameters */
|
||||
$key_parameters = explode(',', $value);
|
||||
|
||||
if (count($key_parameters)) {
|
||||
if (count($key_parameters) > 0) {
|
||||
return $this->builder->where(function ($query) use ($key_parameters) {
|
||||
foreach ($key_parameters as $key) {
|
||||
$query->orWhereJsonContains('line_items', ['product_key' => $key]);
|
||||
@ -183,6 +188,7 @@ class RecurringInvoiceFilters extends QueryFilters
|
||||
*/
|
||||
public function next_send_between(string $range = ''): Builder
|
||||
{
|
||||
/** @var array $parts */
|
||||
$parts = explode('|', $range);
|
||||
|
||||
if (!isset($parts[0]) || !isset($parts[1])) {
|
||||
|
@ -88,7 +88,7 @@ class TaskFilters extends QueryFilters
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
public function project_tasks($project): Builder
|
||||
public function project_tasks(string $project = ''): Builder
|
||||
{
|
||||
if (strlen($project) == 0) {
|
||||
return $this->builder;
|
||||
@ -175,6 +175,7 @@ class TaskFilters extends QueryFilters
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
/** @var array $status_parameters */
|
||||
$status_parameters = explode(',', $value);
|
||||
|
||||
if(count($status_parameters) >= 1) {
|
||||
|
@ -100,7 +100,7 @@ class Nordigen
|
||||
} catch (\Exception $e) {
|
||||
|
||||
nlog("Nordigen getAccount() failed => {$account_id} => " . $e->getMessage());
|
||||
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
@ -151,9 +151,10 @@ class Nordigen
|
||||
public function disabledAccountEmail(BankIntegration $bank_integration): void
|
||||
{
|
||||
$cache_key = "email_quota:{$bank_integration->company->company_key}:{$bank_integration->id}";
|
||||
|
||||
if(Cache::has($cache_key))
|
||||
|
||||
if(Cache::has($cache_key)) {
|
||||
return;
|
||||
}
|
||||
|
||||
App::setLocale($bank_integration->company->getLocale());
|
||||
|
||||
@ -168,7 +169,7 @@ class Nordigen
|
||||
$mo->email_template_subject = 'nordigen_requisition_subject';
|
||||
|
||||
Email::dispatch($mo, $bank_integration->company);
|
||||
|
||||
|
||||
Cache::put($cache_key, true, 60 * 60 * 24);
|
||||
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ class TransactionTransformer implements BankRevenueInterface
|
||||
|
||||
private Company $company;
|
||||
|
||||
function __construct(Company $company)
|
||||
public function __construct(Company $company)
|
||||
{
|
||||
$this->company = $company;
|
||||
}
|
||||
@ -156,22 +156,16 @@ class TransactionTransformer implements BankRevenueInterface
|
||||
private function convertCurrency(string $code)
|
||||
{
|
||||
|
||||
$currencies = Cache::get('currencies');
|
||||
$currencies = app('currencies');
|
||||
|
||||
if (!$currencies) {
|
||||
$this->buildCache(true);
|
||||
}
|
||||
|
||||
$currency = $currencies->filter(function ($item) use ($code) {
|
||||
$currency = $currencies->first(function ($item) use ($code) {
|
||||
/** @var \App\Models\Currency $item */
|
||||
return $item->code == $code;
|
||||
})->first();
|
||||
|
||||
if ($currency) {
|
||||
return $currency->id;
|
||||
}
|
||||
|
||||
return 1;
|
||||
});
|
||||
|
||||
/** @var \App\Models\Currency $currency */
|
||||
return $currency ? $currency->id : 1; //@phpstan-ignore-line
|
||||
|
||||
}
|
||||
|
||||
private function formatDate(string $input)
|
||||
@ -192,7 +186,7 @@ class TransactionTransformer implements BankRevenueInterface
|
||||
}
|
||||
|
||||
try {
|
||||
return Carbon::createFromFormat("d-m-Y", $input)->setTimezone($timezone_name)->format($date_format_default) ?? $input;
|
||||
return Carbon::createFromFormat("d-m-Y", $input)->setTimezone($timezone_name)->format($date_format_default);
|
||||
} catch (\Exception $e) {
|
||||
return $input;
|
||||
}
|
||||
|
@ -1,111 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2024. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\Helpers\Bank\Yodlee\DTO;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
use Spatie\LaravelData\Attributes\MapInputName;
|
||||
use Spatie\LaravelData\Data;
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* [
|
||||
"account": [
|
||||
[
|
||||
"CONTAINER": "bank",
|
||||
"providerAccountId": 1005,
|
||||
"accountName": "Business Acct",
|
||||
"accountStatus": "ACTIVE",
|
||||
"accountNumber": "1011",
|
||||
"aggregationSource": "USER",
|
||||
"isAsset": true,
|
||||
"balance": [
|
||||
"currency": "AUD",
|
||||
"amount": 304.98,
|
||||
],
|
||||
"id": 10139315,
|
||||
"includeInNetWorth": true,
|
||||
"providerId": "3857",
|
||||
"providerName": "Bank",
|
||||
"isManual": false,
|
||||
"availableBalance": {#2966
|
||||
"currency": "AUD",
|
||||
"amount": 304.98,
|
||||
],
|
||||
"currentBalance": [
|
||||
"currency": "AUD",
|
||||
"amount": 3044.98,
|
||||
],
|
||||
"accountType": "CHECKING",
|
||||
"displayedName": "after David",
|
||||
"createdDate": "2023-01-10T08:29:07Z",
|
||||
"classification": "SMALL_BUSINESS",
|
||||
"lastUpdated": "2023-08-01T23:50:13Z",
|
||||
"nickname": "Business ",
|
||||
"bankTransferCode": [
|
||||
[
|
||||
"id": "062",
|
||||
"type": "BSB",
|
||||
],
|
||||
],
|
||||
"dataset": [
|
||||
[
|
||||
"name": "BASIC_AGG_DATA",
|
||||
"additionalStatus": "AVAILABLE_DATA_RETRIEVED",
|
||||
"updateEligibility": "ALLOW_UPDATE",
|
||||
"lastUpdated": "2023-08-01T23:49:53Z",
|
||||
"lastUpdateAttempt": "2023-08-01T23:49:53Z",
|
||||
"nextUpdateScheduled": "2023-08-03T14:45:14Z",
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
*/
|
||||
class AccountSummary extends Data
|
||||
{
|
||||
public ?int $id;
|
||||
|
||||
#[MapInputName('CONTAINER')]
|
||||
public ?string $account_type = '';
|
||||
|
||||
#[MapInputName('accountName')]
|
||||
public ?string $account_name = '';
|
||||
|
||||
#[MapInputName('accountStatus')]
|
||||
public ?string $account_status = '';
|
||||
|
||||
#[MapInputName('accountNumber')]
|
||||
public ?string $account_number = '';
|
||||
|
||||
#[MapInputName('providerAccountId')]
|
||||
public int $provider_account_id;
|
||||
|
||||
#[MapInputName('providerId')]
|
||||
public ?string $provider_id = '';
|
||||
|
||||
#[MapInputName('providerName')]
|
||||
public ?string $provider_name = '';
|
||||
|
||||
public ?string $nickname = '';
|
||||
|
||||
public ?float $current_balance = 0;
|
||||
public ?string $account_currency = '';
|
||||
|
||||
public static function prepareForPipeline(Collection $properties): Collection
|
||||
{
|
||||
|
||||
$properties->put('current_balance', $properties['currentBalance']['amount'] ?? 0);
|
||||
$properties->put('account_currency', $properties['currentBalance']['currency'] ?? 0);
|
||||
|
||||
return $properties;
|
||||
}
|
||||
}
|
@ -171,20 +171,16 @@ class IncomeTransformer implements BankRevenueInterface
|
||||
|
||||
private function convertCurrency(string $code)
|
||||
{
|
||||
$currencies = Cache::get('currencies');
|
||||
|
||||
if (! $currencies) {
|
||||
$this->buildCache(true);
|
||||
}
|
||||
$currencies = app('currencies');
|
||||
|
||||
$currency = $currencies->filter(function ($item) use ($code) {
|
||||
$currency = $currencies->first(function ($item) use ($code) {
|
||||
/** @var \App\Models\Currency $item */
|
||||
return $item->code == $code;
|
||||
})->first();
|
||||
});
|
||||
|
||||
if ($currency) {
|
||||
return $currency->id;
|
||||
}
|
||||
/** @var \App\Models\Currency $currency */
|
||||
return $currency ? $currency->id : 1; //@phpstan-ignore-line
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -26,15 +26,15 @@ use BaconQrCode\Writer;
|
||||
*/
|
||||
class EpcQrGenerator
|
||||
{
|
||||
private array $sepa = [
|
||||
'serviceTag' => 'BCD',
|
||||
'version' => 2,
|
||||
'characterSet' => 1,
|
||||
'identification' => 'SCT',
|
||||
'bic' => '',
|
||||
'purpose' => '',
|
||||
// private array $sepa = [
|
||||
// 'serviceTag' => 'BCD',
|
||||
// 'version' => 2,
|
||||
// 'characterSet' => 1,
|
||||
// 'identification' => 'SCT',
|
||||
// 'bic' => '',
|
||||
// 'purpose' => '',
|
||||
|
||||
];
|
||||
// ];
|
||||
|
||||
public function __construct(protected Company $company, protected Invoice|RecurringInvoice $invoice, protected float $amount)
|
||||
{
|
||||
@ -59,36 +59,47 @@ class EpcQrGenerator
|
||||
<rect x='0' y='0' width='100%'' height='100%' />{$qr}</svg>";
|
||||
|
||||
} catch(\Throwable $e) {
|
||||
// nlog("EPC QR failure => ".$e->getMessage());
|
||||
nlog("EPC QR failure => ".$e->getMessage());
|
||||
return '';
|
||||
} catch(\Exception $e) {
|
||||
// nlog("EPC QR failure => ".$e->getMessage());
|
||||
return '';
|
||||
} catch(InvalidArgumentException $e) {
|
||||
// nlog("EPC QR failure => ".$e->getMessage());
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function encodeMessage()
|
||||
{
|
||||
return rtrim(implode("\n", [
|
||||
$this->sepa['serviceTag'],
|
||||
sprintf('%03d', $this->sepa['version']),
|
||||
$this->sepa['characterSet'],
|
||||
$this->sepa['identification'],
|
||||
isset($this->company?->custom_fields?->company2) ? $this->company->settings->custom_value2 : '',
|
||||
$this->company->present()->name(),
|
||||
isset($this->company?->custom_fields?->company1) ? $this->company->settings->custom_value1 : '',
|
||||
$this->formatMoney($this->amount),
|
||||
$this->sepa['purpose'],
|
||||
substr($this->invoice->number, 0, 34),
|
||||
'',
|
||||
' '
|
||||
]), "\n");
|
||||
// return rtrim(implode("\n", [
|
||||
// $this->sepa['serviceTag'],
|
||||
// sprintf('%03d', $this->sepa['version']),
|
||||
// $this->sepa['characterSet'],
|
||||
// $this->sepa['identification'],
|
||||
// isset($this->company?->custom_fields?->company2) ? $this->company->settings->custom_value2 : '',
|
||||
// $this->company->present()->name(),
|
||||
// isset($this->company?->custom_fields?->company1) ? $this->company->settings->custom_value1 : '',
|
||||
// $this->formatMoney($this->amount),
|
||||
// $this->sepa['purpose'],
|
||||
// substr($this->invoice->number, 0, 34),
|
||||
// '',
|
||||
// ' '
|
||||
// ]), "\n");
|
||||
|
||||
|
||||
$data = [
|
||||
'BCD',
|
||||
'002', // Version
|
||||
'1', // Encoding: 1 = UTF-8
|
||||
'SCT', // Service Tag: SEPA Credit Transfer
|
||||
isset($this->company?->custom_fields?->company2) ? $this->company->settings->custom_value2 : '', // BIC
|
||||
$this->company->present()->name(), // Name of the beneficiary
|
||||
isset($this->company?->custom_fields?->company1) ? $this->company->settings->custom_value1 : '', // IBAN
|
||||
$this->formatMoney($this->amount), // Amount with EUR prefix
|
||||
'', // Reference
|
||||
substr($this->invoice->number, 0, 34) // Unstructured remittance information
|
||||
];
|
||||
|
||||
return implode("\n", $data);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// substr("{$this->invoice->number} {$this->invoice->client->number}", 0,139),
|
||||
|
||||
|
@ -27,7 +27,7 @@ trait CustomValuer
|
||||
|
||||
public function valuerTax($custom_value, $has_custom_invoice_taxes)
|
||||
{
|
||||
|
||||
|
||||
if (isset($custom_value) && is_numeric($custom_value) && $has_custom_invoice_taxes !== false) {
|
||||
return round($custom_value * ($this->invoice->tax_rate1 / 100), 2) + round($custom_value * ($this->invoice->tax_rate2 / 100), 2) + round($custom_value * ($this->invoice->tax_rate3 / 100), 2);
|
||||
}
|
||||
@ -35,17 +35,18 @@ trait CustomValuer
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function multiInclusiveTax($custom_value, $has_custom_invoice_taxes) {
|
||||
public function multiInclusiveTax($custom_value, $has_custom_invoice_taxes)
|
||||
{
|
||||
|
||||
if (isset($custom_value) && is_numeric($custom_value) && $has_custom_invoice_taxes !== false) {
|
||||
|
||||
$tax = 0;
|
||||
$tax = 0;
|
||||
|
||||
$tax += $this->formatValue($custom_value - ($custom_value / (1 + ($this->invoice->tax_rate1 / 100))), 2);
|
||||
$tax += $this->formatValue($custom_value - ($custom_value / (1 + ($this->invoice->tax_rate2 / 100))), 2);
|
||||
$tax += $this->formatValue($custom_value - ($custom_value / (1 + ($this->invoice->tax_rate3 / 100))), 2);
|
||||
$tax += $this->formatValue($custom_value - ($custom_value / (1 + ($this->invoice->tax_rate1 / 100))), 2);
|
||||
$tax += $this->formatValue($custom_value - ($custom_value / (1 + ($this->invoice->tax_rate2 / 100))), 2);
|
||||
$tax += $this->formatValue($custom_value - ($custom_value / (1 + ($this->invoice->tax_rate3 / 100))), 2);
|
||||
|
||||
return round($tax,2);
|
||||
return round($tax, 2);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -29,6 +29,7 @@ class InvoiceItemSum
|
||||
use Discounter;
|
||||
use Taxer;
|
||||
|
||||
//@phpstan-ignore-next-line
|
||||
private array $eu_tax_jurisdictions = [
|
||||
'AT', // Austria
|
||||
'BE', // Belgium
|
||||
@ -170,7 +171,7 @@ class InvoiceItemSum
|
||||
private function shouldCalculateTax(): self
|
||||
{
|
||||
|
||||
if (!$this->invoice->company?->calculate_taxes || $this->invoice->company->account->isFreeHostedClient()) {
|
||||
if (!$this->invoice->company?->calculate_taxes || $this->invoice->company->account->isFreeHostedClient()) { //@phpstan-ignore-line
|
||||
$this->calc_tax = false;
|
||||
return $this;
|
||||
}
|
||||
@ -182,7 +183,7 @@ class InvoiceItemSum
|
||||
$class = "App\DataMapper\Tax\\".$this->client->company->country()->iso_3166_2."\\Rule";
|
||||
|
||||
$this->rule = new $class();
|
||||
|
||||
|
||||
if($this->rule->regionWithNoTaxCoverage($this->client->country->iso_3166_2)) {
|
||||
return $this;
|
||||
}
|
||||
@ -331,7 +332,7 @@ class InvoiceItemSum
|
||||
|
||||
public function setLineTotal($total)
|
||||
{
|
||||
$this->item->line_total = $total;
|
||||
$this->item->line_total = (float) $total;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ class InvoiceItemSumInclusive
|
||||
use Discounter;
|
||||
use Taxer;
|
||||
|
||||
|
||||
//@phpstan-ignore-next-line
|
||||
private array $eu_tax_jurisdictions = [
|
||||
'AT', // Austria
|
||||
'BE', // Belgium
|
||||
@ -98,6 +98,7 @@ class InvoiceItemSumInclusive
|
||||
|
||||
private $total_taxes;
|
||||
|
||||
/** @phpstan-ignore-next-line */
|
||||
private $item;
|
||||
|
||||
private $line_items;
|
||||
@ -399,7 +400,7 @@ class InvoiceItemSumInclusive
|
||||
private function shouldCalculateTax(): self
|
||||
{
|
||||
|
||||
if (!$this->invoice->company?->calculate_taxes || $this->invoice->company->account->isFreeHostedClient()) {
|
||||
if (!$this->invoice->company?->calculate_taxes || $this->invoice->company->account->isFreeHostedClient()) {//@phpstan-ignore-line
|
||||
$this->calc_tax = false;
|
||||
return $this;
|
||||
}
|
||||
|
@ -229,7 +229,7 @@ class InvoiceSum
|
||||
{
|
||||
// $this->invoice->amount = $this->formatValue($this->getTotal(), $this->precision);
|
||||
// $this->invoice->total_taxes = $this->getTotalTaxes();
|
||||
|
||||
|
||||
$this->setCalculatedAttributes();
|
||||
$this->invoice->balance = $this->invoice->amount;
|
||||
$this->invoice->saveQuietly();
|
||||
@ -245,10 +245,9 @@ class InvoiceSum
|
||||
*/
|
||||
private function setCalculatedAttributes(): self
|
||||
{
|
||||
if($this->invoice->status_id == Invoice::STATUS_CANCELLED){
|
||||
if($this->invoice->status_id == Invoice::STATUS_CANCELLED) {
|
||||
$this->invoice->balance = 0;
|
||||
}
|
||||
elseif ($this->invoice->status_id != Invoice::STATUS_DRAFT) {
|
||||
} elseif ($this->invoice->status_id != Invoice::STATUS_DRAFT) {
|
||||
if ($this->invoice->amount != $this->invoice->balance) {
|
||||
$this->invoice->balance = Number::roundValue($this->getTotal(), $this->precision) - $this->invoice->paid_to_date; //21-02-2024 cannot use the calculated $paid_to_date here as it could send the balance backward.
|
||||
} else {
|
||||
@ -258,7 +257,7 @@ class InvoiceSum
|
||||
/* Set new calculated total */
|
||||
$this->invoice->amount = $this->formatValue($this->getTotal(), $this->precision);
|
||||
|
||||
if($this->rappen_rounding){
|
||||
if($this->rappen_rounding) {
|
||||
$this->invoice->amount = $this->roundRappen($this->invoice->amount);
|
||||
$this->invoice->balance = $this->roundRappen($this->invoice->balance);
|
||||
}
|
||||
@ -269,7 +268,7 @@ class InvoiceSum
|
||||
}
|
||||
|
||||
|
||||
function roundRappen($value): float
|
||||
public function roundRappen($value): float
|
||||
{
|
||||
return round($value / .05, 0) * .05;
|
||||
}
|
||||
|
@ -171,7 +171,7 @@ class InvoiceSumInclusive
|
||||
$this->total_taxes += $tax;
|
||||
$this->total_tax_map[] = ['name' => $this->invoice->tax_name3.' '.floatval($this->invoice->tax_rate3).'%', 'total' => $tax];
|
||||
}
|
||||
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -279,10 +279,9 @@ class InvoiceSumInclusive
|
||||
private function setCalculatedAttributes()
|
||||
{
|
||||
/* If amount != balance then some money has been paid on the invoice, need to subtract this difference from the total to set the new balance */
|
||||
if($this->invoice->status_id == Invoice::STATUS_CANCELLED){
|
||||
if($this->invoice->status_id == Invoice::STATUS_CANCELLED) {
|
||||
$this->invoice->balance = 0;
|
||||
}
|
||||
elseif ($this->invoice->status_id != Invoice::STATUS_DRAFT) {
|
||||
} elseif ($this->invoice->status_id != Invoice::STATUS_DRAFT) {
|
||||
if ($this->invoice->amount != $this->invoice->balance) {
|
||||
$this->invoice->balance = $this->formatValue($this->getTotal(), $this->precision) - $this->invoice->paid_to_date;
|
||||
} else {
|
||||
@ -302,8 +301,8 @@ class InvoiceSumInclusive
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
function roundRappen($value): float
|
||||
|
||||
public function roundRappen($value): float
|
||||
{
|
||||
return round($value / .05, 0) * .05;
|
||||
}
|
||||
@ -373,7 +372,7 @@ class InvoiceSumInclusive
|
||||
|
||||
$this->total_taxes += $total_line_tax;
|
||||
}
|
||||
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ class ProRata
|
||||
*/
|
||||
public function refund(float $amount, Carbon $from_date, Carbon $to_date, int $frequency): float
|
||||
{
|
||||
$days = $from_date->copy()->diffInDays($to_date);
|
||||
$days = intval(abs($from_date->copy()->diffInDays($to_date)));
|
||||
$days_in_frequency = $this->getDaysInFrequency($frequency);
|
||||
|
||||
return round((($days / $days_in_frequency) * $amount), 2);
|
||||
@ -48,7 +48,7 @@ class ProRata
|
||||
*/
|
||||
public function charge(float $amount, Carbon $from_date, Carbon $to_date, int $frequency): float
|
||||
{
|
||||
$days = $from_date->copy()->diffInDays($to_date);
|
||||
$days = intval(abs($from_date->copy()->diffInDays($to_date)));
|
||||
$days_in_frequency = $this->getDaysInFrequency($frequency);
|
||||
|
||||
return round((($days / $days_in_frequency) * $amount), 2);
|
||||
@ -58,21 +58,21 @@ class ProRata
|
||||
* Prepares the line items of an invoice
|
||||
* to be pro rata refunded.
|
||||
*
|
||||
* @param Invoice $invoice
|
||||
* @param ?Invoice $invoice
|
||||
* @param bool $is_credit
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
public function refundItems(Invoice $invoice, $is_credit = false): array
|
||||
public function refundItems(?Invoice $invoice, $is_credit = false): array
|
||||
{
|
||||
if (! $invoice) {
|
||||
return [];
|
||||
}
|
||||
|
||||
/** @var \App\Models\RecurringInvoice $recurring_invoice **/
|
||||
$recurring_invoice = RecurringInvoice::find($invoice->recurring_id)->first();
|
||||
$recurring_invoice = RecurringInvoice::find($invoice->recurring_id);
|
||||
|
||||
if (! $recurring_invoice) {
|
||||
if (! $recurring_invoice) { // @phpstan-ignore-line
|
||||
throw new \Exception("Invoice isn't attached to a recurring invoice");
|
||||
}
|
||||
|
||||
@ -107,23 +107,23 @@ class ProRata
|
||||
case RecurringInvoice::FREQUENCY_TWO_WEEKS:
|
||||
return 14;
|
||||
case RecurringInvoice::FREQUENCY_FOUR_WEEKS:
|
||||
return now()->diffInDays(now()->addWeeks(4));
|
||||
return intval(abs(now()->diffInDays(now()->addWeeks(4))));
|
||||
case RecurringInvoice::FREQUENCY_MONTHLY:
|
||||
return now()->diffInDays(now()->addMonthNoOverflow());
|
||||
return intval(abs(now()->diffInDays(now()->addMonthNoOverflow())));
|
||||
case RecurringInvoice::FREQUENCY_TWO_MONTHS:
|
||||
return now()->diffInDays(now()->addMonthsNoOverflow(2));
|
||||
return intval(abs(now()->diffInDays(now()->addMonthsNoOverflow(2))));
|
||||
case RecurringInvoice::FREQUENCY_THREE_MONTHS:
|
||||
return now()->diffInDays(now()->addMonthsNoOverflow(3));
|
||||
return intval(abs(now()->diffInDays(now()->addMonthsNoOverflow(3))));
|
||||
case RecurringInvoice::FREQUENCY_FOUR_MONTHS:
|
||||
return now()->diffInDays(now()->addMonthsNoOverflow(4));
|
||||
return intval(abs(now()->diffInDays(now()->addMonthsNoOverflow(4))));
|
||||
case RecurringInvoice::FREQUENCY_SIX_MONTHS:
|
||||
return now()->diffInDays(now()->addMonthsNoOverflow(6));
|
||||
return intval(abs(now()->diffInDays(now()->addMonthsNoOverflow(6))));
|
||||
case RecurringInvoice::FREQUENCY_ANNUALLY:
|
||||
return now()->diffInDays(now()->addYear());
|
||||
return intval(abs(now()->diffInDays(now()->addYear())));
|
||||
case RecurringInvoice::FREQUENCY_TWO_YEARS:
|
||||
return now()->diffInDays(now()->addYears(2));
|
||||
return intval(abs(now()->diffInDays(now()->addYears(2))));
|
||||
case RecurringInvoice::FREQUENCY_THREE_YEARS:
|
||||
return now()->diffInDays(now()->addYears(3));
|
||||
return intval(abs(now()->diffInDays(now()->addYears(3))));
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ class GmailTransport extends AbstractTransport
|
||||
$message = MessageConverter::toEmail($message->getOriginalMessage());
|
||||
|
||||
/** @phpstan-ignore-next-line **/
|
||||
$token = $message->getHeaders()->get('gmailtoken')->getValue();
|
||||
$token = $message->getHeaders()->get('gmailtoken')->getValue(); // @phpstan-ignore-line
|
||||
$message->getHeaders()->remove('gmailtoken');
|
||||
|
||||
$client = new Client();
|
||||
@ -53,9 +53,8 @@ class GmailTransport extends AbstractTransport
|
||||
if ($bccs) {
|
||||
$bcc_list = 'Bcc: ';
|
||||
|
||||
foreach ($bccs->getAddresses() as $address) {
|
||||
|
||||
/** @phpstan-ignore-next-line **/
|
||||
foreach ($bccs->getAddresses() as $address) {
|
||||
$bcc_list .= $address->getAddress() .',';
|
||||
}
|
||||
|
||||
@ -65,18 +64,18 @@ class GmailTransport extends AbstractTransport
|
||||
$body->setRaw($this->base64_encode($bcc_list.$message->toString()));
|
||||
|
||||
// try {
|
||||
$service->users_messages->send('me', $body, []);
|
||||
$service->users_messages->send('me', $body, []);
|
||||
// } catch(\Google\Service\Exception $e) {
|
||||
// /* Need to slow down */
|
||||
// if ($e->getCode() == '429') {
|
||||
// nlog("429 google - retrying ");
|
||||
|
||||
// sleep(rand(3,8));
|
||||
|
||||
|
||||
// try {
|
||||
// $service->users_messages->send('me', $body, []);
|
||||
// } catch(\Google\Service\Exception $e) {
|
||||
|
||||
|
||||
// }
|
||||
|
||||
// }
|
||||
|
@ -54,17 +54,17 @@ class Office365MailTransport extends AbstractTransport
|
||||
->setReturnType(\Microsoft\Graph\Model\Message::class)
|
||||
->execute();
|
||||
} catch (\Exception $e) {
|
||||
|
||||
sleep(rand(5,10));
|
||||
|
||||
sleep(rand(5, 10));
|
||||
|
||||
try {
|
||||
$graphMessage = $graph->createRequest('POST', '/users/'.$symfony_message->getFrom()[0]->getAddress().'/sendmail')
|
||||
->attachBody(base64_encode($bcc_list.$message->toString()))
|
||||
->addHeaders(['Content-Type' => 'text/plain'])
|
||||
->setReturnType(\Microsoft\Graph\Model\Message::class)
|
||||
->execute();
|
||||
$graphMessage = $graph->createRequest('POST', '/users/'.$symfony_message->getFrom()[0]->getAddress().'/sendmail')
|
||||
->attachBody(base64_encode($bcc_list.$message->toString()))
|
||||
->addHeaders(['Content-Type' => 'text/plain'])
|
||||
->setReturnType(\Microsoft\Graph\Model\Message::class)
|
||||
->execute();
|
||||
} catch (\Exception $e) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ class AccountController extends BaseController
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param CreateAccountRequest $request
|
||||
* @return Response
|
||||
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response
|
||||
*
|
||||
*/
|
||||
public function store(CreateAccountRequest $request)
|
||||
|
@ -11,19 +11,31 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Requests\Activity\DownloadHistoricalEntityRequest;
|
||||
use App\Http\Requests\Activity\ShowActivityRequest;
|
||||
use App\Models\Activity;
|
||||
use App\Transformers\ActivityTransformer;
|
||||
use App\Utils\HostedPDF\NinjaPdf;
|
||||
use App\Utils\Ninja;
|
||||
use App\Utils\PhantomJS\Phantom;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use App\Utils\Traits\Pdf\PageNumbering;
|
||||
use App\Utils\Traits\Pdf\PdfMaker;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use stdClass;
|
||||
use App\Utils\Ninja;
|
||||
use App\Models\Client;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\Activity;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use App\Utils\PhantomJS\Phantom;
|
||||
use App\Utils\HostedPDF\NinjaPdf;
|
||||
use App\Utils\Traits\Pdf\PdfMaker;
|
||||
use App\Utils\Traits\Pdf\PageNumbering;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use App\Transformers\ActivityTransformer;
|
||||
use App\Http\Requests\Activity\StoreNoteRequest;
|
||||
use App\Http\Requests\Activity\ShowActivityRequest;
|
||||
use App\Http\Requests\Activity\DownloadHistoricalEntityRequest;
|
||||
use App\Models\Credit;
|
||||
use App\Models\Expense;
|
||||
use App\Models\Payment;
|
||||
use App\Models\PurchaseOrder;
|
||||
use App\Models\Quote;
|
||||
use App\Models\RecurringExpense;
|
||||
use App\Models\RecurringInvoice;
|
||||
use App\Models\Task;
|
||||
use App\Models\Vendor;
|
||||
|
||||
class ActivityController extends BaseController
|
||||
{
|
||||
@ -105,6 +117,14 @@ class ActivityController extends BaseController
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* downloadHistoricalEntity
|
||||
*
|
||||
* @param DownloadHistoricalEntityRequest $request
|
||||
* @param Activity $activity
|
||||
* @return \Symfony\Component\HttpFoundation\StreamedResponse | \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function downloadHistoricalEntity(DownloadHistoricalEntityRequest $request, Activity $activity)
|
||||
{
|
||||
$backup = $activity->backup;
|
||||
@ -169,4 +189,89 @@ class ActivityController extends BaseController
|
||||
echo $pdf;
|
||||
}, $filename, ['Content-Type' => 'application/pdf']);
|
||||
}
|
||||
|
||||
public function note(StoreNoteRequest $request)
|
||||
{
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
$entity = $request->getEntity();
|
||||
|
||||
$activity = new Activity();
|
||||
$activity->account_id = $user->account_id;
|
||||
$activity->company_id = $user->company()->id;
|
||||
$activity->notes = $request->notes;
|
||||
$activity->user_id = $user->id;
|
||||
$activity->ip = $request->ip();
|
||||
$activity->activity_type_id = Activity::USER_NOTE;
|
||||
|
||||
switch (get_class($entity)) {
|
||||
case Invoice::class:
|
||||
$activity->invoice_id = $entity->id;
|
||||
$activity->client_id = $entity->client_id;
|
||||
$activity->project_id = $entity->project_id;
|
||||
$activity->vendor_id = $entity->vendor_id;
|
||||
break;
|
||||
case Credit::class:
|
||||
$activity->credit_id = $entity->id;
|
||||
$activity->client_id = $entity->client_id;
|
||||
$activity->project_id = $entity->project_id;
|
||||
$activity->vendor_id = $entity->vendor_id;
|
||||
$activity->invoice_id = $entity->invoice_id;
|
||||
break;
|
||||
case Client::class:
|
||||
$activity->client_id = $entity->id;
|
||||
break;
|
||||
case Quote::class:
|
||||
$activity->quote_id = $entity->id;
|
||||
$activity->client_id = $entity->client_id;
|
||||
$activity->project_id = $entity->project_id;
|
||||
$activity->vendor_id = $entity->vendor_id;
|
||||
break;
|
||||
case RecurringInvoice::class:
|
||||
$activity->recurring_invoice_id = $entity->id;
|
||||
$activity->client_id = $entity->client_id;
|
||||
break;
|
||||
case Expense::class:
|
||||
$activity->expense_id = $entity->id;
|
||||
$activity->client_id = $entity->client_id;
|
||||
$activity->project_id = $entity->project_id;
|
||||
$activity->vendor_id = $entity->vendor_id;
|
||||
break;
|
||||
case RecurringExpense::class:
|
||||
$activity->recurring_expense_id = $entity->id;
|
||||
$activity->expense_id = $entity->id;
|
||||
$activity->client_id = $entity->client_id;
|
||||
$activity->project_id = $entity->project_id;
|
||||
$activity->vendor_id = $entity->vendor_id;
|
||||
break;
|
||||
case Vendor::class:
|
||||
$activity->vendor_id = $entity->id;
|
||||
break;
|
||||
case PurchaseOrder::class:
|
||||
$activity->purchase_order_id = $entity->id;
|
||||
$activity->expense_id = $entity->id;
|
||||
$activity->client_id = $entity->client_id;
|
||||
$activity->project_id = $entity->project_id;
|
||||
$activity->vendor_id = $entity->vendor_id;
|
||||
case Task::class:
|
||||
$activity->task_id = $entity->id;
|
||||
$activity->expense_id = $entity->id;
|
||||
$activity->client_id = $entity->client_id;
|
||||
$activity->project_id = $entity->project_id;
|
||||
$activity->vendor_id = $entity->vendor_id;
|
||||
case Payment::class:
|
||||
$activity->payment_id = $entity->id;
|
||||
$activity->expense_id = $entity->id;
|
||||
$activity->client_id = $entity->client_id;
|
||||
$activity->project_id = $entity->project_id;
|
||||
default:
|
||||
# code...
|
||||
break;
|
||||
}
|
||||
|
||||
$activity->save();
|
||||
|
||||
return $this->itemResponse($activity);
|
||||
}
|
||||
}
|
||||
|
@ -118,7 +118,7 @@ class ContactForgotPasswordController extends Controller
|
||||
})->first();
|
||||
}
|
||||
|
||||
$response = false;
|
||||
// $response = false;
|
||||
|
||||
if ($contact) {
|
||||
/* Update all instances of the client */
|
||||
@ -131,16 +131,16 @@ class ContactForgotPasswordController extends Controller
|
||||
}
|
||||
|
||||
if ($request->ajax()) {
|
||||
if ($response == Password::RESET_THROTTLED) {
|
||||
if ($response == Password::RESET_THROTTLED) { // @phpstan-ignore-line
|
||||
return response()->json(['message' => ctrans('passwords.throttled'), 'status' => false], 429);
|
||||
}
|
||||
|
||||
return $response == Password::RESET_LINK_SENT
|
||||
return $response == Password::RESET_LINK_SENT // @phpstan-ignore-line
|
||||
? response()->json(['message' => 'Reset link sent to your email.', 'status' => true], 201)
|
||||
: response()->json(['message' => 'Email not found', 'status' => false], 401);
|
||||
}
|
||||
|
||||
return $response == Password::RESET_LINK_SENT
|
||||
return $response == Password::RESET_LINK_SENT // @phpstan-ignore-line
|
||||
? $this->sendResetLinkResponse($request, $response)
|
||||
: $this->sendResetLinkFailedResponse($request, $response);
|
||||
}
|
||||
|
@ -41,6 +41,9 @@ class ContactLoginController extends Controller
|
||||
$company = false;
|
||||
$account = false;
|
||||
|
||||
if($request->query('intended'))
|
||||
$request->session()->put('url.intended', $request->query('intended'));
|
||||
|
||||
if ($request->session()->has('company_key')) {
|
||||
MultiDB::findAndSetDbByCompanyKey($request->session()->get('company_key'));
|
||||
$company = Company::where('company_key', $request->session()->get('company_key'))->first();
|
||||
@ -52,7 +55,7 @@ class ContactLoginController extends Controller
|
||||
$company = Company::where('company_key', $company_key)->first();
|
||||
}
|
||||
|
||||
/** @var \App\Models\Company $company **/
|
||||
/** @var ?\App\Models\Company $company **/
|
||||
if ($company) {
|
||||
$account = $company->account;
|
||||
} elseif (! $company && strpos($request->getHost(), config('ninja.app_domain')) !== false) {
|
||||
@ -81,6 +84,7 @@ class ContactLoginController extends Controller
|
||||
|
||||
public function login(Request $request)
|
||||
{
|
||||
|
||||
Auth::shouldUse('contact');
|
||||
|
||||
if (Ninja::isHosted() && $request->has('company_key')) {
|
||||
@ -125,6 +129,9 @@ class ContactLoginController extends Controller
|
||||
|
||||
protected function sendLoginResponse(Request $request)
|
||||
{
|
||||
|
||||
$intended = $request->session()->has('url.intended') ? $request->session()->get('url.intended') : false;
|
||||
|
||||
$request->session()->regenerate();
|
||||
|
||||
$this->clearLoginAttempts($request);
|
||||
@ -134,6 +141,9 @@ class ContactLoginController extends Controller
|
||||
}
|
||||
|
||||
$this->setRedirectPath();
|
||||
|
||||
if($intended)
|
||||
$this->redirectTo = $intended;
|
||||
|
||||
return $request->wantsJson()
|
||||
? new JsonResponse([], 204)
|
||||
@ -146,8 +156,8 @@ class ContactLoginController extends Controller
|
||||
|
||||
event(new ContactLoggedIn($client, $client->company, Ninja::eventVars()));
|
||||
|
||||
if (session()->get('url.intended')) {
|
||||
return redirect(session()->get('url.intended'));
|
||||
if ($request->session()->has('url.intended')) {
|
||||
return redirect($request->session()->get('url.intended'));
|
||||
}
|
||||
|
||||
$this->setRedirectPath();
|
||||
@ -165,19 +175,20 @@ class ContactLoginController extends Controller
|
||||
|
||||
private function setRedirectPath()
|
||||
{
|
||||
|
||||
if (auth()->guard('contact')->user()->client->getSetting('enable_client_portal_dashboard') === true) {
|
||||
$this->redirectTo = '/client/dashboard';
|
||||
} elseif (auth()->guard('contact')->user()->company->enabled_modules & PortalComposer::MODULE_INVOICES) {
|
||||
$this->redirectTo = '/client/dashboard';
|
||||
} elseif ((bool)(auth()->guard('contact')->user()->company->enabled_modules & PortalComposer::MODULE_INVOICES)) {
|
||||
$this->redirectTo = '/client/invoices';
|
||||
} elseif (auth()->guard('contact')->user()->company->enabled_modules & PortalComposer::MODULE_RECURRING_INVOICES) {
|
||||
} elseif ((bool)(auth()->guard('contact')->user()->company->enabled_modules & PortalComposer::MODULE_RECURRING_INVOICES)) {
|
||||
$this->redirectTo = '/client/recurring_invoices';
|
||||
} elseif (auth()->guard('contact')->user()->company->enabled_modules & PortalComposer::MODULE_QUOTES) {
|
||||
} elseif ((bool)(auth()->guard('contact')->user()->company->enabled_modules & PortalComposer::MODULE_QUOTES)) {
|
||||
$this->redirectTo = '/client/quotes';
|
||||
} elseif (auth()->guard('contact')->user()->company->enabled_modules & PortalComposer::MODULE_CREDITS) {
|
||||
} elseif ((bool)(auth()->guard('contact')->user()->company->enabled_modules & PortalComposer::MODULE_CREDITS)) {
|
||||
$this->redirectTo = '/client/credits';
|
||||
} elseif (auth()->guard('contact')->user()->company->enabled_modules & PortalComposer::MODULE_TASKS) {
|
||||
} elseif ((bool)(auth()->guard('contact')->user()->company->enabled_modules & PortalComposer::MODULE_TASKS)) {
|
||||
$this->redirectTo = '/client/tasks';
|
||||
} elseif (auth()->guard('contact')->user()->company->enabled_modules & PortalComposer::MODULE_EXPENSES) {
|
||||
} elseif ((bool)(auth()->guard('contact')->user()->company->enabled_modules & PortalComposer::MODULE_EXPENSES)) {
|
||||
$this->redirectTo = '/client/expenses';
|
||||
}
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ class ContactRegisterController extends Controller
|
||||
public function register(RegisterRequest $request)
|
||||
{
|
||||
$request->merge(['company' => $request->company()]);
|
||||
|
||||
|
||||
$service = new ClientRegisterService(
|
||||
company: $request->company(),
|
||||
);
|
||||
|
@ -46,7 +46,7 @@ class ForgotPasswordController extends Controller
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\RedirectResponse
|
||||
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
*/
|
||||
public function sendResetLinkEmail(Request $request)
|
||||
|
@ -13,6 +13,7 @@
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\DataMapper\Analytics\LoginFailure;
|
||||
use App\DataMapper\Analytics\LoginMeta;
|
||||
use App\DataMapper\Analytics\LoginSuccess;
|
||||
use App\Events\User\UserLoggedIn;
|
||||
use App\Http\Controllers\BaseController;
|
||||
@ -111,6 +112,9 @@ class LoginController extends BaseController
|
||||
->increment()
|
||||
->batch();
|
||||
|
||||
LightLogs::create(new LoginMeta($request->email, $request->ip, 'success'))
|
||||
->batch();
|
||||
|
||||
/** @var \App\Models\User $user */
|
||||
$user = $this->guard()->user();
|
||||
|
||||
@ -159,6 +163,9 @@ class LoginController extends BaseController
|
||||
->increment()
|
||||
->batch();
|
||||
|
||||
LightLogs::create(new LoginMeta($request->email, $request->ip, 'failure'))
|
||||
->batch();
|
||||
|
||||
$this->incrementLoginAttempts($request);
|
||||
|
||||
return response()
|
||||
@ -172,7 +179,7 @@ class LoginController extends BaseController
|
||||
* Refreshes the data feed with the current Company User.
|
||||
*
|
||||
* @param Request $request
|
||||
* @return Response|JsonResponse
|
||||
* @return \Illuminate\Http\Response|JsonResponse
|
||||
*/
|
||||
public function refresh(Request $request)
|
||||
{
|
||||
@ -391,8 +398,8 @@ class LoginController extends BaseController
|
||||
$truth->setCompany($set_company);
|
||||
|
||||
//21-03-2024
|
||||
$cu->each(function ($cu){
|
||||
if(CompanyToken::where('company_id', $cu->company_id)->where('user_id', $cu->user_id)->where('is_system', true)->doesntExist()){
|
||||
$cu->each(function ($cu) {
|
||||
if(CompanyToken::where('company_id', $cu->company_id)->where('user_id', $cu->user_id)->where('is_system', true)->doesntExist()) {
|
||||
(new CreateCompanyToken($cu->company, $cu->user, request()->server('HTTP_USER_AGENT')))->handle();
|
||||
}
|
||||
});
|
||||
@ -481,7 +488,7 @@ class LoginController extends BaseController
|
||||
* send login response to oauthed users
|
||||
*
|
||||
* @param \App\Models\User $existing_user
|
||||
* @return Response | JsonResponse
|
||||
* @return Response| \Illuminate\Http\JsonResponse | JsonResponse
|
||||
*/
|
||||
private function existingOauthUser($existing_user)
|
||||
{
|
||||
@ -651,7 +658,9 @@ class LoginController extends BaseController
|
||||
}
|
||||
|
||||
if(request()->hasHeader('X-REACT') || request()->query('react')) {
|
||||
Cache::put("react_redir:".auth()->user()?->account->key, 'true', 300);
|
||||
/**@var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
Cache::put("react_redir:".$user?->account->key, 'true', 300);
|
||||
}
|
||||
|
||||
if (request()->has('code')) {
|
||||
|
@ -78,7 +78,7 @@ class ResetPasswordController extends Controller
|
||||
* Reset the given user's password.
|
||||
*
|
||||
* @param Request $request
|
||||
* @return RedirectResponse|JsonResponse
|
||||
* @return \Illuminate\Http\RedirectResponse | \Illuminate\Http\RedirectResponse|JsonResponse
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
*/
|
||||
public function reset(Request $request)
|
||||
@ -137,8 +137,8 @@ class ResetPasswordController extends Controller
|
||||
return redirect('/#/login');
|
||||
}
|
||||
|
||||
return redirect($this->redirectPath())
|
||||
->with('status', trans($response));
|
||||
// return redirect($this->redirectPath())
|
||||
// ->with('status', trans($response));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -11,7 +11,6 @@
|
||||
|
||||
namespace App\Http\Controllers\Bank;
|
||||
|
||||
use App\Helpers\Bank\Yodlee\DTO\AccountSummary;
|
||||
use App\Helpers\Bank\Yodlee\Yodlee;
|
||||
use App\Http\Controllers\BaseController;
|
||||
use App\Http\Requests\Yodlee\YodleeAdminRequest;
|
||||
@ -301,8 +300,6 @@ class YodleeController extends BaseController
|
||||
|
||||
$summary = $yodlee->getAccountSummary($account_number);
|
||||
|
||||
//@todo remove laravel-data
|
||||
// $transformed_summary = AccountSummary::from($summary[0]);
|
||||
$transformed_summary = $this->transformSummary($summary[0]);
|
||||
|
||||
return response()->json($transformed_summary, 200);
|
||||
@ -310,7 +307,7 @@ class YodleeController extends BaseController
|
||||
|
||||
private function transformSummary($summary): array
|
||||
{
|
||||
$dto = new \stdClass;
|
||||
$dto = new \stdClass();
|
||||
$dto->id = $summary['id'] ?? 0;
|
||||
$dto->account_type = $summary['CONTAINER'] ?? '';
|
||||
|
||||
|
@ -55,7 +55,7 @@ class BankIntegrationController extends BaseController
|
||||
|
||||
/**
|
||||
* @param BankIntegrationFilters $filters
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function index(BankIntegrationFilters $filters)
|
||||
{
|
||||
@ -69,7 +69,7 @@ class BankIntegrationController extends BaseController
|
||||
*
|
||||
* @param ShowBankIntegrationRequest $request
|
||||
* @param BankIntegration $bank_integration
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*
|
||||
*/
|
||||
public function show(ShowBankIntegrationRequest $request, BankIntegration $bank_integration)
|
||||
@ -83,7 +83,7 @@ class BankIntegrationController extends BaseController
|
||||
*
|
||||
* @param EditBankIntegrationRequest $request
|
||||
* @param BankIntegration $bank_integration
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*
|
||||
*/
|
||||
public function edit(EditBankIntegrationRequest $request, BankIntegration $bank_integration)
|
||||
@ -96,7 +96,7 @@ class BankIntegrationController extends BaseController
|
||||
*
|
||||
* @param UpdateBankIntegrationRequest $request
|
||||
* @param BankIntegration $bank_integration
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*
|
||||
*/
|
||||
public function update(UpdateBankIntegrationRequest $request, BankIntegration $bank_integration)
|
||||
@ -111,7 +111,7 @@ class BankIntegrationController extends BaseController
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @param CreateBankIntegrationRequest $request
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*
|
||||
*
|
||||
*/
|
||||
@ -130,7 +130,7 @@ class BankIntegrationController extends BaseController
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param StoreBankIntegrationRequest $request
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*
|
||||
*/
|
||||
public function store(StoreBankIntegrationRequest $request)
|
||||
@ -150,7 +150,7 @@ class BankIntegrationController extends BaseController
|
||||
*
|
||||
* @param DestroyBankIntegrationRequest $request
|
||||
* @param BankIntegration $bank_integration
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
@ -165,7 +165,7 @@ class BankIntegrationController extends BaseController
|
||||
/**
|
||||
* Perform bulk actions on the list view.
|
||||
*
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*
|
||||
*/
|
||||
public function bulk(BulkBankIntegrationRequest $request)
|
||||
@ -270,7 +270,7 @@ class BankIntegrationController extends BaseController
|
||||
|
||||
$nordigen = new Nordigen();
|
||||
|
||||
BankIntegration::where("integration_type", BankIntegration::INTEGRATION_TYPE_NORDIGEN)->whereNotNull('nordigen_account_id')->each(function (BankIntegration $bank_integration) use ($nordigen) {
|
||||
BankIntegration::where("integration_type", BankIntegration::INTEGRATION_TYPE_NORDIGEN)->where('account_id', $user->account_id)->whereNotNull('nordigen_account_id')->each(function (BankIntegration $bank_integration) use ($nordigen) {
|
||||
$is_account_active = $nordigen->isAccountActive($bank_integration->nordigen_account_id);
|
||||
$account = $nordigen->getAccount($bank_integration->nordigen_account_id);
|
||||
|
||||
@ -295,7 +295,7 @@ class BankIntegrationController extends BaseController
|
||||
* Return the remote list of accounts stored on the third party provider
|
||||
* and update our local cache.
|
||||
*
|
||||
* @return Response | JsonResponse
|
||||
* @return Response| \Illuminate\Http\JsonResponse | JsonResponse
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -85,7 +85,7 @@ class BankTransactionRuleController extends BaseController
|
||||
* ),
|
||||
* )
|
||||
* @param BankTransactionRuleFilters $filters
|
||||
* @return Response|mixed
|
||||
* @return Response| \Illuminate\Http\JsonResponse|mixed
|
||||
*/
|
||||
public function index(BankTransactionRuleFilters $filters)
|
||||
{
|
||||
@ -99,7 +99,7 @@ class BankTransactionRuleController extends BaseController
|
||||
*
|
||||
* @param ShowBankTransactionRuleRequest $request
|
||||
* @param BankTransactionRule $bank_transaction_rule
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response|\Illuminate\Http\Response
|
||||
*
|
||||
*
|
||||
* @OA\Get(
|
||||
@ -154,7 +154,7 @@ class BankTransactionRuleController extends BaseController
|
||||
*
|
||||
* @param EditBankTransactionRuleRequest $request
|
||||
* @param BankTransactionRule $bank_transaction_rule
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response
|
||||
*
|
||||
*
|
||||
* @OA\Get(
|
||||
@ -208,7 +208,7 @@ class BankTransactionRuleController extends BaseController
|
||||
*
|
||||
* @param UpdateBankTransactionRuleRequest $request
|
||||
* @param BankTransactionRule $bank_transaction_rule
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response
|
||||
*
|
||||
*
|
||||
*
|
||||
@ -269,7 +269,7 @@ class BankTransactionRuleController extends BaseController
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @param CreateBankTransactionRuleRequest $request
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response
|
||||
*
|
||||
*
|
||||
*
|
||||
@ -317,7 +317,7 @@ class BankTransactionRuleController extends BaseController
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param StoreBankTransactionRuleRequest $request
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response
|
||||
*
|
||||
*
|
||||
*
|
||||
@ -369,7 +369,7 @@ class BankTransactionRuleController extends BaseController
|
||||
*
|
||||
* @param DestroyBankTransactionRuleRequest $request
|
||||
* @param BankTransactionRule $bank_transaction_rule
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response
|
||||
*
|
||||
*
|
||||
* @throws \Exception
|
||||
@ -424,7 +424,7 @@ class BankTransactionRuleController extends BaseController
|
||||
/**
|
||||
* Perform bulk actions on the list view.
|
||||
*
|
||||
* @return \Illuminate\Support\Collection
|
||||
* @return \Illuminate\Http\Response|\Illuminate\Http\JsonResponse
|
||||
*
|
||||
* @OA\Post(
|
||||
* path="/api/v1/bank_transation_rules/bulk",
|
||||
|
@ -262,7 +262,7 @@ class BaseController extends Controller
|
||||
|
||||
/**
|
||||
* 404 for the client portal.
|
||||
* @return Response 404 response
|
||||
* @return Response| \Illuminate\Http\JsonResponse 404 response
|
||||
*/
|
||||
public function notFoundClient()
|
||||
{
|
||||
@ -279,7 +279,7 @@ class BaseController extends Controller
|
||||
*
|
||||
* @param string|array $message The return error message
|
||||
* @param int $httpErrorCode 404/401/403 etc
|
||||
* @return Response The JSON response
|
||||
* @return Response| \Illuminate\Http\JsonResponse The JSON response
|
||||
* @throws BindingResolutionException
|
||||
*/
|
||||
protected function errorResponse($message, $httpErrorCode = 400)
|
||||
@ -297,7 +297,7 @@ class BaseController extends Controller
|
||||
* Refresh API response with latest cahnges
|
||||
*
|
||||
* @param Builder $query
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
protected function refreshResponse($query)
|
||||
{
|
||||
@ -460,7 +460,7 @@ class BaseController extends Controller
|
||||
}
|
||||
},
|
||||
'company.tasks' => function ($query) use ($updated_at, $user) {
|
||||
$query->where('updated_at', '>=', $updated_at)->with('project','documents');
|
||||
$query->where('updated_at', '>=', $updated_at)->with('project', 'documents');
|
||||
|
||||
if (! $user->hasPermission('view_task')) {
|
||||
$query->whereNested(function ($query) use ($user) {
|
||||
@ -798,7 +798,7 @@ class BaseController extends Controller
|
||||
}
|
||||
},
|
||||
'company.tasks' => function ($query) use ($created_at, $user) {
|
||||
$query->where('created_at', '>=', $created_at)->with('project.documents','documents');
|
||||
$query->where('created_at', '>=', $created_at)->with('project.documents', 'documents');
|
||||
|
||||
if (! $user->hasPermission('view_task')) {
|
||||
$query->whereNested(function ($query) use ($user) {
|
||||
@ -969,7 +969,7 @@ class BaseController extends Controller
|
||||
* Sorts the response by keys
|
||||
*
|
||||
* @param mixed $response
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
protected function response($response)
|
||||
{
|
||||
@ -995,15 +995,16 @@ class BaseController extends Controller
|
||||
|
||||
$response_data = Statics::company($user->getCompany()->getLocale());
|
||||
|
||||
if(request()->has('einvoice')){
|
||||
|
||||
$ro = new Schema();
|
||||
$response_data['einvoice_schema'] = $ro('Peppol');
|
||||
if(request()->has('einvoice')) {
|
||||
|
||||
if(class_exists(Schema::class)){
|
||||
$ro = new Schema();
|
||||
$response_data['einvoice_schema'] = $ro('Peppol');
|
||||
}
|
||||
}
|
||||
|
||||
$response['static'] = $response_data;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1020,7 +1021,7 @@ class BaseController extends Controller
|
||||
* Item Response
|
||||
*
|
||||
* @param mixed $item
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
protected function itemResponse($item)
|
||||
{
|
||||
@ -1034,7 +1035,7 @@ class BaseController extends Controller
|
||||
|
||||
$resource = new Item($item, $transformer, $this->entity_type);
|
||||
|
||||
/** @var \App\Models\User $user */
|
||||
/** @var ?\App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
if ($user && request()->include_static) {
|
||||
@ -1157,8 +1158,6 @@ class BaseController extends Controller
|
||||
|
||||
$data['path'] = $this->setBuild();
|
||||
|
||||
$this->buildCache();
|
||||
|
||||
if (Ninja::isSelfHost() && $account->set_react_as_default_ap) {
|
||||
return response()->view('react.index', $data)->header('X-Frame-Options', 'SAMEORIGIN', false);
|
||||
} else {
|
||||
|
@ -19,7 +19,6 @@ use Illuminate\Http\Request;
|
||||
*/
|
||||
class BrevoController extends BaseController
|
||||
{
|
||||
private $invitation;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
|
@ -89,7 +89,7 @@ class ClientController extends BaseController
|
||||
/**
|
||||
*
|
||||
* @param ClientFilters $filters
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*
|
||||
*/
|
||||
public function index(ClientFilters $filters)
|
||||
@ -106,7 +106,7 @@ class ClientController extends BaseController
|
||||
*
|
||||
* @param ShowClientRequest $request
|
||||
* @param Client $client
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*
|
||||
*/
|
||||
public function show(ShowClientRequest $request, Client $client)
|
||||
@ -119,7 +119,7 @@ class ClientController extends BaseController
|
||||
*
|
||||
* @param EditClientRequest $request
|
||||
* @param Client $client
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*
|
||||
*/
|
||||
public function edit(EditClientRequest $request, Client $client)
|
||||
@ -132,7 +132,7 @@ class ClientController extends BaseController
|
||||
*
|
||||
* @param UpdateClientRequest $request
|
||||
* @param Client $client
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*
|
||||
*/
|
||||
public function update(UpdateClientRequest $request, Client $client)
|
||||
@ -141,7 +141,7 @@ class ClientController extends BaseController
|
||||
return $request->disallowUpdate();
|
||||
}
|
||||
|
||||
/** @var \App\Models\User $user */
|
||||
/** @var ?\App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
$client = $this->client_repo->save($request->all(), $client);
|
||||
@ -157,7 +157,7 @@ class ClientController extends BaseController
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @param CreateClientRequest $request
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*
|
||||
*/
|
||||
public function create(CreateClientRequest $request)
|
||||
@ -174,7 +174,7 @@ class ClientController extends BaseController
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param StoreClientRequest $request
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*
|
||||
*/
|
||||
public function store(StoreClientRequest $request)
|
||||
@ -203,7 +203,7 @@ class ClientController extends BaseController
|
||||
*
|
||||
* @param DestroyClientRequest $request
|
||||
* @param Client $client
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
@ -217,7 +217,7 @@ class ClientController extends BaseController
|
||||
/**
|
||||
* Perform bulk actions on the list view.
|
||||
*
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*
|
||||
*/
|
||||
public function bulk(BulkClientRequest $request)
|
||||
@ -250,22 +250,22 @@ class ClientController extends BaseController
|
||||
return response()->json(['message' => $hash_or_response], 200);
|
||||
}
|
||||
|
||||
if($action == 'assign_group' && $user->can('edit', $clients->first())){
|
||||
if($action == 'assign_group' && $user->can('edit', $clients->first())) {
|
||||
|
||||
$this->client_repo->assignGroup($clients, $request->group_settings_id);
|
||||
|
||||
|
||||
return $this->listResponse(Client::query()->withTrashed()->company()->whereIn('id', $request->ids));
|
||||
|
||||
}
|
||||
|
||||
if($action == 'bulk_update' && $user->can('edit', $clients->first())){
|
||||
if($action == 'bulk_update' && $user->can('edit', $clients->first())) {
|
||||
|
||||
$clients = Client::withTrashed()
|
||||
->company()
|
||||
->whereIn('id', $request->ids);
|
||||
|
||||
$this->client_repo->bulkUpdate($clients, $request->column, $request->new_value);
|
||||
|
||||
|
||||
return $this->listResponse(Client::query()->withTrashed()->company()->whereIn('id', $request->ids));
|
||||
|
||||
}
|
||||
@ -284,7 +284,7 @@ class ClientController extends BaseController
|
||||
*
|
||||
* @param UploadClientRequest $request
|
||||
* @param Client $client
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*
|
||||
*/
|
||||
public function upload(UploadClientRequest $request, Client $client)
|
||||
@ -305,7 +305,7 @@ class ClientController extends BaseController
|
||||
*
|
||||
* @param PurgeClientRequest $request
|
||||
* @param Client $client
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response
|
||||
*
|
||||
*/
|
||||
public function purge(PurgeClientRequest $request, Client $client)
|
||||
@ -333,7 +333,7 @@ class ClientController extends BaseController
|
||||
* @param PurgeClientRequest $request
|
||||
* @param Client $client
|
||||
* @param string $mergeable_client
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response
|
||||
*
|
||||
*/
|
||||
|
||||
@ -351,9 +351,10 @@ class ClientController extends BaseController
|
||||
return response()->json(['message' => "Client not found"], 400);
|
||||
}
|
||||
|
||||
if($m_client->id == $client->id)
|
||||
if($m_client->id == $client->id) {
|
||||
return response()->json(['message' => "Attempting to merge the same client is not possible."], 400);
|
||||
|
||||
}
|
||||
|
||||
$merged_client = $client->service()->merge($m_client)->save();
|
||||
|
||||
return $this->itemResponse($merged_client);
|
||||
@ -364,7 +365,7 @@ class ClientController extends BaseController
|
||||
*
|
||||
* @param PurgeClientRequest $request
|
||||
* @param Client $client
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response
|
||||
*/
|
||||
public function updateTaxData(PurgeClientRequest $request, Client $client)
|
||||
{
|
||||
@ -380,7 +381,7 @@ class ClientController extends BaseController
|
||||
*
|
||||
* @param ReactivateClientEmailRequest $request
|
||||
* @param string $bounce_id //could also be the invitationId
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response
|
||||
*/
|
||||
public function reactivateEmail(ReactivateClientEmailRequest $request, string $bounce_id)
|
||||
{
|
||||
@ -425,7 +426,7 @@ class ClientController extends BaseController
|
||||
|
||||
try {
|
||||
|
||||
/** @var \Postmark\Models\DynamicResponseModel $response */
|
||||
/** @var ?\Postmark\Models\DynamicResponseModel $response */
|
||||
$response = $postmark->activateBounce((int)$bounce_id);
|
||||
|
||||
if($response && $response?->Message == 'OK' && !$response->Bounce->Inactive && $response->Bounce->Email) {
|
||||
|
@ -89,7 +89,7 @@ class ClientGatewayTokenController extends BaseController
|
||||
* ),
|
||||
* )
|
||||
* @param ListClientGatewayTokenRequest $request
|
||||
* @return Response|mixed
|
||||
* @return Response| \Illuminate\Http\JsonResponse|mixed
|
||||
*/
|
||||
public function index(ListClientGatewayTokenRequest $request)
|
||||
{
|
||||
@ -103,7 +103,7 @@ class ClientGatewayTokenController extends BaseController
|
||||
*
|
||||
* @param ShowClientGatewayTokenRequest $request
|
||||
* @param ClientGatewayToken $client_gateway_token
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*
|
||||
*
|
||||
* @OA\Get(
|
||||
@ -157,7 +157,7 @@ class ClientGatewayTokenController extends BaseController
|
||||
*
|
||||
* @param EditClientGatewayTokenRequest $request
|
||||
* @param ClientGatewayToken $client_gateway_token
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*
|
||||
*
|
||||
* @OA\Get(
|
||||
@ -211,7 +211,7 @@ class ClientGatewayTokenController extends BaseController
|
||||
*
|
||||
* @param UpdateClientGatewayTokenRequest $request
|
||||
* @param ClientGatewayToken $client_gateway_token
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*
|
||||
*
|
||||
*
|
||||
@ -267,7 +267,7 @@ class ClientGatewayTokenController extends BaseController
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @param CreateClientGatewayTokenRequest $request
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*
|
||||
*
|
||||
*
|
||||
@ -317,7 +317,7 @@ class ClientGatewayTokenController extends BaseController
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param StoreClientGatewayTokenRequest $request
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*
|
||||
*
|
||||
*
|
||||
@ -369,7 +369,7 @@ class ClientGatewayTokenController extends BaseController
|
||||
*
|
||||
* @param DestroyClientGatewayTokenRequest $request
|
||||
* @param ClientGatewayToken $client_gateway_token
|
||||
* @return Response
|
||||
* @return Response| \Illuminate\Http\JsonResponse
|
||||
*
|
||||
*
|
||||
* @throws \Exception
|
||||
|
@ -21,7 +21,7 @@ class ContactHashLoginController extends Controller
|
||||
/**
|
||||
* Logs a user into the client portal using their contact_key
|
||||
* @param string $contact_key The contact key
|
||||
* @return Redirect
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function login(string $contact_key)
|
||||
{
|
||||
@ -50,7 +50,7 @@ class ContactHashLoginController extends Controller
|
||||
/**
|
||||
* Generic error page for client portal.
|
||||
*
|
||||
* @return void
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function errorPage()
|
||||
{
|
||||
@ -66,15 +66,15 @@ class ContactHashLoginController extends Controller
|
||||
{
|
||||
if (auth()->guard('contact')->user()->company->enabled_modules & PortalComposer::MODULE_INVOICES) {
|
||||
return '/client/invoices';
|
||||
} elseif (auth()->guard('contact')->user()->company->enabled_modules & PortalComposer::MODULE_RECURRING_INVOICES) {
|
||||
} elseif ((bool)(auth()->guard('contact')->user()->company->enabled_modules & PortalComposer::MODULE_RECURRING_INVOICES)) {
|
||||
return '/client/recurring_invoices';
|
||||
} elseif (auth()->guard('contact')->user()->company->enabled_modules & PortalComposer::MODULE_QUOTES) {
|
||||
} elseif ((bool)(auth()->guard('contact')->user()->company->enabled_modules & PortalComposer::MODULE_QUOTES)) {
|
||||
return '/client/quotes';
|
||||
} elseif (auth()->guard('contact')->user()->company->enabled_modules & PortalComposer::MODULE_CREDITS) {
|
||||
} elseif ((bool)(auth()->guard('contact')->user()->company->enabled_modules & PortalComposer::MODULE_CREDITS)) {
|
||||
return '/client/credits';
|
||||
} elseif (auth()->guard('contact')->user()->company->enabled_modules & PortalComposer::MODULE_TASKS) {
|
||||
} elseif ((bool)(auth()->guard('contact')->user()->company->enabled_modules & PortalComposer::MODULE_TASKS)) {
|
||||
return '/client/tasks';
|
||||
} elseif (auth()->guard('contact')->user()->company->enabled_modules & PortalComposer::MODULE_EXPENSES) {
|
||||
} elseif ((bool)(auth()->guard('contact')->user()->company->enabled_modules & PortalComposer::MODULE_EXPENSES)) {
|
||||
return '/client/expenses';
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ class DashboardController extends Controller
|
||||
{
|
||||
if (auth()->guard('contact')->user()->client->getSetting('enable_client_portal_dashboard') === false) {
|
||||
return redirect()->route('client.invoices.index');
|
||||
}
|
||||
}
|
||||
|
||||
$total_invoices = Invoice::withTrashed()
|
||||
->where('client_id', auth()->guard('contact')->user()->client_id)
|
||||
|
@ -114,15 +114,17 @@ class InvitationController extends Controller
|
||||
'invitation_key' => $invitation_key
|
||||
]);
|
||||
}
|
||||
|
||||
if(!auth()->guard('contact')->check()){
|
||||
$this->middleware('auth:contact');
|
||||
return redirect()->route('client.login', ['intended' => route('client.'.$entity.'.show', [$entity => $this->encodePrimaryKey($invitation->{$key}), 'silent' => $is_silent])]);
|
||||
}
|
||||
|
||||
$this->middleware('auth:contact');
|
||||
return redirect()->route('client.login');
|
||||
} else {
|
||||
request()->session()->invalidate();
|
||||
auth()->guard('contact')->loginUsingId($client_contact->id, true);
|
||||
}
|
||||
|
||||
|
||||
if (auth()->guard('contact')->user() && ! request()->has('silent') && ! $invitation->viewed_date) {
|
||||
$invitation->markViewed();
|
||||
|
||||
@ -144,6 +146,7 @@ class InvitationController extends Controller
|
||||
|
||||
}
|
||||
|
||||
|
||||
private function fireEntityViewedEvent($invitation, $entity_string)
|
||||
{
|
||||
switch ($entity_string) {
|
||||
|
@ -97,12 +97,12 @@ class InvoiceController extends Controller
|
||||
|
||||
$invitation = false;
|
||||
|
||||
match($data['entity_type'] ?? false) {
|
||||
match($data['entity_type'] ?? 'invoice') {
|
||||
'invoice' => $invitation = InvoiceInvitation::withTrashed()->find($data['invitation_id']),
|
||||
'quote' => $invitation = QuoteInvitation::withTrashed()->find($data['invitation_id']),
|
||||
'credit' => $invitation = CreditInvitation::withTrashed()->find($data['invitation_id']),
|
||||
'recurring_invoice' => $invitation = RecurringInvoiceInvitation::withTrashed()->find($data['invitation_id']),
|
||||
false => $invitation = false,
|
||||
default => $invitation = false,
|
||||
};
|
||||
|
||||
if (! $invitation) {
|
||||
|
@ -77,6 +77,7 @@ class PaymentController extends Controller
|
||||
'EUR' => $data = $bt->formatDataforEur($payment_intent),
|
||||
'JPY' => $data = $bt->formatDataforJp($payment_intent),
|
||||
'GBP' => $data = $bt->formatDataforUk($payment_intent),
|
||||
default => $data = $bt->formatDataforUk($payment_intent),
|
||||
};
|
||||
|
||||
$gateway = $stripe;
|
||||
@ -103,7 +104,7 @@ class PaymentController extends Controller
|
||||
* and invoice ids for reference.
|
||||
*
|
||||
* @param Request $request
|
||||
* @return RedirectResponse|mixed
|
||||
* @return \Illuminate\Http\RedirectResponse|mixed
|
||||
*/
|
||||
public function process(Request $request)
|
||||
{
|
||||
@ -157,7 +158,7 @@ class PaymentController extends Controller
|
||||
* Pay for invoice/s using credits only.
|
||||
*
|
||||
* @param Request $request The request object
|
||||
* @return \Response The response view
|
||||
* @return \Illuminate\Http\RedirectResponse The response view
|
||||
*/
|
||||
public function credit_response(Request $request)
|
||||
{
|
||||
|
@ -127,7 +127,7 @@ class PaymentMethodController extends Controller
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param ClientGatewayToken $payment_method
|
||||
* @return RedirectResponse
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(ClientGatewayToken $payment_method)
|
||||
{
|
||||
|
@ -48,6 +48,9 @@ class PrePaymentController extends Controller
|
||||
'allows_recurring' => true,
|
||||
'minimum' => $minimum,
|
||||
'minimum_amount' => $minimum_amount,
|
||||
'notes' => request()->has('notes') ? request()->input('notes') : "",
|
||||
'amount' => request()->has('amount') ? request()->input('amount') : "",
|
||||
'show' => request()->has('is_recurring') ? "true" : "false",
|
||||
];
|
||||
|
||||
return $this->render('pre_payments.index', $data);
|
||||
@ -105,7 +108,7 @@ class PrePaymentController extends Controller
|
||||
return $invoice;
|
||||
});
|
||||
|
||||
|
||||
|
||||
$variables = false;
|
||||
|
||||
if(($invitation = $invoices->first()->invitations()->first() ?? false) && $invoice->client->getSetting('show_accept_invoice_terms')) {
|
||||
|
@ -38,7 +38,7 @@ class ProfileController extends Controller
|
||||
*
|
||||
* @param UpdateContactRequest $request
|
||||
* @param ClientContact $client_contact
|
||||
* @return RedirectResponse
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(UpdateContactRequest $request, ClientContact $client_contact)
|
||||
{
|
||||
|
@ -178,7 +178,7 @@ class QuoteController extends Controller
|
||||
->where('client_id', auth()->guard('contact')->user()->client->id)
|
||||
->where('company_id', auth()->guard('contact')->user()->client->company_id)
|
||||
->whereIn('status_id', [Quote::STATUS_DRAFT, Quote::STATUS_SENT])
|
||||
->where(function ($q){
|
||||
->where(function ($q) {
|
||||
$q->whereNull('due_date')->orWhere('due_date', '>=', now());
|
||||
})
|
||||
->withTrashed()
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user