better ExpenseMailboxJob

This commit is contained in:
paulwer 2023-12-16 18:13:08 +01:00
parent 9ef5a2501b
commit 8d43eb6664
4 changed files with 44 additions and 34 deletions

View File

@ -9,7 +9,7 @@
* @license https://www.elastic.co/licensing/elastic-license * @license https://www.elastic.co/licensing/elastic-license
*/ */
namespace App\Helpers\Mail; namespace App\Helpers\Mail\Mailbox\Imap;
use Ddeboer\Imap\MessageInterface; use Ddeboer\Imap\MessageInterface;
use Ddeboer\Imap\Server; use Ddeboer\Imap\Server;

View File

@ -11,8 +11,10 @@
namespace App\Helpers\Mail\Webhook; namespace App\Helpers\Mail\Webhook;
use App\Events\Expense\ExpenseWasCreated;
use App\Factory\ExpenseFactory; use App\Factory\ExpenseFactory;
use App\Models\Company; use App\Models\Company;
use App\Utils\Ninja;
use App\Utils\TempFile; use App\Utils\TempFile;
use App\Utils\Traits\GeneratesCounter; use App\Utils\Traits\GeneratesCounter;
use App\Utils\Traits\SavesDocuments; use App\Utils\Traits\SavesDocuments;
@ -44,6 +46,9 @@ abstract class BaseWebhookHandler
$expense->saveQuietly(); $expense->saveQuietly();
event(new ExpenseWasCreated($expense, $expense->company, Ninja::eventVars(null)));
event('eloquent.created: App\Models\Expense', $expense);
return $expense; return $expense;
} }

View File

@ -11,44 +11,28 @@
namespace App\Jobs\Mail; namespace App\Jobs\Mail;
use App\DataMapper\Analytics\EmailFailure;
use App\DataMapper\Analytics\EmailSuccess;
use App\Events\Expense\ExpenseWasCreated; use App\Events\Expense\ExpenseWasCreated;
use App\Events\Invoice\InvoiceWasEmailedAndFailed;
use App\Events\Payment\PaymentWasEmailedAndFailed;
use App\Factory\ExpenseFactory; use App\Factory\ExpenseFactory;
use App\Helpers\Mail\Mailbox\Imap\ImapMailbox; use App\Helpers\Mail\Mailbox\Imap\ImapMailbox;
use App\Jobs\Util\SystemLogger;
use App\Libraries\Google\Google;
use App\Libraries\MultiDB; use App\Libraries\MultiDB;
use App\Models\Account;
use App\Models\ClientContact;
use App\Models\Company; use App\Models\Company;
use App\Models\Expense;
use App\Models\Invoice;
use App\Models\Payment;
use App\Models\SystemLog;
use App\Models\User;
use App\Models\Vendor; use App\Models\Vendor;
use App\Repositories\ExpenseRepository; use App\Repositories\ExpenseRepository;
use App\Utils\Ninja; use App\Utils\Ninja;
use App\Utils\TempFile;
use App\Utils\Traits\MakesHash; use App\Utils\Traits\MakesHash;
use GuzzleHttp\Exception\ClientException; use App\Utils\Traits\SavesDocuments;
use Illuminate\Bus\Queueable; use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels; use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Mail;
use Turbo124\Beacon\Facades\LightLogs;
/*Multi Mailer implemented*/ /*Multi Mailer implemented*/
class ExpenseMailboxJob implements ShouldQueue class ExpenseMailboxJob implements ShouldQueue
{ {
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, MakesHash; use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, MakesHash, SavesDocuments;
public $tries = 4; //number of retries public $tries = 4; //number of retries
@ -70,15 +54,22 @@ class ExpenseMailboxJob implements ShouldQueue
{ {
//multiDB environment, need to //multiDB environment, need to
foreach (MultiDB::$dbs as $db) { if (sizeOf($this->imap_credentials) == 0)
MultiDB::setDB($db); return;
if (sizeOf($this->imap_credentials) != 0) { foreach ($this->imap_companies as $companyId) {
nlog("importing expenses from imap-servers"); $company = MultiDB::findAndSetDbByCompanyId($companyId);
if (!$company) {
nlog("processing of an imap_mailbox skipped because of unknown companyId: " . $companyId);
return;
}
Company::whereIn('id', $this->imap_companies)->cursor()->each(function ($company) { try {
$this->handleImapCompany($company); nlog("start importing expenses from imap-server of company: " . $companyId);
}); $this->handleImapCompany($company);
} catch (\Exception $e) {
nlog("processing of an imap_mailbox failed upnormally: " . $companyId . " message: " . $e->getMessage()); // @turbo124 @todo should this be handled in an other way?
} }
} }
@ -87,15 +78,18 @@ class ExpenseMailboxJob implements ShouldQueue
private function getImapCredentials() private function getImapCredentials()
{ {
$servers = array_map('trim', explode(",", config('ninja.inbound_expense.imap.servers'))); $servers = array_map('trim', explode(",", config('ninja.inbound_expense.imap.servers')));
$ports = explode(",", config('ninja.inbound_expense.imap.servers')); $ports = array_map('trim', explode(",", config('ninja.inbound_expense.imap.ports')));
$users = explode(",", config('ninja.inbound_expense.imap.servers')); $users = array_map('trim', explode(",", config('ninja.inbound_expense.imap.users')));
$passwords = explode(",", config('ninja.inbound_expense.imap.servers')); $passwords = array_map('trim', explode(",", config('ninja.inbound_expense.imap.passwords')));
$companies = explode(",", config('ninja.inbound_expense.imap.servers')); $companies = array_map('trim', explode(",", config('ninja.inbound_expense.imap.companies')));
if (sizeOf($servers) != sizeOf($ports) || sizeOf($servers) != sizeOf($users) || sizeOf($servers) != sizeOf($passwords) || sizeOf($servers) != sizeOf($companies)) 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)'); throw new \Exception('invalid configuration inbound_expense.imap (wrong element-count)');
foreach ($companies as $index => $companyId) { foreach ($companies as $index => $companyId) {
if ($servers[$index] == '') // if property is empty, ignore => this happens exspecialy when no config is provided and it enabled us to set a single default company for env (usefull on self-hosted)
continue;
$this->imap_credentials[$companyId] = [ $this->imap_credentials[$companyId] = [
"server" => $servers[$index], "server" => $servers[$index],
"port" => $ports[$index] != '' ? $ports[$index] : null, "port" => $ports[$index] != '' ? $ports[$index] : null,
@ -137,10 +131,21 @@ class ExpenseMailboxJob implements ShouldQueue
"documents" => $documents, // 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 $expense = ExpenseFactory::create($company->company->id, $company->company->owner()->id);
$expense->vendor_id = $vendor !== null ? $vendor->id : null;
$expense->public_notes = $mail->getSubject();
$expense->private_notes = $mail->getBodyText();
$expense->date = $mail->getDate();
// add html_message as document to the expense
$documents[] = TempFile::UploadedFileFromRaw($mail->getBodyHtml(), "E-Mail.html", "text/html");
$this->saveDocuments($documents, $expense);
$expense->saveQuietly();
event(new ExpenseWasCreated($expense, $expense->company, Ninja::eventVars(null))); event(new ExpenseWasCreated($expense, $expense->company, Ninja::eventVars(null)));
event('eloquent.created: App\Models\Expense', $expense); event('eloquent.created: App\Models\Expense', $expense);
$mail->markAsSeen(); $mail->markAsSeen();

View File

@ -234,7 +234,7 @@ return [
'ports' => env('INBOUND_EXPENSE_IMAP_PORTS', ''), 'ports' => env('INBOUND_EXPENSE_IMAP_PORTS', ''),
'users' => env('INBOUND_EXPENSE_IMAP_USERS', ''), 'users' => env('INBOUND_EXPENSE_IMAP_USERS', ''),
'passwords' => env('INBOUND_EXPENSE_IMAP_PASSWORDS', ''), 'passwords' => env('INBOUND_EXPENSE_IMAP_PASSWORDS', ''),
'companies' => env('INBOUND_EXPENSE_IMAP_COMPANIES', ''), 'companies' => env('INBOUND_EXPENSE_IMAP_COMPANIES', '1'),
], ],
'webhook' => [ 'webhook' => [
'mailbox_template' => env('INBOUND_EXPENSE_WEBHOOK_MAILBOX_TEMPLATE', null), 'mailbox_template' => env('INBOUND_EXPENSE_WEBHOOK_MAILBOX_TEMPLATE', null),