Invoice reminder and shipment update notification emails

This commit is contained in:
Omair Saleh
2022-11-07 09:38:03 +08:00
parent 5d1bb976f8
commit 7f766cde6a
12 changed files with 254 additions and 8 deletions
@@ -70,7 +70,6 @@ class UpdateDoFromYDPortalProcessor
} catch (\Exception $exception){ } catch (\Exception $exception){
dd($exception);
throw new InternalServerErrorException('failed to approve address due to an error related to YD portal'); throw new InternalServerErrorException('failed to approve address due to an error related to YD portal');
} }
} }
@@ -24,6 +24,7 @@ use App\Classes\Modules\Unity\Processors\AssignContractEntityProcessor;
use App\Classes\Modules\Unity\Processors\CreateContractEntityProcessor; use App\Classes\Modules\Unity\Processors\CreateContractEntityProcessor;
use App\Classes\Modules\Unity\Services\CreatesContract; use App\Classes\Modules\Unity\Services\CreatesContract;
use App\Classes\Modules\Unity\Services\UpdatesContractObligation; use App\Classes\Modules\Unity\Services\UpdatesContractObligation;
use App\Classes\Notifications\ShipmentDepartureEmail;
use App\Classes\Notifications\ShipmentRescheduleEmail; use App\Classes\Notifications\ShipmentRescheduleEmail;
use App\Classes\ValueObjects\Constants\ApprovalStatus; use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\ContainerTypes; use App\Classes\ValueObjects\Constants\ContainerTypes;
@@ -406,9 +407,10 @@ class FetchOrderListsFromYdPortalProcessor
$etd = $transport->schedules()->where('status', '=', ApprovalStatus::APPROVED)->first()->etd; $etd = $transport->schedules()->where('status', '=', ApprovalStatus::APPROVED)->first()->etd;
$transport->schedules()->update(['status' => ApprovalStatus::EXPIRED]); $transport->schedules()->update(['status' => ApprovalStatus::EXPIRED]);
$this->createsSchedule->execute($transport, new ScheduleObject($etd, $delayDate, ApprovalStatus::APPROVED)); $this->createsSchedule->execute($transport, new ScheduleObject($etd, $delayDate, ApprovalStatus::APPROVED));
if($order instanceof Order) { foreach ($container->packingLists as $packingList){
$user = $order->companyModule->employees()->first(); if(!($packingList->owner instanceof Order)) continue;
// $user->notify(new ShipmentRescheduleEmail($user, $packingList)); $user = $packingList->owner->companyModule->employees()->first();
$user->notify(new ShipmentRescheduleEmail($user, $packingList));
} }
} }
@@ -3,6 +3,7 @@
namespace App\Classes\Modules\Transactions\ControllersLogic; namespace App\Classes\Modules\Transactions\ControllersLogic;
use App\Classes\Notifications\InvoiceIssuedEmail;
use Illuminate\Http\Request; use Illuminate\Http\Request;
@@ -87,8 +88,9 @@ class ApproveShippingInvoiceTransactionLogic extends AbstractControllerLogic
$document = $this->createsDocument->execute($invoice_transaction, $document_object); $document = $this->createsDocument->execute($invoice_transaction, $document_object);
$this->createsFiles->execute($document, $document_object); $this->createsFiles->execute($document, $document_object);
$user = $packing_list->owner->companyModule->employees()->first();
$user->notify(new InvoiceIssuedEmail($user, $packing_list));
return $this->response([]); return $this->response([]);
} }
} }
+5 -2
View File
@@ -2,14 +2,17 @@
namespace App\Classes\Notifications; namespace App\Classes\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Notification; use Illuminate\Notifications\Notification;
class AbstractEmail extends Notification class AbstractEmail extends Notification implements ShouldQueue
{ {
use Queueable;
public function via() public function via()
{ {
return 'mail'; return 'mail';
} }
} }
@@ -0,0 +1,49 @@
<?php
namespace App\Classes\Notifications;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\PackingList;
use App\Models\PasswordReset;
use App\Models\User;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Support\Facades\Storage;
class InvoiceIssuedEmail extends AbstractEmail
{
/** @var User */
private $user;
/** @var PackingList */
private $packingList;
/**
* @param User $user
* @param PackingList $packingList
*/
public function __construct(User $user, PackingList $packingList)
{
$this->user = $user;
$this->packingList = $packingList;
}
public function toMail()
{
$invoice = $this->packingList->transactions()->where('type', TransactionType::SHIPPING_INVOICE)->where('status', ApprovalStatus::APPROVED)->first();
$invoiceDocument = $invoice->documents()->first()->files;
return (new MailMessage)
->subject('Att: '.$this->user->name.' - Invoice for order no.'. $this->packingList->owner->reference)
->attach(Storage::disk('documents')->get($invoiceDocument->file->file_info->original->file), [
'as' => 'name.pdf',
'mime' => 'application/pdf',
])->view('emails.shipment.invoice', ['user' => $this->user, 'packingList' => $this->packingList]);
}
}
@@ -0,0 +1,51 @@
<?php
namespace App\Classes\Notifications;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\PackingList;
use App\Models\PasswordReset;
use App\Models\User;
use Illuminate\Notifications\Messages\MailMessage;
class ShipmentDepartureEmail extends AbstractEmail
{
/** @var User */
private $user;
/** @var PackingList */
private $packingList;
/**
* @param User $user
* @param PackingList $packingList
*/
public function __construct(User $user, PackingList $packingList)
{
$this->user = $user;
$this->packingList = $packingList;
}
public function toMail()
{
$invoice = $this->packingList->transactions()->where('type', TransactionType::SHIPPING_INVOICE)->where('status', ApprovalStatus::APPROVED)->first();
if(!$invoice) return false;
$invoiceDocument = $invoice->documents()->first()->files;
return (new MailMessage)
->subject('Your packages are on the way to malaysia - Invoice pending payment for order no.'. $this->packingList->owner->reference)
->attach(Storage::disk('documents')->get($invoiceDocument->file->file_info->original->file), [
'as' => 'name.pdf',
'mime' => 'application/pdf',
])->view('emails.shipment.ETD', ['user' => $this->user, 'packingList' => $this->packingList]);
}
}
@@ -0,0 +1,39 @@
<?php
namespace App\Classes\Notifications;
use App\Models\PackingList;
use App\Models\PasswordReset;
use App\Models\User;
use Illuminate\Notifications\Messages\MailMessage;
class ShipmentRescheduleEmail extends AbstractEmail
{
/** @var User */
private $user;
/** @var PackingList */
private $packingList;
/**
* @param User $user
* @param PackingList $packingList
*/
public function __construct(User $user, PackingList $packingList)
{
$this->user = $user;
$this->packingList = $packingList;
}
public function toMail()
{
return (new MailMessage)
->subject('Update on your recent shipment(s)')
->view('emails.shipment.reschedule', ['user' => $this->user, 'packingList' => $this->packingList]);
}
}
@@ -0,0 +1,62 @@
<?php
namespace App\Console\Commands;
use App\Classes\Notifications\InvoiceIssuedEmail;
use App\Classes\Notifications\ShipmentDepartureEmail;
use App\Http\Helpers\General;
use App\Models\Order;
use Carbon\Carbon;
use App\Models\Container;
use Illuminate\Console\Command;
class SendContainerDepartureEmailCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'command:sendContainerDepartureEmailCommand';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Command description';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$containers = Container::whereHas('transports', function ($transport){
return $transport->whereDate('dispatch_date', '=', Carbon::today());
})->get();
foreach ($containers as $container){
foreach ($container->packingLists as $packingList){
if(!($packingList->owner instanceof Order)) continue;
$user = $packingList->owner->companyModule->employees()->first();
$user->notify(new ShipmentDepartureEmail($user, $packingList));
}
}
}
}
+5
View File
@@ -38,6 +38,11 @@ class Kernel extends ConsoleKernel
->withoutOverlapping() ->withoutOverlapping()
->appendOutputTo (storage_path().'/logs/curlyd.log'); ->appendOutputTo (storage_path().'/logs/curlyd.log');
$schedule->command('command:curlYdOrderListCommand')
->cron('0 9 * * *')
->withoutOverlapping()
->appendOutputTo (storage_path().'/logs/departure_email.log');
} }
@@ -0,0 +1,8 @@
@extends('emails.layout.base')
@section('content')
<h4 style="font-size: 1em;">Hello, {{ $user->name }}</h4>
<p style="font-size: 0.9em">We wanted to send you an update on the recent shipment for you order no. <a href="{{ route('order.show', $packingList->owner->reference) }}">{{ $packingList->owner->reference }}</a> you have placed with us. We've just learned that your shipment has just departed from china's port and is estimated to arrive on {{ $packingList->containers()->first()->transports()->first()->schedules()->where('status', \App\Classes\ValueObjects\Constants\ApprovalStatus::APPROVED)->first()->eta->format('d-m-Y') }}.</p>
<p style="margin-top: 20px; font-size: 0.8em">Meanwhile, we would appreciate if you could make the payment as soon as possible so we can deliver your packages as soon as the shipment arrives. please <a href="{{ route('order.show', $packingList->owner->reference) }}">click here</a> to pay your invoice.</p>
<div style="margin-top: 20px;"><small style="font-size: 0.7em">If you wish to ask any additional questions, kindly contact us at our live chat from your account's <a href="{{ route('dashboard') }}">dashboard</a>.</small></div>
@endsection
@@ -0,0 +1,12 @@
@extends('emails.layout.base')
@section('content')
@php
$schedule = $packingList->containers()->first()->transports()->first()->schedules()->where('status', \App\Classes\ValueObjects\Constants\ApprovalStatus::APPROVED)->first();
@endphp
<h4 style="font-size: 1em;">Hello, {{ $user->name }}</h4>
<p style="font-size: 0.9em">Attached is the invoice concerning order no. {{$packingList->owner->reference}}. If the attached file isn't loading, please <a href="{{ route('order.show', $packingList->owner->reference) }}">click here</a> to access your invoice.</p>
<p style="margin-top: 30px; font-size: 0.8em">We would like to also inform you that your packages have been loaded into the container and is estimated to depart on: <span style="color: green; font-weight: bold">{{$schedule->etd->format('d-m-Y')}}</span> and is estimated to arrive on <span style="color: green; font-weight: bold">{{$schedule->eta->format('d-m-Y')}}</span>.</p>
<p style="margin-top: 15px; font-size: 0.8em">We appreciate you choosing us here at CIEF Worldwide to fulfill your shipping needs. We look forward to doing business with you again in the future.</p>
<div style="margin-top: 20px;"><small style="font-size: 0.7em">If you wish to ask any additional questions, kindly contact us at our live chat from your account's <a href="{{ route('dashboard') }}">dashboard</a>.</small></div>
@endsection
@@ -0,0 +1,14 @@
@extends('emails.layout.base')
@section('content')
<h4 style="font-size: 1em;">Hello, {{ $user->name }}</h4>
<p style="font-size: 0.9em">We wanted to send you an update on the recent shipment for you order no. <a href="{{ route('order.show', $packingList->owner->reference) }}">{{ $packingList->owner->reference }}</a> you have placed with us. We've just learned that there has been a shipping delay from the shipping liner, and as a result your packages will arrive a few days later the estimated date we gave you when we shipped your order. The new estimated date for arrival will be {{ $packingList->containers()->first()->transports()->first()->schedules()->where('status', \App\Classes\ValueObjects\Constants\ApprovalStatus::APPROVED)->first()->eta->format('d-m-Y') }}.</p>
<p style="margin-top: 30px; font-size: 0.8em">We're very sorry that you are experiencing this delay. and we wanted to let you know as soon as we learned about it. We are working directly with the shipping liner to minimize the impact, but we don't want you to worry your order is still on its way!</p>
<p style="margin-top: 20px; font-size: 0.8em">Recently shipping liner facing very frequent delay, it's better to estimate longer ETA while purchase to avoid any inconvenience causes.</p>
@if($packingList->transactions()->whereHas('transactions', function ($query){
return $query->where('type', \App\Classes\ValueObjects\Constants\TransactionType::SHIPPING_INVOICE)->where('status', '=', 2);
})->get())
<p style="margin-top: 20px; font-size: 0.8em">Meanwhile, we would appreciate if you could make the payment as soon as possible so we can deliver your packages as soon as the shipment arrives. please <a href="{{ route('order.show', $packingList->owner->reference) }}">click here</a> to pay your invoice.</p>
@endif
<div style="margin-top: 20px;"><small style="font-size: 0.7em">If you wish to ask any additional questions, kindly contact us at our live chat from your account's <a href="{{ route('dashboard') }}">dashboard</a>.</small></div>
@endsection