Merge branch 'dillon/90-e-invoice-shipping-portal-b' into vapor/production

This commit is contained in:
Dillon Ngo
2025-07-03 13:53:09 +08:00
32 changed files with 1496 additions and 353 deletions
@@ -8,16 +8,12 @@ use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
use App\Classes\Modules\Documents\Services\CreatesDocument;
use App\Classes\Modules\Documents\Services\CreatesFiles;
use App\Classes\Modules\Jobs\DataTransferObjects\FixInvoiceV2CommandObject;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\Modules\Transactions\Processors\CreateShippingInvoiceTransactionDocProcessor;
use App\Classes\ValueObjects\Constants\DocumentType;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\CompanyConnection;
use App\Models\Order;
use Mccarlosen\LaravelMpdf\Facades\LaravelMpdf;
use Illuminate\Support\Facades\Log;
class FixInvoiceV2CommandJob implements ShouldQueue
@@ -52,29 +48,10 @@ class FixInvoiceV2CommandJob implements ShouldQueue
dump($invoice->id);
$invoice->documents()->delete();
// $invoice->documents()->delete();
$invoice->documents()->where('document_type', DocumentType::SHIPPING_EINVOICE)->delete();
$view = 'pages.pdfs.shipping_invoice';
$dateToCompare = Carbon::parse(env('SST_START_DATE', '2024-04-01 00:00:00'));
$shippingInvoiceTransactionCreatedDate = Carbon::parse($invoice->created_at);
if ($shippingInvoiceTransactionCreatedDate->isAfter($dateToCompare) && $invoice->tax > 0) {
$view = 'pages.pdfs.shipping_invoice_sst';
}
$transaction_invoice_pdf = LaravelMpdf::loadView($view, ['invoice_transaction' => $invoice]);
$document_object = new DocumentObject(
DocumentType::SHIPPING_INVOICE,
[chunk_split('data:application/pdf;base64,'.base64_encode($transaction_invoice_pdf->output()))],
'',
ApprovalStatus::COMPLETED,
'shipping_invoice'
);
/** @var Document $document */
$document = (App()->make(CreatesDocument::class))->execute($invoice, $document_object);
(App()->make(CreatesFiles::class))->execute($document, $document_object);
(App()->make(CreateShippingInvoiceTransactionDocProcessor::class))->execute($invoice);
}
}
@@ -4,18 +4,12 @@
namespace App\Classes\Modules\Transactions\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\DocumentType;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\Order;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Mccarlosen\LaravelMpdf\Facades\LaravelMpdf;
use App\Classes\Modules\Documents\Services\CreatesDocument;
use App\Classes\Modules\Documents\Services\CreatesFiles;
use App\Models\Document;
use Carbon\Carbon;
use App\Classes\Modules\Transactions\Processors\CreateShippingInvoiceTransactionDocProcessor;
class RegenerateShippingInvoiceTransactionLogic extends AbstractControllerLogic
{
@@ -29,19 +23,15 @@ class RegenerateShippingInvoiceTransactionLogic extends AbstractControllerLogic
];
}
/** @var CreatesDocument */
private $createsDocument;
/** @var CreatesFiles */
private $createsFiles;
/** @var CreateShippingInvoiceTransactionDocProcessor */
private $createShippingInvoiceTransactionDocProcessor;
/**
* @param CreatesDocument $createsDocument
* @param CreateShippingInvoiceTransactionDocProcessor $createShippingInvoiceTransactionDocProcessor
*/
public function __construct(CreatesDocument $createsDocument, CreatesFiles $createsFiles)
public function __construct(CreateShippingInvoiceTransactionDocProcessor $createShippingInvoiceTransactionDocProcessor)
{
$this->createsDocument = $createsDocument;
$this->createsFiles = $createsFiles;
$this->createShippingInvoiceTransactionDocProcessor = $createShippingInvoiceTransactionDocProcessor;
}
public function logic(Request $request) : JsonResponse
@@ -53,28 +43,10 @@ class RegenerateShippingInvoiceTransactionLogic extends AbstractControllerLogic
$invoices = $order->transactions()->where('transactions.type', TransactionType::SHIPPING_INVOICE)->get();
foreach ($invoices as $invoice){
$invoice->documents()->delete();
// $invoice->documents()->delete();
$invoice->documents()->where('document_type', DocumentType::SHIPPING_EINVOICE)->delete();
$view = 'pages.pdfs.shipping_invoice';
$dateToCompare = Carbon::parse(env('SST_START_DATE', '2024-04-01 00:00:00'));
$shippingInvoiceTransactionCreatedDate = Carbon::parse($invoice->created_at);
if ($shippingInvoiceTransactionCreatedDate->isAfter($dateToCompare) && $invoice->tax > 0) {
$view = 'pages.pdfs.shipping_invoice_sst';
}
$transaction_invoice_pdf = LaravelMpdf::loadView($view, ['invoice_transaction' => $invoice]);
$document_object = new DocumentObject(
DocumentType::SHIPPING_INVOICE,
[chunk_split('data:application/pdf;base64,'.base64_encode($transaction_invoice_pdf->output()))],
'',
ApprovalStatus::COMPLETED,
'shipping_invoice'
);
$document =$this->createsDocument->execute($invoice, $document_object);
$this->createsFiles->execute($document, $document_object);
$this->createShippingInvoiceTransactionDocProcessor->execute($invoice);
// dump($document);
}
@@ -82,5 +54,4 @@ class RegenerateShippingInvoiceTransactionLogic extends AbstractControllerLogic
return $this->response([]);
}
}
@@ -0,0 +1,53 @@
<?php
namespace App\Classes\Modules\Transactions\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Classes\Modules\Transactions\Services\FetchesTransaction;
use App\Classes\Modules\Transactions\Processors\CreateSalesOrderDocProcessor;
use App\Classes\ValueObjects\Constants\DocumentType;
class RegenerateSingleSalesOrderLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Regenerate Sales Order',
'message' => 'You have successfully regenerated sales order'
];
}
/** @var FetchesTransaction */
private $fetchesTransaction;
/** @var CreateSalesOrderDocProcessor */
private $createSalesOrderDocProcessor;
/**
* @param FetchesTransaction $fetchesTransaction
* @param CreateSalesOrderDocProcessor $createSalesOrderDocProcessor
*/
public function __construct(FetchesTransaction $fetchesTransaction, CreateSalesOrderDocProcessor $createSalesOrderDocProcessor)
{
$this->fetchesTransaction = $fetchesTransaction;
$this->createSalesOrderDocProcessor = $createSalesOrderDocProcessor;
}
public function logic(Request $request) : JsonResponse
{
$invoice = $this->fetchesTransaction->execute(['id' => $request->route('invoice_id')]);
$invoice->documents()->where('document_type', DocumentType::SALES_ORDER)->delete();
$this->createSalesOrderDocProcessor->execute($invoice);
return $this->response([]);
}
}
@@ -0,0 +1,53 @@
<?php
namespace App\Classes\Modules\Transactions\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Classes\Modules\Transactions\Services\FetchesTransaction;
use App\Classes\Modules\Transactions\Processors\CreateShippingEInvoiceDocProcessor;
use App\Classes\ValueObjects\Constants\DocumentType;
class RegenerateSingleShippingEInvoiceLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Regenerate Shipping E-Invoice',
'message' => 'You have successfully regenerated shipping e-invoice'
];
}
/** @var FetchesTransaction */
private $fetchesTransaction;
/** @var CreateShippingEInvoiceDocProcessor */
private $createShippingEInvoiceDocProcessor;
/**
* @param FetchesTransaction $fetchesTransaction
* @param CreateShippingEInvoiceDocProcessor $createShippingEInvoiceDocProcessor
*/
public function __construct(FetchesTransaction $fetchesTransaction, CreateShippingEInvoiceDocProcessor $createShippingEInvoiceDocProcessor)
{
$this->fetchesTransaction = $fetchesTransaction;
$this->createShippingEInvoiceDocProcessor = $createShippingEInvoiceDocProcessor;
}
public function logic(Request $request) : JsonResponse
{
$invoice = $this->fetchesTransaction->execute(['id' => $request->route('invoice_id')]);
$invoice->documents()->where('document_type', DocumentType::SHIPPING_EINVOICE)->delete();
$this->createShippingEInvoiceDocProcessor->execute($invoice);
return $this->response([]);
}
}
@@ -4,19 +4,11 @@
namespace App\Classes\Modules\Transactions\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\DocumentType;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\Order;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Mccarlosen\LaravelMpdf\Facades\LaravelMpdf;
use App\Classes\Modules\Documents\Services\CreatesDocument;
use App\Classes\Modules\Documents\Services\CreatesFiles;
use App\Classes\Modules\Transactions\Services\FetchesTransaction;
use App\Models\Document;
use Carbon\Carbon;
use App\Classes\Modules\Transactions\Processors\CreateShippingInvoiceTransactionDocProcessor;
class RegenerateSingleShippingInvoiceTransactionLogic extends AbstractControllerLogic
{
@@ -30,51 +22,30 @@ class RegenerateSingleShippingInvoiceTransactionLogic extends AbstractController
];
}
/** @var CreatesDocument */
private $createsDocument;
/** @var CreatesFiles */
private $createsFiles;
/** @var FetchesTransaction */
private $fetchesTransaction;
/** @var CreateShippingInvoiceTransactionDocProcessor */
private $createShippingInvoiceTransactionDocProcessor;
/**
* @param CreatesDocument $createsDocument
* @param FetchesTransaction $fetchesTransaction
* @param CreateShippingInvoiceTransactionDocProcessor $createShippingInvoiceTransactionDocProcessor
*/
public function __construct(CreatesDocument $createsDocument, CreatesFiles $createsFiles, FetchesTransaction $fetchesTransaction)
public function __construct(FetchesTransaction $fetchesTransaction, CreateShippingInvoiceTransactionDocProcessor $createShippingInvoiceTransactionDocProcessor)
{
$this->createsDocument = $createsDocument;
$this->createsFiles = $createsFiles;
$this->fetchesTransaction = $fetchesTransaction;
$this->createShippingInvoiceTransactionDocProcessor = $createShippingInvoiceTransactionDocProcessor;
}
public function logic(Request $request) : JsonResponse
{
$invoice = $this->fetchesTransaction->execute(['id' => $request->route('invoice_id')]);
$invoice->documents()->delete();
// $invoice->documents()->delete();
$invoice->documents()->where('document_type', DocumentType::SHIPPING_INVOICE)->delete();
$view = 'pages.pdfs.shipping_invoice';
$dateToCompare = Carbon::parse(env('SST_START_DATE', '2024-04-01 00:00:00'));
$shippingInvoiceTransactionCreatedDate = Carbon::parse($invoice->created_at);
if ($shippingInvoiceTransactionCreatedDate->isAfter($dateToCompare) && $invoice->tax > 0) {
$view = 'pages.pdfs.shipping_invoice_sst';
}
$transaction_invoice_pdf = LaravelMpdf::loadView($view, ['invoice_transaction' => $invoice]);
$document_object = new DocumentObject(
DocumentType::SHIPPING_INVOICE,
[chunk_split('data:application/pdf;base64,'.base64_encode($transaction_invoice_pdf->output()))],
'',
ApprovalStatus::COMPLETED,
'shipping_invoice'
);
$document =$this->createsDocument->execute($invoice, $document_object);
$this->createsFiles->execute($document, $document_object);
$this->createShippingInvoiceTransactionDocProcessor->execute($invoice);
// dump($document);
@@ -8,18 +8,15 @@ use App\Classes\Notifications\InvoiceIssuedEmail;
use App\Models\Document;
use App\Models\PackingList;
use App\Models\Transaction;
use Mccarlosen\LaravelMpdf\Facades\LaravelMpdf;
use App\Classes\ValueObjects\Constants\DocumentType;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Classes\Modules\Documents\Services\CreatesFiles;
use App\Classes\Modules\Documents\Services\CreatesDocument;
use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
use App\Classes\Jobs\CreatePerfexCRMInvoice;
use App\Classes\Modules\Transactions\Processors\CheckStorageInvoiceTransactionProcessor;
use App\Classes\Modules\Transactions\Processors\CreateShippingInvoiceTransactionDocProcessor;
use App\Classes\Modules\Transactions\Processors\CreateShippingEInvoiceDocProcessor;
use App\Classes\Modules\Transactions\Processors\CreateSalesOrderDocProcessor;
use App\Models\Order;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;
class ApproveShippingInvoiceTransactionProcessor
{
@@ -27,27 +24,32 @@ class ApproveShippingInvoiceTransactionProcessor
/** @var UpdatesTransactionStatus */
private $updatesTransactionStatus;
/** @var CreatesDocument */
private $createsDocument;
/** @var CreatesFiles */
private $createsFiles;
/** @var CheckStorageInvoiceTransactionProcessor */
private $storageInvoiceTransactionProcessor;
/** @var CreateShippingInvoiceTransactionDocProcessor */
private $createShippingInvoiceTransactionDocProcessor;
/** @var CreateSalesOrderDocProcessor */
private $createSalesOrderDocProcessor;
/** @var CreateShippingEInvoiceDocProcessor */
private $createShippingEInvoiceDocProcessor;
/**
* @param UpdatesTransactionStatus $updatesTransactionStatus
* @param CreatesDocument $createsDocument
* @param CreatesFiles $createsFiles
* @param CheckStorageInvoiceTransactionProcessor $storageInvoiceTransactionProcessor
* @param CreateShippingInvoiceTransactionDocProcessor $createShippingInvoiceTransactionDocProcessor
* @param CreateSalesOrderDocProcessor $createSalesOrderDocProcessor
* @param CreateShippingEInvoiceDocProcessor $createShippingEInvoiceDocProcessor
*/
public function __construct(UpdatesTransactionStatus $updatesTransactionStatus, CreatesDocument $createsDocument, CreatesFiles $createsFiles, CheckStorageInvoiceTransactionProcessor $storageInvoiceTransactionProcessor)
public function __construct(UpdatesTransactionStatus $updatesTransactionStatus, CheckStorageInvoiceTransactionProcessor $storageInvoiceTransactionProcessor, CreateShippingInvoiceTransactionDocProcessor $createShippingInvoiceTransactionDocProcessor, CreateSalesOrderDocProcessor $createSalesOrderDocProcessor, CreateShippingEInvoiceDocProcessor $createShippingEInvoiceDocProcessor)
{
$this->updatesTransactionStatus = $updatesTransactionStatus;
$this->createsDocument = $createsDocument;
$this->createsFiles = $createsFiles;
$this->storageInvoiceTransactionProcessor = $storageInvoiceTransactionProcessor;
$this->createShippingInvoiceTransactionDocProcessor = $createShippingInvoiceTransactionDocProcessor;
$this->createSalesOrderDocProcessor = $createSalesOrderDocProcessor;
$this->createShippingEInvoiceDocProcessor = $createShippingEInvoiceDocProcessor;
}
@@ -60,33 +62,25 @@ class ApproveShippingInvoiceTransactionProcessor
/** @var Transaction $invoice_transaction */
$invoice_transaction = $packingList->transactions()->where('transactions.type', TransactionType::SHIPPING_INVOICE)->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::PENDING_SUBMISSION])->first();
$view = 'pages.pdfs.shipping_invoice';
$dateToCompare = Carbon::parse(env('SST_START_DATE', '2024-04-01 00:00:00'));
$shippingInvoiceTransactionCreatedDate = Carbon::parse($invoice_transaction->created_at);
if ($shippingInvoiceTransactionCreatedDate->isAfter($dateToCompare) && $invoice_transaction->tax > 0) {
$view = 'pages.pdfs.shipping_invoice_sst';
}
$companyModule = $invoice_transaction->owner->owner->companyModule;
Log::info('company module einvoice: ' . json_encode($companyModule->company->e_invoice));
if($companyModule->company->e_invoice)
{
$this->createShippingEInvoiceDocProcessor->execute($invoice_transaction);
}
else{
$this->createShippingInvoiceTransactionDocProcessor->execute($invoice_transaction);
}
$this->createSalesOrderDocProcessor->execute($invoice_transaction);
$this->updatesTransactionStatus->execute($invoice_transaction, ApprovalStatus::APPROVED);
$transaction_invoice_pdf = LaravelMpdf::loadView($view, ['invoice_transaction' => $invoice_transaction]);
$document_object = new DocumentObject(
DocumentType::SHIPPING_INVOICE,
[chunk_split('data:application/pdf;base64,'.base64_encode($transaction_invoice_pdf->output()))],
'',
ApprovalStatus::COMPLETED,
'shipping_invoice'
);
/** @var Document $document */
$document = $this->createsDocument->execute($invoice_transaction, $document_object);
$this->createsFiles->execute($document, $document_object);
$user = $packingList->owner->companyModule->employees()->first();
if(app()->environment(['production'])) {
$user->notify(new InvoiceIssuedEmail($user, $packingList));
}
//cief todo: 90 - to determine if sending email is necessary
// if(app()->environment(['production'])) {
// $companyModule = $packingList->owner->companyModule;
// $user = $companyModule->employees()->first();
// $user->notify(new InvoiceIssuedEmail($user, $packingList));
// }
$order = $packingList->owner()->first();
if($order instanceof Order){
@@ -95,5 +89,4 @@ class ApproveShippingInvoiceTransactionProcessor
return;
}
}
@@ -0,0 +1,65 @@
<?php
namespace App\Classes\Modules\Transactions\Processors;
use App\Classes\Exceptions\MalformedRequestException;
use App\Models\Document;
use App\Models\Transaction;
use Mccarlosen\LaravelMpdf\Facades\LaravelMpdf;
use App\Classes\ValueObjects\Constants\DocumentType;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\Modules\Documents\Services\CreatesFiles;
use App\Classes\Modules\Documents\Services\CreatesDocument;
use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
class CreateSalesOrderDocProcessor
{
/** @var CreatesDocument */
private $createsDocument;
/** @var CreatesFiles */
private $createsFiles;
/**
* @param CreatesDocument $createsDocument
* @param CreatesFiles $createsFiles
*/
public function __construct(CreatesDocument $createsDocument, CreatesFiles $createsFiles)
{
$this->createsDocument = $createsDocument;
$this->createsFiles = $createsFiles;
}
/**
* @throws MalformedRequestException
*/
public function execute(Transaction $invoice_transaction)
{
$view = 'pages.pdfs.sales_order';
$companyModule = $invoice_transaction->owner->owner->companyModule;
$user = $companyModule->employees()->first();
$brn = $companyModule->company->documents->where('document_type', DocumentType::SSM_REGISTRATION)->first();
$documentDate = $invoice_transaction->created_at;
$documentIdentifierPrefix = 'S/O No: ';
$documentIdentifier = 'SO-'.$invoice_transaction->bill_no;
$transaction_invoice_pdf = LaravelMpdf::loadView($view, ['invoice_transaction' => $invoice_transaction, 'brn' => $brn, 'document_date' => $documentDate, 'document_identifier' => $documentIdentifier, 'document_identifier_prefix' => $documentIdentifierPrefix]);
$document_object = new DocumentObject(
DocumentType::SALES_ORDER,
[chunk_split('data:application/pdf;base64,'.base64_encode($transaction_invoice_pdf->output()))],
'',
ApprovalStatus::COMPLETED,
'sales_order'
);
/** @var Document $document */
$document =$this->createsDocument->execute($invoice_transaction, $document_object);
$this->createsFiles->execute($document, $document_object);
}
}
@@ -0,0 +1,66 @@
<?php
namespace App\Classes\Modules\Transactions\Processors;
use App\Classes\Exceptions\MalformedRequestException;
use App\Models\Document;
use App\Models\Transaction;
use Mccarlosen\LaravelMpdf\Facades\LaravelMpdf;
use App\Classes\ValueObjects\Constants\DocumentType;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\Modules\Documents\Services\CreatesFiles;
use App\Classes\Modules\Documents\Services\CreatesDocument;
use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
class CreateShippingEInvoiceDocProcessor
{
/** @var CreatesDocument */
private $createsDocument;
/** @var CreatesFiles */
private $createsFiles;
/**
* @param CreatesDocument $createsDocument
* @param CreatesFiles $createsFiles
*/
public function __construct(CreatesDocument $createsDocument, CreatesFiles $createsFiles)
{
$this->createsDocument = $createsDocument;
$this->createsFiles = $createsFiles;
}
/**
* @throws MalformedRequestException
*/
public function execute(Transaction $invoice_transaction)
{
$view = 'pages.pdfs.shipping_einvoice';
$companyModule = $invoice_transaction->owner->owner->companyModule;
$user = $companyModule->employees()->first();
$brn = $companyModule->company->documents->where('document_type', DocumentType::SSM_REGISTRATION)->first();
$lastDayOfMonth = $invoice_transaction->created_at->copy()->endOfMonth();
$documentDate = $lastDayOfMonth;
$documentIdentifierPrefix = 'EI#: ';
$documentIdentifier = 'NONE';
$transaction_invoice_pdf = LaravelMpdf::loadView($view, ['invoice_transaction' => $invoice_transaction, 'brn' => $brn, 'document_date' => $documentDate, 'document_identifier' => $documentIdentifier, 'document_identifier_prefix' => $documentIdentifierPrefix]);
$document_object = new DocumentObject(
DocumentType::SHIPPING_EINVOICE,
[chunk_split('data:application/pdf;base64,'.base64_encode($transaction_invoice_pdf->output()))],
'',
ApprovalStatus::COMPLETED,
'shipping_einvoice'
);
/** @var Document $document */
$document =$this->createsDocument->execute($invoice_transaction, $document_object);
$this->createsFiles->execute($document, $document_object);
}
}
@@ -0,0 +1,75 @@
<?php
namespace App\Classes\Modules\Transactions\Processors;
use App\Classes\Exceptions\MalformedRequestException;
use App\Models\Document;
use App\Models\Transaction;
use Mccarlosen\LaravelMpdf\Facades\LaravelMpdf;
use App\Classes\ValueObjects\Constants\DocumentType;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\Modules\Documents\Services\CreatesFiles;
use App\Classes\Modules\Documents\Services\CreatesDocument;
use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
use Carbon\Carbon;
class CreateShippingInvoiceTransactionDocProcessor
{
/** @var CreatesDocument */
private $createsDocument;
/** @var CreatesFiles */
private $createsFiles;
/**
* @param CreatesDocument $createsDocument
* @param CreatesFiles $createsFiles
*/
public function __construct(CreatesDocument $createsDocument, CreatesFiles $createsFiles)
{
$this->createsDocument = $createsDocument;
$this->createsFiles = $createsFiles;
}
/**
* @throws MalformedRequestException
*/
public function execute(Transaction $invoice_transaction)
{
$view = 'pages.pdfs.shipping_invoice';
$dateToCompare = Carbon::parse(env('SST_START_DATE', '2024-04-01 00:00:00'));
$shippingInvoiceTransactionCreatedDate = Carbon::parse($invoice_transaction->created_at);
if ($shippingInvoiceTransactionCreatedDate->isAfter($dateToCompare) && $invoice_transaction->tax > 0) {
$view = 'pages.pdfs.shipping_invoice_sst';
}
$eInvoiceStartDate = Carbon::parse(env('E_INVOICE_START_DATE', '2025-07-01 00:00:00'));
if ($shippingInvoiceTransactionCreatedDate->isAfter($eInvoiceStartDate)) {
$view = 'pages.pdfs.shipping_invoice_sst_v2';
}
$companyModule = $invoice_transaction->owner->owner->companyModule;
$user = $companyModule->employees()->first();
$brn = $companyModule->company->documents->where('document_type', DocumentType::SSM_REGISTRATION)->first();
$documentDate = $invoice_transaction->created_at;
$documentIdentifierPrefix = 'Invoice No: ';
$documentIdentifier = $invoice_transaction->bill_no;
$transaction_invoice_pdf = LaravelMpdf::loadView($view, ['invoice_transaction' => $invoice_transaction, 'brn' => $brn, 'document_date' => $documentDate, 'document_identifier' => $documentIdentifier, 'document_identifier_prefix' => $documentIdentifierPrefix]);
$document_object = new DocumentObject(
DocumentType::SHIPPING_INVOICE,
[chunk_split('data:application/pdf;base64,'.base64_encode($transaction_invoice_pdf->output()))],
'',
ApprovalStatus::COMPLETED,
'shipping_invoice'
);
/** @var Document $document */
$document =$this->createsDocument->execute($invoice_transaction, $document_object);
$this->createsFiles->execute($document, $document_object);
}
}
@@ -25,5 +25,6 @@ final class DocumentType {
public const SHIPPING_INVOICE = 'SHIPPING_INVOICE';
public const STORAGE_INVOICE = 'STORAGE_INVOICE';
public const SALES_ORDER = 'SALES_ORDER';
public const SHIPPING_EINVOICE = 'SHIPPING_EINVOICE';
}
+4 -22
View File
@@ -7,6 +7,7 @@ use App\Classes\Modules\Documents\Services\CreatesDocument;
use App\Classes\Modules\Documents\Services\CreatesFiles;
use App\Classes\Modules\PackingLists\Services\ListsPackingLists;
use App\Classes\Modules\Transactions\Processors\CreateInvoiceTransactionProcessor;
use App\Classes\Modules\Transactions\Processors\CreateShippingInvoiceTransactionDocProcessor;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\DocumentType;
use App\Classes\ValueObjects\Constants\TransactionType;
@@ -61,29 +62,10 @@ class FixInvoice extends Command
dump($invoice->id);
$invoice->documents()->delete();
// $invoice->documents()->delete();
$invoice->documents()->where('document_type', DocumentType::SHIPPING_EINVOICE)->delete();
$view = 'pages.pdfs.shipping_invoice';
$dateToCompare = Carbon::parse(env('SST_START_DATE', '2024-04-01 00:00:00'));
$shippingInvoiceTransactionCreatedDate = Carbon::parse($invoice->created_at);
if ($shippingInvoiceTransactionCreatedDate->isAfter($dateToCompare) && $invoice->tax > 0) {
$view = 'pages.pdfs.shipping_invoice_sst';
}
$transaction_invoice_pdf = LaravelMpdf::loadView($view, ['invoice_transaction' => $invoice]);
$document_object = new DocumentObject(
DocumentType::SHIPPING_INVOICE,
[chunk_split('data:application/pdf;base64,'.base64_encode($transaction_invoice_pdf->output()))],
'',
ApprovalStatus::COMPLETED,
'shipping_invoice'
);
/** @var Document $document */
$document = (App()->make(CreatesDocument::class))->execute($invoice, $document_object);
(App()->make(CreatesFiles::class))->execute($document, $document_object);
(App()->make(CreateShippingInvoiceTransactionDocProcessor::class))->execute($invoice);
}
}
}
@@ -45,7 +45,10 @@ class MonthlyReportController
});
$packages = $packingLists->map(function ($packingList) {
$replica = in_array(Auth()->user()->type, [RoleTypes::SHADOW_ADMIN, RoleTypes::SUPER_ADMIN]) ? $packingList : $packingList->packingLists()->where('type', PackingListType::SHIPPING_PACKING_LIST_REPLICA)->first();
$userType = Auth() && Auth()->user() ? Auth()->user()->type : RoleTypes::USER;
$exceptionUsers = in_array($userType, [RoleTypes::SHADOW_ADMIN, RoleTypes::SUPER_ADMIN]);
$replica = $exceptionUsers ? $packingList : $packingList->packingLists()->where('type', PackingListType::SHIPPING_PACKING_LIST_REPLICA)->first();
return $replica ? $replica : $packingList;
})->flatMap(function ($packingList) {
return $packingList->packages;
@@ -107,7 +110,9 @@ class MonthlyReportController
});
$packages = $packingLists->map(function ($packingList) {
$replica = in_array(Auth()->user()->type, [RoleTypes::SHADOW_ADMIN, RoleTypes::SUPER_ADMIN]) ? $packingList : $packingList->packingLists()->where('type', PackingListType::SHIPPING_PACKING_LIST_REPLICA)->first();
$userType = Auth() && Auth()->user() ? Auth()->user()->type : RoleTypes::USER;
$exceptionUsers = in_array($userType, [RoleTypes::SHADOW_ADMIN, RoleTypes::SUPER_ADMIN]);
$replica = $exceptionUsers ? $packingList : $packingList->packingLists()->where('type', PackingListType::SHIPPING_PACKING_LIST_REPLICA)->first();
return $replica ? $replica : $packingList;
})->flatMap(function ($packingList) {
return $packingList->packages;
@@ -6,7 +6,8 @@ namespace App\Http\Controllers\Transactions;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Classes\Modules\Transactions\ControllersLogic\RegenerateSingleShippingInvoiceTransactionLogic;
use App\Classes\Modules\Transactions\ControllersLogic\RegenerateSingleSalesOrderLogic;
use App\Classes\Modules\Transactions\ControllersLogic\RegenerateSingleShippingEInvoiceLogic;
class RegenerateSingleShippingInvoiceTransactionController
{
@@ -18,4 +19,22 @@ class RegenerateSingleShippingInvoiceTransactionController
public function regenerate(Request $request, RegenerateSingleShippingInvoiceTransactionLogic $logic) : JsonResponse {
return $logic->execute($request);
}
/**
* @param Request $request
* @param RegenerateSingleSalesOrderLogic $logic
* @return JsonResponse
*/
public function regenerateSalesOrder(Request $request, RegenerateSingleSalesOrderLogic $logic) : JsonResponse {
return $logic->execute($request);
}
/**
* @param Request $request
* @param RegenerateSingleShippingEInvoiceLogic $logic
* @return JsonResponse
*/
public function regenerateEInvoice(Request $request, RegenerateSingleShippingEInvoiceLogic $logic) : JsonResponse {
return $logic->execute($request);
}
}
+10 -3
View File
@@ -4,9 +4,7 @@ namespace App\Http\Resources;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\OrderRoleTypes;
use App\Classes\ValueObjects\Constants\PackingListType;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Classes\ValueObjects\Constants\TransportType;
use Carbon\Carbon;
use Illuminate\Http\Resources\Json\JsonResource;
@@ -20,6 +18,14 @@ class OrderV2Resource extends JsonResource
*/
public function toArray($request)
{
$eInvoice = false;
$eInvoiceStartDate = Carbon::parse(env('E_INVOICE_START_DATE', '2025-07-01 00:00:00'));
$orderCreatedDate = Carbon::parse($this->created_at);
$eInvoiceRequestedDate = Carbon::parse($this->companyModule->company->e_invoice_requested_at);
if ($orderCreatedDate->isAfter($eInvoiceStartDate) && $this->companyModule->company->e_invoice === 1) { //&& $bookingCreatedDate->diffInMinutes($eInvoiceRequestedDate) <= 480 cief todo: 90
$eInvoice = true;
}
return [
'id' => $this->id,
'reference' => $this->reference,
@@ -36,7 +42,8 @@ class OrderV2Resource extends JsonResource
'storages' => $this->storages ? $this->storages : null, //from middleware
'remarks' => RemarkResource::collection($this->remarks),
'supplier_tax_rebate' => SupplierTaxRebateResource::collection($this->supplierTaxRebate),
'created_at' => $this->created_at->format('d-m-Y')
'created_at' => $this->created_at->format('d-m-Y'),
'is_einvoice_applicable' => $eInvoice,
];
}
+3 -2
View File
@@ -3,7 +3,6 @@
namespace App\Http\Resources;
use App\Classes\ValueObjects\Constants\RoleTypes;
use App\Models\Order;
use App\Models\PackingList;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Support\Facades\Crypt;
@@ -18,7 +17,9 @@ class PackageBaseResource extends JsonResource
*/
public function toArray($request)
{
$exceptionUsers = in_array(Auth()->user()->type, [RoleTypes::SHADOW_ADMIN, RoleTypes::SUPER_ADMIN]);
// $exceptionUsers = in_array(Auth()->user()->type, [RoleTypes::SHADOW_ADMIN, RoleTypes::SUPER_ADMIN]);
$userType = Auth() && Auth()->user() ? Auth()->user()->type : RoleTypes::USER;
$exceptionUsers = in_array($userType, [RoleTypes::SHADOW_ADMIN, RoleTypes::SUPER_ADMIN]);
$data = [
'id' => $this->id,
@@ -20,7 +20,10 @@ class PackingListBaseResource extends JsonResource
*/
public function toArray($request)
{
$exceptionUsers = in_array(Auth()->user()->type, [RoleTypes::SHADOW_ADMIN, RoleTypes::SUPER_ADMIN]);
// $exceptionUsers = in_array(Auth()->user()->type, [RoleTypes::SHADOW_ADMIN, RoleTypes::SUPER_ADMIN]);
$userType = Auth() && Auth()->user() ? Auth()->user()->type : RoleTypes::USER;
$exceptionUsers = in_array($userType, [RoleTypes::SHADOW_ADMIN, RoleTypes::SUPER_ADMIN]);
$packages = [];
$receive_packing_list = null;
@@ -2,15 +2,9 @@
namespace App\Http\Resources;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\PackingListType;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Classes\ValueObjects\Constants\RoleTypes;
use App\Models\Order;
use App\Models\PackingList;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\Log;
class PackingListForPackagesReceivedResource extends JsonResource
{
@@ -22,7 +16,9 @@ class PackingListForPackagesReceivedResource extends JsonResource
*/
public function toArray($request)
{
$exceptionUsers = in_array(Auth()->user()->type, [RoleTypes::SHADOW_ADMIN, RoleTypes::SUPER_ADMIN]);
// $exceptionUsers = in_array(Auth()->user()->type, [RoleTypes::SHADOW_ADMIN, RoleTypes::SUPER_ADMIN]);
$userType = Auth() && Auth()->user() ? Auth()->user()->type : RoleTypes::USER;
$exceptionUsers = in_array($userType, [RoleTypes::SHADOW_ADMIN, RoleTypes::SUPER_ADMIN]);
$data = [
'id' => $this->id,
+7 -6
View File
@@ -590,17 +590,17 @@ class DummyDataSeeder extends Seeder
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //
// Generate and Approve Dummmy Invoice //
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //
ini_set('memory_limit', '-1');
ini_set('memory_limit', '-1');
$randomCompanyModule = CompanyModule::latest('id')->take(5)->get();
$centerPostcodeConstantObject = SegmentConstant::where('reference', SegmentConstants::CENTER_POSTCODE)->get();
$centerPostcodeConstant = $centerPostcodeConstantObject->isEmpty() ? [] : (array)$centerPostcodeConstantObject->first()->value;
foreach($randomCompanyModule as $companyModule) {
foreach($companyModule->addresses as $address) {
$postcode = $address->postcode;
$postcodeArea = in_array($postcode, $centerPostcodeConstant) ? 'CENTER_POSTCODE' : null;
if (!$postcodeArea) {
$random = rand(0, 1);
$postcodeArray = ['OUTSTATION_POSTCODE', 'CENTER_POSTCODE'];
@@ -609,10 +609,11 @@ class DummyDataSeeder extends Seeder
}
}
}
Artisan::call('invoice:generate');
Artisan::call('approve:invoice');
// Artisan::call('invoice:generate');
// Artisan::call('approve:invoice');
Artisan::call('invoice-generate-command');
Artisan::call('approve-invoice-command');
}
}
+8
View File
@@ -57,5 +57,13 @@ class SegmentsTableSeeder extends Seeder
'created_at'=>'2022-09-21 03:51:34',
'updated_at'=>'2022-09-21 03:51:34'
] );
Segment::create( [
'company_module_id'=>1,
'name'=>'No Extra Centimeter Charged',
'deleted_at'=>NULL,
'created_at'=>'2025-02-13 10:31:35',
'updated_at'=>'2025-02-13 10:31:35'
] );
}
}
@@ -159,10 +159,10 @@
</div>
<div class="row bg-master-lightest p-t-15" v-for="invoice in order.invoices" v-if="invoice.type === 1">
<div class="col" v-if="getMergedInvoices(invoice).length > 1">
<customer-payments-billing-with-storage-component :data="getMergedInvoices(invoice)" :storage="getStorageInfo(invoice)" invoice_status="Pending Payment" :section="section"></customer-payments-billing-with-storage-component>
<customer-payments-billing-with-storage-component :data="getMergedInvoices(invoice)" :storage="getStorageInfo(invoice)" invoice_status="Pending Payment" :is-einvoice-applicable="order.is_einvoice_applicable" :section="section"></customer-payments-billing-with-storage-component>
</div>
<div class="col" v-else>
<customer-payments-billing-component :data="invoice" invoice_status="Pending Payment" :section="section"></customer-payments-billing-component>
<customer-payments-billing-component :data="invoice" invoice_status="Pending Payment" :is-einvoice-applicable="order.is_einvoice_applicable" :section="section"></customer-payments-billing-component>
</div>
</div>
</div>
@@ -236,6 +236,10 @@
this.$store.dispatch('completeList', {'name': this.section, 'data': []});
this.isLoading = false;
this.order = response.payload.data;
if(this.order.company_module.e_invoice === null && !this.$store.getters.isAdmin){
window.location.href = this.route('dashboard');
}
},
errorHandler(error, status){
if(status == 404){
@@ -1,25 +1,34 @@
<template>
<div class="row m-b-15 m-l-5 m-r-10 parentContainer">
<div class="col bg-white rounded">
<div class="row justify-content-end" v-if="item.type === 1 && $store.getters.isSuperAdmin">
<!-- <div class="btn btn-sm btn block all-caps b-rad-none btn-danger pointer requestModal m-l-20" data-type="deleteInvoice">Delete</div> -->
<span class="d-inline-block m-r-15 text-primary bold text-underline pointer requestModal" data-type="deleteInvoice">
<i class="fa fa-close fa-2x"></i>
</span>
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="deleteInvoice">
<delete-invoice-form-component :data="item" :section="section"></delete-invoice-form-component>
</modal-component>
</div>
<div class="row" :class="[{'b-danger': item.status == 5 ||item.status == 6, 'b-a': item.status == 5||item.status == 6}]">
<div class="col padding-20">
<div class="row align-items-center">
<div class="col-2">
<div class="col">
<div class="row padding-20 align-items-center">
<div class="col-auto">
<p class="no-margin fs-10 all-caps">Invoice Date</p>
<div> {{ item.created_at }}</div>
</div>
<div class="col">
<div class="col-auto">
<p class="no-margin fs-10 all-caps">Status</p>
<div class="all-caps" v-if="item.status == 3">Payment Completed</div>
<div class="all-caps text-danger" v-else-if="item.status == 5">Dispute in progress</div>
<div class="all-caps" v-else-if="item.status == 6">Cancelled Invoice</div>
<div class="all-caps" v-else>Pending Payment</div>
</div>
<div class="col-2">
<div class="col-auto">
<p class="no-margin fs-10 all-caps">Amount</p>
<div>MYR {{ item.amount.toFixed(2) }}</div>
</div>
<div class="col-3" v-if="item.remarks.length">
<div class="col" v-if="item.remarks.length">
<p class="no-margin fs-10 all-caps">Billing Question</p>
<div>
{{ latestComment.content }}
@@ -31,7 +40,7 @@
<remark-component :section="section" :data="item" module_type="Transaction"></remark-component>
</modal-component>
</div>
<div class="col-3" v-else>
<div class="col" v-else>
<p class="no-margin fs-10 all-caps invisible">Billing Question</p>
<div>
<span class="btn requestModal no-border invisible">
@@ -39,22 +48,32 @@
</span>
</div>
</div>
<div class="col-auto p-l-0 p-r-0 d-flex justify-content-center align-items-center">
<div class="col-auto">
<div :class="[{'invisible': [5, 6, 3].includes(item.status)}]">
<span class="d-inline-block m-r-15 text-primary bold text-underline pointer requestModal" data-type="billingRemark">Billing Question?</span>
</div>
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="billingRemark">
<customer-invoice-remark-form-component module_type="Transaction" :data="item" :section="section"></customer-invoice-remark-form-component>
</modal-component>
<div v-if="item.documents.length">
<div v-for="file in item.documents[0].files" v-bind:key="file.id" class="col-auto no-padding">
<document-file-viewer-component :file="file">
<template slot="button">
<div class="btn bg-grey no-border muted">
<i class="fa fa-file-pdf-o"></i>
</div>
</template>
</document-file-viewer-component>
</div>
<!-- PDF - INV -->
<div class="col-auto" v-if="!isEinvoiceApplicable">
<div v-if="item.documents.length && item.documents.some(d => d.document_type === 'SHIPPING_INVOICE')">
<div v-for="doc in item.documents.filter(d => d.document_type === 'SHIPPING_INVOICE')" :key="doc.id">
<div v-for="file in doc.files" v-bind:key="file.id" class="col-auto no-padding">
<document-file-viewer-component :file="file">
<template slot="button">
<div class="bg-grey no-border muted">
<svg width="40" height="48" viewBox="0 0 40 48" xmlns="http://www.w3.org/2000/svg">
<path d="M4 0h24l8 8v40a4 4 0 0 1 -4 4H4a4 4 0 0 1 -4 -4V4a4 4 0 0 1 4 -4z" fill="#27ae60"/>
<path d="M28 0v8h8z" fill="#1e8449"/>
<text x="50%" y="60%" text-anchor="middle" fill="white" font-size="13" font-family="Arial, sans-serif" font-weight="bold" dy=".3em">INV</text>
</svg>
</div>
</template>
</document-file-viewer-component>
</div>
</div>
</div>
<div v-else>
@@ -63,13 +82,97 @@
</div>
</div>
</div>
<div class="col-auto p-l-0 p-r-0 d-flex justify-content-center align-items-center" v-if="$store.getters.isSuperAdmin">
<span class="d-inline-block m-r-15 text-primary bold text-underline pointer requestModal" data-type="regenerateInvoice">
<i class="fa fa-repeat"></i>
</span>
<!-- PDF - EINV -->
<div class="col-auto" v-if="isEinvoiceApplicable">
<div v-if="item.documents.length && item.documents.some(d => d.document_type === 'SHIPPING_EINVOICE')">
<div v-for="doc in item.documents.filter(d => d.document_type === 'SHIPPING_EINVOICE')" :key="doc.id">
<div v-for="file in doc.files" v-bind:key="file.id" class="col-auto no-padding">
<document-file-viewer-component :file="file">
<template slot="button">
<div class="bg-grey no-border muted">
<svg width="48" height="48" viewBox="0 0 40 48" xmlns="http://www.w3.org/2000/svg">
<path d="M4 0h24l8 8v40a4 4 0 0 1 -4 4H4a4 4 0 0 1 -4 -4V4a4 4 0 0 1 4 -4z" fill="#27ae60"/>
<path d="M28 0v8h8z" fill="#1e8449"/>
<text x="50%" y="60%" text-anchor="middle" fill="white" font-size="12" font-family="Arial, sans-serif" font-weight="bold" dy=".3em">EINV</text>
</svg>
</div>
</template>
</document-file-viewer-component>
</div>
</div>
</div>
<div v-else>
<!-- <div class="btn bg-grey no-border muted invisible">
<i class="fa fa-file-pdf-o"></i>
</div> -->
<div class="bg-grey no-border muted">
<svg width="48" height="48" viewBox="0 0 40 48" xmlns="http://www.w3.org/2000/svg">
<path d="M4 0h24l8 8v40a4 4 0 0 1 -4 4H4a4 4 0 0 1 -4 -4V4a4 4 0 0 1 4 -4z" fill="#bdc3c7"/>
<path d="M28 0v8h8z" fill="#95a5a6"/>
<text x="50%" y="60%" text-anchor="middle" fill="white" font-size="12" font-family="Arial, sans-serif" font-weight="bold" dy=".3em">EINV</text>
</svg>
</div>
</div>
</div>
<!-- PDF - SO -->
<div class="col-auto">
<div v-if="item.documents.length && item.documents.some(d => d.document_type === 'SALES_ORDER')">
<div v-for="doc in item.documents.filter(d => d.document_type === 'SALES_ORDER')" :key="doc.id">
<div v-for="file in doc.files" v-bind:key="file.id" class="col-auto no-padding">
<document-file-viewer-component :file="file">
<template slot="button">
<div class="bg-grey no-border muted">
<svg width="40" height="48" viewBox="0 0 40 48" xmlns="http://www.w3.org/2000/svg">
<path d="M4 0h24l8 8v40a4 4 0 0 1 -4 4H4a4 4 0 0 1 -4 -4V4a4 4 0 0 1 4 -4z" fill="#27ae60"/>
<path d="M28 0v8h8z" fill="#1e8449"/>
<text x="50%" y="60%" text-anchor="middle" fill="white" font-size="14" font-family="Arial, sans-serif" font-weight="bold" dy=".3em">SO</text>
</svg>
</div>
</template>
</document-file-viewer-component>
</div>
</div>
</div>
<div v-else>
<!-- <div class="btn bg-grey no-border muted invisible">
<i class="fa fa-file-pdf-o"></i>
</div> -->
<div class="bg-grey no-border muted">
<svg width="40" height="48" viewBox="0 0 40 48" xmlns="http://www.w3.org/2000/svg">
<path d="M4 0h24l8 8v40a4 4 0 0 1 -4 4H4a4 4 0 0 1 -4 -4V4a4 4 0 0 1 4 -4z" fill="#bdc3c7"/>
<path d="M28 0v8h8z" fill="#95a5a6"/>
<text x="50%" y="60%" text-anchor="middle" fill="white" font-size="14" font-family="Arial, sans-serif" font-weight="bold" dy=".3em">SO</text>
</svg>
</div>
</div>
</div>
<!-- cief todo: 90 - why hide??? -->
<!-- <div class="col-auto hide">
<div class="btn btn-sm all-caps b-rad-none btn-block" :class="{'btn-success': !expanded, 'btn-default': expanded}" @click="expanded = !expanded">
{{ expanded ? 'Cancel' : 'Make Payment' }}</div>
</div> -->
</div>
</div>
</div>
<div class="row" v-if="$store.getters.isAdmin">
<div class="col">
<div class="row padding-20">
<div class="col">
<p class="no-margin fs-10 all-caps">Packinglist Reference</p>
<div>
<a :href="route('order.tracking', item.packing_list_reference)" target="_blank">
{{ item.packing_list_reference }}
</a>
</div>
</div>
<div class="col-auto d-flex justify-content-center align-items-center" v-if="$store.getters.isSuperAdmin">
<div class="btn btn-sm btn block all-caps b-rad-none btn-danger pointer requestModal m-l-20" data-type="regenerateInvoice" v-if="!isEinvoiceApplicable">Regenerate Invoice PDF</div>
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="regenerateInvoice">
<general-confirmation-form-component
contentText="Are you sure you want to regenerate this Invoice?"
contentText="Are you sure you want to regenerate this Invoice PDF document?"
modalType="delete"
buttonText="Regenerate"
class="text-center"
@@ -79,30 +182,35 @@
>
</general-confirmation-form-component>
</modal-component>
<span class="d-inline-block m-r-15 text-primary bold text-underline pointer requestModal" data-type="deleteInvoice">
<i class="fa fa-close"></i>
</span>
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="deleteInvoice">
<delete-invoice-form-component :data="item" :section="section"></delete-invoice-form-component>
<div class="btn btn-sm btn block all-caps b-rad-none btn-danger pointer requestModal m-l-20" data-type="regenerateEInvoice" v-if="isEinvoiceApplicable">Regenerate E-Invoice PDF</div>
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="regenerateEInvoice">
<general-confirmation-form-component
contentText="Are you sure you want to regenerate this E-Invoice PDF document?"
modalType="delete"
buttonText="Regenerate"
class="text-center"
:apiRoute="route('api.transaction.einvoice.regenerate', item.id)"
apiMethod="post"
:section="section"
>
</general-confirmation-form-component>
</modal-component>
</div>
<div class="col-auto hide">
<div class="btn btn-sm all-caps b-rad-none btn-block" :class="{'btn-success': !expanded, 'btn-default': expanded}" @click="expanded = !expanded">
{{ expanded ? 'Cancel' : 'Make Payment' }}</div>
</div>
</div>
</div>
</div>
<div class="row" v-if="$store.getters.isAdmin">
<div class="col padding-20">
<div class="row">
<div class="col">
<p class="no-margin fs-10 all-caps">Packinglist Reference</p>
<div>
<a :href="route('order.tracking', item.packing_list_reference)" target="_blank">
{{ item.packing_list_reference }}
</a>
</div>
<div class="btn btn-sm btn block all-caps b-rad-none btn-danger pointer requestModal m-l-20" data-type="regenerateSalesOrder">Regenerate Sales Order PDF</div>
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="regenerateSalesOrder">
<general-confirmation-form-component
contentText="Are you sure you want to regenerate this Sales Order PDF document?"
modalType="delete"
buttonText="Regenerate"
class="text-center"
:apiRoute="route('api.transaction.sales.order.regenerate', item.id)"
apiMethod="post"
:section="section"
>
</general-confirmation-form-component>
</modal-component>
</div>
</div>
</div>
@@ -242,6 +350,10 @@
section:{
type: String,
required: true
},
isEinvoiceApplicable:{
type: Boolean,
default: false
}
},
data(){
@@ -2,24 +2,33 @@
<div class="row m-b-15 m-l-5 m-r-10 parentContainer">
<div class="col bg-white rounded">
<div v-for="item in items" class="row" :class="[{'b-danger': item.status == 5 ||item.status == 6, 'b-a': item.status == 5||item.status == 6}]">
<div class="col padding-20">
<div class="row align-items-center">
<div class="col-2">
<div class="col">
<div class="row justify-content-end" v-if="item.type === 1 && $store.getters.isSuperAdmin">
<!-- <div class="btn btn-sm btn block all-caps b-rad-none btn-danger pointer requestModal m-l-20" :data-type="'deleteInvoice-' + item.id" v-if="item.type === 1">Delete</div> -->
<span class="d-inline-block m-r-15 text-primary bold text-underline pointer requestModal" :data-type="'deleteInvoice-' + item.id">
<i class="fa fa-close fa-2x"></i>
</span>
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" :type="'deleteInvoice-' + item.id">
<delete-invoice-form-component :data="item" :section="section"></delete-invoice-form-component>
</modal-component>
</div>
<div class="row padding-20 align-items-center">
<div class="col-auto">
<p class="no-margin fs-10 all-caps">Invoice Date</p>
<div> {{ item.created_at }}</div>
</div>
<div class="col">
<div class="col-auto">
<p class="no-margin fs-10 all-caps">Status</p>
<div class="all-caps" v-if="item.status == 3">Payment Completed</div>
<div class="all-caps text-danger" v-else-if="item.status == 5">Dispute in progress</div>
<div class="all-caps" v-else-if="item.status == 6">Cancelled Invoice</div>
<div class="all-caps" v-else>Pending Payment</div>
</div>
<div class="col-2">
<div class="col-auto">
<p class="no-margin fs-10 all-caps">Amount</p>
<div>MYR {{ item.amount.toFixed(2) }}</div>
</div>
<div class="col-2">
<div class="col">
<div v-if="item.remarks.length">
<p class="no-margin fs-10 all-caps">Billing Question</p>
<div>
@@ -41,7 +50,15 @@
</div>
</div>
</div>
<div class="col-2 p-l-0 p-r-0 d-flex justify-content-center align-items-center" v-if="$store.getters.isAdmin">
<div class="col-auto">
<div v-if="item.type === 1" :class="[{'invisible': [5, 6, 3].includes(item.status)}]">
<span class="d-inline-block m-r-15 text-primary bold text-underline pointer requestModal" data-type="billingRemark">Billing Question?</span>
</div>
<modal-component v-if="item.type === 1" class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="billingRemark">
<customer-invoice-remark-form-component module_type="Transaction" :data="item" :section="section"></customer-invoice-remark-form-component>
</modal-component>
</div>
<div class="col-auto" v-if="$store.getters.isAdmin">
<span class="d-inline-block m-r-15 text-primary bold text-underline pointer requestModal" v-if="item.type === 16 && item.is_waived === 0 && item.status === 2" :data-type="'waiveInvoice-' + item.id">
Waive Transaction
</span>
@@ -49,94 +66,186 @@
Transaction Waived
</span>
<span class="d-inline-block m-r-15 text-primary bold" v-else>
N/A
Waive N/A
</span>
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" v-if="item.type === 16 && item.is_waived === 0 && item.status === 2" :type="'waiveInvoice-' + item.id">
<waive-invoice-form-component :data="item" :section="section"></waive-invoice-form-component>
</modal-component>
</div>
<div class="col-auto p-l-0 p-r-0 d-flex justify-content-center align-items-center">
<div v-if="item.type === 1" :class="[{'invisible': [5, 6, 3].includes(item.status)}]">
<span class="d-inline-block m-r-15 text-primary bold text-underline pointer requestModal" data-type="billingRemark">Billing Question?</span>
</div>
<div v-else class="invisible">
<span class="d-inline-block m-r-15 text-primary bold text-underline pointer requestModal" data-type="billingRemark">Billing Question?</span>
</div>
<modal-component v-if="item.type === 1" class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="billingRemark">
<customer-invoice-remark-form-component module_type="Transaction" :data="item" :section="section"></customer-invoice-remark-form-component>
</modal-component>
<div v-if="item.documents.length">
<div v-for="file in item.documents[0].files" v-bind:key="file.id" class="col-auto no-padding">
<document-file-viewer-component :file="file">
<template slot="button">
<div class="btn bg-grey no-border muted">
<i class="fa fa-file-pdf-o"></i>
</div>
</template>
</document-file-viewer-component>
<!-- PDF - INV: SHIP + STOR -->
<div class="col-auto" v-if="!isEinvoiceApplicable">
<div v-if="item.documents.length && item.documents.some(d => d.document_type === 'SHIPPING_INVOICE' || d.document_type === 'STORAGE_INVOICE')">
<div v-for="doc in item.documents.filter(d => d.document_type === 'SHIPPING_INVOICE' || d.document_type === 'STORAGE_INVOICE')" :key="doc.id">
<div v-for="file in doc.files" v-bind:key="file.id" class="col-auto no-padding">
<document-file-viewer-component :file="file">
<template slot="button">
<div class="bg-grey no-border muted">
<!-- <i class="fa fa-file-pdf-o"></i> -->
<svg width="40" height="48" viewBox="0 0 40 48" xmlns="http://www.w3.org/2000/svg">
<path d="M4 0h24l8 8v40a4 4 0 0 1 -4 4H4a4 4 0 0 1 -4 -4V4a4 4 0 0 1 4 -4z" fill="#27ae60"/>
<path d="M28 0v8h8z" fill="#1e8449"/>
<text x="50%" y="60%" text-anchor="middle" fill="white" font-size="13" font-family="Arial, sans-serif" font-weight="bold" dy=".3em">INV</text>
</svg>
</div>
</template>
</document-file-viewer-component>
</div>
</div>
</div>
<div v-else>
<div class="btn bg-grey no-border muted invisible">
<i class="fa fa-file-pdf-o"></i>
<div class="bg-grey no-border muted invisible">
<!-- <i class="fa fa-file-pdf-o"></i> -->
<svg width="40" height="48" viewBox="0 0 40 48" xmlns="http://www.w3.org/2000/svg">
<path d="M4 0h24l8 8v40a4 4 0 0 1 -4 4H4a4 4 0 0 1 -4 -4V4a4 4 0 0 1 4 -4z" fill="#bdc3c7"/>
<path d="M28 0v8h8z" fill="#95a5a6"/>
<text x="50%" y="60%" text-anchor="middle" fill="white" font-size="13" font-family="Arial, sans-serif" font-weight="bold" dy=".3em">INV</text>
</svg>
</div>
</div>
</div>
<div class="col-auto p-l-0 p-r-0 d-flex justify-content-center align-items-center" v-if="$store.getters.isSuperAdmin">
<span class="d-inline-block m-r-15 text-primary bold text-underline pointer requestModal" style="min-width:15px;" :data-type="'regenerateStorageInvoice-' + item.id" v-if="item.type === 16 && item.status === 3">
<i class="fa fa-repeat"></i>
</span>
<span class="d-inline-block m-r-15 text-primary bold text-underline pointer requestModal" style="min-width:15px;" v-if="item.type === 16 && item.status !== 3">
<i class="fa fa-ban"></i>
</span>
<span class="d-inline-block m-r-15 text-primary bold text-underline pointer requestModal" style="min-width:15px;" :data-type="'regenerateShippingInvoice-' + item.id" v-if="item.type === 1">
<i class="fa fa-repeat"></i>
</span>
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" :type="'regenerateStorageInvoice-' + item.id" v-if="item.type === 16">
<general-confirmation-form-component
contentText="Are you sure you want to regenerate this storage Invoice?"
modalType="delete"
buttonText="Regenerate"
class="text-center"
:apiRoute="route('api.transaction.storage.invoice.regenerate', item.id)"
apiMethod="post"
:section="section"
>
</general-confirmation-form-component>
</modal-component>
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" :type="'regenerateShippingInvoice-' + item.id" v-else>
<general-confirmation-form-component
contentText="Are you sure you want to regenerate this Invoice?"
modalType="delete"
buttonText="Regenerate"
class="text-center"
:apiRoute="route('api.transaction.invoice.regenerate', item.id)"
apiMethod="post"
:section="section"
>
</general-confirmation-form-component>
</modal-component>
<span class="d-inline-block m-r-15 text-primary bold text-underline pointer requestModal" :data-type="'deleteInvoice-' + item.id">
<i class="fa fa-close"></i>
</span>
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" :type="'deleteInvoice-' + item.id">
<delete-invoice-form-component :data="item" :section="section"></delete-invoice-form-component>
</modal-component>
<!-- PDF - EINV -->
<div class="col-auto" v-if="isEinvoiceApplicable">
<div v-if="item.documents.length && item.documents.some(d => d.document_type === 'SHIPPING_EINVOICE')">
<div v-for="doc in item.documents.filter(d => d.document_type === 'SHIPPING_EINVOICE')" :key="doc.id">
<div v-for="file in doc.files" v-bind:key="file.id" class="col-auto no-padding">
<document-file-viewer-component :file="file">
<template slot="button">
<div class="bg-grey no-border muted">
<svg width="48" height="48" viewBox="0 0 40 48" xmlns="http://www.w3.org/2000/svg">
<path d="M4 0h24l8 8v40a4 4 0 0 1 -4 4H4a4 4 0 0 1 -4 -4V4a4 4 0 0 1 4 -4z" fill="#27ae60"/>
<path d="M28 0v8h8z" fill="#1e8449"/>
<text x="50%" y="60%" text-anchor="middle" fill="white" font-size="12" font-family="Arial, sans-serif" font-weight="bold" dy=".3em">EINV</text>
</svg>
</div>
</template>
</document-file-viewer-component>
</div>
</div>
</div>
<div v-else>
<div class="bg-grey no-border muted">
<svg width="48" height="48" viewBox="0 0 40 48" xmlns="http://www.w3.org/2000/svg">
<path d="M4 0h24l8 8v40a4 4 0 0 1 -4 4H4a4 4 0 0 1 -4 -4V4a4 4 0 0 1 4 -4z" fill="#bdc3c7"/>
<path d="M28 0v8h8z" fill="#95a5a6"/>
<text x="50%" y="60%" text-anchor="middle" fill="white" font-size="12" font-family="Arial, sans-serif" font-weight="bold" dy=".3em">EINV</text>
</svg>
</div>
</div>
</div>
<div class="col-1 hide">
<!-- PDF - SO -->
<div class="col-auto">
<div v-if="item.documents.length && item.documents.some(d => d.document_type === 'SALES_ORDER')">
<div v-for="doc in item.documents.filter(d => d.document_type === 'SALES_ORDER')" :key="doc.id">
<div v-for="file in doc.files" v-bind:key="file.id" class="col-auto no-padding">
<document-file-viewer-component :file="file">
<template slot="button">
<div class="bg-grey no-border muted">
<svg width="40" height="48" viewBox="0 0 40 48" xmlns="http://www.w3.org/2000/svg">
<path d="M4 0h24l8 8v40a4 4 0 0 1 -4 4H4a4 4 0 0 1 -4 -4V4a4 4 0 0 1 4 -4z" fill="#27ae60"/>
<path d="M28 0v8h8z" fill="#1e8449"/>
<text x="50%" y="60%" text-anchor="middle" fill="white" font-size="14" font-family="Arial, sans-serif" font-weight="bold" dy=".3em">SO</text>
</svg>
</div>
</template>
</document-file-viewer-component>
</div>
</div>
</div>
<div v-else>
<div class="bg-grey no-border muted">
<svg width="40" height="48" viewBox="0 0 40 48" xmlns="http://www.w3.org/2000/svg">
<path d="M4 0h24l8 8v40a4 4 0 0 1 -4 4H4a4 4 0 0 1 -4 -4V4a4 4 0 0 1 4 -4z" fill="#bdc3c7"/>
<path d="M28 0v8h8z" fill="#95a5a6"/>
<text x="50%" y="60%" text-anchor="middle" fill="white" font-size="14" font-family="Arial, sans-serif" font-weight="bold" dy=".3em">SO</text>
</svg>
</div>
</div>
</div>
<!-- cief todo: 90 - why hide??? -->
<!-- <div class="col-1 hide">
<div class="btn btn-sm all-caps b-rad-none btn-block" :class="{'btn-success': !expanded, 'btn-default': expanded}" @click="expanded = !expanded">
{{ expanded ? 'Cancel' : 'Make Payment' }}</div>
</div>
</div> -->
</div>
<div class="row">
<div class="row p-t-0 p-b-0 p-l-20 p-r-20">
<div class="col" v-if="storage" v-show="item.type === 16">
<p >Warehouse Storage Fee: {{ storage.numberOfDaysExceeded }} Days x RM {{ storage.pricePerCBM}} x {{ storage.cbm.toFixed(3) }} cbm</p>
</div>
</div>
<div class="row" v-if="$store.getters.isAdmin">
<div class="col">
<div class="row padding-20">
<div class="col"></div>
<div class="col-auto d-flex justify-content-center align-items-center" v-if="$store.getters.isSuperAdmin">
<div class="btn btn-sm btn block all-caps b-rad-none btn-danger pointer requestModal m-l-20" :data-type="'regenerateStorageInvoice-' + item.id" v-if="item.type === 16 && item.status === 3">Regenerate Storage Invoice PDF</div>
<div class="btn btn-sm btn block all-caps b-rad-none btn-danger pointer requestModal m-l-20" :data-type="'regenerateShippingInvoice-' + item.id" v-if="item.type === 1 && !isEinvoiceApplicable">Regenerate Shipping Invoice PDF</div>
<!-- <span class="d-inline-block m-r-15 text-primary bold text-underline pointer requestModal" style="min-width:15px;" v-if="item.type === 16 && item.status !== 3">
<i class="fa fa-ban"></i>
</span> -->
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" :type="'regenerateStorageInvoice-' + item.id" v-if="item.type === 16">
<general-confirmation-form-component
contentText="Are you sure you want to regenerate this Storage Invoice PDF document?"
modalType="delete"
buttonText="Regenerate"
class="text-center"
:apiRoute="route('api.transaction.storage.invoice.regenerate', item.id)"
apiMethod="post"
:section="section"
>
</general-confirmation-form-component>
</modal-component>
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" :type="'regenerateShippingInvoice-' + item.id" v-else>
<general-confirmation-form-component
contentText="Are you sure you want to regenerate this Invoice PDF document?"
modalType="delete"
buttonText="Regenerate"
class="text-center"
:apiRoute="route('api.transaction.invoice.regenerate', item.id)"
apiMethod="post"
:section="section"
>
</general-confirmation-form-component>
</modal-component>
<div class="btn btn-sm btn block all-caps b-rad-none btn-danger pointer requestModal m-l-20" :data-type="'regenerateEInvoice-' + item.id" v-if="item.type === 1 && isEinvoiceApplicable">Regenerate E-Invoice PDF</div>
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" :type="'regenerateEInvoice-' + item.id">
<general-confirmation-form-component
contentText="Are you sure you want to regenerate this E-Invoice PDF document?"
modalType="delete"
buttonText="Regenerate"
class="text-center"
:apiRoute="route('api.transaction.einvoice.regenerate', item.id)"
apiMethod="post"
:section="section"
>
</general-confirmation-form-component>
</modal-component>
<div class="btn btn-sm btn block all-caps b-rad-none btn-danger pointer requestModal m-l-20" :data-type="'regenerateSalesOrder-' + item.id" v-if="item.type === 1">Regenerate Sales Order PDF</div>
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" :type="'regenerateSalesOrder-' + item.id">
<general-confirmation-form-component
contentText="Are you sure you want to regenerate this Sales Order PDF document?"
modalType="delete"
buttonText="Regenerate"
class="text-center"
:apiRoute="route('api.transaction.sales.order.regenerate', item.id)"
apiMethod="post"
:section="section"
>
</general-confirmation-form-component>
</modal-component>
</div>
</div>
</div>
</div>
<div class="row b-t b-grey p-t-10 m-l-5 m-r-5" v-show="expanded" v-if="[5, 6].includes(item.status)">
<div class="col padding-20">
<div class="row bg-master-lightest h-100 padding-20">
@@ -323,6 +432,10 @@
storage:{
type: Object
},
isEinvoiceApplicable:{
type: Boolean,
default: false
}
},
data(){
return {
@@ -6,7 +6,7 @@
<div class="row m-b-20">
<div class="col">
<h5 class="all-caps">Delete Invoice</h5>
<div class="fs-11">Are you sure you want to delete this invoice?</div>
<div class="fs-11">Are you sure you want to delete this invoice (including all related documents (e.g. Invoice PDF, Sales Order PDF, etc...) ?</div>
</div>
</div>
<div class="row">
@@ -0,0 +1,146 @@
<br>
<table>
<tr>
<td class="header-logo">
<img src="{{ asset('images/ri_1.png') }}" alt="logo" id="logo" class="logo">
</td>
<td class="header-cief-address">
<span class="company-name">
<strong>
CIEF WORLDWIDE SDN BHD
</strong>
</span>
<span class="company-reg">(1134596-M)</span><br>
No. 72-3, Jalan Jalil 1,<br>
The Earth Bukit Jalil,<br>
57000 Kuala Lumpur<br>
Tel: 03-8082 1252<br>
TIN: C23880226040, MSIC: 46909<br>
SST: W10-2403-32000643<br>
</td>
<td class="header-details">
<div class="title" style="font-size: 20px; text-transform: uppercase;">
<strong>
Packing List Measurements
</strong>
</div>
<div class="number">{{ $document_identifier_prefix }} {{ $document_identifier }}</div>
@php
$companyModule = $invoice_transaction->owner->owner->companyModule;
@endphp
<div class="date">Date: {{ $document_date->toDateString() }}</div>
<div class="ref">Order No: {{ $invoice_transaction->owner->owner->reference }}</div>
<div class="ref">Container Ref: {{ $invoice_transaction->owner->containers()->first()->reference }}</div>
{{--<div class="d-none">{{ $companyModule->inviters()->withPivot('invitee_reference')->first()->pivot->invitee_reference }}</div>--}}
<div>&nbsp;</div>
</div>
</td>
</tr>
<tr>
<td colspan="3" class="bill-to">
<span class="sub-title">
Bill To
</span>
</td>
</tr>
<tr>
<td colspan="3" class="address">
<div class="label">
{{ $companyModule->name }}
@if ($brn)
(ROC: {{ $brn->reference }})
@endif
</div>
<div class="address">
@php
$addresses = $companyModule->addresses()->where('status', '=', \App\Classes\ValueObjects\Constants\ApprovalStatus::APPROVED)->where('type', '=', \App\Classes\ValueObjects\Constants\AddressType::BILLING)->first();
if ($companyModule->company->e_invoice === 1){
$addresses = $companyModule->addresses()->where('status', '=', \App\Classes\ValueObjects\Constants\ApprovalStatus::APPROVED)->where('type', '=', \App\Classes\ValueObjects\Constants\AddressType::E_INVOICE)->latest()->first();
}
@endphp
@if($addresses)
{{ $addresses->street_one }}
{{ $addresses->street_two }} ,
{{ $addresses->district()->first()->name }},
{{ $addresses->postcode }}
{{ $addresses->state()->first()->name }},
{{ $addresses->country()->first()->name }}
@endif
</div>
<div>
@php
$contact = $companyModule->contacts()->first();
@endphp
Phone: {{ $contact ? $contact->phone : '' }}
@if ($companyModule->company->e_invoice === 1)
<div>Buyer TIN: {{ $companyModule->company->tin }}</div>
@endif
</div>
</td>
</tr>
</table>
<br>
<br>
<table class="line-table" style="overflow: wrap" autosize="1">
<thead>
<tr>
<th width="5%">No</th>
<th class="description">Description</th>
<th width="15%">Measurement</th>
<th width="15%">CBM</th>
<th width="10%">Quantity</th>
<th width="15%">Total CBM</th>
</tr>
</thead>
<tbody>
@php
$billable_packing_list = $invoice_transaction->owner->packingLists()->first();
$billable_packing_list = $billable_packing_list ? $billable_packing_list : $invoice_transaction->owner;
$packages = $billable_packing_list->packages;
$totalCBM = 0;
$totalQty = 0;
$order_reference = $invoice_transaction->owner->owner ? $invoice_transaction->owner->owner->reference : null;
@endphp
@foreach ($packages as $key => $package)
@php
$measurement = "{$package->length} (L) <br> {$package->width} (W) <br> {$package->height} (H)";
$itemCBM = ($package->width / 100) * ($package->height / 100) * ($package->length / 100);
$itemTotalCBM = $itemCBM * $package->quantity;
$totalCBM += $itemTotalCBM;
$totalQty += $package->quantity;
@endphp
<tr>
<td width="5%" class="center top">{{ $key + 1 }}</td>
<!-- <td class="description">{!! $package->description !!}</td> -->
<!-- <td class="description">{!! $order_reference . '<br>' . $billable_packing_list->owner->reference !!}</td> -->
<td class="description">{!! $order_reference !!}</td>
<td width="15%" class="center top" style="text-align: center">
{!! $measurement !!}
</td>
<td width="15%" class="center top" style="text-align: center">
{{ round($itemCBM, 5) }}
</td>
<td width="10%" class="center top" style="text-align: center">{{ $package->quantity }}</td>
<td width="15%" class="right top">
{{ round($itemTotalCBM, 5) }}
</td>
</tr>
@endforeach
</tbody>
<tfoot>
<tr>
<td colspan="3"></td>
<td class="right middle">Total</td>
<td class="total" style="text-align: center">
{{ $totalQty }}
</td>
<td class="total right middle">
{{ round($totalCBM, 5) }}
</td>
</tr>
</tfoot>
</table>
@@ -0,0 +1,21 @@
@extends('layouts.base_pdf')
@section('inner_content')
<br>
<htmlpageheader name="page-header">
<br><br>
<div class="separator"><strong><i>{{ $document_identifier }}</i></strong></div>
</htmlpageheader>
@include('pages.pdfs.sales_order_inner')
<pagebreak />
@include('pages.pdfs.packing_list_measurement_v2')
<htmlpagefooter name="page-footer">
<table width="100%">
<tr>
<td style="text-align: right; ">This is generated by computer. No signature required.</td>
<td style="text-align: right; ">Page {PAGENO} of {nbpg}</td>
</tr>
</table>
</htmlpagefooter>
@endsection
@@ -0,0 +1,150 @@
<style>
body {
font-size: 14px;
}
</style>
<table>
<tr>
<td class="header-logo">
<img src="{{ asset('images/ri_1.png') }}" alt="logo" id="logo" class="logo">
</td>
<td class="header-cief-address">
<span class="company-name">
<strong>
CIEF WORLDWIDE SDN BHD
</strong>
</span>
<span class="company-reg">(1134596-M)</span><br>
No. 72-3, Jalan Jalil 1,<br>
The Earth Bukit Jalil,<br>
57000 Kuala Lumpur<br>
Tel: 03-8082 1252<br>
TIN: C23880226040, MSIC: 46909<br>
SST: W10-2403-32000643<br>
</td>
<td class="header-details">
<div class="title" style="font-size: 20px; text-transform: uppercase;">
<strong>
Sales Order
</strong>
</div>
<div class="number">{{ $document_identifier_prefix }} {{ $document_identifier }}</div>
@php
$companyModule = $invoice_transaction->owner->owner->companyModule;
@endphp
<div class="date">Date: {{ $document_date->toDateString() }}</div>
<div class="ref">Order No: {{ $invoice_transaction->owner->owner->reference }}</div>
<div class="ref">Container Ref: {{ $invoice_transaction->owner->containers()->first()->reference }}</div>
{{--<div class="d-none">{{ $companyModule->inviters()->withPivot('invitee_reference')->first()->pivot->invitee_reference }}</div>--}}
<div>&nbsp;</div>
</div>
</td>
</tr>
<tr>
<td colspan="3" class="bill-to">
<span class="sub-title">
Bill To
</span>
</td>
</tr>
<tr>
<td colspan="3" class="address">
<div class="label">
{{ $companyModule->name }}
@if ($brn)
(ROC: {{ $brn->reference }})
@endif
</div>
<div class="address">
@php
$addresses = $companyModule->addresses()->where('status', '=', \App\Classes\ValueObjects\Constants\ApprovalStatus::APPROVED)->where('type', '=', \App\Classes\ValueObjects\Constants\AddressType::BILLING)->first();
@endphp
@if($addresses)
{{ $addresses->street_one }}
{{ $addresses->street_two }} ,
{{ $addresses->district()->first()->name }},
{{ $addresses->postcode }}
{{ $addresses->state()->first()->name }},
{{ $addresses->country()->first()->name }}
@endif
</div>
<div>
@php
$contact = $companyModule->contacts()->first();
@endphp
Phone: {{ $contact ? $contact->phone : '' }}
@if ($companyModule->company->e_invoice === 1)
<div>Buyer TIN: {{ $companyModule->company->tin }}</div>
@endif
</div>
</td>
</tr>
</table>
<br>
<br>
<table class="line-table" style="overflow: wrap" autosize="1">
<thead>
<tr>
<th width="5%">No</th>
<th class="description">Description</th>
<th width="10%">Qty</th>
<th width="10%">Unit Price <br>(RM)</th>
<th width="10%">Tax (%)</th>
<th width="20%">Tax Amount <br>(RM)</th>
<th width="15%">Sub Total<br>(RM)</th>
</tr>
</thead>
<tbody>
@foreach ($invoice_transaction->transactionDetails as $key => $transaction_detail)
<tr>
<td width="5%" class="center top">{{ $key + 1 }}</td>
<td class="description">{!! $transaction_detail->name !!}</td>
<td width="10%" class="center top" style="text-align: center">{{ round($transaction_detail->quantity, 3) }}</td>
<td width="10%" class="center top" style="text-align: center">
{{ round($transaction_detail->price, 2) }}
</td>
<td width="10%" class="center top" style="text-align: center">
{{ round($transaction_detail->tax_percentage, 2) }}
</td>
<td width="20%" class="center top" style="text-align: center">
{{ number_format(round($transaction_detail->tax_amount, 2), 2) }}
</td>
<td width="15%" class="right top">
{{ number_format(round($transaction_detail->amount, 2), 2) }}
</td>
</tr>
@endforeach
</tbody>
<tfoot>
<tr class="subtotal">
<td colspan="5"></td>
<td class="right middle">Subtotal</td>
<td class="right middle">
{{ number_format(round($invoice_transaction->amount - $invoice_transaction->tax, 2), 2) }}
</td>
</tr>
<tr class="billingcharges">
<td colspan="5"></td>
<td class="right">Service Charges</td>
<td class="right">
{{ number_format(round($invoice_transaction->service_charge, 2), 2) }}
</td>
</tr>
<tr class="billingcharges">
<td colspan="5"></td>
<td class="right">Total SST (6%) RM</td>
<td class="right">{{ number_format($invoice_transaction->tax, 2) }}</td>
</tr>
<tr>
<td colspan="5"></td>
<td class="right middle">Total Amount RM</td>
<td class="total right middle">
{{ number_format(round($invoice_transaction->amount, 2), 2) }}
</td>
</tr>
</tfoot>
</table>
@@ -0,0 +1,21 @@
@extends('layouts.base_pdf')
@section('inner_content')
<br>
<htmlpageheader name="page-header">
<br><br>
<div class="separator"><strong><i>{{ $document_identifier }}</i></strong></div>
</htmlpageheader>
@include('pages.pdfs.shipping_einvoice_inner')
<pagebreak />
@include('pages.pdfs.packing_list_measurement_v2')
<htmlpagefooter name="page-footer">
<table width="100%">
<tr>
<td style="text-align: right; ">This is generated by computer. No signature required.</td>
<td style="text-align: right; ">Page {PAGENO} of {nbpg}</td>
</tr>
</table>
</htmlpagefooter>
@endsection
@@ -0,0 +1,189 @@
<style>
body {
font-size: 14px;
}
</style>
<table>
<tr>
<td class="header-logo">
<img src="{{ asset('images/ri_1.png') }}" alt="logo" id="logo" class="logo">
</td>
<td class="header-cief-address">
<span class="company-name">
<strong>
CIEF WORLDWIDE SDN BHD
</strong>
</span>
<span class="company-reg">(1134596-M)</span><br>
No. 72-3, Jalan Jalil 1,<br>
The Earth Bukit Jalil,<br>
57000 Kuala Lumpur<br>
Tel: 03-8082 1252<br>
TIN: C23880226040, MSIC: 46909<br>
SST: W10-2403-32000643<br>
</td>
<td class="header-details">
<div class="title" style="font-size: 20px; text-transform: uppercase;">
<strong>
E-Invoice
</strong>
</div>
<div class="number">{{ $document_identifier_prefix }} {{ $document_identifier }}</div>
@php
$companyModule = $invoice_transaction->owner->owner->companyModule;
@endphp
<div class="date">Date: {{ $document_date->toDateString() }}</div>
<div class="ref">Order No: {{ $invoice_transaction->owner->owner->reference }}</div>
<div class="ref">Container Ref: {{ $invoice_transaction->owner->containers()->first()->reference }}</div>
{{--<div class="d-none">{{ $companyModule->inviters()->withPivot('invitee_reference')->first()->pivot->invitee_reference }}</div>--}}
<div>&nbsp;</div>
</div>
</td>
</tr>
<tr>
<td colspan="3" class="bill-to">
<span class="sub-title">
Bill To
</span>
</td>
</tr>
<tr>
<td colspan="3" class="address">
<div class="label">
{{ $companyModule->name }}
@if ($brn)
(ROC: {{ $brn->reference }})
@endif
</div>
<div class="address">
@php
$addresses = $companyModule->addresses()->where('status', '=', \App\Classes\ValueObjects\Constants\ApprovalStatus::APPROVED)->where('type', '=', \App\Classes\ValueObjects\Constants\AddressType::E_INVOICE)->latest()->first();
@endphp
@if($addresses)
{{ $addresses->street_one }}
{{ $addresses->street_two }} ,
{{ $addresses->district()->first()->name }},
{{ $addresses->postcode }}
{{ $addresses->state()->first()->name }},
{{ $addresses->country()->first()->name }}
@endif
</div>
<div>
@php
$contact = $companyModule->contacts()->first();
@endphp
Phone: {{ $contact ? $contact->phone : '' }}
@if ($companyModule->company->e_invoice === 1)
<div>Buyer TIN: {{ $companyModule->company->tin }}</div>
@endif
</div>
</td>
</tr>
</table>
<br>
<br>
<table class="line-table" style="overflow: wrap" autosize="1">
<thead>
<tr>
<th width="5%">No</th>
<th class="description">Description</th>
<th width="10%">Qty</th>
<th width="10%">Unit Price <br>(RM)</th>
<th width="10%">Tax (%)</th>
<th width="20%">Tax Amount <br>(RM)</th>
<th width="15%">Sub Total<br>(RM)</th>
</tr>
</thead>
<tbody>
@foreach ($invoice_transaction->transactionDetails as $key => $transaction_detail)
<tr>
<td width="5%" class="center top">{{ $key + 1 }}</td>
<td class="description">{!! $transaction_detail->name !!}</td>
<td width="10%" class="center top" style="text-align: center">{{ round($transaction_detail->quantity, 3) }}</td>
<td width="10%" class="center top" style="text-align: center">
{{ round($transaction_detail->price, 2) }}
</td>
<td width="10%" class="center top" style="text-align: center">
{{ round($transaction_detail->tax_percentage, 2) }}
</td>
<td width="20%" class="center top" style="text-align: center">
{{ number_format(round($transaction_detail->tax_amount, 2), 2) }}
</td>
<td width="15%" class="right top">
{{ number_format(round($transaction_detail->amount, 2), 2) }}
</td>
</tr>
@endforeach
</tbody>
<tfoot>
<tr class="subtotal">
<td colspan="5"></td>
<td class="right middle">Subtotal</td>
<td class="right middle">
{{ number_format(round($invoice_transaction->amount - $invoice_transaction->tax, 2), 2) }}
</td>
</tr>
<tr class="billingcharges">
<td colspan="5"></td>
<td class="right">Service Charges</td>
<td class="right">
{{ number_format(round($invoice_transaction->service_charge, 2), 2) }}
</td>
</tr>
<tr class="billingcharges">
<td colspan="5"></td>
<td class="right">Total SST (6%) RM</td>
<td class="right">{{ number_format($invoice_transaction->tax, 2) }}</td>
</tr>
<tr>
<td colspan="5"></td>
<td class="right middle">Total Amount RM</td>
<td class="total right middle">
{{ number_format(round($invoice_transaction->amount, 2), 2) }}
</td>
</tr>
</tfoot>
</table>
<br /><br />
<table style="width: 100%; border-spacing: 0;">
<tbody>
<tr style="border-spacing: 2em;">
<td width="80%">
<table style="border-spacing:10px 10px;">
<tbody>
<tr>
<td style="border-bottom: solid 2p·x #000000;">
<div class="bank-info">
Please transfer the payment to:<br>
Bank: Maybank Berhad<br>
Account Name: CIEF Worldwide Sdn Bhd<br>
Account No: 568603010762<br>
</div>
</td>
</tr>
</tbody>
</table>
</td>
<td align="center" width="20%" style="float: right;">
<table width="100%">
<tbody>
<tr align="center">
<td>
<img src="{{ url(config('qr.qr_code_img_url') . 'http://e-invoice uuid link') }}" style="width: 230px; height: 230px;" />
</td>
</tr>
<tr align="center">
<td>
<h2 style="margin: 0 !important; font-size: 12px;"><strong>http://e-invoice uuid link</strong></h2>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
@@ -0,0 +1,147 @@
<style>
body {
font-size: 14px;
}
</style>
<table>
<tr>
<td class="header-logo">
<img src="{{ asset('images/ri_1.png') }}" alt="logo" id="logo" class="logo">
</td>
<td class="header-cief-address">
<span class="company-name">
<strong>
CIEF WORLDWIDE SDN BHD
</strong>
</span>
<span class="company-reg">(1134596-M)</span><br>
No. 72-3, Jalan Jalil 1,<br>
The Earth Bukit Jalil,<br>
57000 Kuala Lumpur<br>
Tel: 03-8082 1252<br>
TIN: C23880226040, MSIC: 46909<br>
SST: W10-2403-32000643<br>
</td>
<td class="header-details">
<div class="title" style="font-size: 20px; text-transform: uppercase;">
<strong>
Invoice
</strong>
</div>
<div class="number">{{ $document_identifier_prefix }} {{ $document_identifier }}</div>
@php
$companyModule = $invoice_transaction->owner->owner->companyModule;
@endphp
<div class="date">Date: {{ $document_date->toDateString() }}</div>
<div class="ref">Order No: {{ $invoice_transaction->owner->owner->reference }}</div>
<div class="ref">Container Ref: {{ $invoice_transaction->owner->containers()->first()->reference }}</div>
{{--<div class="d-none">{{ $companyModule->inviters()->withPivot('invitee_reference')->first()->pivot->invitee_reference }}</div>--}}
<div>&nbsp;</div>
</div>
</td>
</tr>
<tr>
<td colspan="3" class="bill-to">
<span class="sub-title">
Bill To
</span>
</td>
</tr>
<tr>
<td colspan="3" class="address">
<div class="label">
{{ $companyModule->name }}
@if ($brn)
(ROC: {{ $brn->reference }})
@endif
</div>
<div class="address">
@php
$addresses = $companyModule->addresses()->where('status', '=', \App\Classes\ValueObjects\Constants\ApprovalStatus::APPROVED)->where('type', '=', \App\Classes\ValueObjects\Constants\AddressType::BILLING)->first();
@endphp
@if($addresses)
{{ $addresses->street_one }}
{{ $addresses->street_two }} ,
{{ $addresses->district()->first()->name }},
{{ $addresses->postcode }}
{{ $addresses->state()->first()->name }},
{{ $addresses->country()->first()->name }}
@endif
</div>
<div>
@php
$contact = $companyModule->contacts()->first();
@endphp
Phone: {{ $contact ? $contact->phone : '' }}
</div>
</td>
</tr>
</table>
<br>
<br>
<table class="line-table" style="overflow: wrap" autosize="1">
<thead>
<tr>
<th width="5%">No</th>
<th class="description">Description</th>
<th width="10%">Qty</th>
<th width="10%">Unit Price <br>(RM)</th>
<th width="10%">Tax (%)</th>
<th width="20%">Tax Amount <br>(RM)</th>
<th width="15%">Sub Total<br>(RM)</th>
</tr>
</thead>
<tbody>
@foreach ($invoice_transaction->transactionDetails as $key => $transaction_detail)
<tr>
<td width="5%" class="center top">{{ $key + 1 }}</td>
<td class="description">{!! $transaction_detail->name !!}</td>
<td width="10%" class="center top" style="text-align: center">{{ round($transaction_detail->quantity, 3) }}</td>
<td width="10%" class="center top" style="text-align: center">
{{ round($transaction_detail->price, 2) }}
</td>
<td width="10%" class="center top" style="text-align: center">
{{ round($transaction_detail->tax_percentage, 2) }}
</td>
<td width="20%" class="center top" style="text-align: center">
{{ number_format(round($transaction_detail->tax_amount, 2), 2) }}
</td>
<td width="15%" class="right top">
{{ number_format(round($transaction_detail->amount, 2), 2) }}
</td>
</tr>
@endforeach
</tbody>
<tfoot>
<tr class="subtotal">
<td colspan="5"></td>
<td class="right middle">Subtotal</td>
<td class="right middle">
{{ number_format(round($invoice_transaction->amount - $invoice_transaction->tax, 2), 2) }}
</td>
</tr>
<tr class="billingcharges">
<td colspan="5"></td>
<td class="right">Service Charges</td>
<td class="right">
{{ number_format(round($invoice_transaction->service_charge, 2), 2) }}
</td>
</tr>
<tr class="billingcharges">
<td colspan="5"></td>
<td class="right">Total SST (6%) RM</td>
<td class="right">{{ number_format($invoice_transaction->tax, 2) }}</td>
</tr>
<tr>
<td colspan="5"></td>
<td class="right middle">Total Amount RM</td>
<td class="total right middle">
{{ number_format(round($invoice_transaction->amount, 2), 2) }}
</td>
</tr>
</tfoot>
</table>
@@ -0,0 +1,21 @@
@extends('layouts.base_pdf')
@section('inner_content')
<br>
<htmlpageheader name="page-header">
<br><br>
<div class="separator"><strong><i>{{ $document_identifier }}</i></strong></div>
</htmlpageheader>
@include('pages.pdfs.shipping_invoice_sst_inner_v2')
<pagebreak />
@include('pages.pdfs.packing_list_measurement_v2')
<htmlpagefooter name="page-footer">
<table width="100%">
<tr>
<td style="text-align: right; ">This is generated by computer. No signature required.</td>
<td style="text-align: right; ">Page {PAGENO} of {nbpg}</td>
</tr>
</table>
</htmlpagefooter>
@endsection
+3
View File
@@ -11,7 +11,10 @@ Route::group(['prefix' => 'transactions', 'namespace' => 'Transactions', 'as' =>
Route::put('{id}/status/update/{status}', 'UpdateTransactionStatusController@update')->where('status', 'approve|expire|reject')->name('update');
route::post('/{invoice_id}/regenerate', 'RegenerateSingleShippingInvoiceTransactionController@regenerate')->name('invoice.regenerate');
Route::post('/waive/{id}', 'WaiveTransactionController@waive')->name('waive');
Route::post('/e-invoice/{invoice_id}/regenerate', 'RegenerateSingleShippingInvoiceTransactionController@regenerateEInvoice')->name('einvoice.regenerate');
Route::post('/storage-invoice/{invoice_id}/regenerate', 'RegenerateSingleStorageInvoiceTransactionController@regenerate')->name('storage.invoice.regenerate');
Route::post('/sales-order/{invoice_id}/regenerate', 'RegenerateSingleShippingInvoiceTransactionController@regenerateSalesOrder')->name('sales.order.regenerate');
Route::get('wallet/list', 'ListWalletTransactionsController@list')->name('wallet.list');
+6 -37
View File
@@ -18,6 +18,7 @@ use App\Classes\Modules\PackingLists\Processors\FetchDeliveryUpdatesFromYdPortal
use App\Classes\Modules\PackingLists\Processors\FetchLoadedContainersFromVTPortalProcessor;
use App\Classes\Modules\PackingLists\Processors\FetchPackingListsFromYdPortalProcessor;
use App\Classes\Modules\Transactions\Processors\ApproveShippingInvoiceTransactionProcessor;
use App\Classes\Modules\Transactions\Processors\CreateShippingInvoiceTransactionDocProcessor;
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\BusinessType;
@@ -215,12 +216,6 @@ Route::get('/orders-table', function () {
Route::get('/order/show/{order_number}', function (Illuminate\Http\Request $request, $orderNumber) {
// return view('pages.orders.profile', ['id' => $orderNumber]);
// $order = Order::where('reference', $orderNumber)->first();
// $isValid = $order->companyModule->company->e_invoice !== null;
// if (!$isValid) {
// return redirect()->route('dashboard');
// }
return view('pages.orders.profile_v2', [
'id' => $orderNumber,
'q' => $request->query('q', null)
@@ -280,13 +275,6 @@ Route::get('/customer/{marking}/payment-and-billing', function ($marking) {
Route::get('/customer-invoices/{company_module_id}/payment-and-billing', function ($company_module_id) {
// todo-new: check company_module_id
// $companyModule = CompanyModule::where('id', $company_module_id)->first();
// $isValid = $companyModule->company->e_invoice !== null;
// if (!$isValid) {
// return redirect()->route('dashboard');
// }
return view('pages.customers.paymentsBilling', ['company_module_id' => $company_module_id]);
})->name('customer.payment-and-billing-by-company-module-id');
@@ -874,34 +862,15 @@ Route::get('/invoices/fix/{company_module_id}', function($company_module_id) {
$invoices = $order->transactions()->where('transactions.type', TransactionType::SHIPPING_INVOICE)->get();
foreach ($invoices as $invoice){
$invoice->documents()->delete();
// $invoice->documents()->delete();
$invoice->documents()->where('document_type', DocumentType::SHIPPING_EINVOICE)->delete();
$view = 'pages.pdfs.shipping_invoice';
$dateToCompare = Carbon::parse(env('SST_START_DATE', '2024-04-01 00:00:00'));
$shippingInvoiceTransactionCreatedDate = Carbon::parse($invoice->created_at);
if ($shippingInvoiceTransactionCreatedDate->isAfter($dateToCompare) && $invoice->tax > 0) {
$view = 'pages.pdfs.shipping_invoice_sst';
}
(App()->make(CreateShippingInvoiceTransactionDocProcessor::class))->execute($invoice);
$transaction_invoice_pdf = LaravelMpdf::loadView($view, ['invoice_transaction' => $invoice]);
$document_object = new DocumentObject(
DocumentType::SHIPPING_INVOICE,
[chunk_split('data:application/pdf;base64,'.base64_encode($transaction_invoice_pdf->output()))],
'',
ApprovalStatus::COMPLETED,
'shipping_invoice'
);
/** @var Document $document */
$document = (App()->make(CreatesDocument::class))->execute($invoice, $document_object);
(App()->make(CreatesFiles::class))->execute($document, $document_object);
dump($document);
dump($invoice);
}
}
echo('?');
});
Route::get('/invoices/combine/{ids}', function($ids){