mirror of
				https://github.com/invoiceninja/invoiceninja.git
				synced 2025-11-04 02:07:33 -05:00 
			
		
		
		
	Merge branch 'v5-develop' of https://github.com/invoiceninja/invoiceninja into fix-nordigen-amount
This commit is contained in:
		
						commit
						cc59ee0b1f
					
				
							
								
								
									
										2
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							@ -43,7 +43,7 @@ jobs:
 | 
			
		||||
        run: |
 | 
			
		||||
          git clone https://${{secrets.commit_secret}}@github.com/invoiceninja/ui.git
 | 
			
		||||
          cd ui
 | 
			
		||||
          git checkout main
 | 
			
		||||
          git checkout develop
 | 
			
		||||
          npm i
 | 
			
		||||
          npm run build
 | 
			
		||||
          
 | 
			
		||||
 | 
			
		||||
@ -1 +1 @@
 | 
			
		||||
5.7.63
 | 
			
		||||
5.8.10
 | 
			
		||||
@ -100,6 +100,31 @@ class CreateSingleAccount extends Command
 | 
			
		||||
        $this->warmCache();
 | 
			
		||||
 | 
			
		||||
        $this->createSmallAccount();
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
        try {
 | 
			
		||||
            $pdo = \DB::connection('ronin')->getPdo();
 | 
			
		||||
            
 | 
			
		||||
            if(class_exists(\Modules\Ronin\app\Models\Admin::class)){
 | 
			
		||||
                $this->info('Creating Ronin Account');
 | 
			
		||||
                $this->createRoninAccount();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        } catch (\Exception $e) {
 | 
			
		||||
            
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function createRoninAccount()
 | 
			
		||||
    {
 | 
			
		||||
        $admin = \Modules\Ronin\app\Models\Admin::create([
 | 
			
		||||
            'first_name' => 'small',
 | 
			
		||||
            'last_name' => 'example',
 | 
			
		||||
            'email' => 'small@example.com',
 | 
			
		||||
            'password' => Hash::make('password'),
 | 
			
		||||
        ]);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function createSmallAccount()
 | 
			
		||||
 | 
			
		||||
@ -50,9 +50,9 @@ class S3Cleanup extends Command
 | 
			
		||||
     */
 | 
			
		||||
    public function handle()
 | 
			
		||||
    {
 | 
			
		||||
        if (!Ninja::isHosted()) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        // if (!Ninja::isHosted()) {
 | 
			
		||||
        //     return;
 | 
			
		||||
        // }
 | 
			
		||||
 | 
			
		||||
        $c1 = Company::on('db-ninja-01')->pluck('company_key');
 | 
			
		||||
        $c2 = Company::on('db-ninja-02')->pluck('company_key');
 | 
			
		||||
 | 
			
		||||
@ -58,6 +58,7 @@ class TranslationsExport extends Command
 | 
			
		||||
        'it',
 | 
			
		||||
        'ja',
 | 
			
		||||
        'km_KH',
 | 
			
		||||
        'lo_LA',
 | 
			
		||||
        'lt',
 | 
			
		||||
        'lv_LV',
 | 
			
		||||
        'mk_MK',
 | 
			
		||||
 | 
			
		||||
@ -76,7 +76,7 @@ class Kernel extends ConsoleKernel
 | 
			
		||||
        /* Runs cleanup code for subscriptions */
 | 
			
		||||
        $schedule->job(new SubscriptionCron)->dailyAt('00:01')->withoutOverlapping()->name('subscription-job')->onOneServer();
 | 
			
		||||
 | 
			
		||||
        /* Sends recurring invoices*/
 | 
			
		||||
        /* Sends recurring expenses*/
 | 
			
		||||
        $schedule->job(new RecurringExpensesCron)->dailyAt('00:10')->withoutOverlapping()->name('recurring-expense-job')->onOneServer();
 | 
			
		||||
 | 
			
		||||
        /* Checks the status of the scheduler */
 | 
			
		||||
 | 
			
		||||
@ -271,6 +271,9 @@ class Handler extends ExceptionHandler
 | 
			
		||||
            case 'vendor':
 | 
			
		||||
                $login = 'vendor.catchall';
 | 
			
		||||
                break;
 | 
			
		||||
            case 'ronin':
 | 
			
		||||
                $login = 'ronin.login';
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                $login = 'default';
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
@ -37,6 +37,7 @@ class ProductSalesExport extends BaseExport
 | 
			
		||||
        'product_key' => 'product_key',
 | 
			
		||||
        'notes' => 'notes',
 | 
			
		||||
        'quantity' => 'quantity',
 | 
			
		||||
        'currency' => 'currency',
 | 
			
		||||
        'cost' => 'price',
 | 
			
		||||
        'price' => 'cost',
 | 
			
		||||
        'markup' => 'markup',
 | 
			
		||||
@ -163,6 +164,7 @@ class ProductSalesExport extends BaseExport
 | 
			
		||||
    private function buildRow($invoice, $invoice_item) :array
 | 
			
		||||
    {
 | 
			
		||||
        $transformed_entity = (array)$invoice_item;
 | 
			
		||||
        $transformed_entity['price'] = ($invoice_item->product_cost ?? 1 ) * ($invoice->exchange_rate ?? 1) ;
 | 
			
		||||
 | 
			
		||||
        $entity = [];
 | 
			
		||||
 | 
			
		||||
@ -171,6 +173,8 @@ class ProductSalesExport extends BaseExport
 | 
			
		||||
 | 
			
		||||
            if (array_key_exists($key, $transformed_entity)) {
 | 
			
		||||
                $entity[$keyval] = $transformed_entity[$key];
 | 
			
		||||
            } elseif($key == 'currency') {
 | 
			
		||||
                $entity['currency'] = $invoice->client->currency()->code;
 | 
			
		||||
            } else {
 | 
			
		||||
                $entity[$keyval] = '';
 | 
			
		||||
            }
 | 
			
		||||
@ -184,9 +188,9 @@ class ProductSalesExport extends BaseExport
 | 
			
		||||
 | 
			
		||||
    private function decorateAdvancedFields(Invoice $invoice, $entity) :array
 | 
			
		||||
    {
 | 
			
		||||
        $product = $this->getProduct($entity['product_key']);
 | 
			
		||||
 | 
			
		||||
        $entity['cost'] = $product->cost ?? 0;
 | 
			
		||||
        
 | 
			
		||||
        //$product = $this->getProduct($entity['product_key']);
 | 
			
		||||
        // $entity['cost'] = $product->cost ?? 0;
 | 
			
		||||
        /** @var float $unit_cost */
 | 
			
		||||
        $unit_cost = $entity['cost'] == 0 ? 1 : $entity['cost'];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -28,7 +28,8 @@ class CloneQuoteToInvoiceFactory
 | 
			
		||||
        unset($quote_array['invoice_id']);
 | 
			
		||||
        unset($quote_array['id']);
 | 
			
		||||
        unset($quote_array['invitations']);
 | 
			
		||||
 | 
			
		||||
        unset($quote_array['user']);
 | 
			
		||||
        
 | 
			
		||||
        //preserve terms if they exist on Quotes
 | 
			
		||||
        //if(array_key_exists('terms', $quote_array) && strlen($quote_array['terms']) < 2)
 | 
			
		||||
        if (! $quote->company->use_quote_terms_on_conversion) {
 | 
			
		||||
@ -38,7 +39,6 @@ class CloneQuoteToInvoiceFactory
 | 
			
		||||
        // unset($quote_array['public_notes']);
 | 
			
		||||
        unset($quote_array['footer']);
 | 
			
		||||
        unset($quote_array['design_id']);
 | 
			
		||||
        unset($quote_array['user']);
 | 
			
		||||
 | 
			
		||||
        foreach ($quote_array as $key => $value) {
 | 
			
		||||
            $invoice->{$key} = $value;
 | 
			
		||||
@ -59,6 +59,7 @@ class CloneQuoteToInvoiceFactory
 | 
			
		||||
        $invoice->last_sent_date = null;
 | 
			
		||||
        $invoice->last_viewed = null;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        return $invoice;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -132,6 +132,8 @@ class ClientFilters extends QueryFilters
 | 
			
		||||
        return  $this->builder->where(function ($query) use ($filter) {
 | 
			
		||||
            $query->where('name', 'like', '%'.$filter.'%')
 | 
			
		||||
                          ->orWhere('id_number', 'like', '%'.$filter.'%')
 | 
			
		||||
                          ->orWhere('number', 'like', '%'.$filter.'%')
 | 
			
		||||
                          
 | 
			
		||||
                          ->orWhereHas('contacts', function ($query) use ($filter) {
 | 
			
		||||
                              $query->where('first_name', 'like', '%'.$filter.'%');
 | 
			
		||||
                              $query->orWhere('last_name', 'like', '%'.$filter.'%');
 | 
			
		||||
 | 
			
		||||
@ -36,6 +36,7 @@ class RecurringInvoiceFilters extends QueryFilters
 | 
			
		||||
        return  $this->builder->where(function ($query) use ($filter) {
 | 
			
		||||
            $query->where('date', 'like', '%'.$filter.'%')
 | 
			
		||||
                  ->orWhere('amount', 'like', '%'.$filter.'%')
 | 
			
		||||
                  ->orWhere('number', 'like', '%'.$filter.'%')
 | 
			
		||||
                  ->orWhere('custom_value1', 'like', '%'.$filter.'%')
 | 
			
		||||
                  ->orWhere('custom_value2', 'like', '%'.$filter.'%')
 | 
			
		||||
                  ->orWhere('custom_value3', 'like', '%'.$filter.'%')
 | 
			
		||||
 | 
			
		||||
@ -66,21 +66,44 @@ class UserFilters extends QueryFilters
 | 
			
		||||
     */
 | 
			
		||||
    public function entityFilter()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->builder->whereHas('company_users', function ($q) {
 | 
			
		||||
            $q->where('company_id', '=', auth()->user()->company()->id);
 | 
			
		||||
 | 
			
		||||
        /** @var \App\Models\User $user */
 | 
			
		||||
        $user = auth()->user();
 | 
			
		||||
 | 
			
		||||
        return $this->builder->whereHas('company_users', function ($q) use ($user){
 | 
			
		||||
            $q->where('company_id', '=', $user->company()->id);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Hides owner users from the list.
 | 
			
		||||
     *
 | 
			
		||||
     * @return Builder
 | 
			
		||||
     */
 | 
			
		||||
    public function hideOwnerUsers(): Builder
 | 
			
		||||
    {
 | 
			
		||||
        /** @var \App\Models\User $user */
 | 
			
		||||
        $user = auth()->user();
 | 
			
		||||
        
 | 
			
		||||
        return $this->builder->whereHas('company_users', function ($q) use ($user) {
 | 
			
		||||
            $q->where('company_id', '=', $user->company()->id)->where('is_owner', false);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Filters users that have been removed from the
 | 
			
		||||
     * company, but not deleted from the system.
 | 
			
		||||
     *
 | 
			
		||||
     * @return void
 | 
			
		||||
     * @return Builder
 | 
			
		||||
     */
 | 
			
		||||
    public function hideRemovedUsers()
 | 
			
		||||
    public function hideRemovedUsers(): Builder
 | 
			
		||||
    {
 | 
			
		||||
        return $this->builder->whereHas('company_users', function ($q) {
 | 
			
		||||
            $q->where('company_id', '=', auth()->user()->company()->id)->whereNull('deleted_at');
 | 
			
		||||
        /** @var \App\Models\User $user */
 | 
			
		||||
        $user = auth()->user();
 | 
			
		||||
 | 
			
		||||
        return $this->builder->whereHas('company_users', function ($q) use ($user) {
 | 
			
		||||
            $q->where('company_id', '=', $user->company()->id)->whereNull('deleted_at');
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -98,12 +121,21 @@ class UserFilters extends QueryFilters
 | 
			
		||||
            return $this->builder;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /** @var \App\Models\User $user */
 | 
			
		||||
        $user = auth()->user();
 | 
			
		||||
 | 
			
		||||
        return $this->builder
 | 
			
		||||
            ->orWhere($this->with_property, $value)
 | 
			
		||||
            ->orderByRaw("{$this->with_property} = ? DESC", [$value])
 | 
			
		||||
            ->where('account_id', auth()->user()->account_id);
 | 
			
		||||
            ->where('account_id', $user->account_id);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
        
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns users with permissions to send emails via OAuth
 | 
			
		||||
     *
 | 
			
		||||
     * @param  string $value
 | 
			
		||||
     * @return Builder
 | 
			
		||||
     */
 | 
			
		||||
    public function sending_users(string $value = ''): Builder
 | 
			
		||||
    {
 | 
			
		||||
        if (strlen($value) == 0 || $value != 'true') {
 | 
			
		||||
 | 
			
		||||
@ -19,8 +19,13 @@
 | 
			
		||||
 | 
			
		||||
namespace App\Helpers\Bank\Nordigen;
 | 
			
		||||
 | 
			
		||||
use App\Services\Email\Email;
 | 
			
		||||
use App\Models\BankIntegration;
 | 
			
		||||
use App\Services\Email\EmailObject;
 | 
			
		||||
use Illuminate\Support\Facades\App;
 | 
			
		||||
use App\Helpers\Bank\Nordigen\Transformer\AccountTransformer;
 | 
			
		||||
use App\Helpers\Bank\Nordigen\Transformer\TransactionTransformer;
 | 
			
		||||
use Illuminate\Mail\Mailables\Address;
 | 
			
		||||
 | 
			
		||||
class Nordigen
 | 
			
		||||
{
 | 
			
		||||
@ -39,7 +44,7 @@ class Nordigen
 | 
			
		||||
 | 
			
		||||
        $this->client = new \Nordigen\NordigenPHP\API\NordigenClient(config('ninja.nordigen.secret_id'), config('ninja.nordigen.secret_key'));
 | 
			
		||||
 | 
			
		||||
        $this->client->createAccessToken(); // access_token is valid 24h -> so we dont have to implement a refresh-cycle
 | 
			
		||||
        $this->client->createAccessToken();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // metadata-section for frontend
 | 
			
		||||
@ -52,12 +57,12 @@ class Nordigen
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // requisition-section
 | 
			
		||||
    public function createRequisition(string $redirect, string $initutionId, string $reference)
 | 
			
		||||
    public function createRequisition(string $redirect, string $initutionId, string $reference, string $userLanguage)
 | 
			
		||||
    {
 | 
			
		||||
        if ($this->test_mode && $initutionId != $this->sandbox_institutionId)
 | 
			
		||||
            throw new \Exception('invalid institutionId while in test-mode');
 | 
			
		||||
 | 
			
		||||
        return $this->client->requisition->createRequisition($redirect, $initutionId, null, $reference);
 | 
			
		||||
        return $this->client->requisition->createRequisition($redirect, $initutionId, null, $reference, $userLanguage);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getRequisition(string $requisitionId)
 | 
			
		||||
@ -85,6 +90,7 @@ class Nordigen
 | 
			
		||||
 | 
			
		||||
            $it = new AccountTransformer();
 | 
			
		||||
            return $it->transform($out);
 | 
			
		||||
            
 | 
			
		||||
        } catch (\Exception $e) {
 | 
			
		||||
            if (strpos($e->getMessage(), "Invalid Account ID") !== false)
 | 
			
		||||
                return false;
 | 
			
		||||
@ -92,8 +98,14 @@ class Nordigen
 | 
			
		||||
            throw $e;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function isAccountActive(string $account_id)
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * isAccountActive
 | 
			
		||||
     *
 | 
			
		||||
     * @param  string $account_id
 | 
			
		||||
     * @return bool
 | 
			
		||||
     */
 | 
			
		||||
    public function isAccountActive(string $account_id): bool
 | 
			
		||||
    {
 | 
			
		||||
        try {
 | 
			
		||||
            $account = $this->client->account($account_id)->getAccountMetaData();
 | 
			
		||||
@ -112,15 +124,40 @@ class Nordigen
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * this method returns booked transactions from the bank_account, pending transactions are not part of the result
 | 
			
		||||
     * @todo @turbo124 should we include pending transactions within the integration-process and mark them with a specific category?!
 | 
			
		||||
     * getTransactions
 | 
			
		||||
     *
 | 
			
		||||
     * @param  string $accountId
 | 
			
		||||
     * @param  string $dateFrom
 | 
			
		||||
     * @return array
 | 
			
		||||
     */
 | 
			
		||||
    public function getTransactions(string $accountId, string $dateFrom = null)
 | 
			
		||||
    public function getTransactions(string $accountId, string $dateFrom = null): array
 | 
			
		||||
    {
 | 
			
		||||
        $transactionResponse = $this->client->account($accountId)->getAccountTransactions($dateFrom);
 | 
			
		||||
 | 
			
		||||
        $it = new TransactionTransformer();
 | 
			
		||||
        return $it->transform($transactionResponse);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function disabledAccountEmail(BankIntegration $bank_integration): void
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        App::setLocale($bank_integration->company->getLocale());
 | 
			
		||||
 | 
			
		||||
        $mo = new EmailObject();
 | 
			
		||||
        $mo->subject = ctrans('texts.nordigen_requisition_subject');
 | 
			
		||||
        $mo->body = ctrans('texts.nordigen_requisition_body');
 | 
			
		||||
        $mo->text_body = ctrans('texts.nordigen_requisition_body');
 | 
			
		||||
        $mo->company_key = $bank_integration->company->company_key;
 | 
			
		||||
        $mo->html_template = 'email.template.generic';
 | 
			
		||||
        $mo->to = [new Address($bank_integration->company->owner()->email, $bank_integration->company->owner()->present()->name())];
 | 
			
		||||
        $mo->email_template_body = 'nordigen_requisition_body';
 | 
			
		||||
        $mo->email_template_subject = 'nordigen_requisition_subject';
 | 
			
		||||
 | 
			
		||||
        Email::dispatch($mo, $bank_integration->company);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -64,85 +64,85 @@ use Log;
 | 
			
		||||
 | 
			
		||||
class TransactionTransformer implements BankRevenueInterface
 | 
			
		||||
{
 | 
			
		||||
    use AppSetup;
 | 
			
		||||
  use AppSetup;
 | 
			
		||||
 | 
			
		||||
    public function transform($transactionResponse)
 | 
			
		||||
    {
 | 
			
		||||
        $data = [];
 | 
			
		||||
  public function transform($transactionResponse)
 | 
			
		||||
  {
 | 
			
		||||
    $data = [];
 | 
			
		||||
 | 
			
		||||
        if (!array_key_exists('transactions', $transactionResponse) || !array_key_exists('booked', $transactionResponse["transactions"]))
 | 
			
		||||
            throw new \Exception('invalid dataset');
 | 
			
		||||
    if (!array_key_exists('transactions', $transactionResponse) || !array_key_exists('booked', $transactionResponse["transactions"]))
 | 
			
		||||
      throw new \Exception('invalid dataset');
 | 
			
		||||
 | 
			
		||||
        foreach ($transactionResponse["transactions"]["booked"] as $transaction) {
 | 
			
		||||
            $data[] = $this->transformTransaction($transaction);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return $data;
 | 
			
		||||
    foreach ($transactionResponse["transactions"]["booked"] as $transaction) {
 | 
			
		||||
      $data[] = $this->transformTransaction($transaction);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function transformTransaction($transaction)
 | 
			
		||||
    {
 | 
			
		||||
    return $data;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
        if (!array_key_exists('transactionId', $transaction) || !array_key_exists('transactionAmount', $transaction))
 | 
			
		||||
            throw new \Exception('invalid dataset');
 | 
			
		||||
  public function transformTransaction($transaction)
 | 
			
		||||
  {
 | 
			
		||||
 | 
			
		||||
        // description could be in varios places
 | 
			
		||||
        $description = '';
 | 
			
		||||
        if (array_key_exists('remittanceInformationStructured', $transaction))
 | 
			
		||||
            $description = $transaction["remittanceInformationStructured"];
 | 
			
		||||
        else if (array_key_exists('remittanceInformationStructuredArray', $transaction))
 | 
			
		||||
            $description = implode('\n', $transaction["remittanceInformationStructuredArray"]);
 | 
			
		||||
        else if (array_key_exists('remittanceInformationUnstructured', $transaction))
 | 
			
		||||
            $description = $transaction["remittanceInformationUnstructured"];
 | 
			
		||||
        else if (array_key_exists('remittanceInformationUnstructuredArray', $transaction))
 | 
			
		||||
            $description = implode('\n', $transaction["remittanceInformationUnstructuredArray"]);
 | 
			
		||||
        else
 | 
			
		||||
            Log::warning("Missing description for the following transaction: " . json_encode($transaction));
 | 
			
		||||
    if (!array_key_exists('transactionId', $transaction) || !array_key_exists('transactionAmount', $transaction))
 | 
			
		||||
      throw new \Exception('invalid dataset');
 | 
			
		||||
 | 
			
		||||
        // participant
 | 
			
		||||
        $participant = array_key_exists('debtorAccount', $transaction) && array_key_exists('iban', $transaction["debtorAccount"]) ?
 | 
			
		||||
            $transaction['debtorAccount']['iban'] :
 | 
			
		||||
            (array_key_exists('creditorAccount', $transaction) && array_key_exists('iban', $transaction["creditorAccount"]) ?
 | 
			
		||||
                $transaction['creditorAccount']['iban'] : null);
 | 
			
		||||
        $participant_name = array_key_exists('debtorName', $transaction) ?
 | 
			
		||||
            $transaction['debtorName'] :
 | 
			
		||||
            (array_key_exists('creditorName', $transaction) ?
 | 
			
		||||
                $transaction['creditorName'] : null);
 | 
			
		||||
    // description could be in varios places
 | 
			
		||||
    $description = '';
 | 
			
		||||
    if (array_key_exists('remittanceInformationStructured', $transaction))
 | 
			
		||||
      $description = $transaction["remittanceInformationStructured"];
 | 
			
		||||
    else if (array_key_exists('remittanceInformationStructuredArray', $transaction))
 | 
			
		||||
      $description = implode('\n', $transaction["remittanceInformationStructuredArray"]);
 | 
			
		||||
    else if (array_key_exists('remittanceInformationUnstructured', $transaction))
 | 
			
		||||
      $description = $transaction["remittanceInformationUnstructured"];
 | 
			
		||||
    else if (array_key_exists('remittanceInformationUnstructuredArray', $transaction))
 | 
			
		||||
      $description = implode('\n', $transaction["remittanceInformationUnstructuredArray"]);
 | 
			
		||||
    else
 | 
			
		||||
      Log::warning("Missing description for the following transaction: " . json_encode($transaction));
 | 
			
		||||
 | 
			
		||||
        return [
 | 
			
		||||
            'transaction_id' => $transaction["transactionId"],
 | 
			
		||||
            'amount' => (int) $transaction["transactionAmount"]["amount"],
 | 
			
		||||
            'currency_id' => $this->convertCurrency($transaction["transactionAmount"]["currency"]),
 | 
			
		||||
            'category_id' => null, // nordigen has no categories
 | 
			
		||||
            'category_type' => array_key_exists('additionalInformation', $transaction) ? $transaction["additionalInformation"] : null, // TODO: institution specific keys like: GUTSCHRIFT, ABSCHLUSS, MONATSABSCHLUSS etc
 | 
			
		||||
            'date' => $transaction["bookingDate"],
 | 
			
		||||
            'description' => $description,
 | 
			
		||||
            'participant' => $participant,
 | 
			
		||||
            'participant_name' => $participant_name,
 | 
			
		||||
            'base_type' => (int) $transaction["transactionAmount"]["amount"] <= 0 ? 'DEBIT' : 'CREDIT',
 | 
			
		||||
        ];
 | 
			
		||||
    // participant
 | 
			
		||||
    $participant = array_key_exists('debtorAccount', $transaction) && array_key_exists('iban', $transaction["debtorAccount"]) ?
 | 
			
		||||
      $transaction['debtorAccount']['iban'] :
 | 
			
		||||
      (array_key_exists('creditorAccount', $transaction) && array_key_exists('iban', $transaction["creditorAccount"]) ?
 | 
			
		||||
        $transaction['creditorAccount']['iban'] : null);
 | 
			
		||||
    $participant_name = array_key_exists('debtorName', $transaction) ?
 | 
			
		||||
      $transaction['debtorName'] :
 | 
			
		||||
      (array_key_exists('creditorName', $transaction) ?
 | 
			
		||||
        $transaction['creditorName'] : null);
 | 
			
		||||
 | 
			
		||||
    return [
 | 
			
		||||
      'transaction_id' => $transaction["transactionId"],
 | 
			
		||||
      'amount' => (int) $transaction["transactionAmount"]["amount"],
 | 
			
		||||
      'currency_id' => $this->convertCurrency($transaction["transactionAmount"]["currency"]),
 | 
			
		||||
      'category_id' => null,
 | 
			
		||||
      'category_type' => array_key_exists('additionalInformation', $transaction) ? $transaction["additionalInformation"] : '',
 | 
			
		||||
      'date' => $transaction["bookingDate"],
 | 
			
		||||
      'description' => $description,
 | 
			
		||||
      'participant' => $participant,
 | 
			
		||||
      'participant_name' => $participant_name,
 | 
			
		||||
      'base_type' => (int) $transaction["transactionAmount"]["amount"] <= 0 ? 'DEBIT' : 'CREDIT',
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private function convertCurrency(string $code)
 | 
			
		||||
  {
 | 
			
		||||
 | 
			
		||||
    $currencies = Cache::get('currencies');
 | 
			
		||||
 | 
			
		||||
    if (!$currencies) {
 | 
			
		||||
      $this->buildCache(true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function convertCurrency(string $code)
 | 
			
		||||
    {
 | 
			
		||||
    $currency = $currencies->filter(function ($item) use ($code) {
 | 
			
		||||
      return $item->code == $code;
 | 
			
		||||
    })->first();
 | 
			
		||||
 | 
			
		||||
        $currencies = Cache::get('currencies');
 | 
			
		||||
    if ($currency)
 | 
			
		||||
      return $currency->id;
 | 
			
		||||
 | 
			
		||||
        if (!$currencies) {
 | 
			
		||||
            $this->buildCache(true);
 | 
			
		||||
        }
 | 
			
		||||
    return 1;
 | 
			
		||||
 | 
			
		||||
        $currency = $currencies->filter(function ($item) use ($code) {
 | 
			
		||||
            return $item->code == $code;
 | 
			
		||||
        })->first();
 | 
			
		||||
 | 
			
		||||
        if ($currency)
 | 
			
		||||
            return $currency->id;
 | 
			
		||||
 | 
			
		||||
        return 1;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										96
									
								
								app/Helpers/Chorus/Piste.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								app/Helpers/Chorus/Piste.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,96 @@
 | 
			
		||||
<?php
 | 
			
		||||
/**
 | 
			
		||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
			
		||||
 *
 | 
			
		||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
			
		||||
 *
 | 
			
		||||
 * @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
 | 
			
		||||
 *
 | 
			
		||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace App\Helpers\Chorus;
 | 
			
		||||
 | 
			
		||||
use Http;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class Piste.
 | 
			
		||||
 */
 | 
			
		||||
class Piste
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    private string $oauth_sandbox_url = 'https://sandbox-oauth.piste.gouv.fr/api/oauth/token';
 | 
			
		||||
    private string $oauth_production_url = 'https://oauth.piste.gouv.fr/api/oauth/token';
 | 
			
		||||
    private string $sandbox_url = 'https://sandbox-api.piste.gouv.fr';
 | 
			
		||||
    private string $production_url = 'https://api.piste.gouv.fr';
 | 
			
		||||
 | 
			
		||||
    private bool $test_mode = false;
 | 
			
		||||
 | 
			
		||||
    public function __construct(private string $username, private string $password)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function setMode($testmode = true): self
 | 
			
		||||
    {
 | 
			
		||||
        $this->test_mode = $testmode;
 | 
			
		||||
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function oauthHeaders(): array
 | 
			
		||||
    {
 | 
			
		||||
        return [
 | 
			
		||||
            'grant_type' => 'client_credentials',
 | 
			
		||||
            'client_id' => config('services.chorus.client_id'),
 | 
			
		||||
            'client_secret' => config('services.chorus.secret'),
 | 
			
		||||
            'scope' => 'openid profile'
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
        
 | 
			
		||||
    private function oauthUrl(): string
 | 
			
		||||
    {
 | 
			
		||||
        return $this->test_mode ? $this->oauth_sandbox_url : $this->oauth_production_url;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function apiUrl(): string
 | 
			
		||||
    {
 | 
			
		||||
        return $this->test_mode ? $this->sandbox_url : $this->production_url;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getOauthAccessToken(): ?string
 | 
			
		||||
    {
 | 
			
		||||
        $response = Http::asForm()->post($this->oauthUrl(), $this->oauthHeaders());
 | 
			
		||||
 | 
			
		||||
        if($response->successful()) {
 | 
			
		||||
            return $response->json()['access_token'];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function execute(string $uri, array $data = [])
 | 
			
		||||
    {
 | 
			
		||||
        $access_token = $this->getOauthAccessToken();
 | 
			
		||||
 | 
			
		||||
        nlog($access_token);
 | 
			
		||||
        nlog($this->username);
 | 
			
		||||
        nlog($this->password);
 | 
			
		||||
        nlog(base64_encode($this->username . ':' . $this->password));
 | 
			
		||||
 | 
			
		||||
        $r = Http::withToken($access_token)
 | 
			
		||||
                    ->withHeaders([
 | 
			
		||||
                        'cpro-account' => base64_encode($this->username . ':' . $this->password),
 | 
			
		||||
                        'Content-Type' => 'application/json;charset=utf-8',
 | 
			
		||||
                        'Accept' => 'application/json;charset=utf-8'
 | 
			
		||||
                    ])
 | 
			
		||||
                    ->post($this->apiUrl() . '/cpro/factures/'. $uri, $data);
 | 
			
		||||
 | 
			
		||||
        nlog($r);
 | 
			
		||||
        nlog($r->json());
 | 
			
		||||
        nlog($r->successful());
 | 
			
		||||
        nlog($r->body());
 | 
			
		||||
        nlog($r->collect());
 | 
			
		||||
        return $r;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -115,7 +115,7 @@ class SwissQrGenerator
 | 
			
		||||
        } else {
 | 
			
		||||
            $tempInvoiceNumber = $this->invoice->number;
 | 
			
		||||
            $tempInvoiceNumber = preg_replace('/[^A-Za-z0-9]/', '', $tempInvoiceNumber);
 | 
			
		||||
            $tempInvoiceNumber = substr($tempInvoiceNumber, 1);
 | 
			
		||||
            // $tempInvoiceNumber = substr($tempInvoiceNumber, 1);
 | 
			
		||||
        
 | 
			
		||||
            $calcInvoiceNumber = "";
 | 
			
		||||
            $array = str_split($tempInvoiceNumber);
 | 
			
		||||
 | 
			
		||||
@ -31,8 +31,11 @@ class NordigenController extends BaseController
 | 
			
		||||
    public function connect(ConnectNordigenBankIntegrationRequest $request)
 | 
			
		||||
    {
 | 
			
		||||
        $data = $request->all();
 | 
			
		||||
 | 
			
		||||
        /** @var array $context */
 | 
			
		||||
        $context = $request->getTokenContent();
 | 
			
		||||
        $lang = $data['lang'] ?? 'en';
 | 
			
		||||
        $company = $request->getCompany();
 | 
			
		||||
        $lang = $company->locale();
 | 
			
		||||
        $context["lang"] = $lang;
 | 
			
		||||
 | 
			
		||||
        if (!$context)
 | 
			
		||||
@ -62,7 +65,7 @@ class NordigenController extends BaseController
 | 
			
		||||
                "redirectUrl" => $context["redirect"] . "?action=nordigen_connect&status=failed&reason=account-config-invalid",
 | 
			
		||||
            ]);
 | 
			
		||||
 | 
			
		||||
        if (!(Ninja::isSelfHost() || (Ninja::isHosted() && $account->isPaid() && $account->plan == 'enterprise')))
 | 
			
		||||
        if (!(Ninja::isSelfHost() || (Ninja::isHosted() && $account->isEnterprisePaidClient())))
 | 
			
		||||
            return view('bank.nordigen.handler', [
 | 
			
		||||
                'lang' => $lang,
 | 
			
		||||
                'company' => $company,
 | 
			
		||||
@ -85,7 +88,7 @@ class NordigenController extends BaseController
 | 
			
		||||
 | 
			
		||||
        // redirect to requisition flow
 | 
			
		||||
        try {
 | 
			
		||||
            $requisition = $nordigen->createRequisition(config('ninja.app_url') . '/nordigen/confirm', $data['institution_id'], $request->token);
 | 
			
		||||
            $requisition = $nordigen->createRequisition(config('ninja.app_url') . '/nordigen/confirm', $data['institution_id'], $request->token, $lang);
 | 
			
		||||
        } catch (NordigenException $e) { // TODO: property_exists returns null in these cases... => why => therefore we just get unknown error everytime $responseBody is typeof GuzzleHttp\Psr7\Stream
 | 
			
		||||
            $responseBody = (string) $e->getResponse()->getBody();
 | 
			
		||||
 | 
			
		||||
@ -128,15 +131,19 @@ class NordigenController extends BaseController
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * VIEW: Confirm Nordigen Bank Integration (redirect after nordigen flow)
 | 
			
		||||
     * @param ConnectNordigenBankIntegrationRequest $request
 | 
			
		||||
     * @param ConfirmNordigenBankIntegrationRequest $request
 | 
			
		||||
     */
 | 
			
		||||
    public function confirm(ConfirmNordigenBankIntegrationRequest $request)
 | 
			
		||||
    {
 | 
			
		||||
        $data = $request->all();
 | 
			
		||||
        $company = $request->getCompany();
 | 
			
		||||
        $account = $company->account;
 | 
			
		||||
        $lang = $company->locale();
 | 
			
		||||
 | 
			
		||||
        /** @var array $context */
 | 
			
		||||
        $context = $request->getTokenContent();
 | 
			
		||||
        if (!array_key_exists('lang', $data) && $context['lang'] != 'en')
 | 
			
		||||
            return redirect()->route('nordigen.confirm', array_merge(["lang" => $context['lang']], $request->query())); // redirect is required in order for the bank-ui to display everything properly
 | 
			
		||||
        $lang = $data['lang'] ?? 'en';
 | 
			
		||||
            return redirect()->route('nordigen.confirm', array_merge(["lang" => $context['lang']], $request->query()));
 | 
			
		||||
 | 
			
		||||
        if (!$context || $context["context"] != "nordigen" || !array_key_exists("requisitionId", $context))
 | 
			
		||||
            return view('bank.nordigen.handler', [
 | 
			
		||||
@ -145,9 +152,6 @@ class NordigenController extends BaseController
 | 
			
		||||
                "redirectUrl" => ($context && array_key_exists("redirect", $context) ? $context["redirect"] : config('ninja.app_url')) . "?action=nordigen_connect&status=failed&reason=ref-invalid",
 | 
			
		||||
            ]);
 | 
			
		||||
 | 
			
		||||
        $company = $request->getCompany();
 | 
			
		||||
        $account = $company->account;
 | 
			
		||||
 | 
			
		||||
        if (!(config('ninja.nordigen.secret_id') && config('ninja.nordigen.secret_key')))
 | 
			
		||||
            return view('bank.nordigen.handler', [
 | 
			
		||||
                'lang' => $lang,
 | 
			
		||||
@ -157,7 +161,7 @@ class NordigenController extends BaseController
 | 
			
		||||
                "redirectUrl" => $context["redirect"] . "?action=nordigen_connect&status=failed&reason=account-config-invalid",
 | 
			
		||||
            ]);
 | 
			
		||||
 | 
			
		||||
        if (!(Ninja::isSelfHost() || (Ninja::isHosted() && $account->isPaid() && $account->plan == 'enterprise')))
 | 
			
		||||
        if (!(Ninja::isSelfHost() || (Ninja::isHosted() && $account->isEnterprisePaidClient())))
 | 
			
		||||
            return view('bank.nordigen.handler', [
 | 
			
		||||
                'lang' => $lang,
 | 
			
		||||
                'company' => $company,
 | 
			
		||||
@ -202,7 +206,7 @@ class NordigenController extends BaseController
 | 
			
		||||
 | 
			
		||||
            $nordigen_account = $nordigen->getAccount($nordigenAccountId);
 | 
			
		||||
 | 
			
		||||
            $existing_bank_integration = BankIntegration::withTrashed()->where('nordigen_account_id', $nordigen_account['id'])->where('company_id', $company->id)->first();
 | 
			
		||||
            $existing_bank_integration = BankIntegration::withTrashed()->where('nordigen_account_id', $nordigen_account['id'])->where('company_id', $company->id)->where('is_deleted', 0)->first();
 | 
			
		||||
 | 
			
		||||
            if (!$existing_bank_integration) {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -212,7 +212,7 @@ class BankIntegrationController extends BaseController
 | 
			
		||||
                ProcessBankTransactionsYodlee::dispatch($user_account->id, $bank_integration);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        if (config('ninja.nordigen.secret_id') && config('ninja.nordigen.secret_key') && (Ninja::isSelfHost() || (Ninja::isHosted() && $user_account->isPaid() && $user_account->plan == 'enterprise')))
 | 
			
		||||
        if (config('ninja.nordigen.secret_id') && config('ninja.nordigen.secret_key') && (Ninja::isSelfHost() || (Ninja::isHosted() && $user_account->isEnterprisePaidClient())))
 | 
			
		||||
            $user_account->bank_integrations->where("integration_type", BankIntegration::INTEGRATION_TYPE_NORDIGEN)->each(function ($bank_integration) {
 | 
			
		||||
                ProcessBankTransactionsNordigen::dispatch($bank_integration);
 | 
			
		||||
            });
 | 
			
		||||
@ -298,11 +298,14 @@ class BankIntegrationController extends BaseController
 | 
			
		||||
 | 
			
		||||
        $account = $user->account;
 | 
			
		||||
 | 
			
		||||
        $bank_integration = BankIntegration::withTrashed()->where('bank_account_id', $acc_id)->orWhere('nordigen_account_id', $acc_id)->company()->firstOrFail(); // @turbo124 please check
 | 
			
		||||
        $bank_integration = BankIntegration::withTrashed()
 | 
			
		||||
                                        ->where('bank_account_id', $acc_id)
 | 
			
		||||
                                        ->orWhere('nordigen_account_id', $acc_id)
 | 
			
		||||
                                        ->company()
 | 
			
		||||
                                        ->firstOrFail();
 | 
			
		||||
 | 
			
		||||
        if ($bank_integration->integration_type == BankIntegration::INTEGRATION_TYPE_YODLEE)
 | 
			
		||||
            $this->removeAccountYodlee($account, $bank_integration);
 | 
			
		||||
        // we dont remove Accounts from nordigen, because they could be used within other companies
 | 
			
		||||
 | 
			
		||||
        $this->bank_integration_repo->delete($bank_integration);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -605,7 +605,7 @@ class CreditController extends BaseController
 | 
			
		||||
                // code...
 | 
			
		||||
                break;
 | 
			
		||||
            case 'mark_sent':
 | 
			
		||||
                $credit->service()->markSent()->save();
 | 
			
		||||
                $credit->service()->markSent(true)->save();
 | 
			
		||||
 | 
			
		||||
                if (! $bulk) {
 | 
			
		||||
                    return $this->itemResponse($credit);
 | 
			
		||||
@ -646,7 +646,7 @@ class CreditController extends BaseController
 | 
			
		||||
                    EmailEntity::dispatch($invitation, $credit->company, 'credit');
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                $credit->sendEvent(Webhook::EVENT_SENT_CREDIT, "client");
 | 
			
		||||
                // $credit->sendEvent(Webhook::EVENT_SENT_CREDIT, "client");
 | 
			
		||||
 | 
			
		||||
                if (! $bulk) {
 | 
			
		||||
                    return response()->json(['message'=>'email sent'], 200);
 | 
			
		||||
 | 
			
		||||
@ -562,6 +562,16 @@ class InvoiceController extends BaseController
 | 
			
		||||
            return response()->json(['message' => $hash_or_response], 200);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if($action == 'set_payment_link' && $request->has('subscription_id')) {
 | 
			
		||||
            
 | 
			
		||||
            $invoices->each(function ($invoice)  use($user, $request){
 | 
			
		||||
                if($user->can('edit', $invoice))
 | 
			
		||||
                    $invoice->service()->setPaymentLink($request->subscription_id)->save();
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            return $this->listResponse(Invoice::query()->withTrashed()->whereIn('id', $this->transformKeys($ids))->company());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
         * Send the other actions to the switch
 | 
			
		||||
         */
 | 
			
		||||
 | 
			
		||||
@ -71,7 +71,6 @@ class PreviewController extends BaseController
 | 
			
		||||
 | 
			
		||||
        $ps = new PdfService($invitation, 'product', [
 | 
			
		||||
            'client' => $client ?? false,
 | 
			
		||||
            // 'vendor' => $vendor ?? false,
 | 
			
		||||
            "{$entity_prop}s" => [$entity_obj],
 | 
			
		||||
        ]);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -191,7 +191,7 @@ class PreviewPurchaseOrderController extends BaseController
 | 
			
		||||
            $invitation->setRelation($request->entity, $entity_obj);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
        $ps = new PdfService($invitation, 'purchase_order', [
 | 
			
		||||
            'client' => $entity_obj->client ?? false,
 | 
			
		||||
            'vendor' => $vendor ?? false,
 | 
			
		||||
 | 
			
		||||
@ -387,7 +387,6 @@ class RecurringInvoiceController extends BaseController
 | 
			
		||||
 | 
			
		||||
        $recurring_invoice->service()
 | 
			
		||||
                          ->triggeredActions($request)
 | 
			
		||||
                        //   ->deletePdf()
 | 
			
		||||
                          ->save();
 | 
			
		||||
 | 
			
		||||
        event(new RecurringInvoiceWasUpdated($recurring_invoice, $recurring_invoice->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
 | 
			
		||||
@ -425,13 +424,26 @@ class RecurringInvoiceController extends BaseController
 | 
			
		||||
 | 
			
		||||
        $recurring_invoices = RecurringInvoice::withTrashed()->find($request->ids);
 | 
			
		||||
 | 
			
		||||
                
 | 
			
		||||
        if($request->action == 'set_payment_link' && $request->has('subscription_id')) {
 | 
			
		||||
 | 
			
		||||
            $recurring_invoices->each(function ($invoice) use ($user, $request) {
 | 
			
		||||
                if($user->can('edit', $invoice)) {
 | 
			
		||||
                    $invoice->service()->setPaymentLink($request->subscription_id)->save();
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            return $this->listResponse(RecurringInvoice::query()->withTrashed()->whereIn('id', $request->ids)->company());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $recurring_invoices->each(function ($recurring_invoice, $key) use ($request, $user) {
 | 
			
		||||
            if ($user->can('edit', $recurring_invoice)) {
 | 
			
		||||
                $this->performAction($recurring_invoice, $request->action, true);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        return $this->listResponse(RecurringInvoice::withTrashed()->whereIn('id', $request->ids));
 | 
			
		||||
        return $this->listResponse(RecurringInvoice::query()->withTrashed()->whereIn('id', $request->ids)->company());
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 | 
			
		||||
@ -56,6 +56,7 @@ class Locale
 | 
			
		||||
                        'bg',
 | 
			
		||||
                        'he',
 | 
			
		||||
                        'km_KH',
 | 
			
		||||
                        'lo_LA',
 | 
			
		||||
                        'hu',
 | 
			
		||||
                        'fr_CH',
 | 
			
		||||
                    ];
 | 
			
		||||
 | 
			
		||||
@ -58,6 +58,7 @@ class VendorLocale
 | 
			
		||||
                    'km_KH',
 | 
			
		||||
                    'hu',
 | 
			
		||||
                    'fr_CH',
 | 
			
		||||
                    'lo_LA',
 | 
			
		||||
                ];
 | 
			
		||||
    /**
 | 
			
		||||
     * Handle an incoming request.
 | 
			
		||||
 | 
			
		||||
@ -28,7 +28,8 @@ class BulkInvoiceRequest extends Request
 | 
			
		||||
            'email_type' => 'sometimes|in:reminder1,reminder2,reminder3,reminder_endless,custom1,custom2,custom3,invoice,quote,credit,payment,payment_partial,statement,purchase_order',
 | 
			
		||||
            'template' => 'sometimes|string',
 | 
			
		||||
            'template_id' => 'sometimes|string',
 | 
			
		||||
            'send_email' => 'sometimes|bool'
 | 
			
		||||
            'send_email' => 'sometimes|bool',
 | 
			
		||||
            'subscriptin_id' => 'sometimes|string',
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -36,7 +36,7 @@ class LoginRequest extends Request
 | 
			
		||||
    public function rules()
 | 
			
		||||
    {
 | 
			
		||||
        if (Ninja::isHosted()) {
 | 
			
		||||
            $email_rules = ['required', new BlackListRule, new EmailBlackListRule];
 | 
			
		||||
            $email_rules = ['required', new EmailBlackListRule];
 | 
			
		||||
        } else {
 | 
			
		||||
            $email_rules = 'required';
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -36,24 +36,19 @@ class ConnectNordigenBankIntegrationRequest extends Request
 | 
			
		||||
    public function rules()
 | 
			
		||||
    {
 | 
			
		||||
        return [
 | 
			
		||||
            'lang' => 'string',
 | 
			
		||||
            'institution_id' => 'string',
 | 
			
		||||
            'redirect' => 'string',
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // @turbo124 @todo please check for validity, when request from frontend
 | 
			
		||||
    public function prepareForValidation()
 | 
			
		||||
    {
 | 
			
		||||
        $input = $this->all();
 | 
			
		||||
 | 
			
		||||
        if (!array_key_exists('redirect', $input)) {
 | 
			
		||||
            $context = $this->getTokenContent();
 | 
			
		||||
        $context = $this->getTokenContent();
 | 
			
		||||
 | 
			
		||||
            $input["redirect"] = isset($context["is_react"]) && $context['is_react'] ? config('ninja.react_url') . "/#/settings/bank_accounts" : config('ninja.app_url');
 | 
			
		||||
        $input["redirect"] = isset($context["is_react"]) && $context['is_react'] ? config('ninja.react_url') . "/#/settings/bank_accounts" : config('ninja.app_url');
 | 
			
		||||
 | 
			
		||||
            $this->replace($input);
 | 
			
		||||
        }
 | 
			
		||||
        $this->replace($input);
 | 
			
		||||
       
 | 
			
		||||
    }
 | 
			
		||||
    public function getTokenContent()
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
@ -58,7 +58,11 @@ class PreviewPurchaseOrderRequest extends Request
 | 
			
		||||
        $input['amount'] = 0;
 | 
			
		||||
        $input['balance'] = 0;
 | 
			
		||||
        $input['number'] = isset($input['number']) ? $input['number'] : ctrans('texts.live_preview').' #'.rand(0, 1000); //30-06-2023
 | 
			
		||||
        
 | 
			
		||||
                
 | 
			
		||||
        if($input['entity_id'] ?? false) {
 | 
			
		||||
            $input['entity_id'] = $this->decodePrimaryKey($input['entity_id'], true);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->replace($input);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -31,10 +31,14 @@ class BulkRecurringInvoiceRequest extends Request
 | 
			
		||||
 | 
			
		||||
    public function rules()
 | 
			
		||||
    {
 | 
			
		||||
        /** @var \App\Models\User $user */
 | 
			
		||||
        $user = auth()->user();
 | 
			
		||||
 | 
			
		||||
        return [
 | 
			
		||||
            'ids' => ['required','bail','array',Rule::exists('recurring_invoices', 'id')->where('company_id', auth()->user()->company()->id)],
 | 
			
		||||
            'action' => 'in:archive,restore,delete,increase_prices,update_prices,start,stop,send_now',
 | 
			
		||||
            'ids' => ['required','bail','array', Rule::exists('recurring_invoices', 'id')->where('company_id', $user->company()->id)],
 | 
			
		||||
            'action' => 'in:archive,restore,delete,increase_prices,update_prices,start,stop,send_now,set_payment_link',
 | 
			
		||||
            'percentage_increase' => 'required_if:action,increase_prices|numeric|min:0|max:100',
 | 
			
		||||
            'subscription_id' => 'sometimes|string'
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -11,14 +11,19 @@
 | 
			
		||||
 | 
			
		||||
namespace App\Http\ValidationRules\Account;
 | 
			
		||||
 | 
			
		||||
use Illuminate\Contracts\Validation\Rule;
 | 
			
		||||
use Closure;
 | 
			
		||||
use Illuminate\Contracts\Validation\ValidationRule;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class BlackListRule.
 | 
			
		||||
 */
 | 
			
		||||
class BlackListRule implements Rule
 | 
			
		||||
class BlackListRule implements ValidationRule
 | 
			
		||||
{
 | 
			
		||||
    /** Bad domains +/- dispoable email domains */
 | 
			
		||||
    private array $blacklist = [
 | 
			
		||||
        'secure-coinspot.com',
 | 
			
		||||
        'casasotombo.com',
 | 
			
		||||
        'otpku.com',
 | 
			
		||||
        'ckptr.com',
 | 
			
		||||
        'pretreer.com',
 | 
			
		||||
        'candassociates.com',
 | 
			
		||||
@ -57,6 +62,8 @@ class BlackListRule implements Rule
 | 
			
		||||
        '10dk.email',
 | 
			
		||||
        '10mail.com',
 | 
			
		||||
        '10mail.org',
 | 
			
		||||
        '10mail.tk',
 | 
			
		||||
        '10minmail.de',
 | 
			
		||||
        '10minut.com.pl',
 | 
			
		||||
        '10minut.xyz',
 | 
			
		||||
        '10minutemail.be',
 | 
			
		||||
@ -75,6 +82,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        '10minutemailbox.com',
 | 
			
		||||
        '10minutemails.in',
 | 
			
		||||
        '10minutenemail.de',
 | 
			
		||||
        '10minutenmail.xyz',
 | 
			
		||||
        '10minutesmail.com',
 | 
			
		||||
        '10minutesmail.fr',
 | 
			
		||||
        '10minutmail.pl',
 | 
			
		||||
@ -268,6 +276,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'affinitywe.us',
 | 
			
		||||
        'affluentwe.us',
 | 
			
		||||
        'affordablewe.us',
 | 
			
		||||
        'afia.pro',
 | 
			
		||||
        'afrobacon.com',
 | 
			
		||||
        'afterhourswe.us',
 | 
			
		||||
        'agedmail.com',
 | 
			
		||||
@ -287,6 +296,8 @@ class BlackListRule implements Rule
 | 
			
		||||
        'akapost.com',
 | 
			
		||||
        'akerd.com',
 | 
			
		||||
        'akgq701.com',
 | 
			
		||||
        'akmail.in',
 | 
			
		||||
        'akugu.com',
 | 
			
		||||
        'al-qaeda.us',
 | 
			
		||||
        'albionwe.us',
 | 
			
		||||
        'alchemywe.us',
 | 
			
		||||
@ -294,6 +305,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'aliaswe.us',
 | 
			
		||||
        'alienware13.com',
 | 
			
		||||
        'aligamel.com',
 | 
			
		||||
        'alina-schiesser.ch',
 | 
			
		||||
        'alisongamel.com',
 | 
			
		||||
        'alivance.com',
 | 
			
		||||
        'alivewe.us',
 | 
			
		||||
@ -376,6 +388,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'antispam.de',
 | 
			
		||||
        'antispam24.de',
 | 
			
		||||
        'antispammail.de',
 | 
			
		||||
        'any.pink',
 | 
			
		||||
        'anyalias.com',
 | 
			
		||||
        'aoeuhtns.com',
 | 
			
		||||
        'apfelkorps.de',
 | 
			
		||||
@ -440,10 +453,12 @@ class BlackListRule implements Rule
 | 
			
		||||
        'badoop.com',
 | 
			
		||||
        'badpotato.tk',
 | 
			
		||||
        'balaket.com',
 | 
			
		||||
        'bangban.uk',
 | 
			
		||||
        'banit.club',
 | 
			
		||||
        'banit.me',
 | 
			
		||||
        'bank-opros1.ru',
 | 
			
		||||
        'bareed.ws',
 | 
			
		||||
        'barooko.com',
 | 
			
		||||
        'barryogorman.com',
 | 
			
		||||
        'bartdevos.be',
 | 
			
		||||
        'basscode.org',
 | 
			
		||||
@ -451,11 +466,15 @@ class BlackListRule implements Rule
 | 
			
		||||
        'bazaaboom.com',
 | 
			
		||||
        'bbbbyyzz.info',
 | 
			
		||||
        'bbhost.us',
 | 
			
		||||
        'bbitf.com',
 | 
			
		||||
        'bbitj.com',
 | 
			
		||||
        'bbitq.com',
 | 
			
		||||
        'bcaoo.com',
 | 
			
		||||
        'bcast.ws',
 | 
			
		||||
        'bcb.ro',
 | 
			
		||||
        'bccto.me',
 | 
			
		||||
        'bdmuzic.pw',
 | 
			
		||||
        'beaconmessenger.com',
 | 
			
		||||
        'bearsarefuzzy.com',
 | 
			
		||||
        'beddly.com',
 | 
			
		||||
        'beefmilk.com',
 | 
			
		||||
@ -477,6 +496,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'betr.co',
 | 
			
		||||
        'bgtmail.com',
 | 
			
		||||
        'bgx.ro',
 | 
			
		||||
        'bheps.com',
 | 
			
		||||
        'bidourlnks.com',
 | 
			
		||||
        'big1.us',
 | 
			
		||||
        'bigprofessor.so',
 | 
			
		||||
@ -520,9 +540,11 @@ class BlackListRule implements Rule
 | 
			
		||||
        'bouncr.com',
 | 
			
		||||
        'boxformail.in',
 | 
			
		||||
        'boximail.com',
 | 
			
		||||
        'boxmail.lol',
 | 
			
		||||
        'boxomail.live',
 | 
			
		||||
        'boxtemp.com.br',
 | 
			
		||||
        'bptfp.net',
 | 
			
		||||
        'brand-app.biz',
 | 
			
		||||
        'brandallday.net',
 | 
			
		||||
        'brasx.org',
 | 
			
		||||
        'breakthru.com',
 | 
			
		||||
@ -543,8 +565,10 @@ class BlackListRule implements Rule
 | 
			
		||||
        'budaya-tionghoa.com',
 | 
			
		||||
        'budayationghoa.com',
 | 
			
		||||
        'buffemail.com',
 | 
			
		||||
        'bugfoo.com',
 | 
			
		||||
        'bugmenever.com',
 | 
			
		||||
        'bugmenot.com',
 | 
			
		||||
        'bukhariansiddur.com',
 | 
			
		||||
        'bulrushpress.com',
 | 
			
		||||
        'bum.net',
 | 
			
		||||
        'bumpymail.com',
 | 
			
		||||
@ -582,6 +606,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'caseedu.tk',
 | 
			
		||||
        'cashflow35.com',
 | 
			
		||||
        'casualdx.com',
 | 
			
		||||
        'catgroup.uk',
 | 
			
		||||
        'cavi.mx',
 | 
			
		||||
        'cbair.com',
 | 
			
		||||
        'cbes.net',
 | 
			
		||||
@ -605,6 +630,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'cheaphub.net',
 | 
			
		||||
        'cheatmail.de',
 | 
			
		||||
        'chenbot.email',
 | 
			
		||||
        'chewydonut.com',
 | 
			
		||||
        'chibakenma.ml',
 | 
			
		||||
        'chickenkiller.com',
 | 
			
		||||
        'chielo.com',
 | 
			
		||||
@ -621,6 +647,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'chong-mail.org',
 | 
			
		||||
        'chumpstakingdumps.com',
 | 
			
		||||
        'cigar-auctions.com',
 | 
			
		||||
        'civikli.com',
 | 
			
		||||
        'civx.org',
 | 
			
		||||
        'ckaazaza.tk',
 | 
			
		||||
        'ckiso.com',
 | 
			
		||||
@ -637,6 +664,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'clonemoi.tk',
 | 
			
		||||
        'cloud-mail.top',
 | 
			
		||||
        'cloudns.cx',
 | 
			
		||||
        'clout.wiki',
 | 
			
		||||
        'clrmail.com',
 | 
			
		||||
        'cmail.club',
 | 
			
		||||
        'cmail.com',
 | 
			
		||||
@ -678,6 +706,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'crazymailing.com',
 | 
			
		||||
        'cream.pink',
 | 
			
		||||
        'crepeau12.com',
 | 
			
		||||
        'cringemonster.com',
 | 
			
		||||
        'cross-law.ga',
 | 
			
		||||
        'cross-law.gq',
 | 
			
		||||
        'crossmailjet.com',
 | 
			
		||||
@ -733,6 +762,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'daymailonline.com',
 | 
			
		||||
        'dayrep.com',
 | 
			
		||||
        'dbunker.com',
 | 
			
		||||
        'dcctb.com',
 | 
			
		||||
        'dcemail.com',
 | 
			
		||||
        'ddcrew.com',
 | 
			
		||||
        'de-a.org',
 | 
			
		||||
@ -769,6 +799,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'dev-null.ga',
 | 
			
		||||
        'dev-null.gq',
 | 
			
		||||
        'dev-null.ml',
 | 
			
		||||
        'developermail.com',
 | 
			
		||||
        'devnullmail.com',
 | 
			
		||||
        'deyom.com',
 | 
			
		||||
        'dharmatel.net',
 | 
			
		||||
@ -800,6 +831,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'discardmail.com',
 | 
			
		||||
        'discardmail.de',
 | 
			
		||||
        'discos4.com',
 | 
			
		||||
        'dishcatfish.com',
 | 
			
		||||
        'disign-concept.eu',
 | 
			
		||||
        'disign-revelation.com',
 | 
			
		||||
        'dispo.in',
 | 
			
		||||
@ -851,10 +883,12 @@ class BlackListRule implements Rule
 | 
			
		||||
        'domforfb8.tk',
 | 
			
		||||
        'domforfb9.tk',
 | 
			
		||||
        'domozmail.com',
 | 
			
		||||
        'donebyngle.com',
 | 
			
		||||
        'donemail.ru',
 | 
			
		||||
        'dongqing365.com',
 | 
			
		||||
        'dontreg.com',
 | 
			
		||||
        'dontsendmespam.de',
 | 
			
		||||
        'doojazz.com',
 | 
			
		||||
        'doquier.tk',
 | 
			
		||||
        'dotman.de',
 | 
			
		||||
        'dotmsg.com',
 | 
			
		||||
@ -869,13 +903,17 @@ class BlackListRule implements Rule
 | 
			
		||||
        'dred.ru',
 | 
			
		||||
        'drevo.si',
 | 
			
		||||
        'drivetagdev.com',
 | 
			
		||||
        'drmail.in',
 | 
			
		||||
        'droolingfanboy.de',
 | 
			
		||||
        'dropcake.de',
 | 
			
		||||
        'dropjar.com',
 | 
			
		||||
        'droplar.com',
 | 
			
		||||
        'dropmail.me',
 | 
			
		||||
        'dropsin.net',
 | 
			
		||||
        'drowblock.com',
 | 
			
		||||
        'dsgvo.party',
 | 
			
		||||
        'dsgvo.ru',
 | 
			
		||||
        'dshfjdafd.cloud',
 | 
			
		||||
        'dsiay.com',
 | 
			
		||||
        'dspwebservices.com',
 | 
			
		||||
        'duam.net',
 | 
			
		||||
@ -944,6 +982,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'emailage.ml',
 | 
			
		||||
        'emailage.tk',
 | 
			
		||||
        'emailate.com',
 | 
			
		||||
        'emailbin.net',
 | 
			
		||||
        'emailcu.icu',
 | 
			
		||||
        'emaildienst.de',
 | 
			
		||||
        'emaildrop.io',
 | 
			
		||||
@ -1017,8 +1056,11 @@ class BlackListRule implements Rule
 | 
			
		||||
        'eposta.buzz',
 | 
			
		||||
        'eposta.work',
 | 
			
		||||
        'eqiluxspam.ga',
 | 
			
		||||
        'ereplyzy.com',
 | 
			
		||||
        'ericjohnson.ml',
 | 
			
		||||
        'eripo.net',
 | 
			
		||||
        'ero-tube.org',
 | 
			
		||||
        'esadverse.com',
 | 
			
		||||
        'esbano-ru.ru',
 | 
			
		||||
        'esc.la',
 | 
			
		||||
        'escapehatchapp.com',
 | 
			
		||||
@ -1043,16 +1085,19 @@ class BlackListRule implements Rule
 | 
			
		||||
        'evopo.com',
 | 
			
		||||
        'evyush.com',
 | 
			
		||||
        'exdonuts.com',
 | 
			
		||||
        'exelica.com',
 | 
			
		||||
        'existiert.net',
 | 
			
		||||
        'exitstageleft.net',
 | 
			
		||||
        'explodemail.com',
 | 
			
		||||
        'express.net.ua',
 | 
			
		||||
        'extracurricularsociety.com',
 | 
			
		||||
        'extremail.ru',
 | 
			
		||||
        'eyepaste.com',
 | 
			
		||||
        'ez.lv',
 | 
			
		||||
        'ezehe.com',
 | 
			
		||||
        'ezfill.com',
 | 
			
		||||
        'ezstest.com',
 | 
			
		||||
        'ezztt.com',
 | 
			
		||||
        'f4k.es',
 | 
			
		||||
        'f5.si',
 | 
			
		||||
        'facebook-email.cf',
 | 
			
		||||
@ -1108,12 +1153,14 @@ class BlackListRule implements Rule
 | 
			
		||||
        'fbma.tk',
 | 
			
		||||
        'fddns.ml',
 | 
			
		||||
        'fdfdsfds.com',
 | 
			
		||||
        'femailtor.com',
 | 
			
		||||
        'fer-gabon.org',
 | 
			
		||||
        'fermaxxi.ru',
 | 
			
		||||
        'fettometern.com',
 | 
			
		||||
        'fexbox.org',
 | 
			
		||||
        'fexbox.ru',
 | 
			
		||||
        'fexpost.com',
 | 
			
		||||
        'fextemp.com',
 | 
			
		||||
        'ficken.de',
 | 
			
		||||
        'fictionsite.com',
 | 
			
		||||
        'fightallspam.com',
 | 
			
		||||
@ -1127,6 +1174,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'filzmail.com',
 | 
			
		||||
        'findemail.info',
 | 
			
		||||
        'findu.pl',
 | 
			
		||||
        'finews.biz',
 | 
			
		||||
        'fir.hk',
 | 
			
		||||
        'firemailbox.club',
 | 
			
		||||
        'fitnesrezink.ru',
 | 
			
		||||
@ -1135,12 +1183,14 @@ class BlackListRule implements Rule
 | 
			
		||||
        'fizmail.com',
 | 
			
		||||
        'fleckens.hu',
 | 
			
		||||
        'flemail.ru',
 | 
			
		||||
        'fliegender.fish',
 | 
			
		||||
        'flowu.com',
 | 
			
		||||
        'flu.cc',
 | 
			
		||||
        'fluidsoft.us',
 | 
			
		||||
        'flurred.com',
 | 
			
		||||
        'fly-ts.de',
 | 
			
		||||
        'flyinggeek.net',
 | 
			
		||||
        'flymail.tk',
 | 
			
		||||
        'flyspam.com',
 | 
			
		||||
        'foobarbot.net',
 | 
			
		||||
        'footard.com',
 | 
			
		||||
@ -1158,6 +1208,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'fosil.pro',
 | 
			
		||||
        'foxja.com',
 | 
			
		||||
        'foxtrotter.info',
 | 
			
		||||
        'fr.cr',
 | 
			
		||||
        'fr.nf',
 | 
			
		||||
        'fr33mail.info',
 | 
			
		||||
        'fragolina2.tk',
 | 
			
		||||
@ -1204,11 +1255,15 @@ class BlackListRule implements Rule
 | 
			
		||||
        'fuirio.com',
 | 
			
		||||
        'fukaru.com',
 | 
			
		||||
        'fukurou.ch',
 | 
			
		||||
        'fullangle.org',
 | 
			
		||||
        'fulvie.com',
 | 
			
		||||
        'fun64.com',
 | 
			
		||||
        'funnycodesnippets.com',
 | 
			
		||||
        'funnymail.de',
 | 
			
		||||
        'furzauflunge.de',
 | 
			
		||||
        'futuramind.com',
 | 
			
		||||
        'fuwa.be',
 | 
			
		||||
        'fuwa.li',
 | 
			
		||||
        'fuwamofu.com',
 | 
			
		||||
        'fuwari.be',
 | 
			
		||||
        'fux0ringduh.com',
 | 
			
		||||
@ -1291,6 +1346,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'giveh2o.info',
 | 
			
		||||
        'givememail.club',
 | 
			
		||||
        'givmail.com',
 | 
			
		||||
        'gixenmixen.com',
 | 
			
		||||
        'glitch.sx',
 | 
			
		||||
        'globaltouron.com',
 | 
			
		||||
        'glubex.com',
 | 
			
		||||
@ -1304,6 +1360,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'gnctr-calgary.com',
 | 
			
		||||
        'go2usa.info',
 | 
			
		||||
        'go2vpn.net',
 | 
			
		||||
        'goatmail.uk',
 | 
			
		||||
        'goemailgo.com',
 | 
			
		||||
        'golemico.com',
 | 
			
		||||
        'gomail.in',
 | 
			
		||||
@ -1363,6 +1420,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'guerrillamail.net',
 | 
			
		||||
        'guerrillamail.org',
 | 
			
		||||
        'guerrillamailblock.com',
 | 
			
		||||
        'gufum.com',
 | 
			
		||||
        'gustr.com',
 | 
			
		||||
        'gxemail.men',
 | 
			
		||||
        'gynzi.co.uk',
 | 
			
		||||
@ -1389,6 +1447,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'haltospam.com',
 | 
			
		||||
        'hamham.uk',
 | 
			
		||||
        'hangxomcuatoilatotoro.ml',
 | 
			
		||||
        'happy2023year.com',
 | 
			
		||||
        'happydomik.ru',
 | 
			
		||||
        'harakirimail.com',
 | 
			
		||||
        'haribu.com',
 | 
			
		||||
@ -1467,6 +1526,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'huskion.net',
 | 
			
		||||
        'hvastudiesucces.nl',
 | 
			
		||||
        'hwsye.net',
 | 
			
		||||
        'hypenated-domain.com',
 | 
			
		||||
        'i2pmail.org',
 | 
			
		||||
        'i6.cloudns.cc',
 | 
			
		||||
        'iaoss.com',
 | 
			
		||||
@ -1476,6 +1536,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'ichigo.me',
 | 
			
		||||
        'icx.in',
 | 
			
		||||
        'icx.ro',
 | 
			
		||||
        'icznn.com',
 | 
			
		||||
        'idx4.com',
 | 
			
		||||
        'idxue.com',
 | 
			
		||||
        'ieatspam.eu',
 | 
			
		||||
@ -1498,9 +1559,12 @@ class BlackListRule implements Rule
 | 
			
		||||
        'imgof.com',
 | 
			
		||||
        'imgv.de',
 | 
			
		||||
        'immo-gerance.info',
 | 
			
		||||
        'imperialcnk.com',
 | 
			
		||||
        'imstations.com',
 | 
			
		||||
        'imul.info',
 | 
			
		||||
        'in-ulm.de',
 | 
			
		||||
        'in2reach.com',
 | 
			
		||||
        'inactivemachine.com',
 | 
			
		||||
        'inbax.tk',
 | 
			
		||||
        'inbound.plus',
 | 
			
		||||
        'inbox.si',
 | 
			
		||||
@ -1530,6 +1594,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'ineec.net',
 | 
			
		||||
        'infocom.zp.ua',
 | 
			
		||||
        'inggo.org',
 | 
			
		||||
        'inkiny.com',
 | 
			
		||||
        'inkomail.com',
 | 
			
		||||
        'inmynetwork.tk',
 | 
			
		||||
        'inoutmail.de',
 | 
			
		||||
@ -1540,12 +1605,16 @@ class BlackListRule implements Rule
 | 
			
		||||
        'insanumingeniumhomebrew.com',
 | 
			
		||||
        'insorg-mail.info',
 | 
			
		||||
        'instaddr.ch',
 | 
			
		||||
        'instaddr.uk',
 | 
			
		||||
        'instaddr.win',
 | 
			
		||||
        'instance-email.com',
 | 
			
		||||
        'instant-mail.de',
 | 
			
		||||
        'instantblingmail.info',
 | 
			
		||||
        'instantemailaddress.com',
 | 
			
		||||
        'instantmail.fr',
 | 
			
		||||
        'instmail.uk',
 | 
			
		||||
        'internet-v-stavropole.ru',
 | 
			
		||||
        'internetkeno.com',
 | 
			
		||||
        'internetoftags.com',
 | 
			
		||||
        'interstats.org',
 | 
			
		||||
        'intersteller.com',
 | 
			
		||||
@ -1577,6 +1646,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'italy-mail.com',
 | 
			
		||||
        'itcompu.com',
 | 
			
		||||
        'itfast.net',
 | 
			
		||||
        'itsjiff.com',
 | 
			
		||||
        'itunesgiftcodegenerator.com',
 | 
			
		||||
        'iubridge.com',
 | 
			
		||||
        'iuemail.men',
 | 
			
		||||
@ -1585,6 +1655,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'ixx.io',
 | 
			
		||||
        'j-p.us',
 | 
			
		||||
        'jafps.com',
 | 
			
		||||
        'jaga.email',
 | 
			
		||||
        'jajxz.com',
 | 
			
		||||
        'janproz.com',
 | 
			
		||||
        'jaqis.com',
 | 
			
		||||
@ -1599,11 +1670,15 @@ class BlackListRule implements Rule
 | 
			
		||||
        'jetable.net',
 | 
			
		||||
        'jetable.org',
 | 
			
		||||
        'jetable.pp.ua',
 | 
			
		||||
        'ji5.de',
 | 
			
		||||
        'ji6.de',
 | 
			
		||||
        'ji7.de',
 | 
			
		||||
        'jiooq.com',
 | 
			
		||||
        'jmail.ovh',
 | 
			
		||||
        'jmail.ro',
 | 
			
		||||
        'jnxjn.com',
 | 
			
		||||
        'jobbikszimpatizans.hu',
 | 
			
		||||
        'jobbrett.com',
 | 
			
		||||
        'jobposts.net',
 | 
			
		||||
        'jobs-to-be-done.net',
 | 
			
		||||
        'joelpet.com',
 | 
			
		||||
@ -1660,6 +1735,8 @@ class BlackListRule implements Rule
 | 
			
		||||
        'killmail.com',
 | 
			
		||||
        'killmail.net',
 | 
			
		||||
        'kimsdisk.com',
 | 
			
		||||
        'kinda.email',
 | 
			
		||||
        'kindamail.com',
 | 
			
		||||
        'kingsq.ga',
 | 
			
		||||
        'kino-100.ru',
 | 
			
		||||
        'kiois.com',
 | 
			
		||||
@ -1668,16 +1745,20 @@ class BlackListRule implements Rule
 | 
			
		||||
        'kitnastar.com',
 | 
			
		||||
        'kjkszpjcompany.com',
 | 
			
		||||
        'kkmail.be',
 | 
			
		||||
        'kkoup.com',
 | 
			
		||||
        'kksm.be',
 | 
			
		||||
        'klassmaster.com',
 | 
			
		||||
        'klassmaster.net',
 | 
			
		||||
        'klick-tipp.us',
 | 
			
		||||
        'klipschx12.com',
 | 
			
		||||
        'kloap.com',
 | 
			
		||||
        'klovenode.com',
 | 
			
		||||
        'kludgemush.com',
 | 
			
		||||
        'klzlk.com',
 | 
			
		||||
        'kmail.li',
 | 
			
		||||
        'kmail.live',
 | 
			
		||||
        'kmhow.com',
 | 
			
		||||
        'knickerbockerban.de',
 | 
			
		||||
        'knol-power.nl',
 | 
			
		||||
        'kobrandly.com',
 | 
			
		||||
        'kommunity.biz',
 | 
			
		||||
@ -1711,6 +1792,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'kwilco.net',
 | 
			
		||||
        'kyal.pl',
 | 
			
		||||
        'kyois.com',
 | 
			
		||||
        'kzccv.com',
 | 
			
		||||
        'l-c-a.us',
 | 
			
		||||
        'l33r.eu',
 | 
			
		||||
        'l6factors.com',
 | 
			
		||||
@ -1725,9 +1807,12 @@ class BlackListRule implements Rule
 | 
			
		||||
        'lak.pp.ua',
 | 
			
		||||
        'lakelivingstonrealestate.com',
 | 
			
		||||
        'lakqs.com',
 | 
			
		||||
        'lamasticots.com',
 | 
			
		||||
        'lambsauce.de',
 | 
			
		||||
        'landmail.co',
 | 
			
		||||
        'laoeq.com',
 | 
			
		||||
        'larisia.com',
 | 
			
		||||
        'larland.com',
 | 
			
		||||
        'last-chance.pro',
 | 
			
		||||
        'lastmail.co',
 | 
			
		||||
        'lastmail.com',
 | 
			
		||||
@ -1757,6 +1842,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'ligsb.com',
 | 
			
		||||
        'lillemap.net',
 | 
			
		||||
        'lilo.me',
 | 
			
		||||
        'lilspam.com',
 | 
			
		||||
        'lindenbaumjapan.com',
 | 
			
		||||
        'link2mail.net',
 | 
			
		||||
        'linkedintuts2016.pw',
 | 
			
		||||
@ -1802,6 +1888,8 @@ class BlackListRule implements Rule
 | 
			
		||||
        'lukop.dk',
 | 
			
		||||
        'luv2.us',
 | 
			
		||||
        'lyfestylecreditsolutions.com',
 | 
			
		||||
        'lyft.live',
 | 
			
		||||
        'lyricspad.net',
 | 
			
		||||
        'lzoaq.com',
 | 
			
		||||
        'm21.cc',
 | 
			
		||||
        'm4ilweb.info',
 | 
			
		||||
@ -1847,6 +1935,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'mailapp.top',
 | 
			
		||||
        'mailback.com',
 | 
			
		||||
        'mailbidon.com',
 | 
			
		||||
        'mailbiscuit.com',
 | 
			
		||||
        'mailbiz.biz',
 | 
			
		||||
        'mailblocks.com',
 | 
			
		||||
        'mailbox.in.ua',
 | 
			
		||||
@ -1876,6 +1965,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'mailed.ro',
 | 
			
		||||
        'maileimer.de',
 | 
			
		||||
        'maileme101.com',
 | 
			
		||||
        'mailers.edu.pl',
 | 
			
		||||
        'mailexpire.com',
 | 
			
		||||
        'mailf5.com',
 | 
			
		||||
        'mailfa.tk',
 | 
			
		||||
@ -1943,6 +2033,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'mailonaut.com',
 | 
			
		||||
        'mailorc.com',
 | 
			
		||||
        'mailorg.org',
 | 
			
		||||
        'mailosaur.net',
 | 
			
		||||
        'mailox.fun',
 | 
			
		||||
        'mailpick.biz',
 | 
			
		||||
        'mailpluss.com',
 | 
			
		||||
@ -2006,18 +2097,22 @@ class BlackListRule implements Rule
 | 
			
		||||
        'mcache.net',
 | 
			
		||||
        'mciek.com',
 | 
			
		||||
        'mdhc.tk',
 | 
			
		||||
        'mdz.email',
 | 
			
		||||
        'meantinc.com',
 | 
			
		||||
        'mebelnu.info',
 | 
			
		||||
        'mechanicalresumes.com',
 | 
			
		||||
        'medkabinet-uzi.ru',
 | 
			
		||||
        'meepsheep.eu',
 | 
			
		||||
        'meidecn.com',
 | 
			
		||||
        'meinspamschutz.de',
 | 
			
		||||
        'meltedbrownies.com',
 | 
			
		||||
        'meltmail.com',
 | 
			
		||||
        'memsg.site',
 | 
			
		||||
        'mentonit.net',
 | 
			
		||||
        'mepost.pw',
 | 
			
		||||
        'merepost.com',
 | 
			
		||||
        'merry.pink',
 | 
			
		||||
        'meruado.uk',
 | 
			
		||||
        'messagebeamer.de',
 | 
			
		||||
        'messwiththebestdielikethe.rest',
 | 
			
		||||
        'metadownload.org',
 | 
			
		||||
@ -2043,6 +2138,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'migumail.com',
 | 
			
		||||
        'mihep.com',
 | 
			
		||||
        'mijnhva.nl',
 | 
			
		||||
        'minimail.gq',
 | 
			
		||||
        'ministry-of-silly-walks.de',
 | 
			
		||||
        'minsmail.com',
 | 
			
		||||
        'mintemail.com',
 | 
			
		||||
@ -2054,6 +2150,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'mjukglass.nu',
 | 
			
		||||
        'mkpfilm.com',
 | 
			
		||||
        'ml8.ca',
 | 
			
		||||
        'mliok.com',
 | 
			
		||||
        'mm.my',
 | 
			
		||||
        'mm5.se',
 | 
			
		||||
        'mnode.me',
 | 
			
		||||
@ -2109,6 +2206,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'mucincanon.com',
 | 
			
		||||
        'muehlacker.tk',
 | 
			
		||||
        'muell.icu',
 | 
			
		||||
        'muell.io',
 | 
			
		||||
        'muell.monster',
 | 
			
		||||
        'muell.xyz',
 | 
			
		||||
        'muellemail.com',
 | 
			
		||||
@ -2128,16 +2226,19 @@ class BlackListRule implements Rule
 | 
			
		||||
        'mycleaninbox.net',
 | 
			
		||||
        'mycorneroftheinter.net',
 | 
			
		||||
        'myde.ml',
 | 
			
		||||
        'mydefipet.live',
 | 
			
		||||
        'mydemo.equipment',
 | 
			
		||||
        'myecho.es',
 | 
			
		||||
        'myemailboxy.com',
 | 
			
		||||
        'mygeoweb.info',
 | 
			
		||||
        'myindohome.services',
 | 
			
		||||
        'myinfoinc.com',
 | 
			
		||||
        'myinterserver.ml',
 | 
			
		||||
        'mykickassideas.com',
 | 
			
		||||
        'mymail-in.net',
 | 
			
		||||
        'mymail90.com',
 | 
			
		||||
        'mymailoasis.com',
 | 
			
		||||
        'mymaily.lol',
 | 
			
		||||
        'mynetstore.de',
 | 
			
		||||
        'myopang.com',
 | 
			
		||||
        'mypacks.net',
 | 
			
		||||
@ -2171,10 +2272,12 @@ class BlackListRule implements Rule
 | 
			
		||||
        'naslazhdai.ru',
 | 
			
		||||
        'nationalgardeningclub.com',
 | 
			
		||||
        'nawmin.info',
 | 
			
		||||
        'naymedia.com',
 | 
			
		||||
        'nbzmr.com',
 | 
			
		||||
        'negated.com',
 | 
			
		||||
        'neko2.net',
 | 
			
		||||
        'nekochan.fr',
 | 
			
		||||
        'nekosan.uk',
 | 
			
		||||
        'neomailbox.com',
 | 
			
		||||
        'neotlozhniy-zaim.ru',
 | 
			
		||||
        'nepwk.com',
 | 
			
		||||
@ -2263,6 +2366,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'nwytg.com',
 | 
			
		||||
        'nwytg.net',
 | 
			
		||||
        'ny7.me',
 | 
			
		||||
        'nyasan.com',
 | 
			
		||||
        'nypato.com',
 | 
			
		||||
        'nyrmusic.com',
 | 
			
		||||
        'o2stk.org',
 | 
			
		||||
@ -2280,6 +2384,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'oepia.com',
 | 
			
		||||
        'oerpub.org',
 | 
			
		||||
        'offshore-proxies.net',
 | 
			
		||||
        'ofisher.net',
 | 
			
		||||
        'ohaaa.de',
 | 
			
		||||
        'ohi.tw',
 | 
			
		||||
        'oida.icu',
 | 
			
		||||
@ -2305,6 +2410,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'onlatedotcom.info',
 | 
			
		||||
        'online.ms',
 | 
			
		||||
        'onlineidea.info',
 | 
			
		||||
        'onlyapp.net',
 | 
			
		||||
        'onqin.com',
 | 
			
		||||
        'ontyne.biz',
 | 
			
		||||
        'oohioo.com',
 | 
			
		||||
@ -2330,6 +2436,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'ourklips.com',
 | 
			
		||||
        'ourpreviewdomain.com',
 | 
			
		||||
        'outlawspam.com',
 | 
			
		||||
        'outlook.edu.pl',
 | 
			
		||||
        'outmail.win',
 | 
			
		||||
        'ovomail.co',
 | 
			
		||||
        'ovpn.to',
 | 
			
		||||
@ -2337,6 +2444,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'owlpic.com',
 | 
			
		||||
        'ownsyou.de',
 | 
			
		||||
        'oxopoha.com',
 | 
			
		||||
        'ozatvn.com',
 | 
			
		||||
        'ozyl.de',
 | 
			
		||||
        'p-banlis.ru',
 | 
			
		||||
        'p33.org',
 | 
			
		||||
@ -2347,6 +2455,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'pagamenti.tk',
 | 
			
		||||
        'paharpurmim.ga',
 | 
			
		||||
        'pakadebu.ga',
 | 
			
		||||
        'pamaweb.com',
 | 
			
		||||
        'pancakemail.com',
 | 
			
		||||
        'papierkorb.me',
 | 
			
		||||
        'paplease.com',
 | 
			
		||||
@ -2384,6 +2493,8 @@ class BlackListRule implements Rule
 | 
			
		||||
        'pisls.com',
 | 
			
		||||
        'pitaniezdorovie.ru',
 | 
			
		||||
        'pivo-bar.ru',
 | 
			
		||||
        'pixiil.com',
 | 
			
		||||
        'pizzajunk.com',
 | 
			
		||||
        'pjjkp.com',
 | 
			
		||||
        'placebomail10.com',
 | 
			
		||||
        'pleasenoham.org',
 | 
			
		||||
@ -2435,6 +2546,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'prin.be',
 | 
			
		||||
        'privacy.net',
 | 
			
		||||
        'privatdemail.net',
 | 
			
		||||
        'privmail.edu.pl',
 | 
			
		||||
        'privy-mail.com',
 | 
			
		||||
        'privy-mail.de',
 | 
			
		||||
        'privymail.de',
 | 
			
		||||
@ -2454,6 +2566,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'prtz.eu',
 | 
			
		||||
        'psh.me',
 | 
			
		||||
        'psles.com',
 | 
			
		||||
        'psnator.com',
 | 
			
		||||
        'psoxs.com',
 | 
			
		||||
        'puglieisi.com',
 | 
			
		||||
        'puji.pro',
 | 
			
		||||
@ -2464,11 +2577,13 @@ class BlackListRule implements Rule
 | 
			
		||||
        'put2.net',
 | 
			
		||||
        'puttanamaiala.tk',
 | 
			
		||||
        'putthisinyourspamdatabase.com',
 | 
			
		||||
        'pwpwa.com',
 | 
			
		||||
        'pwrby.com',
 | 
			
		||||
        'qasti.com',
 | 
			
		||||
        'qbfree.us',
 | 
			
		||||
        'qc.to',
 | 
			
		||||
        'qibl.at',
 | 
			
		||||
        'qiott.com',
 | 
			
		||||
        'qipmail.net',
 | 
			
		||||
        'qiq.us',
 | 
			
		||||
        'qisdo.com',
 | 
			
		||||
@ -2485,6 +2600,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'quickinbox.com',
 | 
			
		||||
        'quickmail.nl',
 | 
			
		||||
        'quicksend.ch',
 | 
			
		||||
        'quipas.com',
 | 
			
		||||
        'ququb.com',
 | 
			
		||||
        'qvy.me',
 | 
			
		||||
        'qwickmail.com',
 | 
			
		||||
@ -2496,6 +2612,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'raetp9.com',
 | 
			
		||||
        'rainbowly.ml',
 | 
			
		||||
        'raketenmann.de',
 | 
			
		||||
        'ramenmail.de',
 | 
			
		||||
        'rancidhome.net',
 | 
			
		||||
        'randomail.io',
 | 
			
		||||
        'randomail.net',
 | 
			
		||||
@ -2512,6 +2629,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        're-gister.com',
 | 
			
		||||
        'reality-concept.club',
 | 
			
		||||
        'reallymymail.com',
 | 
			
		||||
        'realquickemail.com',
 | 
			
		||||
        'realtyalerts.ca',
 | 
			
		||||
        'rebates.stream',
 | 
			
		||||
        'receiveee.com',
 | 
			
		||||
@ -2542,6 +2660,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'rippb.com',
 | 
			
		||||
        'risingsuntouch.com',
 | 
			
		||||
        'riski.cf',
 | 
			
		||||
        'risu.be',
 | 
			
		||||
        'rklips.com',
 | 
			
		||||
        'rkomo.com',
 | 
			
		||||
        'rm2rf.com',
 | 
			
		||||
@ -2578,6 +2697,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        's33db0x.com',
 | 
			
		||||
        'sabrestlouis.com',
 | 
			
		||||
        'sackboii.com',
 | 
			
		||||
        'saeoil.com',
 | 
			
		||||
        'safaat.cf',
 | 
			
		||||
        'safermail.info',
 | 
			
		||||
        'safersignup.de',
 | 
			
		||||
@ -2630,10 +2750,13 @@ class BlackListRule implements Rule
 | 
			
		||||
        'sexforswingers.com',
 | 
			
		||||
        'sexical.com',
 | 
			
		||||
        'sexyalwasmi.top',
 | 
			
		||||
        'sfolkar.com',
 | 
			
		||||
        'shadap.org',
 | 
			
		||||
        'shalar.net',
 | 
			
		||||
        'sharedmailbox.org',
 | 
			
		||||
        'sharkfaces.com',
 | 
			
		||||
        'sharklasers.com',
 | 
			
		||||
        'shchiba.uk',
 | 
			
		||||
        'sheryli.com',
 | 
			
		||||
        'shhmail.com',
 | 
			
		||||
        'shhuut.org',
 | 
			
		||||
@ -2662,6 +2785,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'sify.com',
 | 
			
		||||
        'sika3.com',
 | 
			
		||||
        'sikux.com',
 | 
			
		||||
        'silenceofthespam.com',
 | 
			
		||||
        'siliwangi.ga',
 | 
			
		||||
        'silvercoin.life',
 | 
			
		||||
        'sim-simka.ru',
 | 
			
		||||
@ -2681,6 +2805,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'skrx.tk',
 | 
			
		||||
        'sky-inbox.com',
 | 
			
		||||
        'sky-ts.de',
 | 
			
		||||
        'skygazerhub.com',
 | 
			
		||||
        'skyrt.de',
 | 
			
		||||
        'slapsfromlastnight.com',
 | 
			
		||||
        'slaskpost.se',
 | 
			
		||||
@ -2698,6 +2823,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'smapfree24.eu',
 | 
			
		||||
        'smapfree24.info',
 | 
			
		||||
        'smapfree24.org',
 | 
			
		||||
        'smartnator.com',
 | 
			
		||||
        'smarttalent.pw',
 | 
			
		||||
        'smashmail.de',
 | 
			
		||||
        'smellfear.com',
 | 
			
		||||
@ -2705,12 +2831,14 @@ class BlackListRule implements Rule
 | 
			
		||||
        'smellypotato.tk',
 | 
			
		||||
        'smtp99.com',
 | 
			
		||||
        'smwg.info',
 | 
			
		||||
        'snakebutt.com',
 | 
			
		||||
        'snakemail.com',
 | 
			
		||||
        'snapwet.com',
 | 
			
		||||
        'sneakmail.de',
 | 
			
		||||
        'snece.com',
 | 
			
		||||
        'social-mailer.tk',
 | 
			
		||||
        'socialfurry.org',
 | 
			
		||||
        'sociallymediocre.com',
 | 
			
		||||
        'sofia.re',
 | 
			
		||||
        'sofimail.com',
 | 
			
		||||
        'sofort-mail.de',
 | 
			
		||||
@ -2731,6 +2859,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'soodmail.com',
 | 
			
		||||
        'soodomail.com',
 | 
			
		||||
        'soodonims.com',
 | 
			
		||||
        'soombo.com',
 | 
			
		||||
        'soon.it',
 | 
			
		||||
        'spacebazzar.ru',
 | 
			
		||||
        'spam-be-gone.com',
 | 
			
		||||
@ -2763,6 +2892,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'spamday.com',
 | 
			
		||||
        'spamdecoy.net',
 | 
			
		||||
        'spamex.com',
 | 
			
		||||
        'spamfellas.com',
 | 
			
		||||
        'spamfighter.cf',
 | 
			
		||||
        'spamfighter.ga',
 | 
			
		||||
        'spamfighter.gq',
 | 
			
		||||
@ -2791,6 +2921,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'spamobox.com',
 | 
			
		||||
        'spamoff.de',
 | 
			
		||||
        'spamsalad.in',
 | 
			
		||||
        'spamsandwich.com',
 | 
			
		||||
        'spamslicer.com',
 | 
			
		||||
        'spamsphere.com',
 | 
			
		||||
        'spamspot.com',
 | 
			
		||||
@ -2810,11 +2941,13 @@ class BlackListRule implements Rule
 | 
			
		||||
        'spikio.com',
 | 
			
		||||
        'spindl-e.com',
 | 
			
		||||
        'spoofmail.de',
 | 
			
		||||
        'sportrid.com',
 | 
			
		||||
        'spr.io',
 | 
			
		||||
        'spritzzone.de',
 | 
			
		||||
        'spruzme.com',
 | 
			
		||||
        'spybox.de',
 | 
			
		||||
        'spymail.com',
 | 
			
		||||
        'spymail.one',
 | 
			
		||||
        'squizzy.de',
 | 
			
		||||
        'squizzy.net',
 | 
			
		||||
        'sroff.com',
 | 
			
		||||
@ -2852,10 +2985,12 @@ class BlackListRule implements Rule
 | 
			
		||||
        'submic.com',
 | 
			
		||||
        'suburbanthug.com',
 | 
			
		||||
        'suckmyd.com',
 | 
			
		||||
        'sudern.de',
 | 
			
		||||
        'sueshaw.com',
 | 
			
		||||
        'suexamplesb.com',
 | 
			
		||||
        'suioe.com',
 | 
			
		||||
        'super-auswahl.de',
 | 
			
		||||
        'superblohey.com',
 | 
			
		||||
        'supergreatmail.com',
 | 
			
		||||
        'supermailer.jp',
 | 
			
		||||
        'superplatyna.com',
 | 
			
		||||
@ -2872,6 +3007,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'sweetxxx.de',
 | 
			
		||||
        'swift-mail.net',
 | 
			
		||||
        'swift10minutemail.com',
 | 
			
		||||
        'syinxun.com',
 | 
			
		||||
        'sylvannet.com',
 | 
			
		||||
        'symphonyresume.com',
 | 
			
		||||
        'syosetu.gq',
 | 
			
		||||
@ -2891,6 +3027,8 @@ class BlackListRule implements Rule
 | 
			
		||||
        'tastrg.com',
 | 
			
		||||
        'taukah.com',
 | 
			
		||||
        'tb-on-line.net',
 | 
			
		||||
        'tcwlm.com',
 | 
			
		||||
        'tcwlx.com',
 | 
			
		||||
        'tdtda.com',
 | 
			
		||||
        'tech69.com',
 | 
			
		||||
        'techblast.ch',
 | 
			
		||||
@ -2901,6 +3039,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'teewars.org',
 | 
			
		||||
        'tefl.ro',
 | 
			
		||||
        'telecomix.pl',
 | 
			
		||||
        'teleg.eu',
 | 
			
		||||
        'teleworm.com',
 | 
			
		||||
        'teleworm.us',
 | 
			
		||||
        'tellos.xyz',
 | 
			
		||||
@ -2965,6 +3104,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'thecloudindex.com',
 | 
			
		||||
        'thediamants.org',
 | 
			
		||||
        'thedirhq.info',
 | 
			
		||||
        'theeyeoftruth.com',
 | 
			
		||||
        'thejoker5.com',
 | 
			
		||||
        'thelightningmail.net',
 | 
			
		||||
        'thelimestones.com',
 | 
			
		||||
@ -2974,6 +3114,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'thereddoors.online',
 | 
			
		||||
        'theroyalweb.club',
 | 
			
		||||
        'thescrappermovie.com',
 | 
			
		||||
        'thespamfather.com',
 | 
			
		||||
        'theteastory.info',
 | 
			
		||||
        'thex.ro',
 | 
			
		||||
        'thichanthit.com',
 | 
			
		||||
@ -3010,9 +3151,13 @@ class BlackListRule implements Rule
 | 
			
		||||
        'tkitc.de',
 | 
			
		||||
        'tlpn.org',
 | 
			
		||||
        'tmail.com',
 | 
			
		||||
        'tmail.io',
 | 
			
		||||
        'tmail.ws',
 | 
			
		||||
        'tmail3.com',
 | 
			
		||||
        'tmail9.com',
 | 
			
		||||
        'tmailinator.com',
 | 
			
		||||
        'tmails.net',
 | 
			
		||||
        'tmmbt.net',
 | 
			
		||||
        'tmpbox.net',
 | 
			
		||||
        'tmpemails.com',
 | 
			
		||||
        'tmpeml.com',
 | 
			
		||||
@ -3020,6 +3165,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'tmpjr.me',
 | 
			
		||||
        'tmpmail.net',
 | 
			
		||||
        'tmpmail.org',
 | 
			
		||||
        'tmpx.sa.com',
 | 
			
		||||
        'toddsbighug.com',
 | 
			
		||||
        'tofeat.com',
 | 
			
		||||
        'toiea.com',
 | 
			
		||||
@ -3049,6 +3195,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'totoan.info',
 | 
			
		||||
        'tourcc.com',
 | 
			
		||||
        'tp-qa-mail.com',
 | 
			
		||||
        'tpwlb.com',
 | 
			
		||||
        'tqoai.com',
 | 
			
		||||
        'tqosi.com',
 | 
			
		||||
        'tradermail.info',
 | 
			
		||||
@ -3097,6 +3244,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'trialmail.de',
 | 
			
		||||
        'trickmail.net',
 | 
			
		||||
        'trillianpro.com',
 | 
			
		||||
        'triots.com',
 | 
			
		||||
        'trixtrux1.ru',
 | 
			
		||||
        'trollproject.com',
 | 
			
		||||
        'tropicalbass.info',
 | 
			
		||||
@ -3112,6 +3260,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'turoid.com',
 | 
			
		||||
        'turual.com',
 | 
			
		||||
        'turuma.com',
 | 
			
		||||
        'tutuapp.bid',
 | 
			
		||||
        'tvchd.com',
 | 
			
		||||
        'tverya.com',
 | 
			
		||||
        'twinmail.de',
 | 
			
		||||
@ -3150,6 +3299,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'unit7lahaina.com',
 | 
			
		||||
        'unmail.ru',
 | 
			
		||||
        'uooos.com',
 | 
			
		||||
        'uorak.com',
 | 
			
		||||
        'upliftnow.com',
 | 
			
		||||
        'uplipht.com',
 | 
			
		||||
        'uploadnolimit.com',
 | 
			
		||||
@ -3268,6 +3418,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'watchever.biz',
 | 
			
		||||
        'watchfull.net',
 | 
			
		||||
        'watchironman3onlinefreefullmovie.com',
 | 
			
		||||
        'waterisgone.com',
 | 
			
		||||
        'wazabi.club',
 | 
			
		||||
        'wbdev.tech',
 | 
			
		||||
        'wbml.net',
 | 
			
		||||
@ -3307,6 +3458,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'wegwrfmail.de',
 | 
			
		||||
        'wegwrfmail.net',
 | 
			
		||||
        'wegwrfmail.org',
 | 
			
		||||
        'weizixu.com',
 | 
			
		||||
        'wekawa.com',
 | 
			
		||||
        'welikecookies.com',
 | 
			
		||||
        'wellsfargocomcardholders.com',
 | 
			
		||||
@ -3316,6 +3468,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'wfgdfhj.tk',
 | 
			
		||||
        'wg0.com',
 | 
			
		||||
        'wh4f.org',
 | 
			
		||||
        'whaaaaaaaaaat.com',
 | 
			
		||||
        'whatiaas.com',
 | 
			
		||||
        'whatifanalytics.com',
 | 
			
		||||
        'whatpaas.com',
 | 
			
		||||
@ -3327,6 +3480,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'wickmail.net',
 | 
			
		||||
        'widaryanto.info',
 | 
			
		||||
        'widget.gg',
 | 
			
		||||
        'wiemei.com',
 | 
			
		||||
        'wierie.tk',
 | 
			
		||||
        'wifimaple.com',
 | 
			
		||||
        'wifioak.com',
 | 
			
		||||
@ -3355,6 +3509,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'wudet.men',
 | 
			
		||||
        'wuespdj.xyz',
 | 
			
		||||
        'wupics.com',
 | 
			
		||||
        'wuuvo.com',
 | 
			
		||||
        'wuzup.net',
 | 
			
		||||
        'wuzupmail.net',
 | 
			
		||||
        'wwjmp.com',
 | 
			
		||||
@ -3387,6 +3542,9 @@ class BlackListRule implements Rule
 | 
			
		||||
        'xrap.de',
 | 
			
		||||
        'xrho.com',
 | 
			
		||||
        'xvx.us',
 | 
			
		||||
        'xwaretech.com',
 | 
			
		||||
        'xwaretech.info',
 | 
			
		||||
        'xwaretech.net',
 | 
			
		||||
        'xww.ro',
 | 
			
		||||
        'xxhamsterxx.ga',
 | 
			
		||||
        'xxi2.com',
 | 
			
		||||
@ -3463,6 +3621,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'zebins.eu',
 | 
			
		||||
        'zehnminuten.de',
 | 
			
		||||
        'zehnminutenmail.de',
 | 
			
		||||
        'zemzar.net',
 | 
			
		||||
        'zepp.dk',
 | 
			
		||||
        'zetmail.com',
 | 
			
		||||
        'zfymail.com',
 | 
			
		||||
@ -3473,6 +3632,7 @@ class BlackListRule implements Rule
 | 
			
		||||
        'zhorachu.com',
 | 
			
		||||
        'zik.dj',
 | 
			
		||||
        'zipcad.com',
 | 
			
		||||
        'zipcatfish.com',
 | 
			
		||||
        'zipo1.gq',
 | 
			
		||||
        'zippymail.info',
 | 
			
		||||
        'zipsendtest.com',
 | 
			
		||||
@ -3494,27 +3654,13 @@ class BlackListRule implements Rule
 | 
			
		||||
        'zzz.com',
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param string $attribute
 | 
			
		||||
     * @param mixed $value
 | 
			
		||||
     * @return bool
 | 
			
		||||
     */
 | 
			
		||||
    public function passes($attribute, $value): bool
 | 
			
		||||
    public function validate(string $attribute, mixed $value, Closure $fail): void
 | 
			
		||||
    {
 | 
			
		||||
        $parts = explode("@", $value);
 | 
			
		||||
 | 
			
		||||
        if (is_array($parts)) {
 | 
			
		||||
            return ! in_array($parts[1], $this->blacklist);
 | 
			
		||||
        } else {
 | 
			
		||||
            return true;
 | 
			
		||||
        if (is_array($parts) && in_array($parts[1], $this->blacklist)) {
 | 
			
		||||
            $fail('This domain is blacklisted, if you think this is in error, please email contact@invoiceninja.com');
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @return string
 | 
			
		||||
     */
 | 
			
		||||
    public function message(): string
 | 
			
		||||
    {
 | 
			
		||||
        return 'This domain is blacklisted, if you think this is in error, please email contact@invoiceninja.com';
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -11,32 +11,26 @@
 | 
			
		||||
 | 
			
		||||
namespace App\Http\ValidationRules\Account;
 | 
			
		||||
 | 
			
		||||
use Illuminate\Contracts\Validation\Rule;
 | 
			
		||||
use Closure;
 | 
			
		||||
use Illuminate\Contracts\Validation\ValidationRule;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class EmailBlackListRule.
 | 
			
		||||
 */
 | 
			
		||||
class EmailBlackListRule implements Rule
 | 
			
		||||
class EmailBlackListRule implements ValidationRule
 | 
			
		||||
{
 | 
			
		||||
    public array $blacklist = [
 | 
			
		||||
 | 
			
		||||
        'noddy@invoiceninja.com',
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param string $attribute
 | 
			
		||||
     * @param mixed $value
 | 
			
		||||
     * @return bool
 | 
			
		||||
     */
 | 
			
		||||
    public function passes($attribute, $value)
 | 
			
		||||
 | 
			
		||||
    public function validate(string $attribute, mixed $value, Closure $fail): void
 | 
			
		||||
    {
 | 
			
		||||
        return ! in_array($value, $this->blacklist);
 | 
			
		||||
 | 
			
		||||
        if (in_array($value, $this->blacklist)) {
 | 
			
		||||
            $fail('This email address is blacklisted, if you think this is in error, please email contact@invoiceninja.com');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @return string
 | 
			
		||||
     */
 | 
			
		||||
    public function message()
 | 
			
		||||
    {
 | 
			
		||||
        return 'This email address is blacklisted, if you think this is in error, please email contact@invoiceninja.com';
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -28,6 +28,8 @@ class BankTransactionMap
 | 
			
		||||
            9 => 'transaction.base_type',
 | 
			
		||||
            10 => 'transaction.payment_type_Credit',
 | 
			
		||||
            11 => 'transaction.payment_type_Debit',
 | 
			
		||||
            12 => 'transaction.participant',
 | 
			
		||||
            13 => 'transaction.participant_name',
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -46,6 +48,8 @@ class BankTransactionMap
 | 
			
		||||
            9 => 'texts.type',
 | 
			
		||||
            10 => 'transaction.credit',
 | 
			
		||||
            11 => 'transaction.debit',
 | 
			
		||||
            12 => 'transaction.participant',
 | 
			
		||||
            13 => 'transaction.participant_name',
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -140,6 +140,10 @@ class BaseImport
 | 
			
		||||
        $delimiters = [',', '.', ';', '|'];
 | 
			
		||||
        $bestDelimiter = ',';
 | 
			
		||||
        $count = 0;
 | 
			
		||||
 | 
			
		||||
        // 10-01-2024 - A better way to resolve the csv file delimiter.
 | 
			
		||||
        $csvfile = substr($csvfile, 0, strpos($csvfile, "\n"));
 | 
			
		||||
 | 
			
		||||
        foreach ($delimiters as $delimiter) {
 | 
			
		||||
 | 
			
		||||
            if (substr_count(strstr($csvfile, "\n", true), $delimiter) >= $count) {
 | 
			
		||||
@ -162,7 +166,6 @@ class BaseImport
 | 
			
		||||
 | 
			
		||||
    private function groupTasks($csvData, $key)
 | 
			
		||||
    {
 | 
			
		||||
        nlog($csvData[0]);
 | 
			
		||||
 | 
			
		||||
        if (! $key || !is_array($csvData) || count($csvData) == 0 || !isset($csvData[0]['task.number']) || empty($csvData[0]['task.number'])) {
 | 
			
		||||
            return $csvData;
 | 
			
		||||
 | 
			
		||||
@ -44,6 +44,8 @@ class BankTransformer extends BaseTransformer
 | 
			
		||||
            'updated_at' => $now,
 | 
			
		||||
            'company_id' => $this->company->id,
 | 
			
		||||
            'user_id' => $this->company->owner()->id,
 | 
			
		||||
            'participant' => $this->getString($transaction, 'transaction.participant'),
 | 
			
		||||
            'participant_name' => $this->getString($transaction, 'transaction.participant_name'),
 | 
			
		||||
        ];
 | 
			
		||||
 | 
			
		||||
        return $transformed;
 | 
			
		||||
 | 
			
		||||
@ -316,7 +316,7 @@ class BaseTransformer
 | 
			
		||||
    {
 | 
			
		||||
        if (array_key_exists($field, $data)) {
 | 
			
		||||
            //$number = preg_replace('/[^0-9-.]+/', '', $data[$field]);
 | 
			
		||||
            return Number::parseStringFloat($data[$field]);
 | 
			
		||||
            return Number::parseFloat($data[$field]);
 | 
			
		||||
        } else {
 | 
			
		||||
            //$number = 0;
 | 
			
		||||
            return 0;
 | 
			
		||||
@ -334,7 +334,7 @@ class BaseTransformer
 | 
			
		||||
    public function getFloatOrOne($data, $field)
 | 
			
		||||
    {
 | 
			
		||||
        if (array_key_exists($field, $data)) {
 | 
			
		||||
            return Number::parseStringFloat($data[$field]) > 0 ? Number::parseStringFloat($data[$field]) : 1;
 | 
			
		||||
            return Number::parseFloat($data[$field]) > 0 ? Number::parseFloat($data[$field]) : 1;
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
        return 1;
 | 
			
		||||
 | 
			
		||||
@ -35,7 +35,7 @@ class ProcessBankTransactionsNordigen implements ShouldQueue
 | 
			
		||||
    public Company $company;
 | 
			
		||||
    public Nordigen $nordigen;
 | 
			
		||||
    public $nordigen_account;
 | 
			
		||||
 | 
			
		||||
    private bool $stop_loop = false;
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a new job instance.
 | 
			
		||||
     */
 | 
			
		||||
@ -114,6 +114,9 @@ class ProcessBankTransactionsNordigen implements ShouldQueue
 | 
			
		||||
            $this->stop_loop = false;
 | 
			
		||||
            nlog("Nordigen: account inactive: " . $this->bank_integration->nordigen_account_id);
 | 
			
		||||
            // @turbo124 @todo send email for expired account
 | 
			
		||||
            
 | 
			
		||||
            $this->nordigen->disabledAccountEmail($this->bank_integration);
 | 
			
		||||
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -155,12 +158,13 @@ class ProcessBankTransactionsNordigen implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        foreach ($transactions as $transaction) {
 | 
			
		||||
 | 
			
		||||
            if (BankTransaction::where('transaction_id', $transaction['transaction_id'])->where('company_id', $this->company->id)->where('bank_integration_id', $this->bank_integration->id)->withTrashed()->exists())
 | 
			
		||||
            if (BankTransaction::where('nordigen_transaction_id', $transaction['nordigen_transaction_id'])->where('company_id', $this->company->id)->where('bank_integration_id', $this->bank_integration->id)->where('is_deleted', 0)->withTrashed()->exists())
 | 
			
		||||
                continue;
 | 
			
		||||
 | 
			
		||||
            //this should be much faster to insert than using ::create()
 | 
			
		||||
            \DB::table('bank_transactions')->insert(
 | 
			
		||||
                array_merge($transaction, [
 | 
			
		||||
                    'transaction_id' => 0,
 | 
			
		||||
                    'company_id' => $this->company->id,
 | 
			
		||||
                    'user_id' => $user_id,
 | 
			
		||||
                    'bank_integration_id' => $this->bank_integration->id,
 | 
			
		||||
 | 
			
		||||
@ -162,7 +162,7 @@ class ProcessBankTransactionsYodlee implements ShouldQueue
 | 
			
		||||
        $now = now();
 | 
			
		||||
 | 
			
		||||
        foreach ($transactions as $transaction) {
 | 
			
		||||
            if (BankTransaction::query()->where('transaction_id', $transaction['transaction_id'])->where('company_id', $this->company->id)->where('bank_integration_id', $this->bank_integration->id)->withTrashed()->exists()) { // @turbo124 was not scoped to bank_integration_id => from my pov this should be present, because when an account was historized (is_deleted) a transaction can occur multiple (in the archived bank_integration and in the new one
 | 
			
		||||
            if (BankTransaction::query()->where('transaction_id', $transaction['transaction_id'])->where('company_id', $this->company->id)->where('bank_integration_id', $this->bank_integration->id)->withTrashed()->exists()) { 
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -64,7 +64,7 @@ class CompanyExport implements ShouldQueue
 | 
			
		||||
    {
 | 
			
		||||
        MultiDB::setDb($this->company->db);
 | 
			
		||||
 | 
			
		||||
        $this->company = Company::query()->where('company_key', $this->company->company_key)->first();
 | 
			
		||||
        // $this->company = Company::query()->where('company_key', $this->company->company_key)->first();
 | 
			
		||||
 | 
			
		||||
        set_time_limit(0);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -64,13 +64,13 @@ class BankTransactionSync implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
    private function processYodlee()
 | 
			
		||||
    {
 | 
			
		||||
        if (Ninja::isHosted()) { // @turbo124 @todo I migrated the schedule for the job within the kernel to execute on all platforms and use the same expression here to determine if yodlee can run or not. Please chek/verify
 | 
			
		||||
        if (Ninja::isHosted()) {
 | 
			
		||||
            nlog("syncing transactions - yodlee");
 | 
			
		||||
 | 
			
		||||
            Account::with('bank_integrations')->whereNotNull('bank_integration_account_id')->cursor()->each(function ($account) {
 | 
			
		||||
 | 
			
		||||
                if ($account->isPaid() && $account->plan == 'enterprise') {
 | 
			
		||||
                    $account->bank_integrations()->where('integration_type', BankIntegration::INTEGRATION_TYPE_YODLEE)->where('auto_sync', true)->cursor()->each(function ($bank_integration) use ($account) {
 | 
			
		||||
                if ($account->isEnterprisePaidClient()) {
 | 
			
		||||
                    $account->bank_integrations()->where('integration_type', BankIntegration::INTEGRATION_TYPE_YODLEE)->where('auto_sync', true)->where('disabled_upstream', 0)->cursor()->each(function ($bank_integration) use ($account) {
 | 
			
		||||
                        (new ProcessBankTransactionsYodlee($account->id, $bank_integration))->handle();
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
@ -80,13 +80,13 @@ class BankTransactionSync implements ShouldQueue
 | 
			
		||||
    }
 | 
			
		||||
    private function processNordigen()
 | 
			
		||||
    {
 | 
			
		||||
        if (config("ninja.nordigen.secret_id") && config("ninja.nordigen.secret_key")) { // @turbo124 check condition, when to execute this should be placed here (isSelfHosted || isPro/isEnterprise)
 | 
			
		||||
        if (config("ninja.nordigen.secret_id") && config("ninja.nordigen.secret_key")) { 
 | 
			
		||||
            nlog("syncing transactions - nordigen");
 | 
			
		||||
 | 
			
		||||
            Account::with('bank_integrations')->cursor()->each(function ($account) {
 | 
			
		||||
 | 
			
		||||
                if ((Ninja::isSelfHost() || (Ninja::isHosted() && $account->isPaid() && $account->plan == 'enterprise'))) {
 | 
			
		||||
                    $account->bank_integrations()->where('integration_type', BankIntegration::INTEGRATION_TYPE_NORDIGEN)->where('auto_sync', true)->cursor()->each(function ($bank_integration) {
 | 
			
		||||
                if ((Ninja::isSelfHost() || (Ninja::isHosted() && $account->isEnterprisePaidClient()))) {
 | 
			
		||||
                    $account->bank_integrations()->where('integration_type', BankIntegration::INTEGRATION_TYPE_NORDIGEN)->where('auto_sync', true)->where('disabled_upstream', 0)->cursor()->each(function ($bank_integration) {
 | 
			
		||||
                        (new ProcessBankTransactionsNordigen($bank_integration))->handle();
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@ -30,6 +30,7 @@ use Illuminate\Foundation\Bus\Dispatchable;
 | 
			
		||||
use App\DataMapper\Analytics\Mail\EmailSpam;
 | 
			
		||||
use App\DataMapper\Analytics\Mail\EmailBounce;
 | 
			
		||||
use App\Notifications\Ninja\EmailSpamNotification;
 | 
			
		||||
use App\Notifications\Ninja\EmailBounceNotification;
 | 
			
		||||
 | 
			
		||||
class ProcessPostmarkWebhook implements ShouldQueue
 | 
			
		||||
{
 | 
			
		||||
@ -103,6 +104,11 @@ class ProcessPostmarkWebhook implements ShouldQueue
 | 
			
		||||
            case 'Delivery':
 | 
			
		||||
                return $this->processDelivery();
 | 
			
		||||
            case 'Bounce':
 | 
			
		||||
 | 
			
		||||
                if($this->request['Subject'] == ctrans('texts.confirmation_subject')) {
 | 
			
		||||
                    $company->notification(new EmailBounceNotification($this->request['Email']))->ninja();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                return $this->processBounce();
 | 
			
		||||
            case 'SpamComplaint':
 | 
			
		||||
                return $this->processSpamComplaint();
 | 
			
		||||
@ -263,8 +269,6 @@ class ProcessPostmarkWebhook implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        (new SystemLogger($data, SystemLog::CATEGORY_MAIL, SystemLog::EVENT_MAIL_BOUNCED, SystemLog::TYPE_WEBHOOK_RESPONSE, $this->invitation->contact->client, $this->invitation->company))->handle();
 | 
			
		||||
 | 
			
		||||
        // if(config('ninja.notification.slack'))
 | 
			
		||||
        // $this->invitation->company->notification(new EmailBounceNotification($this->invitation->company->account))->ninja();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // {
 | 
			
		||||
 | 
			
		||||
@ -43,7 +43,7 @@ class CreatedClientActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->client->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->client->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->client_id = $event->client->id;
 | 
			
		||||
        $fields->user_id = $user_id;
 | 
			
		||||
 | 
			
		||||
@ -43,7 +43,7 @@ class CreatedCreditActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->credit->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->credit->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->credit_id = $event->credit->id;
 | 
			
		||||
        $fields->user_id = $user_id;
 | 
			
		||||
 | 
			
		||||
@ -43,7 +43,7 @@ class CreatedExpenseActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->expense->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->expense->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->expense_id = $event->expense->id;
 | 
			
		||||
        $fields->user_id = $user_id;
 | 
			
		||||
 | 
			
		||||
@ -43,7 +43,7 @@ class CreatedQuoteActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->quote->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->quote->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->quote_id = $event->quote->id;
 | 
			
		||||
        $fields->client_id = $event->quote->client_id;
 | 
			
		||||
 | 
			
		||||
@ -43,7 +43,7 @@ class CreatedSubscriptionActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->subscription->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->subscription->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->subscription_id = $event->subscription->id;
 | 
			
		||||
        $fields->user_id = $user_id;
 | 
			
		||||
 | 
			
		||||
@ -43,7 +43,7 @@ class CreatedTaskActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->task->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->task->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->task_id = $event->task->id;
 | 
			
		||||
        $fields->user_id = $user_id;
 | 
			
		||||
 | 
			
		||||
@ -43,7 +43,7 @@ class CreatedVendorActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->vendor->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->vendor->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->vendor_id = $event->vendor->id;
 | 
			
		||||
        $fields->user_id = $user_id;
 | 
			
		||||
 | 
			
		||||
@ -43,7 +43,7 @@ class CreditArchivedActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->credit->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->credit->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->credit_id = $event->credit->id;
 | 
			
		||||
        $fields->client_id = $event->credit->client_id;
 | 
			
		||||
 | 
			
		||||
@ -43,7 +43,7 @@ class DeleteClientActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->client->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->client->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->client_id = $event->client->id;
 | 
			
		||||
        $fields->user_id = $user_id;
 | 
			
		||||
 | 
			
		||||
@ -43,7 +43,7 @@ class DeleteCreditActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->credit->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->credit->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->client_id = $event->credit->client_id;
 | 
			
		||||
        $fields->credit_id = $event->credit->id;
 | 
			
		||||
 | 
			
		||||
@ -45,7 +45,7 @@ class ExpenseArchivedActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->expense->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->expense->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->expense_id = $expense->id;
 | 
			
		||||
        $fields->user_id = $user_id;
 | 
			
		||||
 | 
			
		||||
@ -43,7 +43,7 @@ class ExpenseDeletedActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->expense->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->expense->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->expense_id = $event->expense->id;
 | 
			
		||||
        $fields->user_id = $user_id;
 | 
			
		||||
 | 
			
		||||
@ -43,7 +43,7 @@ class ExpenseRestoredActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->expense->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->expense->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->expense_id = $event->expense->id;
 | 
			
		||||
        $fields->user_id = $user_id;
 | 
			
		||||
 | 
			
		||||
@ -43,7 +43,7 @@ class ExpenseUpdatedActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $expense = $event->expense;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->expense->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->expense->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -48,7 +48,7 @@ class PaymentArchivedActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->payment->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->payment->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->payment_id = $payment->id;
 | 
			
		||||
        $fields->client_id = $payment->client_id;
 | 
			
		||||
 | 
			
		||||
@ -50,7 +50,7 @@ class PaymentCreatedActivity implements ShouldQueue
 | 
			
		||||
            $invoice_id = $payment->invoices()->first()->id;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->payment->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->payment->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
@ -60,7 +60,8 @@ class PaymentCreatedActivity implements ShouldQueue
 | 
			
		||||
        $fields->user_id = $user_id;
 | 
			
		||||
        $fields->company_id = $payment->company_id;
 | 
			
		||||
        $fields->activity_type_id = Activity::CREATE_PAYMENT;
 | 
			
		||||
 | 
			
		||||
        $fields->client_contact_id = $payment->client_contact_id ?? null;
 | 
			
		||||
        
 | 
			
		||||
        $this->activity_repo->save($fields, $payment, $event->event_vars);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -43,7 +43,7 @@ class PaymentDeletedActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $payment = $event->payment;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->payment->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->payment->user_id;
 | 
			
		||||
 | 
			
		||||
        $invoices = $payment->invoices;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -43,7 +43,7 @@ class PaymentRefundedActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->payment->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->payment->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->client_id = $event->payment->client_id;
 | 
			
		||||
        $fields->user_id = $user_id;
 | 
			
		||||
 | 
			
		||||
@ -48,7 +48,7 @@ class PaymentUpdatedActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->payment->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->payment->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->payment_id = $payment->id;
 | 
			
		||||
        $fields->client_id = $payment->client_id;
 | 
			
		||||
 | 
			
		||||
@ -43,7 +43,7 @@ class PaymentVoidedActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->payment->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->payment->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->client_id = $event->payment->id;
 | 
			
		||||
        $fields->user_id = $user_id;
 | 
			
		||||
 | 
			
		||||
@ -45,7 +45,7 @@ class QuoteUpdatedActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->quote->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->quote->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->quote_id = $quote->id;
 | 
			
		||||
        $fields->client_id = $quote->client_id;
 | 
			
		||||
 | 
			
		||||
@ -43,7 +43,7 @@ class RestoreClientActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->client->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->client->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->client_id = $event->client->id;
 | 
			
		||||
        $fields->user_id = $user_id;
 | 
			
		||||
 | 
			
		||||
@ -45,7 +45,7 @@ class SubscriptionArchivedActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->subscription->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->subscription->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->subscription_id = $subscription->id;
 | 
			
		||||
        $fields->user_id = $user_id;
 | 
			
		||||
 | 
			
		||||
@ -43,7 +43,7 @@ class SubscriptionDeletedActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->subscription->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->subscription->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->subscription_id = $event->subscription->id;
 | 
			
		||||
        $fields->user_id = $user_id;
 | 
			
		||||
 | 
			
		||||
@ -43,7 +43,7 @@ class SubscriptionRestoredActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->subscription->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->subscription->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->subscription_id = $event->subscription->id;
 | 
			
		||||
        $fields->user_id = $user_id;
 | 
			
		||||
 | 
			
		||||
@ -45,7 +45,7 @@ class SubscriptionUpdatedActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->subscription->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->subscription->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->subscription_id = $subscription->id;
 | 
			
		||||
        $fields->user_id = $user_id;
 | 
			
		||||
 | 
			
		||||
@ -45,7 +45,7 @@ class TaskArchivedActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->task->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->task->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->task_id = $task->id;
 | 
			
		||||
        $fields->user_id = $user_id;
 | 
			
		||||
 | 
			
		||||
@ -43,7 +43,7 @@ class TaskDeletedActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->task->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->task->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->task_id = $event->task->id;
 | 
			
		||||
        $fields->user_id = $user_id;
 | 
			
		||||
 | 
			
		||||
@ -43,7 +43,7 @@ class TaskRestoredActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->task->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->task->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->task_id = $event->task->id;
 | 
			
		||||
        $fields->user_id = $user_id;
 | 
			
		||||
 | 
			
		||||
@ -45,7 +45,7 @@ class TaskUpdatedActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->task->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->task->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->task_id = $task->id;
 | 
			
		||||
        $fields->user_id = $user_id;
 | 
			
		||||
 | 
			
		||||
@ -43,7 +43,7 @@ class UpdatedCreditActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->credit->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->credit->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->credit_id = $event->credit->id;
 | 
			
		||||
        $fields->client_id = $event->credit->client_id;
 | 
			
		||||
 | 
			
		||||
@ -45,7 +45,7 @@ class VendorArchivedActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->vendor->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->vendor->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->vendor_id = $vendor->id;
 | 
			
		||||
        $fields->user_id = $user_id;
 | 
			
		||||
 | 
			
		||||
@ -43,7 +43,7 @@ class VendorDeletedActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->vendor->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->vendor->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->vendor_id = $event->vendor->id;
 | 
			
		||||
        $fields->user_id = $user_id;
 | 
			
		||||
 | 
			
		||||
@ -43,7 +43,7 @@ class VendorRestoredActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->vendor->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->vendor->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->vendor_id = $event->vendor->id;
 | 
			
		||||
        $fields->user_id = $user_id;
 | 
			
		||||
 | 
			
		||||
@ -45,7 +45,7 @@ class VendorUpdatedActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->vendor->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->vendor->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->vendor_id = $vendor->id;
 | 
			
		||||
        $fields->user_id = $user_id;
 | 
			
		||||
 | 
			
		||||
@ -47,12 +47,9 @@ class CreditEmailedNotification implements ShouldQueue
 | 
			
		||||
        foreach ($event->invitation->company->company_users as $company_user) {
 | 
			
		||||
            $user = $company_user->user;
 | 
			
		||||
 | 
			
		||||
            // $notification = new EntitySentNotification($event->invitation, 'credit');
 | 
			
		||||
 | 
			
		||||
            $methods = $this->findUserNotificationTypes($event->invitation, $company_user, 'credit', ['all_notifications', 'credit_sent', 'credit_sent_all', 'credit_sent_user']);
 | 
			
		||||
 | 
			
		||||
            if (($key = array_search('mail', $methods)) !== false) {
 | 
			
		||||
                // if (($key = array_search('mail', $methods))) {
 | 
			
		||||
                unset($methods[$key]);
 | 
			
		||||
 | 
			
		||||
                $nmo = new NinjaMailerObject;
 | 
			
		||||
 | 
			
		||||
@ -43,7 +43,7 @@ class CreditRestoredActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->credit->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->credit->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->credit_id = $event->credit->id;
 | 
			
		||||
        $fields->client_id = $event->credit->client_id;
 | 
			
		||||
 | 
			
		||||
@ -45,7 +45,7 @@ class CreditViewedActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->invitation->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->invitation->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->user_id = $user_id;
 | 
			
		||||
        $fields->company_id = $event->invitation->company_id;
 | 
			
		||||
 | 
			
		||||
@ -45,7 +45,7 @@ class CreateInvoiceActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->invoice->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->invoice->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->user_id = $user_id;
 | 
			
		||||
        $fields->invoice_id = $event->invoice->id;
 | 
			
		||||
 | 
			
		||||
@ -45,7 +45,7 @@ class InvoiceArchivedActivity implements ShouldQueue
 | 
			
		||||
        
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->invoice->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->invoice->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->user_id = $user_id;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -45,7 +45,7 @@ class InvoiceCancelledActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->invoice->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->invoice->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->user_id = $user_id;
 | 
			
		||||
        $fields->invoice_id = $event->invoice->id;
 | 
			
		||||
 | 
			
		||||
@ -45,7 +45,7 @@ class InvoiceDeletedActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->invoice->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->invoice->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->user_id = $user_id;
 | 
			
		||||
        $fields->invoice_id = $event->invoice->id;
 | 
			
		||||
 | 
			
		||||
@ -45,7 +45,7 @@ class InvoiceEmailActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->invitation->invoice->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->invitation->invoice->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->user_id = $user_id;
 | 
			
		||||
        $fields->invoice_id = $event->invitation->invoice->id;
 | 
			
		||||
 | 
			
		||||
@ -49,7 +49,7 @@ class InvoiceEmailFailedActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->invitation->invoice->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->invitation->invoice->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->user_id = $user_id;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -45,11 +45,12 @@ class InvoicePaidActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->invoice->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->invoice->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->user_id = $user_id;
 | 
			
		||||
        $fields->invoice_id = $event->invoice->id;
 | 
			
		||||
        $fields->client_id = $event->payment->client_id;
 | 
			
		||||
        $fields->client_contact_id = $event->payment->client_contact_id ?? null;
 | 
			
		||||
        $fields->company_id = $event->invoice->company_id;
 | 
			
		||||
        $fields->activity_type_id = Activity::PAID_INVOICE;
 | 
			
		||||
        $fields->payment_id = $event->payment->id;
 | 
			
		||||
 | 
			
		||||
@ -44,7 +44,7 @@ class InvoiceReminderEmailActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->invitation->invoice->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->invitation->invoice->user_id;
 | 
			
		||||
 | 
			
		||||
        $reminder = match($event->template) {
 | 
			
		||||
            'reminder1' => 63,
 | 
			
		||||
 | 
			
		||||
@ -45,7 +45,7 @@ class InvoiceRestoredActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->invitation->invoice->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->invitation->invoice->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->user_id = $user_id;
 | 
			
		||||
        $fields->invoice_id = $event->invoice->id;
 | 
			
		||||
 | 
			
		||||
@ -45,7 +45,7 @@ class InvoiceReversedActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->invitation->invoice->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->invitation->invoice->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->user_id = $user_id;
 | 
			
		||||
        $fields->invoice_id = $event->invoice->id;
 | 
			
		||||
 | 
			
		||||
@ -45,7 +45,7 @@ class InvoiceViewedActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->invitation->invoice->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->invitation->invoice->user_id;
 | 
			
		||||
 | 
			
		||||
        $event->invitation->invoice->service()->markSent()->save();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -43,7 +43,7 @@ class UpdateInvoiceActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->invoice->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->invoice->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->user_id = $user_id;
 | 
			
		||||
        $fields->client_id = $event->invoice->client_id;
 | 
			
		||||
 | 
			
		||||
@ -41,7 +41,7 @@ class PaymentEmailedActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new \stdClass();
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->payment->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->payment->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->user_id = $user_id;
 | 
			
		||||
        $fields->client_id = $event->payment->client_id;
 | 
			
		||||
 | 
			
		||||
@ -45,7 +45,7 @@ class PaymentRestoredActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->payment->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->payment->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->user_id = $user_id;
 | 
			
		||||
        $fields->payment_id = $event->payment->id;
 | 
			
		||||
 | 
			
		||||
@ -45,7 +45,7 @@ class CreatePurchaseOrderActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->purchase_order->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->purchase_order->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->user_id = $user_id;
 | 
			
		||||
        $fields->purchase_order_id = $event->purchase_order->id;
 | 
			
		||||
 | 
			
		||||
@ -45,7 +45,7 @@ class PurchaseOrderAcceptedActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->purchase_order->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->purchase_order->user_id;
 | 
			
		||||
 | 
			
		||||
        $event->purchase_order->service()->markSent()->save();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -45,7 +45,7 @@ class PurchaseOrderArchivedActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->purchase_order->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->purchase_order->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->user_id = $user_id;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -45,7 +45,7 @@ class PurchaseOrderDeletedActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->purchase_order->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->purchase_order->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->user_id = $user_id;
 | 
			
		||||
        $fields->purchase_order_id = $event->purchase_order->id;
 | 
			
		||||
 | 
			
		||||
@ -45,7 +45,7 @@ class PurchaseOrderEmailActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->invitation->purchase_order->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->invitation->purchase_order->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->user_id = $user_id;
 | 
			
		||||
        $fields->purchase_order_id = $event->invitation->purchase_order->id;
 | 
			
		||||
 | 
			
		||||
@ -45,7 +45,7 @@ class PurchaseOrderRestoredActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->purchase_order->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->purchase_order->user_id;
 | 
			
		||||
 | 
			
		||||
        $fields->user_id = $user_id;
 | 
			
		||||
        $fields->purchase_order_id = $event->purchase_order->id;
 | 
			
		||||
 | 
			
		||||
@ -45,7 +45,7 @@ class PurchaseOrderViewedActivity implements ShouldQueue
 | 
			
		||||
 | 
			
		||||
        $fields = new stdClass;
 | 
			
		||||
 | 
			
		||||
        $user_id = array_key_exists('user_id', $event->event_vars) ? $event->event_vars['user_id'] : $event->invitation->purchase_order->user_id;
 | 
			
		||||
        $user_id = isset($event->event_vars['user_id']) ? $event->event_vars['user_id'] : $event->invitation->purchase_order->user_id;
 | 
			
		||||
 | 
			
		||||
        $event->invitation->purchase_order->service()->markSent()->save();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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