credentials = []; $this->getImapCredentials(); $this->expense_repo = new ExpenseRepository(); // @turbo124 @todo is this the right aproach? should it be handled just with the model? } public function handle() { //multiDB environment, need to foreach (MultiDB::$dbs as $db) { MultiDB::setDB($db); if (sizeOf($this->imap_credentials) != 0) { nlog("importing expenses from imap-servers"); Company::whereIn('id', $this->imap_companies)->cursor()->each(function ($company) { $this->handleImapCompany($company); }); } } } private function getImapCredentials() { $servers = array_map('trim', explode(",", config('ninja.inbound_expense.imap.servers'))); $ports = explode(",", config('ninja.inbound_expense.imap.servers')); $users = explode(",", config('ninja.inbound_expense.imap.servers')); $passwords = explode(",", config('ninja.inbound_expense.imap.servers')); $companies = explode(",", config('ninja.inbound_expense.imap.servers')); if (sizeOf($servers) != sizeOf($ports) || sizeOf($servers) != sizeOf($users) || sizeOf($servers) != sizeOf($passwords) || sizeOf($servers) != sizeOf($companies)) throw new \Exception('invalid configuration inbound_expense.imap (wrong element-count)'); foreach ($companies as $index => $companyId) { $this->imap_credentials[$companyId] = [ "server" => $servers[$index], "port" => $ports[$index] != '' ? $ports[$index] : null, "user" => $users[$index], "password" => $passwords[$index], ]; $this->imap_companies[] = $companyId; } } private function handleImapCompany(Company $company) { nlog("importing expenses for company: " . $company->id); $credentials = $this->imap_credentials[$company->id]; $imapMailbox = new ImapMailbox($credentials->server, $credentials->port, $credentials->user, $credentials->password); $emails = $imapMailbox->getUnprocessedEmails(); foreach ($emails as $mail) { try { $sender = $mail->getSender(); $vendor = Vendor::where('expense_sender_email', $sender)->first(); if ($vendor == null) $vendor = Vendor::where($sender, 'LIKE', "CONCAT('%',expense_sender_domain)")->first(); if ($vendor == null) $vendor = Vendor::where("email", $sender)->first(); $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" => $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 event(new ExpenseWasCreated($expense, $expense->company, Ninja::eventVars(null))); event('eloquent.created: App\Models\Expense', $expense); $mail->markAsSeen(); $imapMailbox->moveProcessed($mail); } catch (\Exception $e) { $imapMailbox->moveFailed($mail); nlog("processing of an email failed upnormally: " . $company->id . " message: " . $e->getMessage()); // @turbo124 @todo should this be handled in an other way? } } } public function backoff() { // return [5, 10, 30, 240]; return [rand(5, 10), rand(30, 40), rand(60, 79), rand(160, 400)]; } }