mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-08 20:22:42 +01:00
Minor refactors for inbound email processing
This commit is contained in:
parent
8f88c408f7
commit
93c382eae1
@ -11,9 +11,11 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Jobs\Mailgun\ProcessMailgunInboundWebhook;
|
||||
use App\Jobs\Mailgun\ProcessMailgunWebhook;
|
||||
use App\Models\Company;
|
||||
use App\Libraries\MultiDB;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Jobs\Mailgun\ProcessMailgunWebhook;
|
||||
use App\Jobs\Mailgun\ProcessMailgunInboundWebhook;
|
||||
|
||||
/**
|
||||
* Class MailgunController.
|
||||
@ -126,9 +128,15 @@ class MailgunController extends BaseController
|
||||
$authorizedByHash = \hash_equals(\hash_hmac('sha256', $input['timestamp'] . $input['token'], config('services.mailgun.webhook_signing_key')), $input['signature']);
|
||||
$authorizedByToken = $request->has('token') && $request->get('token') == config('ninja.inbound_mailbox.inbound_webhook_token');
|
||||
if (!$authorizedByHash && !$authorizedByToken)
|
||||
return response()->json(['message' => 'Unauthorized'], 403);
|
||||
return response()->json(['message' => 'Unauthorized'], 403);
|
||||
|
||||
ProcessMailgunInboundWebhook::dispatch($input["sender"], $input["recipient"], $input["message-url"])->delay(rand(2, 10));
|
||||
/** @var \App\Models\Company $company */
|
||||
$company = MultiDB::findAndSetDbByExpenseMailbox($input["recipient"]);
|
||||
|
||||
if(!$company)
|
||||
return response()->json(['message' => 'Ok'], 200); // Fail gracefully
|
||||
|
||||
ProcessMailgunInboundWebhook::dispatch($input["sender"], $input["recipient"], $input["message-url"], $company)->delay(rand(2, 10));
|
||||
|
||||
return response()->json(['message' => 'Success.'], 200);
|
||||
}
|
||||
|
@ -280,20 +280,21 @@ class PostMarkController extends BaseController
|
||||
nlog('Failed: Message could not be parsed, because required parameters are missing.');
|
||||
return response()->json(['message' => 'Failed. Missing/Invalid Parameters.'], 400);
|
||||
}
|
||||
|
||||
$company = MultiDB::findAndSetDbByExpenseMailbox($input["To"]);
|
||||
|
||||
$inboundEngine = new InboundMailEngine();
|
||||
if (!$company) {
|
||||
nlog('[PostmarkInboundWebhook] unknown Expense Mailbox occured while handling an inbound email from postmark: ' . $input["To"]);
|
||||
// $inboundEngine->saveMeta($input["From"], $input["To"], true); // important to save this, to protect from spam
|
||||
return response()->json(['message' => 'Ok'], 200);
|
||||
}
|
||||
|
||||
$inboundEngine = new InboundMailEngine($company);
|
||||
|
||||
if ($inboundEngine->isInvalidOrBlocked($input["From"], $input["To"])) {
|
||||
return response()->json(['message' => 'Blocked.'], 403);
|
||||
}
|
||||
|
||||
$company = MultiDB::findAndSetDbByExpenseMailbox($input["To"]);
|
||||
if (!$company) {
|
||||
nlog('[PostmarkInboundWebhook] unknown Expense Mailbox occured while handling an inbound email from postmark: ' . $input["To"]);
|
||||
$inboundEngine->saveMeta($input["From"], $input["To"], true); // important to save this, to protect from spam
|
||||
return;
|
||||
}
|
||||
|
||||
try { // important to save meta if something fails here to prevent spam
|
||||
|
||||
// prepare data for ingresEngine
|
||||
|
@ -23,10 +23,7 @@ class ValidExpenseMailbox implements Rule
|
||||
{
|
||||
|
||||
private $validated_schema = false;
|
||||
private $isEnterprise = false;
|
||||
private array $endings;
|
||||
private bool $hasCompanyKey;
|
||||
private array $enterprise_endings;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
|
@ -11,19 +11,20 @@
|
||||
|
||||
namespace App\Jobs\Brevo;
|
||||
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Services\InboundMail\InboundMail;
|
||||
use App\Services\InboundMail\InboundMailEngine;
|
||||
use App\Utils\TempFile;
|
||||
use Brevo\Client\Api\InboundParsingApi;
|
||||
use Brevo\Client\Configuration;
|
||||
use Illuminate\Support\Carbon;
|
||||
use App\Libraries\MultiDB;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Brevo\Client\Configuration;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Brevo\Client\Api\InboundParsingApi;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use App\Services\InboundMail\InboundMail;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use App\Services\InboundMail\InboundMailEngine;
|
||||
use Illuminate\Queue\Middleware\WithoutOverlapping;
|
||||
|
||||
class ProcessBrevoInboundWebhook implements ShouldQueue
|
||||
{
|
||||
@ -111,7 +112,6 @@ class ProcessBrevoInboundWebhook implements ShouldQueue
|
||||
*/
|
||||
public function __construct(private array $input)
|
||||
{
|
||||
$this->engine = new InboundMailEngine();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -134,18 +134,24 @@ class ProcessBrevoInboundWebhook implements ShouldQueue
|
||||
|
||||
// match company
|
||||
$company = MultiDB::findAndSetDbByExpenseMailbox($recipient);
|
||||
|
||||
if (!$company) {
|
||||
nlog('[ProcessBrevoInboundWebhook] unknown Expense Mailbox occured while handling an inbound email from brevo: ' . $recipient);
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->engine = new InboundMailEngine($company);
|
||||
|
||||
$foundOneRecipient = true;
|
||||
|
||||
try { // important to save meta if something fails here to prevent spam
|
||||
|
||||
$company_brevo_secret = $company->settings?->email_sending_method === 'client_brevo' && $company->settings?->brevo_secret ? $company->settings?->brevo_secret : null;
|
||||
if (empty($company_brevo_secret) && empty(config('services.brevo.secret')))
|
||||
if(strlen($company->getSetting('brevo_secret') ?? '') < 2 && empty(config('services.brevo.secret'))){
|
||||
nlog("No Brevo Configuration available for this company");
|
||||
throw new \Error("[ProcessBrevoInboundWebhook] no brevo credenitals found, we cannot get the attachement");
|
||||
}
|
||||
|
||||
$company_brevo_secret = strlen($company->getSetting('brevo_secret') ?? '') < 2 ? $company->getSetting('brevo_secret') : config('services.brevo.secret');
|
||||
|
||||
// prepare data for ingresEngine
|
||||
$inboundMail = new InboundMail();
|
||||
@ -160,8 +166,10 @@ class ProcessBrevoInboundWebhook implements ShouldQueue
|
||||
// parse documents as UploadedFile from webhook-data
|
||||
foreach ($this->input["Attachments"] as $attachment) {
|
||||
|
||||
// @todo - i think this allows switching between client configured brevo AND system configured brevo
|
||||
// download file and save to tmp dir
|
||||
if (!empty($company_brevo_secret)) {
|
||||
if (!empty($company_brevo_secret))
|
||||
{
|
||||
|
||||
try {
|
||||
|
||||
@ -220,4 +228,17 @@ class ProcessBrevoInboundWebhook implements ShouldQueue
|
||||
$this->engine->saveMeta($this->input["From"]["Address"], $recipient, true);
|
||||
}
|
||||
}
|
||||
|
||||
public function middleware()
|
||||
{
|
||||
return [new WithoutOverlapping($this->input["From"]["Address"])];
|
||||
}
|
||||
|
||||
public function failed($exception)
|
||||
{
|
||||
nlog("BREVO:: Ingest Exception:: => ".$exception->getMessage());
|
||||
config(['queue.failed.driver' => null]);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -11,16 +11,17 @@
|
||||
|
||||
namespace App\Jobs\Mailgun;
|
||||
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Services\InboundMail\InboundMail;
|
||||
use App\Services\InboundMail\InboundMailEngine;
|
||||
use App\Models\Company;
|
||||
use App\Utils\TempFile;
|
||||
use Illuminate\Support\Carbon;
|
||||
use App\Libraries\MultiDB;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use App\Services\InboundMail\InboundMail;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use App\Services\InboundMail\InboundMailEngine;
|
||||
|
||||
class ProcessMailgunInboundWebhook implements ShouldQueue
|
||||
{
|
||||
@ -34,9 +35,9 @@ class ProcessMailgunInboundWebhook implements ShouldQueue
|
||||
* Create a new job instance.
|
||||
* $input consists of 3 informations: sender/from|recipient/to|messageUrl
|
||||
*/
|
||||
public function __construct(private string $sender, private string $recipient, private string $message_url)
|
||||
public function __construct(private string $sender, private string $recipient, private string $message_url, private Company $company)
|
||||
{
|
||||
$this->engine = new InboundMailEngine();
|
||||
$this->engine = new InboundMailEngine($company);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -176,19 +177,20 @@ class ProcessMailgunInboundWebhook implements ShouldQueue
|
||||
return;
|
||||
}
|
||||
|
||||
// lets assess this at a higher level to ensure that only valid email inboxes are processed.
|
||||
// match company
|
||||
$company = MultiDB::findAndSetDbByExpenseMailbox($to);
|
||||
if (!$company) {
|
||||
nlog('[ProcessMailgunInboundWebhook] unknown Expense Mailbox occured while handling an inbound email from mailgun: ' . $to);
|
||||
$this->engine->saveMeta($from, $to, true); // important to save this, to protect from spam
|
||||
return;
|
||||
}
|
||||
// $company = MultiDB::findAndSetDbByExpenseMailbox($to);
|
||||
// if (!$company) {
|
||||
// nlog('[ProcessMailgunInboundWebhook] unknown Expense Mailbox occured while handling an inbound email from mailgun: ' . $to);
|
||||
// $this->engine->saveMeta($from, $to, true); // important to save this, to protect from spam
|
||||
// return;
|
||||
// }
|
||||
|
||||
try { // important to save meta if something fails here to prevent spam
|
||||
|
||||
// fetch message from mailgun-api
|
||||
$company_mailgun_domain = $company->getSetting('email_sending_method') == 'client_mailgun' && strlen($company->getSetting('mailgun_domain') ?? '') > 2 ? $company->getSetting('mailgun_domain') : null;
|
||||
$company_mailgun_secret = $company->getSetting('email_sending_method') == 'client_mailgun' && strlen($company->getSetting('mailgun_secret') ?? '') > 2 ? $company->getSetting('mailgun_secret') : null;
|
||||
$company_mailgun_domain = $this->company->getSetting('email_sending_method') == 'client_mailgun' && strlen($this->company->getSetting('mailgun_domain') ?? '') > 2 ? $this->company->getSetting('mailgun_domain') : null;
|
||||
$company_mailgun_secret = $this->company->getSetting('email_sending_method') == 'client_mailgun' && strlen($this->company->getSetting('mailgun_secret') ?? '') > 2 ? $this->company->getSetting('mailgun_secret') : null;
|
||||
if (!($company_mailgun_domain && $company_mailgun_secret) && !(config('services.mailgun.domain') && config('services.mailgun.secret')))
|
||||
throw new \Error("[ProcessMailgunInboundWebhook] no mailgun credentials found, we cannot get the attachements and files");
|
||||
|
||||
|
@ -47,8 +47,10 @@ class MindeeEDocument extends AbstractService
|
||||
public function run(): Expense
|
||||
{
|
||||
$api_key = config('services.mindee.api_key');
|
||||
|
||||
if (!$api_key)
|
||||
throw new Exception('Mindee API key not configured');
|
||||
|
||||
$this->checkLimits();
|
||||
|
||||
// perform parsing
|
||||
@ -69,42 +71,52 @@ class MindeeEDocument extends AbstractService
|
||||
$invoiceCurrency = $prediction->locale->currency;
|
||||
$country = $prediction->locale->country;
|
||||
|
||||
$expense = Expense::where('amount', $grandTotalAmount)->where("transaction_reference", $documentno)->whereDate("date", $documentdate)->first();
|
||||
if (empty($expense)) {
|
||||
$expense = Expense::query()
|
||||
->where('company_id', $this->company->id)
|
||||
->where('amount', $grandTotalAmount)
|
||||
->where("transaction_reference", $documentno)
|
||||
->whereDate("date", $documentdate)
|
||||
->first();
|
||||
|
||||
if (!$expense) {
|
||||
// The document does not exist as an expense
|
||||
// Handle accordingly
|
||||
|
||||
/** @var \App\Models\Currency $currency */
|
||||
$currency = app('currencies')->first(function ($c) use ($invoiceCurrency){
|
||||
/** @var \App\Models\Currency $c */
|
||||
return $c->code == $invoiceCurrency;
|
||||
});
|
||||
|
||||
$expense = ExpenseFactory::create($this->company->id, $this->company->owner()->id);
|
||||
$expense->date = $documentdate;
|
||||
$expense->user_id = $this->company->owner()->id;
|
||||
$expense->company_id = $this->company->id;
|
||||
$expense->public_notes = $documentno;
|
||||
$expense->currency_id = Currency::whereCode($invoiceCurrency)->first()?->id || $this->company->settings->currency_id;
|
||||
$expense->currency_id = $currency ? $currency->id : $this->company->settings->currency_id;
|
||||
$expense->save();
|
||||
|
||||
$this->saveDocuments([
|
||||
$this->file,
|
||||
TempFile::UploadedFileFromRaw(strval($result->document), $documentno . "_mindee_orc_result.txt", "text/plain")
|
||||
], $expense);
|
||||
$expense->saveQuietly();
|
||||
// $expense->saveQuietly();
|
||||
|
||||
$expense->uses_inclusive_taxes = True;
|
||||
$expense->amount = $grandTotalAmount;
|
||||
$counter = 1;
|
||||
|
||||
foreach ($prediction->taxes as $taxesElem) {
|
||||
$expense->{"tax_amount$counter"} = $taxesElem->amount;
|
||||
$expense->{"tax_rate$counter"} = $taxesElem->rate;
|
||||
$expense->{"tax_amount{$counter}"} = $taxesElem->amount;
|
||||
$expense->{"tax_rate{$counter}"} = $taxesElem->rate;
|
||||
$counter++;
|
||||
}
|
||||
|
||||
$vendor = null;
|
||||
$vendor_contact = VendorContact::where("company_id", $this->company->id)->where("email", $prediction->supplierEmail)->first();
|
||||
if ($vendor_contact)
|
||||
$vendor = $vendor_contact->vendor;
|
||||
if (!$vendor)
|
||||
$vendor = Vendor::where("company_id", $this->company->id)->where("name", $prediction->supplierName)->first();
|
||||
|
||||
/** @var \App\Models\VendorContact $vendor_contact */
|
||||
$vendor_contact = VendorContact::query()->where("company_id", $this->company->id)->where("email", $prediction->supplierEmail)->first();
|
||||
|
||||
/** @var \App\Models\Vendor|null $vendor */
|
||||
$vendor = $vendor_contact ? $vendor_contact->vendor : Vendor::query()->where("company_id", $this->company->id)->where("name", $prediction->supplierName)->first();
|
||||
|
||||
if ($vendor) {
|
||||
// Vendor found
|
||||
$expense->vendor_id = $vendor->id;
|
||||
} else {
|
||||
$vendor = VendorFactory::create($this->company->id, $this->company->owner()->id);
|
||||
@ -116,15 +128,19 @@ class MindeeEDocument extends AbstractService
|
||||
// $vendor->address2 = $address_2;
|
||||
// $vendor->city = $city;
|
||||
// $vendor->postal_code = $postcode;
|
||||
|
||||
/** @var ?\App\Models\Country $country */
|
||||
$country = app('countries')->first(function ($c) use ($country) {
|
||||
/** @var \App\Models\Country $c */
|
||||
return $c->iso_3166_2 == $country || $c->iso_3166_3 == $country;
|
||||
});
|
||||
|
||||
if ($country)
|
||||
$vendor->country_id = $country->id;
|
||||
|
||||
$vendor->save();
|
||||
|
||||
if ($prediction->supplierEmail) {
|
||||
if (strlen($prediction->supplierEmail ?? '') > 2) {
|
||||
$vendor_contact = VendorContactFactory::create($this->company->id, $this->company->owner()->id);
|
||||
$vendor_contact->vendor_id = $vendor->id;
|
||||
$vendor_contact->email = $prediction->supplierEmail;
|
||||
@ -138,8 +154,9 @@ class MindeeEDocument extends AbstractService
|
||||
// The document exists as an expense
|
||||
// Handle accordingly
|
||||
nlog("Mindee: Document already exists");
|
||||
$expense->private_notes = $expense->private_notes . ctrans("texts.edocument_import_already_exists", ["date" => time()]);
|
||||
$expense->private_notes = $expense->private_notes . ctrans("texts.edocument_import_already_exists", ["date" => now()->format('Y-m-d')]);
|
||||
}
|
||||
|
||||
$expense->save();
|
||||
return $expense;
|
||||
}
|
||||
|
@ -102,17 +102,20 @@ class ZugferdEDocument extends AbstractService
|
||||
if (array_key_exists("VA", $taxtype)) {
|
||||
$taxid = $taxtype["VA"];
|
||||
}
|
||||
$vendor = Vendor::where("company_id", $user->company()->id)->where('vat_number', $taxid)->first();
|
||||
if (!$vendor) {
|
||||
$vendor_contact = VendorContact::where("company_id", $user->company()->id)->where("email", $contact_email)->first();
|
||||
if ($vendor_contact)
|
||||
$vendor = $vendor_contact->vendor;
|
||||
}
|
||||
if (!$vendor)
|
||||
$vendor = Vendor::where("company_id", $user->company()->id)->where("name", $person_name)->first();
|
||||
|
||||
if (!empty($vendor)) {
|
||||
// Vendor found
|
||||
$vendor = Vendor::query()
|
||||
->where("company_id", $user->company()->id)
|
||||
->where(function ($q) use($taxid, $person_name, $contact_email){
|
||||
$q->when(!is_null($taxid), function ($when_query) use($taxid){
|
||||
$when_query->orWhere('vat_number', $taxid);
|
||||
})
|
||||
->orWhere("name", $person_name)
|
||||
->orWhereHas('contacts', function ($qq) use ($contact_email){
|
||||
$qq->where("email", $contact_email);
|
||||
});
|
||||
})->first();
|
||||
|
||||
if ($vendor) {
|
||||
$expense->vendor_id = $vendor->id;
|
||||
} else {
|
||||
$vendor = VendorFactory::create($this->company->id, $user->id);
|
||||
|
@ -35,7 +35,7 @@ class InboundMailEngine
|
||||
|
||||
private array $globalBlacklist;
|
||||
private array $globalWhitelist; // only for global validation, not for allowing to send something into the company, should be used to disabled blocking for mass-senders
|
||||
public function __construct()
|
||||
public function __construct(private Company $company)
|
||||
{
|
||||
|
||||
// only for global validation, not for allowing to send something into the company, should be used to disabled blocking for mass-senders
|
||||
@ -52,19 +52,19 @@ class InboundMailEngine
|
||||
return;
|
||||
|
||||
// Expense Mailbox => will create an expense
|
||||
$company = MultiDB::findAndSetDbByExpenseMailbox($email->to);
|
||||
if (!$company) {
|
||||
$this->saveMeta($email->from, $email->to, true);
|
||||
return;
|
||||
}
|
||||
// $company = MultiDB::findAndSetDbByExpenseMailbox($email->to);
|
||||
// if (!$company) {
|
||||
// $this->saveMeta($email->from, $email->to, true);
|
||||
// return;
|
||||
// }
|
||||
|
||||
// check if company plan matches requirements
|
||||
if (Ninja::isHosted() && !($company->account->isPaid() && $company->account->plan == 'enterprise')) {
|
||||
if (Ninja::isHosted() && !($this->company->account->isPaid() && $this->company->account->plan == 'enterprise')) {
|
||||
$this->saveMeta($email->from, $email->to);
|
||||
return;
|
||||
}
|
||||
|
||||
$this->createExpenses($company, $email);
|
||||
$this->createExpenses($email);
|
||||
$this->saveMeta($email->from, $email->to);
|
||||
}
|
||||
|
||||
@ -145,6 +145,8 @@ class InboundMailEngine
|
||||
// TODO: ignore, when known sender (for heavy email-usage mostly on isHosted())
|
||||
// TODO: handle external blocking
|
||||
}
|
||||
|
||||
//@todo - refactor
|
||||
public function saveMeta(string $from, string $to, bool $isUnknownRecipent = false)
|
||||
{
|
||||
// save cache
|
||||
@ -161,24 +163,24 @@ class InboundMailEngine
|
||||
}
|
||||
|
||||
// MAIN-PROCESSORS
|
||||
protected function createExpenses(Company $company, InboundMail $email)
|
||||
protected function createExpenses(InboundMail $email)
|
||||
{
|
||||
// Skipping executions: will not result in not saving Metadata to prevent usage of these conditions, to spam
|
||||
if (!($company?->expense_mailbox_active ?: false)) {
|
||||
$this->logBlocked($company, 'mailbox not active for this company. from: ' . $email->from);
|
||||
if (!$this->company->expense_mailbox_active) {
|
||||
$this->logBlocked($this->company, 'mailbox not active for this company. from: ' . $email->from);
|
||||
return;
|
||||
}
|
||||
if (!$this->validateExpenseSender($company, $email)) {
|
||||
$this->logBlocked($company, 'invalid sender of an ingest email for this company. from: ' . $email->from);
|
||||
if (!$this->validateExpenseSender($email)) {
|
||||
$this->logBlocked($this->company, 'invalid sender of an ingest email for this company. from: ' . $email->from);
|
||||
return;
|
||||
}
|
||||
if (sizeOf($email->documents) == 0) {
|
||||
$this->logBlocked($company, 'email does not contain any attachments and is likly not an expense. from: ' . $email->from);
|
||||
$this->logBlocked($this->company, 'email does not contain any attachments and is likly not an expense. from: ' . $email->from);
|
||||
return;
|
||||
}
|
||||
|
||||
// prepare data
|
||||
$expense_vendor = $this->getVendor($company, $email);
|
||||
$expense_vendor = $this->getVendor($email);
|
||||
$this->processHtmlBodyToDocument($email);
|
||||
|
||||
$parsed_expense_ids = []; // used to check if an expense was already matched within this job
|
||||
@ -192,7 +194,7 @@ class InboundMailEngine
|
||||
// check if document can be parsed to an expense
|
||||
try {
|
||||
|
||||
$expense = (new ParseEDocument($document, $company))->run();
|
||||
$expense = (new ParseEDocument($document, $this->company))->run();
|
||||
|
||||
// check if expense was already matched within this job and skip if true
|
||||
if (array_search($expense->id, $parsed_expense_ids))
|
||||
@ -213,7 +215,7 @@ class InboundMailEngine
|
||||
|
||||
// populate missing data with data from email
|
||||
if (!$expense)
|
||||
$expense = ExpenseFactory::create($company->id, $company->owner()->id);
|
||||
$expense = ExpenseFactory::create($this->company->id, $this->company->owner()->id);
|
||||
|
||||
$is_imported_by_parser = array_search($expense->id, $parsed_expense_ids);
|
||||
|
||||
@ -256,61 +258,61 @@ class InboundMailEngine
|
||||
$email->body_document = TempFile::UploadedFileFromRaw($email->body, "E-Mail.html", "text/html");
|
||||
|
||||
}
|
||||
private function validateExpenseSender(Company $company, InboundMail $email)
|
||||
private function validateExpenseSender(InboundMail $email)
|
||||
{
|
||||
$parts = explode('@', $email->from);
|
||||
$domain = array_pop($parts);
|
||||
|
||||
// whitelists
|
||||
$whitelist = explode(",", $company->inbound_mailbox_whitelist);
|
||||
$whitelist = explode(",", $this->company->inbound_mailbox_whitelist);
|
||||
if (in_array($email->from, $whitelist))
|
||||
return true;
|
||||
if (in_array($domain, $whitelist))
|
||||
return true;
|
||||
$blacklist = explode(",", $company->inbound_mailbox_blacklist);
|
||||
$blacklist = explode(",", $this->company->inbound_mailbox_blacklist);
|
||||
if (in_array($email->from, $blacklist))
|
||||
return false;
|
||||
if (in_array($domain, $blacklist))
|
||||
return false;
|
||||
|
||||
// allow unknown
|
||||
if ($company->inbound_mailbox_allow_unknown)
|
||||
if ($this->company->inbound_mailbox_allow_unknown)
|
||||
return true;
|
||||
|
||||
// own users
|
||||
if ($company->inbound_mailbox_allow_company_users && $company->users()->where("email", $email->from)->exists())
|
||||
if ($this->company->inbound_mailbox_allow_company_users && $this->company->users()->where("email", $email->from)->exists())
|
||||
return true;
|
||||
|
||||
// from vendors
|
||||
if ($company->inbound_mailbox_allow_vendors && VendorContact::where("company_id", $company->id)->where("email", $email->from)->exists())
|
||||
if ($this->company->inbound_mailbox_allow_vendors && VendorContact::where("company_id", $this->company->id)->where("email", $email->from)->exists())
|
||||
return true;
|
||||
|
||||
// from clients
|
||||
if ($company->inbound_mailbox_allow_clients && ClientContact::where("company_id", $company->id)->where("email", $email->from)->exists())
|
||||
if ($this->company->inbound_mailbox_allow_clients && ClientContact::where("company_id", $this->company->id)->where("email", $email->from)->exists())
|
||||
return true;
|
||||
|
||||
// denie
|
||||
return false;
|
||||
}
|
||||
private function getClient(Company $company, InboundMail $email)
|
||||
{
|
||||
$clientContact = ClientContact::where("company_id", $company->id)->where("email", $email->from)->first();
|
||||
if (!$clientContact)
|
||||
return null;
|
||||
|
||||
return $clientContact->client();
|
||||
}
|
||||
private function getVendor(Company $company, InboundMail $email)
|
||||
{
|
||||
$vendorContact = VendorContact::where("company_id", $company->id)->where("email", $email->from)->first();
|
||||
if (!$vendorContact)
|
||||
return null;
|
||||
// private function getClient(InboundMail $email)
|
||||
// {
|
||||
// $clientContact = ClientContact::where("company_id", $this->company->id)->where("email", $email->from)->first();
|
||||
// if (!$clientContact)
|
||||
// return null;
|
||||
|
||||
return $vendorContact->vendor();
|
||||
// return $clientContact->client();
|
||||
// }
|
||||
private function getVendor(InboundMail $email)
|
||||
{
|
||||
$vendorContact = VendorContact::with('vendor')->where("company_id", $this->company->id)->where("email", $email->from)->first();
|
||||
|
||||
return $vendorContact ? $vendorContact->vendor : null;
|
||||
}
|
||||
|
||||
private function logBlocked(Company $company, string $data)
|
||||
{
|
||||
nlog("[InboundMailEngine][company:" . $company->company_key . "] " . $data);
|
||||
nlog("[InboundMailEngine][company:" . $this->company->company_key . "] " . $data);
|
||||
|
||||
(
|
||||
new SystemLogger(
|
||||
|
@ -11,7 +11,7 @@ return new class extends Migration {
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('companies', function (Blueprint $table) {
|
||||
$table->boolean("expense_mailbox_active")->default(true);
|
||||
$table->boolean("expense_mailbox_active")->default(false);
|
||||
$table->string("expense_mailbox")->nullable();
|
||||
$table->boolean("inbound_mailbox_allow_company_users")->default(false);
|
||||
$table->boolean("inbound_mailbox_allow_vendors")->default(false);
|
||||
|
Loading…
Reference in New Issue
Block a user