Refactor bulk emails to use Email::class

This commit is contained in:
David Bomba 2024-11-10 20:07:25 +11:00
parent 1ddd4f64aa
commit adbb225633
10 changed files with 129 additions and 43 deletions

View File

@ -359,7 +359,7 @@ class BaseRule implements RuleInterface
public function tax($item = null): self
{
if ($this->client->is_tax_exempt || !property_exists($item, 'tax_id')) {
if ($this->client->is_tax_exempt || !property_exists($item, 'tax_id') ) {
return $this->taxExempt($item);

View File

@ -72,6 +72,7 @@ class EmailController extends BaseController
$user = auth()->user();
$company = $entity_obj->company;
//@todo - need to resolve if this entity is email only
//Only handle Peppol Invoices for now. //double check if the identifier here was
if($entity_obj instanceof Invoice && !isset($entity_obj->sync->email)){
// if($entity_obj instanceof Invoice && $company->isPeppolSender()){

View File

@ -144,7 +144,7 @@ class MailgunController extends BaseController
nlog($parts);
if(count($parts) != 4 && $parts[0] != 'peppol' && stripos('db-ninja-0', $parts[3]) !== false)
if(!in_array(count($parts), [4,5]) && $parts[0] != 'peppol' && stripos('db-ninja-0', $parts[3]) !== false)
return;
$entity = ucfirst($parts[1]);
@ -164,12 +164,10 @@ class MailgunController extends BaseController
return;
}
foreach ($request->files as $file) {
$this->saveDocuments($file, $entity, true);
}
$this->saveDocuments($request->allFiles(), $entity, true);
if(empty($entity->sync))
// if sync is empty OR there is a 5th part to the email - just save.
if(empty($entity->sync) || count($parts) == 5)
return; //just save the document, do not email it!
$sync = $entity->sync;

View File

@ -13,8 +13,10 @@ namespace App\Jobs\Invoice;
use App\Models\Invoice;
use App\Models\Webhook;
use App\Services\Email\Email;
use Illuminate\Bus\Queueable;
use App\Jobs\Entity\EmailEntity;
use App\Services\Email\EmailObject;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
@ -27,15 +29,24 @@ class BulkInvoiceJob implements ShouldQueue
use Queueable;
use SerializesModels;
public $invoice;
private array $templates = [
'email_template_invoice',
'email_template_quote',
'email_template_credit',
'email_template_payment',
'email_template_payment_partial',
'email_template_statement',
'email_template_reminder1',
'email_template_reminder2',
'email_template_reminder3',
'email_template_reminder_endless',
'email_template_custom1',
'email_template_custom2',
'email_template_custom3',
'email_template_purchase_order',
];
public $reminder_template;
public function __construct(Invoice $invoice, string $reminder_template)
{
$this->invoice = $invoice;
$this->reminder_template = $reminder_template;
}
public function __construct(public Invoice $invoice, public string $reminder_template){}
/**
* Execute the job.
@ -49,7 +60,24 @@ class BulkInvoiceJob implements ShouldQueue
$this->invoice->service()->markSent()->save();
$this->invoice->invitations->load('contact.client.country', 'invoice.client.country', 'invoice.company')->each(function ($invitation) {
EmailEntity::dispatch($invitation, $this->invoice->company, $this->reminder_template)->delay(now()->addSeconds(5));
// EmailEntity::dispatch($invitation, $this->invoice->company, $this->reminder_template)->delay(now()->addSeconds(5));
//@refactor 2024-11-10 - move email into EmailObject/Email::class
$template = $this->resolveTemplateString($this->reminder_template);
$mo = new EmailObject();
$mo->entity_id = $invitation->invoice_id;
$mo->template = $template; //full template name in use
$mo->email_template_body = $template;
$mo->email_template_subject = str_replace("template", "subject", $template);
$mo->entity_class = get_class($invitation->invoice);
$mo->invitation_id = $invitation->id;
$mo->client_id = $invitation->contact->client_id ?? null;
$mo->vendor_id = $invitation->contact->vendor_id ?? null;
Email::dispatch($mo, $invitation->company);
});
if ($this->invoice->invitations->count() >= 1) {
@ -58,4 +86,20 @@ class BulkInvoiceJob implements ShouldQueue
}
}
private function resolveTemplateString(string $template): string
{
return match ($template) {
'reminder1' => 'email_template_reminder1',
'reminder2' => 'email_template_reminder2',
'reminder3' => 'email_template_reminder3',
'endless_reminder' => 'email_template_reminder_endless',
'custom1' => 'email_template_custom1',
'custom2' => 'email_template_custom2',
'custom3' => 'email_template_custom3',
default => "email_template_{$template}",
};
}
}

View File

@ -191,7 +191,7 @@ class TemplateEmail extends Mailable
}
} elseif ($this->invitation->quote) {//@phpstan-ignore-line
if ($this->invitation->quote->client->getSetting('enable_e_invoice') && $this->invitation->invoice->client->getSetting('ubl_email_attachment') && $this->company->account->hasFeature(Account::FEATURE_PDF_ATTACHMENT)) {
if ($this->invitation->quote->client->getSetting('enable_e_invoice') && $this->invitation->quote->client->getSetting('ubl_email_attachment') && $this->company->account->hasFeature(Account::FEATURE_PDF_ATTACHMENT)) {
$xml_string = $this->invitation->quote->service()->getEQuote($this->invitation->contact);
if ($xml_string) {
@ -200,7 +200,7 @@ class TemplateEmail extends Mailable
}
} elseif ($this->invitation->purchase_order) {
if ($this->invitation->purchase_order->vendor->getSetting('enable_e_invoice') && $this->invitation->invoice->client->getSetting('ubl_email_attachment') && $this->company->account->hasFeature(Account::FEATURE_PDF_ATTACHMENT)) {
if ($this->invitation->purchase_order->vendor->getSetting('enable_e_invoice') && $this->invitation->purchase_order->vendor->getSetting('ubl_email_attachment') && $this->company->account->hasFeature(Account::FEATURE_PDF_ATTACHMENT)) {
$xml_string = $this->invitation->purchase_order->service()->getEPurchaseOrder($this->invitation->contact);
if ($xml_string) {

View File

@ -581,9 +581,13 @@ class Mutator implements MutatorInterface
{
$code = $this->getClientRoutingCode();
if($this->invoice->client->classification == 'individual' || (strlen($this->invoice->client->vat_number ?? '') < 2 && strlen($this->invoice->client->id_number ?? '') < 2)){
if($this->invoice->client->classification == 'government'){
$this->setEmailRouting("peppol_invoice_{$this->invoice->id}_{$this->invoice->company->db}_storeonly@mail.invoicing.co");
}
else if($this->invoice->client->classification == 'individual' || (strlen($this->invoice->client->vat_number ?? '') < 2 && strlen($this->invoice->client->id_number ?? '') < 2)){
return $this->setEmailRouting($this->getIndividualEmailRoute());
}else {
}
else {
$this->setEmailRouting("peppol_invoice_{$this->invoice->id}_{$this->invoice->company->db}_storeonly@mail.invoicing.co");
}
@ -592,6 +596,9 @@ class Mutator implements MutatorInterface
else
$vat = $this->invoice->client->vat_number;
if($this->invoice->client->country->iso_3166_2 == 'DE' && $this->invoice->client->classification == 'government')
$vat = $this->invoice->client->routing_id;
$this->setStorecoveMeta($this->buildRouting([
["scheme" => $code, "id" => $vat]
]));
@ -665,7 +672,7 @@ class Mutator implements MutatorInterface
private function setStorecoveMeta(array $meta): self
{
$this->storecove_meta = array_merge($this->storecove_meta, $meta);
$this->storecove_meta = array_merge_recursive($this->storecove_meta, $meta);
return $this;
}

View File

@ -365,8 +365,6 @@ class StorecoveAdapter
$this->nexus = $company_country_code;
} elseif (in_array($client_country_code, $eu_countries)) {
//EU Sale where Company country != Client Country
// First, determine if we're over threshold
$is_over_threshold = isset($this->ninja_invoice->company->tax_data->regions->EU->has_sales_above_threshold) &&
$this->ninja_invoice->company->tax_data->regions->EU->has_sales_above_threshold;
@ -405,6 +403,19 @@ class StorecoveAdapter
}
if($company_country_code == 'DE' && $client_country_code == 'DE' && $this->ninja_invoice->client->classification == 'government') {
$this->removeSupplierVatNumber();
}
return $this;
}
private function removeSupplierVatNumber(): self
{
$asp = $this->storecove_invoice->getAccountingSupplierParty();
$asp->setPublicIdentifiers([]);
$this->storecove_invoice->setAccountingSupplierParty($asp);
return $this;
}

View File

@ -407,7 +407,6 @@ class Peppol extends AbstractService
$id->value = $this->invoice->po_number;
$order_reference->ID = $id;
$this->p_invoice->OrderReference = $order_reference;
}
@ -1069,7 +1068,6 @@ class Peppol extends AbstractService
$party->PartyTaxScheme[] = $pts;
}
$party_name = new PartyName();

View File

@ -13,23 +13,16 @@ namespace App\Services\Quote;
use App\Models\Webhook;
use App\Models\ClientContact;
use App\Services\Email\Email;
use App\Jobs\Entity\EmailEntity;
use App\Models\Quote;
use App\Services\Email\EmailObject;
class SendEmail
{
public $quote;
protected $reminder_template;
protected $contact;
public function __construct($quote, $reminder_template = null, ClientContact $contact = null)
public function __construct(public Quote $quote, public ?string $reminder_template = null, protected ?ClientContact $contact = null)
{
$this->quote = $quote;
$this->reminder_template = $reminder_template;
$this->contact = $contact;
}
/**
@ -39,15 +32,31 @@ class SendEmail
public function run()
{
if (! $this->reminder_template) {
$this->reminder_template = $this->quote->calculateTemplate('quote');
}
$this->reminder_template = $this->reminder_template ? "email_template_{$this->reminder_template}" : "email_template_".$this->quote->calculateTemplate('quote');
// if (! $this->reminder_template) {
// $this->reminder_template = $this->quote->calculateTemplate('quote');
// }
$this->quote->service()->markSent()->save();
$this->quote->invitations->each(function ($invitation) {
if (! $invitation->contact->trashed() && $invitation->contact->email) {
EmailEntity::dispatch($invitation, $invitation->company, $this->reminder_template);
// EmailEntity::dispatch($invitation, $invitation->company, $this->reminder_template);
//@refactor 2024-11-10
$mo = new EmailObject();
$mo->entity_id = $invitation->quote_id;
$mo->template = $this->reminder_template; //full template name in use
$mo->email_template_body = $this->reminder_template;
$mo->email_template_subject = str_replace("template", "subject", $this->reminder_template);
$mo->entity_class = get_class($invitation->quote);
$mo->invitation_id = $invitation->id;
$mo->client_id = $invitation->contact->client_id ?? null;
$mo->vendor_id = $invitation->contact->vendor_id ?? null;
Email::dispatch($mo, $invitation->company);
}
});

View File

@ -15,8 +15,10 @@ use App\Utils\Ninja;
use App\Models\Quote;
use App\Models\Webhook;
use Illuminate\Http\Request;
use App\Services\Email\Email;
use App\Jobs\Entity\EmailEntity;
use App\Services\AbstractService;
use App\Services\Email\EmailObject;
use App\Events\Quote\QuoteWasEmailed;
use App\Utils\Traits\GeneratesCounter;
@ -80,9 +82,25 @@ class TriggeredActions extends AbstractService
{
$reminder_template = $this->quote->calculateTemplate('quote');
// $reminder_template = 'email_template_quote';
// $quote_template = 'email_template_reminder1
$reminder_template = "email_template_{$reminder_template}";
$this->quote->invitations->load('contact.client.country', 'quote.client.country', 'quote.company')->each(function ($invitation) use ($reminder_template) {
EmailEntity::dispatch($invitation, $this->quote->company, $reminder_template);
// EmailEntity::dispatch($invitation, $this->quote->company, $reminder_template);
$mo = new EmailObject();
$mo->entity_id = $invitation->quote_id;
$mo->template = $reminder_template; //full template name in use
$mo->email_template_body = $reminder_template;
$mo->email_template_subject = str_replace("template", "subject", $reminder_template);
$mo->entity_class = get_class($invitation->quote);
$mo->invitation_id = $invitation->id;
$mo->client_id = $invitation->contact->client_id ?? null;
$mo->vendor_id = $invitation->contact->vendor_id ?? null;
Email::dispatch($mo, $invitation->company);
});
if ($this->quote->invitations->count() > 0) {