From b065542020556f09264484642285d7a74cc27448 Mon Sep 17 00:00:00 2001 From: paulwer Date: Thu, 14 Dec 2023 08:32:15 +0100 Subject: [PATCH] env-config --- app/Helpers/Mail/IncomingMailHandler.php | 4 +- ...portJob.php => ImapInboundExpensesJob.php} | 62 +++++++++++++------ config/ninja.php | 13 +++- ...10951_create_imap_configuration_fields.php | 7 +-- 4 files changed, 58 insertions(+), 28 deletions(-) rename app/Jobs/Mail/{ExpenseImportJob.php => ImapInboundExpensesJob.php} (63%) diff --git a/app/Helpers/Mail/IncomingMailHandler.php b/app/Helpers/Mail/IncomingMailHandler.php index 3c98293d7714..1da4e1437fe9 100644 --- a/app/Helpers/Mail/IncomingMailHandler.php +++ b/app/Helpers/Mail/IncomingMailHandler.php @@ -24,9 +24,9 @@ class IncomingMailHandler { private $server; public $connection; - public function __construct(string $server, string $user, string $password) + public function __construct(string $server, string $port, string $user, string $password) { - $this->server = new Server($server); + $this->server = new Server($server, $port == '' ? null : $port); $this->connection = $this->server->authenticate($user, $password); } diff --git a/app/Jobs/Mail/ExpenseImportJob.php b/app/Jobs/Mail/ImapInboundExpensesJob.php similarity index 63% rename from app/Jobs/Mail/ExpenseImportJob.php rename to app/Jobs/Mail/ImapInboundExpensesJob.php index a31c2bace073..0a04c7d53c7e 100644 --- a/app/Jobs/Mail/ExpenseImportJob.php +++ b/app/Jobs/Mail/ImapInboundExpensesJob.php @@ -46,32 +46,26 @@ use Turbo124\Beacon\Facades\LightLogs; /*Multi Mailer implemented*/ -class ExpenseImportJob implements ShouldQueue +class InboundExpensesJob implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, MakesHash; public $tries = 4; //number of retries public $deleteWhenMissingModels = true; - - /** @var null|\App\Models\Company $company **/ - public Company $company; - + private array $imap_companies; + private array $imap_credentials; private $expense_repo; public function __construct() { + $this->credentials = []; + + $this->getImapCredentials(); $this->expense_repo = new ExpenseRepository(); } - public function backoff() - { - // return [5, 10, 30, 240]; - return [rand(5, 10), rand(30, 40), rand(60, 79), rand(160, 400)]; - - } - public function handle() { @@ -81,8 +75,8 @@ class ExpenseImportJob implements ShouldQueue nlog("importing expenses from imap-servers"); - $a = Account::with('companies')->cursor()->each(function ($account) { - $account->companies()->where('expense_import', true)->whereNotNull('expense_mailbox_imap_host')->whereNotNull('expense_mailbox_imap_user')->whereNotNull('expense_mailbox_imap_password')->cursor()->each(function ($company) { + Account::with('companies')->cursor()->each(function ($account) { + $account->companies()->whereIn('id', $this->imap_companies)->cursor()->each(function ($company) { $this->handleCompanyImap($company); }); }); @@ -90,9 +84,33 @@ class ExpenseImportJob implements ShouldQueue } + private function getImapCredentials() + { + $servers = explode(",", config('ninja.imap_inbound_expense.servers')); + $ports = explode(",", config('ninja.imap_inbound_expense.servers')); + $users = explode(",", config('ninja.imap_inbound_expense.servers')); + $passwords = explode(",", config('ninja.imap_inbound_expense.servers')); + $companies = explode(",", config('ninja.imap_inbound_expense.servers')); + + if (sizeOf($servers) != sizeOf($ports) || sizeOf($servers) != sizeOf($users) || sizeOf($servers) != sizeOf($passwords) || sizeOf($servers) != sizeOf($companies)) + throw new \Exception('invalid configuration imap_inbound_expenses (wrong element-count)'); + + foreach ($companies as $index => $companyId) { + $this->imap_credentials[$companyId] = [ + "server" => $servers[$index], + "port" => $servers[$index], + "user" => $servers[$index], + "password" => $servers[$index], + ]; + $this->imap_companies[] = $companyId; + } + } + private function handleCompanyImap(Company $company) { - $incommingMails = new IncomingMailHandler($company->expense_mailbox_imap_host, $company->company->expense_mailbox_imap_user, $company->company->expense_mailbox_imap_password); + $credentials = $this->imap_credentials[$company->id]; + + $incommingMails = new IncomingMailHandler($credentials->server, $credentials->port, $credentials->user, $credentials->password); $emails = $incommingMails->getUnprocessedEmails(); @@ -100,18 +118,19 @@ class ExpenseImportJob implements ShouldQueue $sender = $mail->getSender(); - $vendor = Vendor::where('expense_sender_email', $sender)->orWhere($sender, 'LIKE', "CONCAT('%',expense_sender_email)")->first(); + $vendor = Vendor::where('expense_sender_email', $sender)->orWhere($sender, 'LIKE', "CONCAT('%',expense_sender_domain)")->first(); if ($vendor !== null) $vendor = Vendor::where("email", $sender)->first(); - // TODO: check email for existing vendor?! + $documents = []; // TODO: $mail->getAttachments() + save email as document (.html) + $data = [ "vendor_id" => $vendor !== null ? $vendor->id : null, "date" => $mail->getDate(), "public_notes" => $mail->getSubject(), "private_notes" => $mail->getCompleteBodyText(), - "documents" => $mail->getAttachments(), // FIXME: https://github.com/ddeboer/imap?tab=readme-ov-file#message-attachments + "documents" => $documents, // FIXME: https://github.com/ddeboer/imap?tab=readme-ov-file#message-attachments ]; $expense = $this->expense_repo->save($data, ExpenseFactory::create($company->company->id, $company->company->owner()->id)); // TODO: dont assign a new number at beginning @@ -128,4 +147,11 @@ class ExpenseImportJob implements ShouldQueue } } + public function backoff() + { + // return [5, 10, 30, 240]; + return [rand(5, 10), rand(30, 40), rand(60, 79), rand(160, 400)]; + + } + } diff --git a/config/ninja.php b/config/ninja.php index 94d0a307fc6a..d94ec91a01b1 100644 --- a/config/ninja.php +++ b/config/ninja.php @@ -7,7 +7,7 @@ return [ 'license_url' => 'https://app.invoiceninja.com', 'react_url' => env('REACT_URL', 'https://app.invoicing.co'), 'production' => env('NINJA_PROD', false), - 'license' => env('NINJA_LICENSE', ''), + 'license' => env('NINJA_LICENSE', ''), 'version_url' => 'https://pdf.invoicing.co/api/version', 'app_name' => env('APP_NAME', 'Invoice Ninja'), 'app_env' => env('APP_ENV', 'selfhosted'), @@ -86,7 +86,7 @@ return [ 'password' => 'password', 'stripe' => env('STRIPE_KEYS', ''), 'paypal' => env('PAYPAL_KEYS', ''), - 'ppcp' => env('PPCP_KEYS', ''), + 'ppcp' => env('PPCP_KEYS', ''), 'paypal_rest' => env('PAYPAL_REST_KEYS', ''), 'authorize' => env('AUTHORIZE_KEYS', ''), 'checkout' => env('CHECKOUT_KEYS', ''), @@ -196,7 +196,7 @@ return [ 'ninja_default_company_id' => env('NINJA_COMPANY_ID', null), 'ninja_default_company_gateway_id' => env('NINJA_COMPANY_GATEWAY_ID', null), 'ninja_hosted_secret' => env('NINJA_HOSTED_SECRET', ''), - 'ninja_hosted_header' =>env('NINJA_HEADER', ''), + 'ninja_hosted_header' => env('NINJA_HEADER', ''), 'ninja_connect_secret' => env('NINJA_CONNECT_SECRET', ''), 'internal_queue_enabled' => env('INTERNAL_QUEUE_ENABLED', true), 'ninja_apple_api_key' => env('APPLE_API_KEY', false), @@ -227,5 +227,12 @@ return [ 'paypal' => [ 'secret' => env('PAYPAL_SECRET', null), 'client_id' => env('PAYPAL_CLIENT_ID', null), + ], + 'imap_inbound_expense' => [ + 'servers' => env('IMAP_INBOUND_EXPENSE_SERVERS', ''), + 'ports' => env('IMAP_INBOUND_EXPENSE_PORTS', ''), + 'users' => env('IMAP_INBOUND_EXPENSE_USERS', ''), + 'passwords' => env('IMAP_INBOUND_EXPENSE_PASSWORDS', ''), + 'companies' => env('IMAP_INBOUND_EXPENSE_COMPANIES', ''), ] ]; diff --git a/database/migrations/2023_12_10_110951_create_imap_configuration_fields.php b/database/migrations/2023_12_10_110951_create_imap_configuration_fields.php index a4a788c38553..e5b8a03b3abe 100644 --- a/database/migrations/2023_12_10_110951_create_imap_configuration_fields.php +++ b/database/migrations/2023_12_10_110951_create_imap_configuration_fields.php @@ -11,14 +11,11 @@ return new class extends Migration { public function up(): void { Schema::table('company', function (Blueprint $table) { - $table->string("expense_mailbox_imap_host")->nullable(); - $table->string("expense_mailbox_imap_port")->nullable(); - $table->string("expense_mailbox_imap_user")->nullable(); - $table->string("expense_mailbox_imap_password")->nullable(); + $table->string("expense_import")->default(true); }); Schema::table('vendor', function (Blueprint $table) { $table->string("expense_sender_email")->nullable(); - $table->string("expense_sender_url")->nullable(); + $table->string("expense_sender_domain")->nullable(); }); }