mirror of
https://gitlab.com/CIEFWorldwideSdnBhd/shipping-portal.git
synced 2026-08-21 13:34:00 +00:00
Compare commits
105 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1110838e35 | |||
| 9d87987488 | |||
| 4c0984c9b8 | |||
| 5517f16684 | |||
| 4b967981dd | |||
| e63b959714 | |||
| a1751f274d | |||
| ef6538feca | |||
| de61d9a9fd | |||
| 2c1b857255 | |||
| 5b4a3507a3 | |||
| 3d6543e467 | |||
| 006a327a5f | |||
| 295e6454b1 | |||
| f389efa6af | |||
| 4ea3132334 | |||
| 8fc3ac1b55 | |||
| ed252e630b | |||
| b6c9c8843d | |||
| d80e996d02 | |||
| 064ee3e41a | |||
| 3bda84dac5 | |||
| e2b378e197 | |||
| 0f2e1297e1 | |||
| d034a285fc | |||
| ee94943d00 | |||
| a9e89a45bd | |||
| f6b10b5763 | |||
| 9b9057ea81 | |||
| 33d2d02cb0 | |||
| e5be6eaceb | |||
| a545e6bad6 | |||
| b64b25ff05 | |||
| d1426c7f05 | |||
| 3375934651 | |||
| c79f58d246 | |||
| ee17ac0b0c | |||
| 26742a7335 | |||
| 0e822ff1dd | |||
| 085b8b349f | |||
| c1164397e8 | |||
| 3c16253795 | |||
| 18a201611e | |||
| 7e754a9c7b | |||
| beb200fd6a | |||
| f0cb7828c3 | |||
| 1956a4095d | |||
| 71559701f4 | |||
| 9ceba30680 | |||
| 3b2d06ed8f | |||
| 81e04e9cb0 | |||
| 286ca64413 | |||
| 51a96812fd | |||
| 07459b9a1b | |||
| ee69f9123c | |||
| 7a2ed92147 | |||
| 894481591d | |||
| e5580c2abd | |||
| 47ee304da1 | |||
| 6427e2996f | |||
| f54aae5dc9 | |||
| f0ef9a5602 | |||
| 4d682c2ac6 | |||
| 8ea00e0383 | |||
| e0805a9601 | |||
| 6f36c4b7ee | |||
| 87194794f2 | |||
| b4eca67a2f | |||
| 1770b06498 | |||
| 5c9fd6e2a6 | |||
| 18df1c0c7b | |||
| 359c103d01 | |||
| ed7a636a18 | |||
| 19bd548127 | |||
| 55ac8064b1 | |||
| e7279ec4d0 | |||
| a7d4299897 | |||
| 2b507d1006 | |||
| 138a4f1cf6 | |||
| b54d897060 | |||
| c12959b4a8 | |||
| f94f380c16 | |||
| f46ec19f01 | |||
| c7a6a5b020 | |||
| 8f64769214 | |||
| cb74228a68 | |||
| b22cc0f7e3 | |||
| 2e8ba4f630 | |||
| e987838d5a | |||
| 48fa67ae8c | |||
| 1e9e94b581 | |||
| 67653b60fb | |||
| 26fffb8af1 | |||
| fb0c74d645 | |||
| 53293f26d6 | |||
| 56fe5520ad | |||
| 61c801e216 | |||
| 6f0acec390 | |||
| 76e3668563 | |||
| ce94dd1393 | |||
| c1ea087c58 | |||
| 8595d0987f | |||
| 48d0460eef | |||
| 06751fdc78 | |||
| b5bcd5c553 |
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Exceptions;
|
||||
|
||||
use App\Classes\ValueObjects\Constants\HttpStatus;
|
||||
|
||||
final class JobResourceNotFoundException extends ServiceApiException {
|
||||
public function __construct(?string $message = null) {
|
||||
parent::__construct($message ?? 'Unable to find the requested resource', HttpStatus::RESOURCE_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,8 @@ use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
use Illuminate\Http\Resources\Json\ResourceCollection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use App\Classes\Exceptions\JobResourceNotFoundException;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
abstract class AbstractControllerLogic
|
||||
{
|
||||
@@ -62,6 +64,19 @@ abstract class AbstractControllerLogic
|
||||
return $response;
|
||||
|
||||
} catch (ErrorException|GeneralExceptions|TypeError $exception){
|
||||
if ($exception instanceof JobResourceNotFoundException) {
|
||||
Log::error(sprintf(
|
||||
"Uncaught exception '%s' with message '%s' in %s:%d",
|
||||
get_class($exception),
|
||||
$exception->getMessage(),
|
||||
$exception->getTrace()[0]['file'],
|
||||
$exception->getTrace()[0]['line']
|
||||
));
|
||||
}
|
||||
else{
|
||||
Log::error($exception);
|
||||
}
|
||||
|
||||
return (new ApiResponseObject($this->getNotificationTitle().' failed', $exception->getMessage(),
|
||||
!in_array($exception->getCode(), [0, 42000]) ? $exception->getCode() : HttpStatus::SERVER_ERROR))->handler();
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@ namespace App\Classes\General\Eloquent;
|
||||
use App\Classes\Exceptions\ResourceNotFoundException;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use App\Classes\Exceptions\JobResourceNotFoundException;
|
||||
|
||||
|
||||
abstract class AbstractFetchRecord extends AbstractGetRecord
|
||||
{
|
||||
@@ -26,12 +28,18 @@ abstract class AbstractFetchRecord extends AbstractGetRecord
|
||||
* @return Model
|
||||
* @throws ResourceNotFoundException
|
||||
*/
|
||||
public function getResults(Builder $query): Model {
|
||||
public function getResults(Builder $query, array $param = []): Model {
|
||||
if(!$query->exists()){
|
||||
throw new ResourceNotFoundException('Unable to find any record based on the criteria provided');
|
||||
$table = $query->getModel()->getTable();
|
||||
if($table ==='job_results'){
|
||||
throw new JobResourceNotFoundException('Unable to find any job based on the criteria provided');
|
||||
}
|
||||
else{
|
||||
throw new ResourceNotFoundException('Unable to find any record based on the criteria provided');
|
||||
}
|
||||
}
|
||||
|
||||
return $query->first();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,9 +50,9 @@ abstract class AbstractGetRecord
|
||||
* @param array $filters
|
||||
* @return mixed
|
||||
*/
|
||||
public function handler(array $filters){
|
||||
public function handler(array $filters, array $params = []){
|
||||
$this->filters = collect($filters);
|
||||
return $this->getResults($this->applyFiltersToQuery());
|
||||
return $this->getResults($this->applyFiltersToQuery(), $params);
|
||||
}
|
||||
|
||||
|
||||
@@ -65,6 +65,6 @@ abstract class AbstractGetRecord
|
||||
* @param Builder $query
|
||||
* @return mixed
|
||||
*/
|
||||
abstract function getResults(Builder $query);
|
||||
abstract function getResults(Builder $query, array $params = []);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,11 +16,10 @@ abstract class AbstractListRecord extends AbstractGetRecord
|
||||
* @return mixed
|
||||
* @throws MalformedRequestException
|
||||
*/
|
||||
public function execute(array $filters = []){
|
||||
public function execute(array $filters = [], array $param = []){
|
||||
|
||||
try{
|
||||
|
||||
return $this->handler($filters);
|
||||
return $this->handler($filters, $param);
|
||||
|
||||
} catch (QueryException $exception){
|
||||
throw new MalformedRequestException('Unable to fetch the list of records due to unexpected error');
|
||||
@@ -32,7 +31,7 @@ abstract class AbstractListRecord extends AbstractGetRecord
|
||||
* @param Builder $query
|
||||
* @return mixed
|
||||
*/
|
||||
public function getResults(Builder $query) {
|
||||
public function getResults(Builder $query, array $param = []) {
|
||||
$filters = $this->getDecorationFilters();
|
||||
|
||||
if($filters->has('order_by')){
|
||||
@@ -44,8 +43,12 @@ abstract class AbstractListRecord extends AbstractGetRecord
|
||||
}
|
||||
|
||||
//dd($query->toSql());
|
||||
return $filters->has('per_page') ? $query->paginate($filters->get('per_page')) : $query->get();
|
||||
|
||||
if(!empty($param)){
|
||||
return $filters->has('per_page') ? $query->paginate($filters->get('per_page'), ['*'], 'page', $param['page']) : $query->get(); //page data from query parameters e.g ?page=1
|
||||
}
|
||||
else{
|
||||
return $filters->has('per_page') ? $query->paginate($filters->get('per_page')) : $query->get();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\General\Eloquent\Filters;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class JobId implements Filter
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Builder $builder
|
||||
* @param $value
|
||||
* @return Builder|mixed
|
||||
*/
|
||||
public static function apply(Builder $builder, $value)
|
||||
{
|
||||
return $builder->where('job_id', $value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\General\Eloquent\Filters;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class OrderByIdDesc implements Filter
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Builder $builder
|
||||
* @param $value
|
||||
* @return Builder|mixed
|
||||
*/
|
||||
public static function apply(Builder $builder, $value)
|
||||
{
|
||||
return $builder->orderBy('id', 'desc');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\General\Eloquent\Filters;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class OrderByUpdatedAtDesc implements Filter
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Builder $builder
|
||||
* @param $value
|
||||
* @return Builder|mixed
|
||||
*/
|
||||
public static function apply(Builder $builder, $value)
|
||||
{
|
||||
return $builder->orderBy('updated_at', 'desc');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\General\Eloquent\Filters;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class PostcodeLike implements Filter
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Builder $builder
|
||||
* @param $value
|
||||
* @return Builder|mixed
|
||||
*/
|
||||
public static function apply(Builder $builder, $value)
|
||||
{
|
||||
return $builder->where('postcode', 'LIKE', '%'.$value.'%');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\General\Eloquent\Filters;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class RequestSignature implements Filter
|
||||
{
|
||||
/**
|
||||
* @param Builder $builder
|
||||
* @param $value
|
||||
* @return Builder|mixed
|
||||
*/
|
||||
public static function apply(Builder $builder, $value)
|
||||
{
|
||||
return $builder->where('request_signature', $value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\General\Eloquent\Filters;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class ResultNotNull implements Filter
|
||||
{
|
||||
/**
|
||||
* @param Builder $builder
|
||||
* @param $value
|
||||
* @return Builder|mixed
|
||||
*/
|
||||
public static function apply(Builder $builder, $value)
|
||||
{
|
||||
return $builder->whereNotNull('result');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\General\Eloquent\Filters;
|
||||
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class WithContainersPackages implements Filter
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Builder $builder
|
||||
* @param $value
|
||||
* @return mixed
|
||||
*/
|
||||
public static function apply(Builder $builder, $value)
|
||||
{
|
||||
return $builder->with(['containers', 'packages']);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\General\Eloquent\Filters;
|
||||
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class WithTrashed implements Filter
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Builder $builder
|
||||
* @param $value
|
||||
* @return mixed
|
||||
*/
|
||||
public static function apply(Builder $builder, $value)
|
||||
{
|
||||
return $builder->withTrashed();
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Classes\General;
|
||||
|
||||
use Illuminate\Http\Resources\Json\ResourceCollection;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
@@ -40,4 +41,12 @@ class Helper
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ResourceCollection $collection
|
||||
* @return array
|
||||
*/
|
||||
static function collectionResponse(ResourceCollection $collection){
|
||||
return json_decode($collection->response()->getContent(), true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Jobs;
|
||||
|
||||
use App\Classes\Modules\PackingLists\Processors\ListPackingListsJobProcessor;
|
||||
use App\Classes\Modules\Jobs\DataTransferObjects\ListGenericJobObject;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
|
||||
class ListPackingListsJob implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
public $timeout = 900;
|
||||
|
||||
/** @var ListGenericJobObject */
|
||||
private $listGenericJobObject;
|
||||
|
||||
/**
|
||||
* ListPackingListsJob constructor.
|
||||
* @param ListGenericJobObject $listGenericJobObject
|
||||
*/
|
||||
public function __construct(ListGenericJobObject $listGenericJobObject)
|
||||
{
|
||||
$this->listGenericJobObject = $listGenericJobObject;
|
||||
}
|
||||
|
||||
public function handle()
|
||||
{
|
||||
$rawPayload = $this->job->payload();
|
||||
if(isset($rawPayload['data']['commandName'])){
|
||||
$this->listGenericJobObject->setJobCommandName($rawPayload['data']['commandName']);
|
||||
}
|
||||
|
||||
if(isset($rawPayload['data']['command'])){
|
||||
$this->listGenericJobObject->setJobCommand($rawPayload['data']['command']);
|
||||
}
|
||||
|
||||
$result = (App()->make(ListPackingListsJobProcessor::class))->execute($this->listGenericJobObject);
|
||||
}
|
||||
}
|
||||
@@ -18,11 +18,13 @@ use App\Classes\Modules\Billplzs\Processors\CallbackBillplzProcessor;
|
||||
use App\Classes\Modules\Transactions\Services\FetchesTransaction;
|
||||
use App\Classes\Modules\Transactions\Processors\CreatePaymentTransactionProcessor;
|
||||
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
|
||||
use App\Classes\Modules\Transactions\Processors\CheckStorageInvoiceTransactionProcessor;
|
||||
use App\Classes\ValueObjects\Constants\PaymentMethodType;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Models\Group;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class CallbackBillplzLogic
|
||||
{
|
||||
@@ -50,6 +52,9 @@ class CallbackBillplzLogic
|
||||
/** @var CallbackBillplzProcessor */
|
||||
private $callbackBillplzProcessor;
|
||||
|
||||
/** @var CheckStorageInvoiceTransactionProcessor */
|
||||
private $storageInvoiceTransactionProcessor;
|
||||
|
||||
/**
|
||||
* CallbackBillplzLogic constructor.
|
||||
* @param GetBillplzBill $getBillplzBill
|
||||
@@ -59,8 +64,9 @@ class CallbackBillplzLogic
|
||||
* @param UpdateDoFromYDPortalProcessor $updateDoFromYDPortalProcessor
|
||||
* @param CreatePaymentTransactionProcessor $createPaymentTransactionProcessor
|
||||
* @param CallbackBillplzProcessor $callbackBillplzProcessor
|
||||
* @param CheckStorageInvoiceTransactionProcessor $storageInvoiceTransactionProcessor
|
||||
*/
|
||||
public function __construct(GetBillplzBill $getBillplzBill, FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus, UpdateDoFromVTPortalProcessor $updateDoFromVTPortalProcessor, UpdateDoFromYDPortalProcessor $updateDoFromYDPortalProcessor, UpdatesWalletBalance $updatesWalletBalance, CreatePaymentTransactionProcessor $createPaymentTransactionProcessor, CallbackBillplzProcessor $callbackBillplzProcessor)
|
||||
public function __construct(GetBillplzBill $getBillplzBill, FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus, UpdateDoFromVTPortalProcessor $updateDoFromVTPortalProcessor, UpdateDoFromYDPortalProcessor $updateDoFromYDPortalProcessor, UpdatesWalletBalance $updatesWalletBalance, CreatePaymentTransactionProcessor $createPaymentTransactionProcessor, CallbackBillplzProcessor $callbackBillplzProcessor, CheckStorageInvoiceTransactionProcessor $storageInvoiceTransactionProcessor)
|
||||
{
|
||||
$this->getBillplzBill = $getBillplzBill;
|
||||
$this->fetchesTransaction = $fetchesTransaction;
|
||||
@@ -70,6 +76,7 @@ class CallbackBillplzLogic
|
||||
$this->updatesWalletBalance = $updatesWalletBalance;
|
||||
$this->createPaymentTransactionProcessor = $createPaymentTransactionProcessor;
|
||||
$this->callbackBillplzProcessor = $callbackBillplzProcessor;
|
||||
$this->storageInvoiceTransactionProcessor = $storageInvoiceTransactionProcessor;
|
||||
}
|
||||
|
||||
|
||||
@@ -109,10 +116,13 @@ class CallbackBillplzLogic
|
||||
$status = $billplzXSignatureObject->getStatus() === 'failed' ? ApprovalStatus::REJECTED : ApprovalStatus::PENDING_VERIFICATION;
|
||||
}
|
||||
|
||||
Log::info('Debug billPlz status: '.$status);
|
||||
|
||||
$token = Auth::fromUser(User::find(1));
|
||||
$request->headers->set('Authorization', 'Bearer '.$token);
|
||||
|
||||
$this->callbackBillplzProcessor->execute($transaction, $status);
|
||||
$this->storageInvoiceBackDoorPreventionCheck($transaction, $status);
|
||||
$result = $this->callbackBillplzProcessor->execute($transaction, $status);
|
||||
|
||||
$company_module_marking = $transaction->owner->owner->connections? $transaction->owner->owner->connections->first()->invitee_reference: null;
|
||||
|
||||
@@ -123,6 +133,22 @@ class CallbackBillplzLogic
|
||||
$company_module_marking = $order->companyModule->connections? $order->companyModule->connections->first()->invitee_reference: null;
|
||||
}
|
||||
|
||||
return $request->method() === 'POST' ? true : view('pages.payments_redirect', ['marking' => $order->reference ?? null, 'company_module_marking' => $company_module_marking ?? null, 'transaction' => $transaction, 'status' => $status]);
|
||||
return $request->method() === 'POST' ? true : view('pages.payments_redirect', ['marking' => $order->reference ?? null, 'company_module_marking' => $company_module_marking ?? null, 'transaction' => $transaction, 'status' => $status, 'result' => $result]);
|
||||
}
|
||||
|
||||
private function storageInvoiceBackDoorPreventionCheck($transaction, $status){
|
||||
if ($transaction->owner instanceof Wallet && $status === ApprovalStatus::APPROVED) {
|
||||
$group = Group::where('reference', $transaction->payment_reference)->first();
|
||||
if ($group) {
|
||||
foreach ($group->groupTransactions as $groupTransaction) {
|
||||
$invoice = $groupTransaction->transaction;
|
||||
$pL = $invoice->owner;
|
||||
$order = $pL->owner;
|
||||
if($order){
|
||||
$this->storageInvoiceTransactionProcessor->executeOrder($order, false); //original was set true here so that no group is soft deleted or billplz bill got deleted
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,13 +6,14 @@ use Illuminate\Http\Request;
|
||||
use App\Models\Wallet;
|
||||
use App\Models\Group;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Classes\ValueObjects\Constants\PaymentMethodType;
|
||||
use App\Classes\Modules\Transactions\Processors\CreatePaymentTransactionProcessor;
|
||||
use App\Classes\Modules\Transactions\Processors\ReleaseGoodsToCustomerProcessor;
|
||||
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
|
||||
use App\Classes\Modules\Wallets\Services\UpdatesWalletBalance;
|
||||
use App\Classes\Modules\Orders\Processors\UpdateDoFromVTPortalProcessor;
|
||||
use App\Classes\Modules\Orders\Processors\UpdateDoFromYDPortalProcessor;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class CallbackBillplzProcessor
|
||||
{
|
||||
@@ -31,6 +32,9 @@ class CallbackBillplzProcessor
|
||||
/** @var CreatePaymentTransactionProcessor */
|
||||
private $createPaymentTransactionProcessor;
|
||||
|
||||
/** @var ReleaseGoodsToCustomerProcessor */
|
||||
private $releaseGoodsToCustomerProcessor;
|
||||
|
||||
/**
|
||||
* CreateUserProcessor constructor.
|
||||
* @param UpdatesTransactionStatus $updatesTransactionStatus
|
||||
@@ -38,14 +42,16 @@ class CallbackBillplzProcessor
|
||||
* @param UpdateDoFromYDPortalProcessor $updateDoFromYDPortalProcessor
|
||||
* @param UpdatesWalletBalance $updatesWalletBalance
|
||||
* @param CreatePaymentTransactionProcessor $createPaymentTransactionProcessor
|
||||
* @param ReleaseGoodsToCustomerProcessor $releaseGoodsToCustomerProcessor
|
||||
*/
|
||||
public function __construct(UpdatesTransactionStatus $updatesTransactionStatus, UpdateDoFromVTPortalProcessor $updateDoFromVTPortalProcessor, UpdateDoFromYDPortalProcessor $updateDoFromYDPortalProcessor, UpdatesWalletBalance $updatesWalletBalance, CreatePaymentTransactionProcessor $createPaymentTransactionProcessor)
|
||||
public function __construct(UpdatesTransactionStatus $updatesTransactionStatus, UpdateDoFromVTPortalProcessor $updateDoFromVTPortalProcessor, UpdateDoFromYDPortalProcessor $updateDoFromYDPortalProcessor, UpdatesWalletBalance $updatesWalletBalance, CreatePaymentTransactionProcessor $createPaymentTransactionProcessor, ReleaseGoodsToCustomerProcessor $releaseGoodsToCustomerProcessor)
|
||||
{
|
||||
$this->updatesTransactionStatus = $updatesTransactionStatus;
|
||||
$this->updateDoFromVTPortalProcessor = $updateDoFromVTPortalProcessor;
|
||||
$this->updateDoFromYDPortalProcessor = $updateDoFromYDPortalProcessor;
|
||||
$this->updatesWalletBalance = $updatesWalletBalance;
|
||||
$this->createPaymentTransactionProcessor = $createPaymentTransactionProcessor;
|
||||
$this->releaseGoodsToCustomerProcessor = $releaseGoodsToCustomerProcessor;
|
||||
}
|
||||
|
||||
|
||||
@@ -58,6 +64,9 @@ class CallbackBillplzProcessor
|
||||
$invoice = $transaction->owner;
|
||||
$packingList = $invoice->owner;
|
||||
|
||||
$proceed = $this->checkForGroupPayment($transaction);
|
||||
if(!$proceed) return false;
|
||||
|
||||
$this->updatesTransactionStatus->execute($transaction, $status);
|
||||
|
||||
// check if is wallet top up
|
||||
@@ -66,33 +75,54 @@ class CallbackBillplzProcessor
|
||||
$this->updatesWalletBalance->execute($transaction->owner, $transaction->amount);
|
||||
|
||||
$group = Group::where('reference', $transaction->payment_reference)->first();
|
||||
|
||||
|
||||
// check if is group payment
|
||||
if ($group) {
|
||||
foreach ($group->groupTransactions as $groupTransaction) {
|
||||
$invoice = $groupTransaction->transaction;
|
||||
$this->createPaymentTransactionProcessor->execute($invoice, PaymentMethodType::WALLET, null);
|
||||
|
||||
$paymentTransaction = $this->createPaymentTransactionProcessor->execute($invoice, PaymentMethodType::WALLET, null, false);
|
||||
|
||||
if($paymentTransaction && $paymentTransaction->status == ApprovalStatus::APPROVED){
|
||||
$pL = $invoice->owner;
|
||||
$this->releaseGoodsToCustomerProcessor->execute($pL, $invoice);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$group->status = $status;
|
||||
$group->save();
|
||||
}
|
||||
}
|
||||
|
||||
if (!$transaction->owner instanceof Wallet) {
|
||||
$totalPaidAmount = $invoice->transactions->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->sum('amount');
|
||||
$this->releaseGoodsToCustomerProcessor->execute($packingList, $invoice);
|
||||
}
|
||||
|
||||
if (($invoice->amount - $totalPaidAmount) < 0.01) {
|
||||
$this->updatesTransactionStatus->execute($invoice, ApprovalStatus::COMPLETED);
|
||||
return true;
|
||||
}
|
||||
|
||||
$packingList->status = ApprovalStatus::APPROVED;
|
||||
$packingList->save();
|
||||
private function checkForGroupPayment($transaction){
|
||||
//This check is targetting group payment that expired and soft deleted
|
||||
//command:check-storage-invoices must already run for this part of the code to work properly
|
||||
$group = Group::withTrashed()->where('reference', $transaction->payment_reference)->first();
|
||||
if ($group) {
|
||||
$totalAmountToBePaid = 0;
|
||||
$actualAmountPaid = $transaction->amount;
|
||||
|
||||
if (app()->environment('production')) {
|
||||
$this->updateDoFromVTPortalProcessor->execute($packingList);
|
||||
$this->updateDoFromYDPortalProcessor->execute($packingList);
|
||||
}
|
||||
foreach ($group->groupTransactions as $groupTransaction) {
|
||||
$invoice = $groupTransaction->transaction;
|
||||
$totalAmountToBePaid += $invoice->amount;
|
||||
}
|
||||
|
||||
if(($totalAmountToBePaid - $actualAmountPaid) < 0.01){
|
||||
|
||||
}
|
||||
else{
|
||||
Log::channel('storage_invoices')->info('Total amount from current transaction: '.$totalAmountToBePaid); //cief todo: to be removed
|
||||
Log::channel('storage_invoices')->info('Total amount from paid transaction: '.$transaction->amount); //cief todo: to be removed
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Billplzs\Services;
|
||||
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use App\Classes\Exceptions\MalformedRequestException;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class DeletesBillplzBill
|
||||
{
|
||||
|
||||
/**
|
||||
* @param string $billID
|
||||
* @throws MalformedRequestException
|
||||
*/
|
||||
public function execute(string $billID) {
|
||||
try{
|
||||
$response = Http::withBasicAuth(config('billplz.api_key').':', '')->delete(config('billplz.base_url').'/api/v3/bills/'.$billID);
|
||||
Log::channel('storage_invoices')->info('DeletesBillplzBill response: '.json_encode($response));
|
||||
|
||||
if($response->successful()){
|
||||
$data = $response->json();
|
||||
|
||||
// $data['url'] = $data['url'].'?auto_submit=true';
|
||||
|
||||
return (object) $data;
|
||||
}else{
|
||||
return null;
|
||||
}
|
||||
}catch(\Exception $exception){
|
||||
throw new MalformedRequestException('Unable to get correct response from billplz server: ' . $exception->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -74,7 +74,8 @@ class ExportsPaymentTransactions implements FromQuery, WithHeadings, WithHeading
|
||||
$approvalStatus = ApprovalStatus::APPROVED;
|
||||
}
|
||||
|
||||
$query->where('type', TransactionType::SHIPPING_INVOICE)->whereIn('status', [$approvalStatus]);
|
||||
// $query->where('type', TransactionType::SHIPPING_INVOICE)->whereIn('status', [$approvalStatus]);
|
||||
$query->whereIn('type', [TransactionType::SHIPPING_INVOICE, TransactionType::STORAGE_INVOICE])->whereIn('status', [$approvalStatus]);
|
||||
|
||||
if($start_date && $end_date) {
|
||||
$query->whereBetween('updated_at', [
|
||||
@@ -102,7 +103,12 @@ class ExportsPaymentTransactions implements FromQuery, WithHeadings, WithHeading
|
||||
$container = $transaction->owner->containers()->first();
|
||||
$order = $transaction->owner->owner;
|
||||
$company = $order->companyModule->company;
|
||||
$shippingTransactionDetails = $transaction->transactionDetails()->where('reference', 'SHIPPING_FEE')->first();
|
||||
if($transaction->type === TransactionType::STORAGE_INVOICE){
|
||||
$shippingTransactionDetails = $transaction->transactionDetails()->where('reference', 'STORAGE_FEE')->first();
|
||||
}
|
||||
else{
|
||||
$shippingTransactionDetails = $transaction->transactionDetails()->where('reference', 'SHIPPING_FEE')->first();
|
||||
}
|
||||
$marking = $order->companyModule->inviters()->withPivot('invitee_reference')->first()->pivot->invitee_reference;
|
||||
$contact = $order->companyModule->company->contacts->first();
|
||||
$userName = $order->companyModule->employees()->first();
|
||||
@@ -118,6 +124,8 @@ class ExportsPaymentTransactions implements FromQuery, WithHeadings, WithHeading
|
||||
$furtherDescription .= $item->name.' '.$item->quantity.' CBM'."\n";
|
||||
elseif($item->reference === 'MIN_CBM_CHARGES')
|
||||
$furtherDescription .= $item->name.' '.$item->quantity.' CBM'."\n";
|
||||
elseif($item->reference === 'STORAGE_FEE')
|
||||
$furtherDescription .= str_replace('<br>', ' | ', $item->name).' '."\n";
|
||||
else
|
||||
$furtherDescription .= $item->name.' '.$item->quantity.' X '.$item->price."\n";
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Imports\Services;
|
||||
|
||||
use Maatwebsite\Excel\Concerns\WithHeadingRow;
|
||||
use Illuminate\Support\Collection;
|
||||
use Maatwebsite\Excel\Concerns\ToCollection;
|
||||
|
||||
|
||||
class GenericImport implements ToCollection, WithHeadingRow
|
||||
{
|
||||
function headingRow(): int { return 1; }
|
||||
|
||||
public $rows;
|
||||
|
||||
/**
|
||||
* @param Collection $collection
|
||||
*/
|
||||
public function collection(Collection $collection)
|
||||
{
|
||||
$this->rows = $collection;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Jobs\ControllersLogic;
|
||||
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Jobs\Processors\FetchesJobResultProcessor;
|
||||
use App\Http\Resources\JobResultResource;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class FetchJobResultLogic extends AbstractControllerLogic
|
||||
{
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function notification():array {
|
||||
return [
|
||||
'title' => 'Retrieved Data',
|
||||
'message' => 'You have successfully retrieved data'
|
||||
];
|
||||
}
|
||||
|
||||
/** @var FetchesJobResultProcessor */
|
||||
private $fetchesJobResultProcessor;
|
||||
|
||||
/**
|
||||
* FetchJobResultLogic constructor.
|
||||
* @param FetchesJobResultProcessor $fetchesJobResultProcessor
|
||||
*/
|
||||
public function __construct(FetchesJobResultProcessor $fetchesJobResultProcessor)
|
||||
{
|
||||
$this->fetchesJobResultProcessor = $fetchesJobResultProcessor;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
* @throws \App\Classes\Exceptions\AccessForbiddenException
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
* @throws \App\Classes\Exceptions\RequestValidationException
|
||||
*/
|
||||
public function logic(Request $request) : JsonResponse
|
||||
{
|
||||
$query = $this->fetchesJobResultProcessor->execute($request);
|
||||
|
||||
return $this->resourceResponse(new JobResultResource($query));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Jobs\DataTransferObjects;
|
||||
|
||||
use App\Classes\General\Interfaces\DataTransferObject;
|
||||
|
||||
class ListGenericJobObject implements DataTransferObject
|
||||
{
|
||||
/** @var string */
|
||||
private $name;
|
||||
|
||||
/** @var array */
|
||||
private $payload;
|
||||
|
||||
/** @var string */
|
||||
private $jobId;
|
||||
|
||||
/** @var string */
|
||||
private $requestSignature;
|
||||
|
||||
/** @var string */
|
||||
private $resultSignature;
|
||||
|
||||
/** @var object */
|
||||
private $userInfo;
|
||||
|
||||
/** @var string */
|
||||
private $jobCommandName;
|
||||
|
||||
/** @var string */
|
||||
private $jobCommand;
|
||||
|
||||
public function __construct(string $name, array $payload, string $requestSignature, ?string $resultSignature, string $jobId, object $userInfo = null)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->payload = $payload;
|
||||
$this->jobId = $jobId;
|
||||
$this->requestSignature = $requestSignature;
|
||||
$this->resultSignature = $resultSignature;
|
||||
$this->userInfo = $userInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getPayload(): array
|
||||
{
|
||||
return $this->payload;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getJobId(): string
|
||||
{
|
||||
return $this->jobId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getRequestSignature(): string
|
||||
{
|
||||
return $this->requestSignature;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getResultSignature(): ?string
|
||||
{
|
||||
return $this->resultSignature;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return object
|
||||
*/
|
||||
public function getUserInfo(): object
|
||||
{
|
||||
return $this->userInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getJobCommandName(): string
|
||||
{
|
||||
return $this->jobCommandName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getJobCommand(): string
|
||||
{
|
||||
return $this->jobCommand;
|
||||
}
|
||||
|
||||
|
||||
public function setJobCommandName(string $jobCommandName)
|
||||
{
|
||||
$this->jobCommandName = $jobCommandName;
|
||||
}
|
||||
|
||||
public function setJobCommand(string $jobCommand)
|
||||
{
|
||||
$this->jobCommand = $jobCommand;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Jobs\DataTransferObjects;
|
||||
|
||||
use App\Classes\General\Interfaces\DataTransferObject;
|
||||
|
||||
class UpdateJobResultObject implements DataTransferObject
|
||||
{
|
||||
/** @var string */
|
||||
private $result;
|
||||
|
||||
/** @var string */
|
||||
private $resultSignature;
|
||||
|
||||
/** @var string */
|
||||
private $jobCommandName;
|
||||
|
||||
/** @var string */
|
||||
private $jobCommand;
|
||||
|
||||
public function __construct(string $result, string $resultSignature, string $jobCommandName, string $jobCommand)
|
||||
{
|
||||
$this->result = $result;
|
||||
$this->resultSignature = $resultSignature;
|
||||
$this->jobCommandName = $jobCommandName;
|
||||
$this->jobCommand = $jobCommand;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getResult(): string
|
||||
{
|
||||
return $this->result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getResultSignature(): string
|
||||
{
|
||||
return $this->resultSignature;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getJobCommandName(): string
|
||||
{
|
||||
return $this->jobCommandName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getJobCommand(): string
|
||||
{
|
||||
return $this->jobCommand;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Jobs\Processors;
|
||||
|
||||
use App\Classes\Exceptions\JobResourceNotFoundException;
|
||||
use App\Classes\Modules\Jobs\Services\FetchesJobResult;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
|
||||
class FetchesJobResultProcessor
|
||||
{
|
||||
/** @var FetchesJobResult */
|
||||
private $fetchesJobResult;
|
||||
|
||||
|
||||
/**
|
||||
* FetchesJobResultProcessor constructor.
|
||||
* @param FetchesJobResult $fetchesJobResult
|
||||
*/
|
||||
public function __construct(FetchesJobResult $fetchesJobResult)
|
||||
{
|
||||
$this->fetchesJobResult = $fetchesJobResult;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return Model
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
* @throws \App\Classes\Exceptions\JobResourceNotFoundException
|
||||
* @throws \App\Classes\Exceptions\ResourceNotFoundException
|
||||
*/
|
||||
public function execute(Request $request){
|
||||
|
||||
$res1 = $this->fetchesJobResult->execute(['job_id' => $request->route('job_id')]);
|
||||
if($request->route('is_last')){
|
||||
$res2 = $this->fetchesJobResult->execute(['request_signature' => $res1->request_signature, 'result_not_null' => true, 'order_by_id_desc' => true]);
|
||||
return $res2;
|
||||
}
|
||||
|
||||
if(!$res1->result){
|
||||
throw new JobResourceNotFoundException('Unable to find any job based on the criteria provided');
|
||||
}
|
||||
|
||||
return $res1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Jobs\Processors;
|
||||
|
||||
|
||||
use App\Classes\Modules\Jobs\Services\UpdatesJobResult;
|
||||
use App\Classes\Modules\Jobs\Services\FetchesJobResult;
|
||||
use App\Classes\Exceptions\JobResourceNotFoundException;
|
||||
use App\Classes\Modules\Jobs\DataTransferObjects\ListGenericJobObject;
|
||||
use App\Classes\Modules\Jobs\DataTransferObjects\UpdateJobResultObject;
|
||||
|
||||
class UpdateJobResultProcessor
|
||||
{
|
||||
|
||||
/** @var FetchesJobResult */
|
||||
private $fetchesJobResult;
|
||||
|
||||
/** @var UpdatesJobResult */
|
||||
private $updatesJobResult;
|
||||
|
||||
/**
|
||||
* UpdateJobResultProcessor constructor.
|
||||
* @param FetchesJobResult $fetchesJobResult
|
||||
* @param UpdatesJobResult $updatesJobResult
|
||||
*/
|
||||
public function __construct(FetchesJobResult $fetchesJobResult, UpdatesJobResult $updatesJobResult)
|
||||
{
|
||||
$this->fetchesJobResult = $fetchesJobResult;
|
||||
$this->updatesJobResult = $updatesJobResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ListGenericJobObject $listGenericJobObject
|
||||
* @param array $resultCurrent
|
||||
* @return void
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
* @throws \App\Classes\Exceptions\JobResourceNotFoundException
|
||||
*/
|
||||
public function execute(ListGenericJobObject $listGenericJobObject, $resultCurrent) {
|
||||
$jobResultCurrent = $this->fetchesJobResult->execute(['job_id' => $listGenericJobObject->getJobId()]);
|
||||
$resultCurrentJson = json_encode($resultCurrent);
|
||||
$resultSignatureCurrent = md5($resultCurrentJson);
|
||||
|
||||
try{
|
||||
$jobResultExisting = $this->fetchesJobResult->execute(['request_signature' => $jobResultCurrent->request_signature, 'result_not_null' => true, 'order_by_id_desc' => true]);
|
||||
$resultSignatureExisting = $jobResultExisting->result_signature;
|
||||
//if($resultSignatureExisting != $resultSignatureCurrent){
|
||||
$this->updateJobResult($jobResultCurrent, $resultCurrentJson, $resultSignatureCurrent, $listGenericJobObject->getJobCommandName(), $listGenericJobObject->getJobCommand());
|
||||
//}
|
||||
} catch (JobResourceNotFoundException $exception){
|
||||
$this->updateJobResult($jobResultCurrent, $resultCurrentJson, $resultSignatureCurrent, $listGenericJobObject->getJobCommandName(), $listGenericJobObject->getJobCommand());
|
||||
}
|
||||
}
|
||||
|
||||
private function updateJobResult($jobResultCurrent, $resultCurrentJson, $resultSignatureCurrent, $jobCommandName, $jobCommand){
|
||||
$updateJobResultObject = new UpdateJobResultObject(
|
||||
$resultCurrentJson,
|
||||
$resultSignatureCurrent,
|
||||
$jobCommandName,
|
||||
$jobCommand
|
||||
);
|
||||
$create = $this->updatesJobResult->execute($jobResultCurrent, $updateJobResultObject);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Jobs\Services;
|
||||
|
||||
use App\Classes\General\Eloquent\AbstractUpdateRecord;
|
||||
use App\Models\JobResult;
|
||||
use App\Classes\Modules\Jobs\DataTransferObjects\ListGenericJobObject;
|
||||
|
||||
class CreatesJobResult extends AbstractUpdateRecord
|
||||
{
|
||||
/**
|
||||
* @param ListGenericJobObject $listGenericJobObject
|
||||
* @return \Illuminate\Database\Eloquent\Model
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
*/
|
||||
public function execute(ListGenericJobObject $listGenericJobObject)
|
||||
{
|
||||
$model = new JobResult();
|
||||
$model->job_id = $listGenericJobObject->getJobId();
|
||||
$model->request_signature = $listGenericJobObject->getRequestSignature();
|
||||
$model->result_signature = $listGenericJobObject->getResultSignature();
|
||||
$model->url = $listGenericJobObject->getName();
|
||||
|
||||
return $this->handler($model);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Jobs\Services;
|
||||
|
||||
|
||||
use App\Classes\General\Eloquent\AbstractFetchRecord;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use App\Models\JobResult;
|
||||
|
||||
class FetchesJobResult extends AbstractFetchRecord
|
||||
{
|
||||
|
||||
/** @var JobResult */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* FetchesJobResult constructor.
|
||||
* @param JobResult $repository
|
||||
*/
|
||||
public function __construct(JobResult $repository)
|
||||
{
|
||||
$this->repository = $repository;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return Builder
|
||||
*/
|
||||
public function getRepository(): Builder
|
||||
{
|
||||
return $this->repository->newQuery();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Jobs\Services;
|
||||
|
||||
|
||||
use App\Classes\General\Eloquent\AbstractListRecord;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use App\Models\JobResult;
|
||||
|
||||
class ListsJobResult extends AbstractListRecord
|
||||
{
|
||||
|
||||
/** @var JobResult */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* ListsJobResult constructor.
|
||||
* @param JobResult $repository
|
||||
*/
|
||||
public function __construct(JobResult $repository)
|
||||
{
|
||||
$this->repository = $repository;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return Builder
|
||||
*/
|
||||
function getRepository(): Builder
|
||||
{
|
||||
return $this->repository->newQuery();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Jobs\Services;
|
||||
|
||||
use App\Classes\General\Eloquent\AbstractUpdateRecord;
|
||||
use App\Classes\Modules\Jobs\DataTransferObjects\UpdateJobResultObject;
|
||||
use App\Models\JobResult;
|
||||
|
||||
class UpdatesJobResult extends AbstractUpdateRecord
|
||||
{
|
||||
|
||||
/**
|
||||
* @param JobResult $model
|
||||
* @param UpdateJobResultObject $updateJobResultObject
|
||||
* @return \Illuminate\Database\Eloquent\Model
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
*/
|
||||
public function execute(JobResult $model, UpdateJobResultObject $updateJobResultObject) {
|
||||
|
||||
$model->result = $updateJobResultObject->getResult();
|
||||
$model->result_signature = $updateJobResultObject->getResultSignature();
|
||||
$model->job_command_name = $updateJobResultObject->getJobCommandName();
|
||||
$model->job_command = $updateJobResultObject->getJobCommand();
|
||||
|
||||
return $this->handler($model);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -53,8 +53,12 @@ class FetchOrderV2Logic extends AbstractControllerLogic
|
||||
|
||||
$query = $this->fetchesOrder->execute(['reference' => $request->route('id'), 'with_packing_lists' => true]);
|
||||
|
||||
if($request->input('storages')){
|
||||
$query->storages = $request->input('storages'); //from middleware
|
||||
}
|
||||
|
||||
return $this->resourceResponse(new OrderV2Resource($query));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ class UpdateDoFromYDPortalProcessor
|
||||
*/
|
||||
public function execute(PackingList $packingList) {
|
||||
Log::info('Trying to Call UpdateDoFromYDPortalProcessor');
|
||||
Log::channel('storage_invoices')->info('UpdateDoFromYDPortalProcessor: '.json_encode($packingList));
|
||||
|
||||
if(!app()->environment(['production'])){
|
||||
return;
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace App\Classes\Modules\PackingLists\ControllersLogic;
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Jobs\ListPackingListsJob;
|
||||
use App\Classes\Modules\Jobs\DataTransferObjects\ListGenericJobObject;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use App\Classes\Modules\Jobs\Services\CreatesJobResult;
|
||||
|
||||
class ListPackingListsJobLogic extends AbstractControllerLogic
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function notification():array {
|
||||
return [
|
||||
'title' => 'Job Retrieving PackingLists',
|
||||
'message' => 'You have successfully submit a job to retrieve a list of PackingLists'
|
||||
];
|
||||
}
|
||||
|
||||
/** @var CreatesJobResult */
|
||||
private $createsJobResult;
|
||||
|
||||
/**
|
||||
* ListPackingListsJobLogic constructor.
|
||||
* @param CreatesJobResult $createsJobResult
|
||||
*/
|
||||
public function __construct(CreatesJobResult $createsJobResult)
|
||||
{
|
||||
$this->createsJobResult = $createsJobResult;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function logic(Request $request) : JsonResponse
|
||||
{
|
||||
$jobId = uniqid();
|
||||
|
||||
$user = Auth::user();
|
||||
$userInfo = (object) [
|
||||
// 'email' => $user->email,
|
||||
'type' => $user->type,
|
||||
];
|
||||
|
||||
|
||||
$userInfoJson = json_encode($userInfo);
|
||||
$requestSignature = md5($userInfoJson . $request->fullUrl());
|
||||
|
||||
|
||||
$listGenericJobObject = new ListGenericJobObject(
|
||||
$request->fullUrl(),
|
||||
$request->all(),
|
||||
$requestSignature,
|
||||
null,
|
||||
$jobId,
|
||||
$userInfo
|
||||
);
|
||||
|
||||
ListPackingListsJob::dispatch($listGenericJobObject);
|
||||
|
||||
$result = [];
|
||||
$result['job_id'] = $jobId;
|
||||
|
||||
|
||||
$this->createsJobResult->execute($listGenericJobObject);
|
||||
|
||||
return $this->response(['data' => $result]);
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -121,7 +121,7 @@ class FetchContainersFromYdPortalProcessor
|
||||
$containerReference = explode('预计到港时间', $tracking[1])[0];
|
||||
$loadingDate = Carbon::parse($trackingRow->trackingtime);
|
||||
$etd = Carbon::parse($tracking[2])->subDays(5);
|
||||
$eta = Carbon::parse($tracking[2])->addDays(2);
|
||||
$eta = Carbon::parse($tracking[2]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-1
@@ -147,7 +147,6 @@ class FetchContainersUpdatesFromYdPortalProcessor
|
||||
|
||||
if($delayDate){
|
||||
|
||||
$delayDate = $delayDate->addDays(2);
|
||||
$transport = $container->transports()->first();
|
||||
|
||||
if(!$transport->schedules()->whereDate('eta', '>=', $delayDate)->first()) {
|
||||
|
||||
+2
-2
@@ -162,7 +162,7 @@ class FetchLoadedContainersFromVTPortalProcessor
|
||||
$container = $this->createContainerProcessor->execute($containerObject, $originWarehouse);
|
||||
}
|
||||
|
||||
$eta = Carbon::parse($containerInfo[4])->addDays(2);
|
||||
$eta = Carbon::parse($containerInfo[4]);
|
||||
$etd = Carbon::parse($eta)->subDays(7);
|
||||
|
||||
$delayDate = $containerInfo[7];
|
||||
@@ -183,7 +183,7 @@ class FetchLoadedContainersFromVTPortalProcessor
|
||||
}
|
||||
|
||||
if($delayDate){
|
||||
$delayDate = Carbon::parse($delayDate)->addDays(2);
|
||||
$delayDate = Carbon::parse($delayDate);
|
||||
$transport = $container->transports()->first();
|
||||
|
||||
if(!$transport->schedules()->where('eta', '=', $delayDate)->first()) {
|
||||
|
||||
+2
-2
@@ -199,7 +199,7 @@ class FetchOrderListsFromYdPortalProcessor
|
||||
$containerReference = explode('预计到港时间', $tracking[1])[0];
|
||||
$loadingDate = Carbon::parse($trackingRow->trackingtime);
|
||||
$etd = Carbon::parse($tracking[2])->subDays(5);
|
||||
$eta = Carbon::parse($tracking[2])->addDays(2);
|
||||
$eta = Carbon::parse($tracking[2]);
|
||||
}
|
||||
|
||||
$rescheduleETD = strpos($trackingRow->remark, '开') || strpos($trackingRow->remark, '到港');
|
||||
@@ -415,7 +415,7 @@ class FetchOrderListsFromYdPortalProcessor
|
||||
}
|
||||
|
||||
if($delayDate){
|
||||
$delayDate = $delayDate->addDays(2);
|
||||
$delayDate = $delayDate;
|
||||
$transport = $container->transports()->first();
|
||||
|
||||
if(!$transport->schedules()->whereDate('eta', '>=', $delayDate)->first()) {
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\PackingLists\Processors;
|
||||
|
||||
|
||||
use App\Classes\Modules\PackingLists\Services\ListsPackingLists;
|
||||
use App\Classes\Modules\Jobs\Processors\UpdateJobResultProcessor;
|
||||
use App\Classes\General\Helper;
|
||||
use App\Classes\Modules\Jobs\DataTransferObjects\ListGenericJobObject;
|
||||
use App\Http\Resources\ListPackingListJobResource;
|
||||
|
||||
class ListPackingListsJobProcessor
|
||||
{
|
||||
|
||||
/** @var ListsPackingLists */
|
||||
private $listsPackingLists;
|
||||
|
||||
/** @var UpdateJobResultProcessor */
|
||||
private $updateJobResultProcessor;
|
||||
|
||||
/**
|
||||
* ListPackingListsJobProcessor constructor.
|
||||
* @param ListsPackingLists $listsPackingLists
|
||||
* @param UpdateJobResultProcessor $updateJobResultProcessor
|
||||
*/
|
||||
public function __construct(ListsPackingLists $listsPackingLists, UpdateJobResultProcessor $updateJobResultProcessor)
|
||||
{
|
||||
$this->listsPackingLists = $listsPackingLists;
|
||||
$this->updateJobResultProcessor = $updateJobResultProcessor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ListGenericJobObject $listGenericJobObject
|
||||
* @return void
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
* @throws \App\Classes\Exceptions\JobResourceNotFoundException
|
||||
*/
|
||||
public function execute(ListGenericJobObject $listGenericJobObject) {
|
||||
|
||||
// $query = $this->listsPackingLists->execute($this->listsPackingLists->deserializeFilters($listGenericJobObject->getPayload()['filters']), ['page' => $listGenericJobObject->getPayload()['page'], 'with_containers_packages' => true]);
|
||||
|
||||
$query = $this->listsPackingLists->execute(array_merge($this->listsPackingLists->deserializeFilters($listGenericJobObject->getPayload()['filters']), ['page' => $listGenericJobObject->getPayload()['page'], 'with_containers_packages' => true]));
|
||||
|
||||
foreach ($query->items() as &$item) {
|
||||
$item['userInfo'] = $listGenericJobObject->getUserInfo();
|
||||
}
|
||||
$resultCurrent = Helper::collectionResponse(ListPackingListJobResource::collection($query));
|
||||
$this->updateJobResultProcessor->execute($listGenericJobObject, $resultCurrent);
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,8 @@ use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Models\GroupTransaction;
|
||||
use App\Http\Resources\WalletTransactionResource;
|
||||
use App\Models\Wallet;
|
||||
use App\Classes\Modules\Transactions\Processors\ReleaseGoodsToCustomerProcessor;
|
||||
|
||||
|
||||
class CreateGroupsLogic extends AbstractControllerLogic
|
||||
{
|
||||
@@ -55,13 +57,18 @@ class CreateGroupsLogic extends AbstractControllerLogic
|
||||
/** @var CreatesGroup */
|
||||
private $createsGroup;
|
||||
|
||||
/** @var ReleaseGoodsToCustomerProcessor */
|
||||
private $releaseGoodsToCustomerProcessor;
|
||||
|
||||
|
||||
public function __construct(
|
||||
FetchesTransaction $fetchesTransaction,
|
||||
GeneratesTransactionBillNumber $generatesTransactionBillNumber,
|
||||
FetchesTransaction $fetchesTransaction,
|
||||
GeneratesTransactionBillNumber $generatesTransactionBillNumber,
|
||||
FetchesCompanyModule $fetchesCompanyModule,
|
||||
CreateWalletTopUpTransactionProcessor $createWalletTopUpTransactionProcessor,
|
||||
CreatePaymentTransactionProcessor $createPaymentTransactionProcessor,
|
||||
CreatesGroup $createsGroup
|
||||
CreatesGroup $createsGroup,
|
||||
ReleaseGoodsToCustomerProcessor $releaseGoodsToCustomerProcessor
|
||||
)
|
||||
{
|
||||
$this->fetchesTransaction = $fetchesTransaction;
|
||||
@@ -70,6 +77,7 @@ class CreateGroupsLogic extends AbstractControllerLogic
|
||||
$this->createWalletTopUpTransactionProcessor = $createWalletTopUpTransactionProcessor;
|
||||
$this->createPaymentTransactionProcessor = $createPaymentTransactionProcessor;
|
||||
$this->createsGroup = $createsGroup;
|
||||
$this->releaseGoodsToCustomerProcessor = $releaseGoodsToCustomerProcessor;
|
||||
}
|
||||
|
||||
public function logic(Request $request) : JsonResponse
|
||||
@@ -146,7 +154,12 @@ class CreateGroupsLogic extends AbstractControllerLogic
|
||||
|
||||
foreach ($invoices as $invoice) {
|
||||
if ($payment_method == PaymentMethodType::WALLET) {
|
||||
$this->createPaymentTransactionProcessor->execute($invoice, PaymentMethodType::WALLET, $request->input('bank_code'));
|
||||
$paymentTransaction = $this->createPaymentTransactionProcessor->execute($invoice, PaymentMethodType::WALLET, $request->input('bank_code'), false);
|
||||
|
||||
if($paymentTransaction && $paymentTransaction->status == ApprovalStatus::APPROVED){
|
||||
$pL = $invoice->owner;
|
||||
$this->releaseGoodsToCustomerProcessor->execute($pL, $invoice);
|
||||
}
|
||||
}
|
||||
|
||||
$issuer = $invoice->issuer;
|
||||
|
||||
+17
-2
@@ -10,6 +10,8 @@ use App\Http\Resources\TransactionResource;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Classes\Modules\Transactions\Processors\CreatePaymentTransactionProcessor;
|
||||
use App\Classes\Modules\Transactions\Processors\ReleaseGoodsToCustomerProcessor;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
|
||||
class CreatePaymentTransactionLogic extends AbstractControllerLogic
|
||||
{
|
||||
@@ -30,13 +32,18 @@ class CreatePaymentTransactionLogic extends AbstractControllerLogic
|
||||
/** @var CreatePaymentTransactionProcessor */
|
||||
private $createPaymentTransactionProcessor;
|
||||
|
||||
/** @var ReleaseGoodsToCustomerProcessor */
|
||||
private $releaseGoodsToCustomerProcessor;
|
||||
|
||||
public function __construct(
|
||||
FetchesTransaction $fetchesTransaction,
|
||||
CreatePaymentTransactionProcessor $createPaymentTransactionProcessor
|
||||
CreatePaymentTransactionProcessor $createPaymentTransactionProcessor,
|
||||
ReleaseGoodsToCustomerProcessor $releaseGoodsToCustomerProcessor
|
||||
)
|
||||
{
|
||||
$this->fetchesTransaction = $fetchesTransaction;
|
||||
$this->createPaymentTransactionProcessor = $createPaymentTransactionProcessor;
|
||||
$this->releaseGoodsToCustomerProcessor = $releaseGoodsToCustomerProcessor;
|
||||
}
|
||||
|
||||
public function logic(Request $request) : JsonResponse
|
||||
@@ -45,7 +52,12 @@ class CreatePaymentTransactionLogic extends AbstractControllerLogic
|
||||
|
||||
$invoice_transaction = $this->fetchesTransaction->execute(['id' => $request->input('transaction_id')]);
|
||||
|
||||
$payment_transaction = $this->createPaymentTransactionProcessor->execute($invoice_transaction, $payment_method , $request->input('bank_code'));
|
||||
$payment_transaction = $this->createPaymentTransactionProcessor->execute($invoice_transaction, $payment_method , $request->input('bank_code'), false);
|
||||
|
||||
if($payment_transaction && $payment_transaction->status == ApprovalStatus::APPROVED){
|
||||
$pL = $invoice_transaction->owner;
|
||||
$this->releaseGoodsToCustomerProcessor->execute($pL, $invoice_transaction);
|
||||
}
|
||||
|
||||
//cief todo: at exchange there is a transition step - starts
|
||||
// if(PaymentMethodType::PAYMENT_METHODS[$request->input('payment_method')] == PaymentMethodType::PAYMENT_GATEWAY){
|
||||
@@ -63,4 +75,7 @@ class CreatePaymentTransactionLogic extends AbstractControllerLogic
|
||||
|
||||
return $this->resourceResponse(new TransactionResource($payment_transaction));
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -5,10 +5,11 @@ namespace App\Classes\Modules\Transactions\ControllersLogic;
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Transactions\Services\ListsTransactions;
|
||||
use App\Http\Resources\BookingResource;
|
||||
use App\Http\Resources\TransactionResource;
|
||||
use App\Http\Resources\TransactionWithStorageResource;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
|
||||
class ListTransactionsLogic extends AbstractControllerLogic
|
||||
{
|
||||
@@ -38,13 +39,18 @@ class ListTransactionsLogic extends AbstractControllerLogic
|
||||
|
||||
public function logic(Request $request) : JsonResponse
|
||||
{
|
||||
|
||||
$query = $this->listsTransactions->execute($this->listsTransactions->deserializeFilters($request->input('filters')));
|
||||
|
||||
return $this->collectionResponse(TransactionResource::collection($query));
|
||||
if($request->input('storages')){
|
||||
foreach ($query->items() as &$item) {
|
||||
$transactionId = $item['id'];
|
||||
$filteredStorages = array_filter($request->input('storages'), function ($storage) use ($transactionId) {
|
||||
return isset($storage['parentInvoiceId']) && $storage['parentInvoiceId'] == $transactionId;
|
||||
});
|
||||
$item['storages'] = $filteredStorages;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->collectionResponse(TransactionWithStorageResource::collection($query));
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
+12
-2
@@ -17,6 +17,8 @@ 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\Models\Order;
|
||||
|
||||
class ApproveShippingInvoiceTransactionProcessor
|
||||
{
|
||||
@@ -30,17 +32,21 @@ class ApproveShippingInvoiceTransactionProcessor
|
||||
/** @var CreatesFiles */
|
||||
private $createsFiles;
|
||||
|
||||
/** @var CheckStorageInvoiceTransactionProcessor */
|
||||
private $storageInvoiceTransactionProcessor;
|
||||
|
||||
|
||||
/**
|
||||
* @param UpdatesTransactionStatus $updatesTransactionStatus
|
||||
* @param CreatesDocument $createsDocument
|
||||
* @param CreatesFiles $createsFiles
|
||||
*/
|
||||
public function __construct(UpdatesTransactionStatus $updatesTransactionStatus, CreatesDocument $createsDocument, CreatesFiles $createsFiles)
|
||||
public function __construct(UpdatesTransactionStatus $updatesTransactionStatus, CreatesDocument $createsDocument, CreatesFiles $createsFiles, CheckStorageInvoiceTransactionProcessor $storageInvoiceTransactionProcessor)
|
||||
{
|
||||
$this->updatesTransactionStatus = $updatesTransactionStatus;
|
||||
$this->createsDocument = $createsDocument;
|
||||
$this->createsFiles = $createsFiles;
|
||||
$this->storageInvoiceTransactionProcessor = $storageInvoiceTransactionProcessor;
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +56,6 @@ class ApproveShippingInvoiceTransactionProcessor
|
||||
*/
|
||||
public function execute(PackingList $packingList)
|
||||
{
|
||||
|
||||
/** @var Transaction $invoice_transaction */
|
||||
$invoice_transaction = $packingList->transactions()->where('transactions.type', TransactionType::SHIPPING_INVOICE)->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::PENDING_SUBMISSION])->first();
|
||||
|
||||
@@ -75,6 +80,11 @@ class ApproveShippingInvoiceTransactionProcessor
|
||||
$user->notify(new InvoiceIssuedEmail($user, $packingList));
|
||||
}
|
||||
|
||||
$order = $packingList->owner()->first();
|
||||
if($order instanceof Order){
|
||||
$this->storageInvoiceTransactionProcessor->executeOrder($order);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+372
@@ -0,0 +1,372 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace App\Classes\Modules\Transactions\Processors;
|
||||
|
||||
use App\Classes\Exceptions\MalformedRequestException;
|
||||
use App\Classes\Modules\Orders\Services\FetchesOrder;
|
||||
use App\Classes\Modules\Transactions\Services\GeneratesTransactionBillNumber;
|
||||
use App\Classes\Modules\Transactions\Services\CreatesTransaction;
|
||||
use App\Classes\Modules\Transactions\Services\CreatesTransactionDetail;
|
||||
use App\Classes\Modules\Transactions\Services\UpdatesTransaction;
|
||||
use App\Classes\Modules\Transactions\Services\FetchesTransaction;
|
||||
use App\Classes\Modules\Transactions\Services\UpdatesTransactionDetail;
|
||||
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
|
||||
use App\Classes\Modules\Transactions\Services\DeletesGroup;
|
||||
use App\Classes\Modules\Billplzs\Services\DeletesBillplzBill;
|
||||
use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject;
|
||||
use App\Classes\Modules\Transactions\DataTransferObjects\TransactionDetailObject;
|
||||
|
||||
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Classes\ValueObjects\Constants\PaymentMethodType;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\PackageType;
|
||||
use App\Classes\ValueObjects\Constants\PackingListType;
|
||||
use App\Classes\ValueObjects\Constants\TransactionDetailType;
|
||||
use App\Http\Resources\TransactionWithStorageResource;
|
||||
use App\Models\Order;
|
||||
use App\Models\PackingList;
|
||||
use App\Models\Transaction;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
|
||||
class CheckStorageInvoiceTransactionProcessor
|
||||
{
|
||||
/** @var FetchesOrder */
|
||||
private $fetchesOrder;
|
||||
|
||||
/** @var GeneratesTransactionBillNumber */
|
||||
private $generatesTransactionBillNumber;
|
||||
|
||||
/** @var FetchesTransaction */
|
||||
private $fetchesTransaction;
|
||||
|
||||
/** @var CreatesTransaction */
|
||||
private $createsTransaction;
|
||||
|
||||
/** @var CreatesTransactionDetail */
|
||||
private $createsTransactionDetail;
|
||||
|
||||
/** @var UpdatesTransaction */
|
||||
private $updatesTransaction;
|
||||
|
||||
/** @var UpdatesTransactionDetail */
|
||||
private $updatesTransactionDetail;
|
||||
|
||||
/** @var UpdatesTransactionStatus */
|
||||
private $updatesTransactionStatus;
|
||||
|
||||
/** @var DeletesGroup */
|
||||
private $deletesGroup;
|
||||
|
||||
/** @var DeletesBillplzBill */
|
||||
private $deletesBillplzBill;
|
||||
|
||||
/**
|
||||
* @param FetchesOrder $fetchesOrder
|
||||
* @param GeneratesTransactionBillNumber $generatesTransactionBillNumber
|
||||
* @param FetchesTransaction $fetchesTransaction
|
||||
* @param CreatesTransaction $createsTransaction
|
||||
* @param CreatesTransactionDetail $createsTransactionDetail
|
||||
* @param UpdatesTransaction $updatesTransaction
|
||||
* @param UpdatesTransactionDetail $updatesTransactionDetail
|
||||
* @param UpdatesTransactionStatus $updatesTransactionStatus
|
||||
* @param DeletesGroup $deletesGroup
|
||||
* @param DeletesBillplzBill $deletesBillplzBill
|
||||
*/
|
||||
public function __construct(FetchesOrder $fetchesOrder, GeneratesTransactionBillNumber $generatesTransactionBillNumber, FetchesTransaction $fetchesTransaction, CreatesTransaction $createsTransaction, CreatesTransactionDetail $createsTransactionDetail, UpdatesTransaction $updatesTransaction, UpdatesTransactionDetail $updatesTransactionDetail, UpdatesTransactionStatus $updatesTransactionStatus, DeletesGroup $deletesGroup, DeletesBillplzBill $deletesBillplzBill)
|
||||
{
|
||||
$this->fetchesOrder = $fetchesOrder;
|
||||
$this->generatesTransactionBillNumber = $generatesTransactionBillNumber;
|
||||
$this->fetchesTransaction = $fetchesTransaction;
|
||||
$this->createsTransaction = $createsTransaction;
|
||||
$this->createsTransactionDetail = $createsTransactionDetail;
|
||||
$this->updatesTransaction = $updatesTransaction;
|
||||
$this->updatesTransactionDetail = $updatesTransactionDetail;
|
||||
$this->updatesTransactionStatus = $updatesTransactionStatus;
|
||||
$this->deletesGroup = $deletesGroup;
|
||||
$this->deletesBillplzBill = $deletesBillplzBill;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws MalformedRequestException
|
||||
*/
|
||||
public function execute(int $orderReference)
|
||||
{
|
||||
$order = $this->fetchesOrder->execute(['reference' => $orderReference, 'with_packing_lists' => true]);
|
||||
return $this->executeOrder($order);
|
||||
}
|
||||
|
||||
public function executeOrder(Order $order, bool $isBackDoorCheck = false){
|
||||
$results = [];
|
||||
$marking = $order->companyModule->inviters()->withPivot('invitee_reference')->first()->pivot->invitee_reference;
|
||||
$is_credit_term = $order->companyModule->inviters()->withPivot('is_credit_term')->first()->pivot->is_credit_term;
|
||||
if(!$is_credit_term){
|
||||
Log::channel('storage_invoices')->info('orderId: '.$order->id.', orderReference: '.$order->reference.', marking: '.$marking.', is_credit_term: '.$is_credit_term);
|
||||
$packingLists = $order->destinationWarehousePackages;
|
||||
|
||||
foreach ($packingLists as $packingList){
|
||||
$arrivalDateAtChinaWarehouse = $this->getArrivalDateAtChinaWarehoue($packingList);
|
||||
Log::channel('storage_invoices')->info('arrivalDateAtChinaWarehouse: '.json_encode($arrivalDateAtChinaWarehouse));
|
||||
Log::channel('storage_invoices')->info('destinationWarehousePackage: '.json_encode($packingList));
|
||||
$eta = $this->getEtaFromPackingList($packingList);
|
||||
if($arrivalDateAtChinaWarehouse && $eta){
|
||||
$transactions = $packingList->transactions()->where('transactions.type', TransactionType::SHIPPING_INVOICE)->whereIn('transactions.status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->get();
|
||||
// $transactions = $destinationWarehousePackage->transactions()->where('transactions.type', TransactionType::SHIPPING_INVOICE)->where('transactions.status', ApprovalStatus::APPROVED)->get();
|
||||
|
||||
/** @var Transaction $invoice_transaction */
|
||||
foreach ($transactions as $invoice_transaction){
|
||||
$result = $this->processSingleTransactionOfTypeShippingInvoice($invoice_transaction, $packingList, $order->company_module_id, $eta, $isBackDoorCheck);
|
||||
if($result){
|
||||
$results[] = $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $results;
|
||||
}
|
||||
|
||||
private function getArrivalDateAtChinaWarehoue($packingList){
|
||||
if($packingList->type === PackingListType::SHIPPING_PACKING_LIST){
|
||||
$receive_packing_list = PackingList::where('reference', $packingList->reference)->where('type', PackingListType::WAREHOUSE_RECEIVE_LIST)->first();
|
||||
Log::channel('storage_invoices')->info('receive_packing_list: '.json_encode($receive_packing_list->transports));
|
||||
$transport = $receive_packing_list->transports->first();
|
||||
if ($transport) {
|
||||
$arrivalDateAtChinaWarehouse = Carbon::parse($transport->drop_date);
|
||||
$dateToCompare = Carbon::parse(env('STORAGE_FEE_LAUNCH_DATE', '2023-12-11 00:00:00'));
|
||||
// dd($dateToCompare);
|
||||
if ($arrivalDateAtChinaWarehouse->isAfter($dateToCompare)) {
|
||||
Log::channel('storage_invoices')->info('transport: '.json_encode($transport));
|
||||
Log::channel('storage_invoices')->info('dateToCompare: '.$dateToCompare.', arrivalDateAtChinaWarehouse: '.$arrivalDateAtChinaWarehouse);
|
||||
return $arrivalDateAtChinaWarehouse;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private function getEtaFromPackingList($packingList){
|
||||
if ($packingList) {
|
||||
$package = $packingList->packages->first();
|
||||
if ($package) {
|
||||
$container = $package->container()->first();
|
||||
if ($container) {
|
||||
$transport = $container->transports->first();
|
||||
if ($transport) {
|
||||
$schedule = $transport->schedules->last();
|
||||
if ($schedule) {
|
||||
return $schedule->eta;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private function processSingleTransactionOfTypeShippingInvoice($transaction, $destinationWarehousePackage, $company_module_id, $eta, $isBackDoorCheck){
|
||||
$pricePerCBM = 3;
|
||||
$resultNumberOfDaysFree = 10;
|
||||
$dt1 = $eta->copy()->addDay()->startOfDay();
|
||||
$resultStartDate = $dt1->format('Y-m-d');
|
||||
$currentDatetime = Carbon::now();
|
||||
$dt2 = $currentDatetime->copy()->addDay()->startOfDay();
|
||||
$resultCurrentDate = $dt2->format('Y-m-d H:i:s');
|
||||
$interval = Carbon::parse($dt2)->diff($dt1);
|
||||
|
||||
$resultNumberOfDaysExceeded = $interval->days - $resultNumberOfDaysFree;
|
||||
$storageInvoice = $destinationWarehousePackage->transactions()->where('transactions.type', TransactionType::STORAGE_INVOICE)->first();
|
||||
$storageInvoiceId = 0;
|
||||
$transactionDetailsItems = $transaction->transactionDetails()->get();
|
||||
$cbm = 0.00;
|
||||
foreach ($transactionDetailsItems as $tdItem){
|
||||
$quantity = $tdItem->quantity;
|
||||
if($tdItem->price < 0.00){
|
||||
$quantity = $quantity * -1;
|
||||
}
|
||||
$cbm = $cbm + $quantity;
|
||||
}
|
||||
|
||||
$price_cbm = $pricePerCBM * $cbm * $resultNumberOfDaysExceeded;
|
||||
Log::channel('storage_invoices')->info('storageInvoice: '.json_encode($storageInvoice).', $transaction->status: '.$transaction->status);
|
||||
if(!$storageInvoice && $resultNumberOfDaysExceeded > 0 && $transaction->status != ApprovalStatus::COMPLETED){
|
||||
Log::channel('storage_invoices')->info('Created $transaction->id: '.$transaction->id);
|
||||
$billNumber = $this->generatesTransactionBillNumber->execute('STOR-');
|
||||
$storageInvoice = $this->createStorageInvoiceTransaction($destinationWarehousePackage, $billNumber, $company_module_id, $price_cbm);
|
||||
$storageInvoiceId = $storageInvoice->id;
|
||||
$this->createStorageInvoiceTransactionDetails($storageInvoice, $destinationWarehousePackage, $cbm, $pricePerCBM, $resultNumberOfDaysExceeded);
|
||||
}
|
||||
else if($storageInvoice){
|
||||
//Additional handling for giving selected storage invoice a waiver
|
||||
if(isset($storageInvoice->is_waived) && $storageInvoice->is_waived){
|
||||
$pricePerCBM = 0;
|
||||
$price_cbm = $pricePerCBM * $cbm * $resultNumberOfDaysExceeded;
|
||||
}
|
||||
|
||||
//Additional handling for calculation of numberOfDaysExceeded in the event of the storage already paid
|
||||
$paymentStorageTransaction = $storageInvoice->transactions()->where('transactions.type', TransactionType::PAYMENT)->where('transactions.status', ApprovalStatus::APPROVED)->first();
|
||||
if($paymentStorageTransaction){
|
||||
$dateStorageInvoicePaid = $paymentStorageTransaction->created_at->copy()->addDay()->startOfDay();
|
||||
Log::channel('storage_invoices')->info('dateStorageInvoicePaid: '.$dateStorageInvoicePaid.', resultCurrentDate: '.$resultCurrentDate);
|
||||
$intervalRecalculate = Carbon::parse($dateStorageInvoicePaid)->diff($dt1);
|
||||
$resultNumberOfDaysExceeded = $intervalRecalculate->days - $resultNumberOfDaysFree;
|
||||
$price_cbm = $pricePerCBM * $cbm * $resultNumberOfDaysExceeded;
|
||||
}
|
||||
|
||||
$amount = $storageInvoice->amount;
|
||||
$epsilon = 0.0001; // Tolerance for the comparison
|
||||
Log::channel('storage_invoices')->info('Update $transaction->id: '.$transaction->id);
|
||||
Log::channel('storage_invoices')->info('$storageInvoice->status: '.$storageInvoice->status);
|
||||
Log::channel('storage_invoices')->info('price_cbm: '.$price_cbm."-".gettype($price_cbm));
|
||||
Log::channel('storage_invoices')->info('amount: '.$amount);
|
||||
|
||||
$proceedToUpdate = false;
|
||||
|
||||
if(abs($price_cbm - $amount) > $epsilon && $storageInvoice->status !== ApprovalStatus::COMPLETED){
|
||||
$paymentTransactions = $storageInvoice->transactions()->where('transactions.type', TransactionType::PAYMENT)->where('transactions.status', ApprovalStatus::PENDING_SUBMISSION)->get();
|
||||
if(!$isBackDoorCheck){
|
||||
if(count($paymentTransactions) > 0){
|
||||
$this->updatePaymentTransactionViaNonGroupPayment($paymentTransactions);
|
||||
}
|
||||
else{
|
||||
$this->updatePaymentTransactionViaGroupPayment($storageInvoice);
|
||||
}
|
||||
}
|
||||
|
||||
$proceedToUpdate = true;
|
||||
}
|
||||
|
||||
if($proceedToUpdate || ($pricePerCBM == 0 && $amount != 0)){
|
||||
Log::channel('storage_invoices')->info('proceedToUpdate');
|
||||
$storageInvoice = $this->updateStorageInvoiceTransaction($storageInvoice, $price_cbm);
|
||||
$invoiceTransactionDetails = $storageInvoice->transactionDetails()->first();
|
||||
$this->updateStorageInvoiceTransactionDetails($invoiceTransactionDetails, $destinationWarehousePackage, $cbm, $pricePerCBM, $resultNumberOfDaysExceeded);
|
||||
}
|
||||
|
||||
$storageInvoiceId = $storageInvoice->id;
|
||||
}
|
||||
|
||||
if($storageInvoiceId !== 0){
|
||||
$result = [
|
||||
'parentInvoiceId' => $transaction->id,
|
||||
'storageInvoiceId' => $storageInvoiceId,
|
||||
'numberOfDaysExceeded' => $resultNumberOfDaysExceeded,
|
||||
'numberOfDaysFree' => $resultNumberOfDaysFree,
|
||||
'startDate' => $resultStartDate,
|
||||
'currentDate' => $resultCurrentDate,
|
||||
'cbm' => $cbm,
|
||||
'pricePerCBM' => $pricePerCBM,
|
||||
'storageInvoice' => new TransactionWithStorageResource($storageInvoice)
|
||||
];
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function updatePaymentTransactionViaGroupPayment($storageInvoice){
|
||||
Log::channel('storage_invoices')->info('updatePaymentTransactionViaGroupPayment');
|
||||
$groups = $storageInvoice->groups()->get();
|
||||
foreach ($groups as $grp){
|
||||
$groupReference = $grp->reference;
|
||||
$walletTransaction = $this->fetchesTransaction->execute(['payment_reference' => $groupReference]);
|
||||
if($walletTransaction->status === ApprovalStatus::PENDING_SUBMISSION || $walletTransaction->status === ApprovalStatus::PENDING_VERIFICATION){
|
||||
$grp->status = ApprovalStatus::EXPIRED;
|
||||
$grp->save();
|
||||
$this->deletesGroup->execute($grp);
|
||||
$this->updatesTransactionStatus->execute($walletTransaction, ApprovalStatus::EXPIRED);
|
||||
if($walletTransaction->payment_reference){
|
||||
$deletedBillplzBill = $this->deletesBillplzBill->execute($walletTransaction->payment_reference);
|
||||
Log::channel('storage_invoices')->info('deletedBillplzBill TransactionType::WALLET: '.json_encode($deletedBillplzBill));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function updatePaymentTransactionViaNonGroupPayment($paymentTransactions){
|
||||
Log::channel('storage_invoices')->info('updatePaymentTransactionViaNonGroupPayment');
|
||||
foreach ($paymentTransactions as $paymentTransaction){
|
||||
$this->updatesTransactionStatus->execute($paymentTransaction, ApprovalStatus::EXPIRED);
|
||||
if($paymentTransaction->payment_reference){
|
||||
$deletedBillplzBill = $this->deletesBillplzBill->execute($paymentTransaction->payment_reference);
|
||||
Log::channel('storage_invoices')->info('deletedBillplzBill TransactionType::WALLET: '.json_encode($deletedBillplzBill));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function updateStorageInvoiceTransaction(Transaction $transaction, float $totalAmount){
|
||||
|
||||
$object = new TransactionObject(
|
||||
$transaction->bill_no,
|
||||
TransactionType::STORAGE_INVOICE,
|
||||
1,
|
||||
$transaction->receiver,
|
||||
1,
|
||||
PaymentMethodType::CASH,
|
||||
$totalAmount,
|
||||
$totalAmount,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
null,
|
||||
ApprovalStatus::APPROVED
|
||||
);
|
||||
|
||||
/** @var Transaction $invoice_transaction */
|
||||
$invoice_transaction = $this->updatesTransaction->execute($transaction, $object);
|
||||
|
||||
return $invoice_transaction;
|
||||
}
|
||||
|
||||
private function updateStorageInvoiceTransactionDetails($invoice_transaction_details, PackingList $packing_list, $cbm, $pricePerCBM, $numberOfDays){
|
||||
$object_detail = new TransactionDetailObject(
|
||||
'STORAGE_FEE',
|
||||
TransactionDetailType::STORAGE_FEE.' for '.$numberOfDays. ' days * RM'.$pricePerCBM.'<br>'.round($packing_list->packages->where('type', '!=', PackageType::OVER_WEIGHT)->sum('quantity'), 3).' CTNS - '.round($cbm, 3).' CBM',
|
||||
$cbm,
|
||||
$pricePerCBM * $numberOfDays
|
||||
);
|
||||
|
||||
$this->updatesTransactionDetail->execute($invoice_transaction_details, $object_detail);
|
||||
}
|
||||
|
||||
private function createStorageInvoiceTransaction(PackingList $packing_list, string $billNumber, int $companyModuleId, float $totalAmount){
|
||||
|
||||
$object = new TransactionObject(
|
||||
$billNumber,
|
||||
TransactionType::STORAGE_INVOICE,
|
||||
1,
|
||||
$companyModuleId,
|
||||
1,
|
||||
PaymentMethodType::CASH,
|
||||
$totalAmount,
|
||||
$totalAmount,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
null,
|
||||
ApprovalStatus::APPROVED
|
||||
);
|
||||
|
||||
/** @var Transaction $invoice_transaction */
|
||||
$invoice_transaction = $this->createsTransaction->execute($packing_list, $object);
|
||||
|
||||
return $invoice_transaction;
|
||||
}
|
||||
|
||||
private function createStorageInvoiceTransactionDetails($invoice_transaction, PackingList $packing_list, $cbm, $pricePerCBM, $numberOfDays){
|
||||
$object_detail = new TransactionDetailObject(
|
||||
'STORAGE_FEE',
|
||||
TransactionDetailType::STORAGE_FEE.' for '.$numberOfDays. ' days * RM'.$pricePerCBM.'<br>'.round($packing_list->packages->where('type', '!=', PackageType::OVER_WEIGHT)->sum('quantity'), 3).' CTNS - '.round($cbm, 3).' CBM',
|
||||
$cbm,
|
||||
$pricePerCBM * $numberOfDays
|
||||
);
|
||||
|
||||
$this->createsTransactionDetail->execute($invoice_transaction, $object_detail);
|
||||
}
|
||||
}
|
||||
@@ -85,7 +85,7 @@ class CreatePaymentTransactionProcessor
|
||||
/**
|
||||
* @throws MalformedRequestException
|
||||
*/
|
||||
public function execute(Transaction $invoice, $payment_method, $bank_code)
|
||||
public function execute(Transaction $invoice, $payment_method, $bank_code, $run = true)
|
||||
{
|
||||
$amount = $invoice->amount;
|
||||
Log::info($invoice->owner);
|
||||
@@ -127,22 +127,26 @@ class CreatePaymentTransactionProcessor
|
||||
|
||||
$this->updatesWalletBalance->execute($wallet, ($amount * -1));
|
||||
|
||||
$packingList = $invoice->owner;
|
||||
$order = $packingList->owner;
|
||||
$packingList->status = ApprovalStatus::APPROVED;
|
||||
$packingList->save();
|
||||
if($run)
|
||||
{
|
||||
$packingList = $invoice->owner;
|
||||
$order = $packingList->owner;
|
||||
$packingList->status = ApprovalStatus::APPROVED;
|
||||
$packingList->save();
|
||||
|
||||
if(app()->environment('production')){
|
||||
$this->updateDoFromVTPortalProcessor->execute($packingList);
|
||||
$this->updateDoFromYDPortalProcessor->execute($packingList);
|
||||
if(app()->environment('production')){
|
||||
$this->updateDoFromVTPortalProcessor->execute($packingList);
|
||||
$this->updateDoFromYDPortalProcessor->execute($packingList);
|
||||
}
|
||||
}
|
||||
|
||||
// later use this variabke to create a approved payment transaction
|
||||
$approvalStatus = ApprovalStatus::APPROVED;
|
||||
|
||||
// update invoice to completed
|
||||
$this->updatesTransactionStatus->execute($invoice, ApprovalStatus::COMPLETED);
|
||||
|
||||
if($run){
|
||||
$this->updatesTransactionStatus->execute($invoice, ApprovalStatus::COMPLETED);
|
||||
}
|
||||
}
|
||||
else {
|
||||
$payment_method = PaymentMethodType::CASH;
|
||||
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Transactions\Processors;
|
||||
|
||||
|
||||
use App\Classes\Exceptions\MalformedRequestException;
|
||||
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;
|
||||
|
||||
class CreateStorageInvoiceDocTransactionFixProcessor
|
||||
{
|
||||
|
||||
/** @var UpdatesTransactionStatus */
|
||||
private $updatesTransactionStatus;
|
||||
|
||||
/** @var CreatesDocument */
|
||||
private $createsDocument;
|
||||
|
||||
/** @var CreatesFiles */
|
||||
private $createsFiles;
|
||||
|
||||
|
||||
/**
|
||||
* @param UpdatesTransactionStatus $updatesTransactionStatus
|
||||
* @param CreatesDocument $createsDocument
|
||||
* @param CreatesFiles $createsFiles
|
||||
*/
|
||||
public function __construct(UpdatesTransactionStatus $updatesTransactionStatus, CreatesDocument $createsDocument, CreatesFiles $createsFiles)
|
||||
{
|
||||
$this->updatesTransactionStatus = $updatesTransactionStatus;
|
||||
$this->createsDocument = $createsDocument;
|
||||
$this->createsFiles = $createsFiles;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @throws MalformedRequestException
|
||||
*/
|
||||
public function execute(PackingList $packingList)
|
||||
{
|
||||
/** @var Transaction $invoice_transaction */
|
||||
$invoice_transaction = $packingList->transactions()->where('transactions.type', TransactionType::STORAGE_INVOICE)->whereIn('status', [ApprovalStatus::COMPLETED])->first();
|
||||
|
||||
// $this->updatesTransactionStatus->execute($invoice_transaction, ApprovalStatus::APPROVED);
|
||||
|
||||
$transaction_invoice_pdf = LaravelMpdf::loadView('pages.pdfs.shipping_invoice', ['invoice_transaction' => $invoice_transaction]);
|
||||
|
||||
$document_object = new DocumentObject(
|
||||
DocumentType::STORAGE_INVOICE,
|
||||
[chunk_split('data:application/pdf;base64,'.base64_encode($transaction_invoice_pdf->output()))],
|
||||
'',
|
||||
ApprovalStatus::COMPLETED,
|
||||
'storage_invoice'
|
||||
);
|
||||
|
||||
// $invouce_transaction_document = $invoice_transaction->documents()->where('document_type', DocumentType::STORAGE_INVOICE)->first();
|
||||
// if(!$invouce_transaction_document){
|
||||
/** @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));
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Transactions\Processors;
|
||||
|
||||
|
||||
use App\Classes\Exceptions\MalformedRequestException;
|
||||
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;
|
||||
|
||||
class CreateStorageInvoiceDocTransactionProcessor
|
||||
{
|
||||
|
||||
/** @var UpdatesTransactionStatus */
|
||||
private $updatesTransactionStatus;
|
||||
|
||||
/** @var CreatesDocument */
|
||||
private $createsDocument;
|
||||
|
||||
/** @var CreatesFiles */
|
||||
private $createsFiles;
|
||||
|
||||
|
||||
/**
|
||||
* @param UpdatesTransactionStatus $updatesTransactionStatus
|
||||
* @param CreatesDocument $createsDocument
|
||||
* @param CreatesFiles $createsFiles
|
||||
*/
|
||||
public function __construct(UpdatesTransactionStatus $updatesTransactionStatus, CreatesDocument $createsDocument, CreatesFiles $createsFiles)
|
||||
{
|
||||
$this->updatesTransactionStatus = $updatesTransactionStatus;
|
||||
$this->createsDocument = $createsDocument;
|
||||
$this->createsFiles = $createsFiles;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @throws MalformedRequestException
|
||||
*/
|
||||
public function execute(PackingList $packingList)
|
||||
{
|
||||
/** @var Transaction $invoice_transaction */
|
||||
$invoice_transaction = $packingList->transactions()->where('transactions.type', TransactionType::STORAGE_INVOICE)->whereIn('status', [ApprovalStatus::COMPLETED])->first();
|
||||
|
||||
// $this->updatesTransactionStatus->execute($invoice_transaction, ApprovalStatus::APPROVED);
|
||||
|
||||
$transaction_invoice_pdf = LaravelMpdf::loadView('pages.pdfs.shipping_invoice', ['invoice_transaction' => $invoice_transaction]);
|
||||
|
||||
$document_object = new DocumentObject(
|
||||
DocumentType::STORAGE_INVOICE,
|
||||
[chunk_split('data:application/pdf;base64,'.base64_encode($transaction_invoice_pdf->output()))],
|
||||
'',
|
||||
ApprovalStatus::COMPLETED,
|
||||
'storage_invoice'
|
||||
);
|
||||
|
||||
$invouce_transaction_document = $invoice_transaction->documents()->where('document_type', DocumentType::STORAGE_INVOICE)->first();
|
||||
if(!$invouce_transaction_document){
|
||||
/** @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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Transactions\Processors;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Classes\Modules\Transactions\Processors\CreateStorageInvoiceDocTransactionProcessor;
|
||||
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
|
||||
use App\Classes\Modules\Orders\Processors\UpdateDoFromVTPortalProcessor;
|
||||
use App\Classes\Modules\Orders\Processors\UpdateDoFromYDPortalProcessor;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class ReleaseGoodsToCustomerProcessor
|
||||
{
|
||||
/** @var UpdatesTransactionStatus */
|
||||
private $updatesTransactionStatus;
|
||||
|
||||
/** @var UpdateDoFromVTPortalProcessor */
|
||||
private $updateDoFromVTPortalProcessor;
|
||||
|
||||
/** @var UpdateDoFromYDPortalProcessor */
|
||||
private $updateDoFromYDPortalProcessor;
|
||||
|
||||
/** @var CreateStorageInvoiceDocTransactionProcessor */
|
||||
private $createStorageInvoiceDocTransactionProcessor;
|
||||
|
||||
/**
|
||||
* ReleaseGoodsToCustomerProcessor constructor.
|
||||
* @param UpdatesTransactionStatus $updatesTransactionStatus
|
||||
* @param UpdateDoFromVTPortalProcessor $updateDoFromVTPortalProcessor
|
||||
* @param UpdateDoFromYDPortalProcessor $updateDoFromYDPortalProcessor
|
||||
* @param CreateStorageInvoiceDocTransactionProcessor $createStorageInvoiceDocTransactionProcessor
|
||||
*/
|
||||
public function __construct(UpdatesTransactionStatus $updatesTransactionStatus, UpdateDoFromVTPortalProcessor $updateDoFromVTPortalProcessor, UpdateDoFromYDPortalProcessor $updateDoFromYDPortalProcessor, CreateStorageInvoiceDocTransactionProcessor $createStorageInvoiceDocTransactionProcessor)
|
||||
{
|
||||
$this->updatesTransactionStatus = $updatesTransactionStatus;
|
||||
$this->updateDoFromVTPortalProcessor = $updateDoFromVTPortalProcessor;
|
||||
$this->updateDoFromYDPortalProcessor = $updateDoFromYDPortalProcessor;
|
||||
$this->createStorageInvoiceDocTransactionProcessor = $createStorageInvoiceDocTransactionProcessor;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $packingList
|
||||
* @param $invoice
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
*/
|
||||
public function execute($packingList, $invoice = null)
|
||||
{
|
||||
$result = false;
|
||||
$totalInvoicesAmountPaid = 0.00;
|
||||
$totalInvoicesAmount = 0.00;
|
||||
$invoiceTransactions = $packingList->transactions()->where('status', [ApprovalStatus::APPROVED])->whereIn('type', [TransactionType::SHIPPING_INVOICE, TransactionType::STORAGE_INVOICE])->get();
|
||||
|
||||
//Part 1: Process each single invoice type and get the total of all invoices
|
||||
foreach($invoiceTransactions as $invoiceTransaction){
|
||||
|
||||
$totalInvoiceAmountPaid = $invoiceTransaction->transactions->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->sum('amount');
|
||||
if ($invoice && $invoice->type == $invoiceTransaction->type) {
|
||||
if(($invoice->amount - $totalInvoiceAmountPaid) < 0.01){
|
||||
$this->updatesTransactionStatus->execute($invoice, ApprovalStatus::COMPLETED);
|
||||
|
||||
if($invoice->type == TransactionType::STORAGE_INVOICE){
|
||||
$this->createStorageInvoiceDocTransactionProcessor->execute($packingList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$totalInvoicesAmount = $totalInvoicesAmount + $invoiceTransaction->amount;
|
||||
$totalInvoicesAmountPaid = $totalInvoicesAmountPaid + $totalInvoiceAmountPaid;
|
||||
}
|
||||
|
||||
Log::channel('storage_invoices')->info('Total invoice amount paid 1: '.$totalInvoicesAmount); //cief todo: to be removed
|
||||
Log::channel('storage_invoices')->info('Total invoice amount paid 2: '.$totalInvoicesAmountPaid); //cief todo: to be removed
|
||||
|
||||
//Part 2: Based on the collected info for all the total of all invoices
|
||||
if (($totalInvoicesAmount - $totalInvoicesAmountPaid) < 0.01 && $totalInvoicesAmountPaid > 0.01) {
|
||||
Log::channel('storage_invoices')->info('Total invoice amount paid 3: '.$totalInvoicesAmountPaid); //cief todo: to be removed
|
||||
|
||||
$packingList->status = ApprovalStatus::APPROVED;
|
||||
$packingList->save();
|
||||
|
||||
if (app()->environment('production')) {
|
||||
$this->updateDoFromVTPortalProcessor->execute($packingList);
|
||||
$this->updateDoFromYDPortalProcessor->execute($packingList);
|
||||
}
|
||||
|
||||
$result = true;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Notifications;
|
||||
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
|
||||
class PermitsReminderEmail extends AbstractEmail
|
||||
{
|
||||
|
||||
/** @var User */
|
||||
private $user;
|
||||
|
||||
private $reminders;
|
||||
|
||||
/**
|
||||
* SendResetPasswordEmail constructor.
|
||||
* @param User $user
|
||||
* @param PasswordReset $attempt
|
||||
*/
|
||||
public function __construct(User $user, $reminders)
|
||||
{
|
||||
$this->user = $user;
|
||||
$this->reminders = $reminders;
|
||||
}
|
||||
|
||||
public function toMail()
|
||||
{
|
||||
return (new MailMessage)
|
||||
->subject('Permits Renew Remidner Email')
|
||||
->view('emails.reminder.permits_reminder', ['user' => $this->user, 'reminders' => $this->reminders]);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -24,5 +24,6 @@ final class DocumentType {
|
||||
|
||||
|
||||
public const SHIPPING_INVOICE = 'SHIPPING_INVOICE';
|
||||
public const STORAGE_INVOICE = 'STORAGE_INVOICE';
|
||||
|
||||
}
|
||||
|
||||
@@ -11,4 +11,6 @@ final class TransactionDetailType {
|
||||
public const MIN_CBM_CHARGES = 'Minimum Charge for 0.3 CBM Per Container';
|
||||
|
||||
public const CUSTOM_CHARGES = 'Custom charges';
|
||||
|
||||
public const STORAGE_FEE = 'Malaysia Warehouse Storage Fee';
|
||||
}
|
||||
|
||||
@@ -5,9 +5,9 @@ namespace App\Classes\ValueObjects\Constants;
|
||||
final class TransactionType {
|
||||
|
||||
// public const PAYMENT_ATTEMPT = 0;
|
||||
|
||||
|
||||
public const SHIPPING_INVOICE = 1;
|
||||
|
||||
|
||||
public const PAYMENT = 2;
|
||||
|
||||
// public const BILL = 3;
|
||||
@@ -35,10 +35,11 @@ final class TransactionType {
|
||||
// public const SHIPPING_COST = 14;
|
||||
|
||||
public const GROUP_PAYMENT = 15;
|
||||
|
||||
|
||||
public const TRANSACTION_TYPE_ID = [
|
||||
self::SHIPPING_INVOICE => "Shipping Invoice",
|
||||
self::PAYMENT => "Payment",
|
||||
];
|
||||
|
||||
public const STORAGE_INVOICE = 16;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
|
||||
use App\Classes\Modules\Transactions\Services\ListsGroups;
|
||||
use App\Classes\Modules\Transactions\Processors\CheckStorageInvoiceTransactionProcessor;
|
||||
use App\Models\Order;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class CheckStorageInvoicesGroupTransactions extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'check-storage-invoices-group-transactions';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Check all storage invoices due to make sure that they are up to date daily, prevent \'back door\' cases';
|
||||
|
||||
/** @var ListsGroups */
|
||||
private $listsGroups;
|
||||
|
||||
/** @var CheckStorageInvoiceTransactionProcessor */
|
||||
private $storageInvoiceTransactionProcessor;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(ListsGroups $listsGroups, CheckStorageInvoiceTransactionProcessor $storageInvoiceTransactionProcessor)
|
||||
{
|
||||
parent::__construct();
|
||||
$this->listsGroups = $listsGroups;
|
||||
$this->storageInvoiceTransactionProcessor = $storageInvoiceTransactionProcessor;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
ini_set('memory_limit', '-1');
|
||||
|
||||
$this->info(Carbon::now() . ': Start Check all pending group payment with storage invoice is valid.');
|
||||
$start = new Carbon();
|
||||
|
||||
|
||||
$newfilters['order_by_updated_at_desc'] = true;
|
||||
$newfilters['status_in'] = [0, 1];
|
||||
$groups = $this->listsGroups->execute($newfilters);
|
||||
|
||||
foreach ($groups as $group){
|
||||
$this->info('CheckForStorageInvoiceByTransactions group: '.json_encode($group));
|
||||
foreach ($group->groupTransactions as $groupTransaction) {
|
||||
$invoice = $groupTransaction->transaction;
|
||||
$packingList = $invoice->owner()->first();
|
||||
if($packingList){
|
||||
$order = $packingList->owner()->first();
|
||||
if($order instanceof Order){
|
||||
$storages = $this->storageInvoiceTransactionProcessor->executeOrder($order);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$end = new Carbon();
|
||||
$elapsedTime = $start->diff($end)->format('%H:%I:%S');
|
||||
|
||||
$this->info(Carbon::now() . ': Done Check all pending group payment with storage invoice is valid. ElapsedTime: ' . $elapsedTime . '.');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
|
||||
use App\Classes\Modules\Orders\Services\ListsOrders;
|
||||
use App\Classes\Modules\Transactions\Processors\CheckStorageInvoiceTransactionProcessor;
|
||||
use App\Classes\ValueObjects\Constants\OrderType;
|
||||
use App\Models\Order;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class CheckStorageInvoicesOrders extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'check-storage-invoices-orders';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Check all storage invoices due to make sure that they are up to date daily, prevent \'back door\' cases';
|
||||
|
||||
/** @var ListsOrders */
|
||||
private $listsOrders;
|
||||
|
||||
/** @var CheckStorageInvoiceTransactionProcessor */
|
||||
private $storageInvoiceTransactionProcessor;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(ListsOrders $listsOrders, CheckStorageInvoiceTransactionProcessor $storageInvoiceTransactionProcessor)
|
||||
{
|
||||
parent::__construct();
|
||||
$this->listsOrders = $listsOrders;
|
||||
$this->storageInvoiceTransactionProcessor = $storageInvoiceTransactionProcessor;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
ini_set('memory_limit', '-1');
|
||||
|
||||
$this->info(Carbon::now() . ': Start Check all orders for storage invoice.');
|
||||
$start = new Carbon();
|
||||
|
||||
$orders = $this->listsOrders->execute(['with_parcels' => true, 'type_in' => [OrderType::SHARED_CONTAINER, OrderType::DEDICATED_CONTAINER]]);
|
||||
|
||||
$count = 0;
|
||||
foreach ($orders as $order){
|
||||
try{
|
||||
$storages = $this->storageInvoiceTransactionProcessor->executeOrder($order);
|
||||
$count = $count + 1;
|
||||
$this->info('Order '.$count);
|
||||
}
|
||||
catch(\Exception $ex){
|
||||
$this->info('Exception '.$ex->getMessage());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$end = new Carbon();
|
||||
$elapsedTime = $start->diff($end)->format('%H:%I:%S');
|
||||
|
||||
$this->info(Carbon::now() . ': Done Check all orders for storage invoice. ElapsedTime: ' . $elapsedTime . '.');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
|
||||
use App\Classes\Modules\Transactions\Services\FetchesGroup;
|
||||
use App\Classes\Modules\Orders\Services\FetchesOrder;
|
||||
use App\Classes\Modules\Transactions\Processors\ReleaseGoodsToCustomerProcessor;
|
||||
use App\Classes\Modules\Transactions\Processors\CreateStorageInvoiceDocTransactionFixProcessor;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class FixGroupPaymentProblem extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'fix-group-payment-problem';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'This is a one time data patch for a problem result from Storage Invoice Implementation';
|
||||
|
||||
/** @var FetchesGroup */
|
||||
private $fetchesGroup;
|
||||
|
||||
/** @var ReleaseGoodsToCustomerProcessor */
|
||||
private $releaseGoodsToCustomerProcessor;
|
||||
|
||||
/** @var FetchesOrder */
|
||||
private $fetchesOrder;
|
||||
|
||||
/** @var CreateStorageInvoiceDocTransactionFixProcessor */
|
||||
private $createStorageInvoiceDocTransactionProcessor;
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(FetchesGroup $fetchesGroup, ReleaseGoodsToCustomerProcessor $releaseGoodsToCustomerProcessor, FetchesOrder $fetchesOrder, CreateStorageInvoiceDocTransactionFixProcessor $createStorageInvoiceDocTransactionProcessor)
|
||||
{
|
||||
parent::__construct();
|
||||
$this->fetchesGroup = $fetchesGroup;
|
||||
$this->releaseGoodsToCustomerProcessor = $releaseGoodsToCustomerProcessor;
|
||||
$this->fetchesOrder = $fetchesOrder;
|
||||
$this->createStorageInvoiceDocTransactionProcessor = $createStorageInvoiceDocTransactionProcessor;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
ini_set('memory_limit', '-1');
|
||||
|
||||
$this->info(Carbon::now() . ': Start data patch.');
|
||||
$start = new Carbon();
|
||||
|
||||
/*
|
||||
$group = $this->fetchesGroup->execute(['id' => 325]);
|
||||
$this->info('FixGroupPaymentProblem group: '.json_encode($group));
|
||||
if ($group) {
|
||||
foreach ($group->groupTransactions as $groupTransaction) {
|
||||
$invoice = $groupTransaction->transaction;
|
||||
$this->info('FixGroupPaymentProblem group: '.json_encode($invoice));
|
||||
$pL = $invoice->owner;
|
||||
$this->releaseGoodsToCustomerProcessor->execute($pL, $invoice);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
$order = $this->fetchesOrder->execute(['reference' => '729251424']);
|
||||
$packingLists = $order->destinationWarehousePackages;
|
||||
|
||||
foreach ($packingLists as $packingList){
|
||||
$this->createStorageInvoiceDocTransactionProcessor->execute($packingList, true);
|
||||
dd(json_encode($packingList));
|
||||
}
|
||||
|
||||
|
||||
$end = new Carbon();
|
||||
$elapsedTime = $start->diff($end)->format('%H:%I:%S');
|
||||
|
||||
$this->info(Carbon::now() . ': Done data patch. ElapsedTime: ' . $elapsedTime . '.');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Classes\Notifications\PermitsReminderEmail;
|
||||
use App\Models\PermitsReminder;
|
||||
use App\Models\User;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class SendPermitsReminderEmails extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'permitsReminder:send';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Send Permits Reminders Email';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$now = now();
|
||||
$startRange = $now->subDays(3)->startOfDay();
|
||||
$endRange = $now->copy()->addDays(6)->endOfDay();
|
||||
|
||||
$reminders = PermitsReminder::whereDate('reminder_date', '>=', $startRange)
|
||||
->whereDate('reminder_date', '<=', $endRange)
|
||||
->pluck('model');
|
||||
|
||||
$this->info($this->getTimeStamp() . json_encode($reminders));
|
||||
|
||||
$users = User::whereIn(
|
||||
'email',
|
||||
[
|
||||
// 'edmond.wuiming2021@gmail.com',
|
||||
'anithagurl96@gmail.com'
|
||||
]
|
||||
)->get();
|
||||
|
||||
foreach ($users as $user) {
|
||||
$this->info($this->getTimeStamp() . 'Reminder email sent to ' . $user->email);
|
||||
if (app()->environment('production')) {
|
||||
$user->notify(new PermitsReminderEmail($user, $reminders));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getTimeStamp()
|
||||
{
|
||||
return '[' . Carbon::now()->format('Y-m-d H:i:s') . '] - ';
|
||||
}
|
||||
}
|
||||
@@ -62,6 +62,16 @@ class Kernel extends ConsoleKernel
|
||||
->hourly()
|
||||
->withoutOverlapping()
|
||||
->appendOutputTo (storage_path().'/logs/fix_failed_callback_from_billplz.log');
|
||||
|
||||
$schedule->command('check-storage-invoices-group-transactions')
|
||||
->dailyAt('0:01')
|
||||
->withoutOverlapping()
|
||||
->appendOutputTo(storage_path().'/logs/check_storage_invoices.log');
|
||||
|
||||
$schedule->command('permitsReminder:send')
|
||||
->dailyAt('09:30')
|
||||
->withoutOverlapping()
|
||||
->appendOutputTo(storage_path().'/logs/permits-reminder-send.log');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Imports;
|
||||
|
||||
use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
|
||||
use App\Classes\Modules\Imports\Services\GenericImport;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Models\PermitsReminder;
|
||||
use Carbon\Carbon;
|
||||
use DateTime;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Maatwebsite\Excel\Facades\Excel;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date;
|
||||
|
||||
class ImportPermitsReminderController
|
||||
{
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function import(Request $request)
|
||||
{
|
||||
$object = new DocumentObject('', $request->input('files'), '', ApprovalStatus::APPROVED, 'imports');
|
||||
$file = json_decode($object->getFiles()[0])->file_info->original->file;
|
||||
$file = storage_path('app/documents/' . $file);
|
||||
|
||||
$import = new GenericImport();
|
||||
Excel::import($import, $file);
|
||||
$excelRows = $import->rows->toArray();
|
||||
$successRows = [];
|
||||
$returnArray = []; // Initialize the return array
|
||||
|
||||
foreach ($excelRows as $row) {
|
||||
if (is_null($row['expiry_date']) && is_null($row['reminder_date'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$row['expiry_date'] = $this->changeExcelDate($row['expiry_date']);
|
||||
$row['reminder_date'] = $this->changeExcelDate($row['reminder_date']);
|
||||
|
||||
$validator = Validator::make($row, [
|
||||
'model' => 'required|unique:permits_reminders,model',
|
||||
'expiry_date' => 'required|date|after_or_equal:today',
|
||||
'reminder_date' => 'required|date|after_or_equal:today',
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
$row['status'] = 'failed';
|
||||
$row['message'] = $validator->errors()->all();
|
||||
|
||||
$returnArray[] = $row;
|
||||
} else {
|
||||
$row['created_at'] = Carbon::now();
|
||||
$row['updated_at'] = Carbon::now();
|
||||
$successRows[] = $row;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($successRows)) {
|
||||
PermitsReminder::insert($successRows); // Insert only if there are successful rows
|
||||
}
|
||||
|
||||
$successCount = count($successRows);
|
||||
|
||||
return response()->json([
|
||||
'completedRows' => $successCount,
|
||||
'failedRows' => count($returnArray),
|
||||
'remark' => "Successful Imported {$successCount} data.",
|
||||
'data' => $returnArray
|
||||
]);
|
||||
}
|
||||
|
||||
public function changeExcelDate($date)
|
||||
{
|
||||
$formatedDate = DateTime::createFromFormat('d/m/Y', $date);
|
||||
if ($formatedDate instanceof DateTime) {
|
||||
return $formatedDate->format('Y-m-d');
|
||||
}
|
||||
|
||||
$unixTime = (($date - 25569) * 86400);
|
||||
|
||||
return (new DateTime("@$unixTime"))->format('Y-m-d');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Jobs;
|
||||
|
||||
use App\Classes\Modules\Jobs\ControllersLogic\FetchJobResultLogic;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class FetchJobResultController
|
||||
{
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param FetchJobResultLogic $logic
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function fetch(Request $request, FetchJobResultLogic $logic): JsonResponse {
|
||||
return $logic->execute($request);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace App\Http\Controllers\PackingLists;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Classes\Modules\PackingLists\ControllersLogic\ListPackingListsJobLogic;
|
||||
|
||||
|
||||
class ListPackingListsJobController
|
||||
{
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param ListPackingListsJobLogic $logic
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function list(Request $request, ListPackingListsJobLogic $logic) : JsonResponse {
|
||||
return $logic->execute($request);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\PermitsReminder;
|
||||
|
||||
use App\Classes\Exceptions\RequestValidationException;
|
||||
use App\Models\PermitsReminder;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
class CreatePermitsReminderController
|
||||
{
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function create(Request $request): JsonResponse
|
||||
{
|
||||
// Define validation rules
|
||||
$rules = [
|
||||
'model' => 'required|unique:permits_reminders,model',
|
||||
'expiry_date' => 'required|date|after_or_equal:today',
|
||||
'reminder_date' => 'required|date|after_or_equal:today',
|
||||
];
|
||||
|
||||
// Perform validation
|
||||
$validator = Validator::make($request->all(), $rules);
|
||||
|
||||
if ($validator->fails()) {
|
||||
$validationErrors = $validator->errors()->all();
|
||||
$validationError = implode("<br>", $validationErrors);
|
||||
|
||||
// Return validation error response
|
||||
return response()->json([
|
||||
'title' => 'Create Permits Reminder Failed',
|
||||
'message' => $validationError,
|
||||
"payload" => []
|
||||
], 422); // 422 Unprocessable Entity status code for validation errors
|
||||
}
|
||||
|
||||
// If validation passes, create the record
|
||||
$record = PermitsReminder::create([
|
||||
'expiry_date' => Carbon::parse($request->input('expiry_date'))->format('Y-m-d'),
|
||||
'reminder_date' => Carbon::parse($request->input('reminder_date'))->format('Y-m-d'),
|
||||
'model' => $request->input('model'),
|
||||
]);
|
||||
|
||||
$response = [
|
||||
"title" => "Create Permits Reminder Successful",
|
||||
"message" => "You have successfully created a Permits Reminder",
|
||||
"payload" => [
|
||||
"data" => $record
|
||||
]
|
||||
];
|
||||
|
||||
return response()->json($response);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\PermitsReminder;
|
||||
|
||||
use App\Models\PermitsReminder;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class DeletePermitsReminderController
|
||||
{
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function delete(Request $request): JsonResponse
|
||||
{
|
||||
$record = PermitsReminder::find($request->route('id'));
|
||||
$record->delete();
|
||||
|
||||
$response = [
|
||||
"title" => "Delete Permits Reminder Successful",
|
||||
"message" => "You have successfully deleted a Permits Reminder",
|
||||
"payload" => []
|
||||
];
|
||||
|
||||
return response()->json($response);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\PermitsReminder;
|
||||
|
||||
use App\Models\PermitsReminder;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ListPermitsReminderController
|
||||
{
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function list(Request $request): JsonResponse
|
||||
{
|
||||
$perPage = 10; // Number of items per page
|
||||
$page = request('page', 1); // Get the current page from the request
|
||||
|
||||
// Paginate the PermitsReminder model
|
||||
$query = PermitsReminder::orderBy('id', 'desc');
|
||||
$paginator = $query->paginate($perPage, ['*'], 'page', $page);
|
||||
|
||||
// Convert paginated data to an array
|
||||
$data = $paginator->items();
|
||||
|
||||
// Create pagination links
|
||||
$links = [
|
||||
"first" => $paginator->url(1),
|
||||
"last" => $paginator->url($paginator->lastPage()),
|
||||
"prev" => $paginator->previousPageUrl(),
|
||||
"next" => $paginator->nextPageUrl(),
|
||||
];
|
||||
|
||||
$response = [
|
||||
"title" => "List Permits Reminder",
|
||||
"message" => "You have successfully retrieved a list of Permits Reminder",
|
||||
"payload" => [
|
||||
'data' => $data,
|
||||
"links" => $links,
|
||||
"meta" => [
|
||||
"current_page" => $paginator->currentPage(),
|
||||
"from" => $paginator->firstItem(),
|
||||
"last_page" => $paginator->lastPage(),
|
||||
"path" => $request->path(),
|
||||
"per_page" => $paginator->perPage(),
|
||||
"to" => $paginator->lastItem(),
|
||||
"total" => $paginator->total(),
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
return response()->json($response);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\PermitsReminder;
|
||||
|
||||
use App\Models\PermitsReminder;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
class UpdatePermitsReminderController
|
||||
{
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function update(Request $request): JsonResponse
|
||||
{
|
||||
$rules = [
|
||||
'model' => 'required|unique:permits_reminders,model,' . $request->route('id'),
|
||||
'expiry_date' => 'required|date|after_or_equal:today',
|
||||
'reminder_date' => 'required|date|after_or_equal:today',
|
||||
];
|
||||
|
||||
$validator = Validator::make($request->all(), $rules);
|
||||
|
||||
if ($validator->fails()) {
|
||||
$validationErrors = $validator->errors()->all();
|
||||
$validationError = implode("<br>", $validationErrors);
|
||||
|
||||
return response()->json([
|
||||
'title' => 'Update Permits Reminder Failed',
|
||||
'message' => $validationError,
|
||||
"payload" => []
|
||||
], 422);
|
||||
}
|
||||
|
||||
$record = PermitsReminder::findOrFail($request->route('id'));
|
||||
|
||||
$record->model = $request->input('model');
|
||||
$record->expiry_date = Carbon::parse($request->input('expiry_date'))->format('Y-m-d');
|
||||
$record->reminder_date = Carbon::parse($request->input('reminder_date'))->format('Y-m-d');
|
||||
$record->save();
|
||||
|
||||
return response()->json([
|
||||
'title' => 'Permits Reminder Updated',
|
||||
'message' => 'The permits reminder has been successfully updated.',
|
||||
"payload" => $record
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -70,5 +70,8 @@ class Kernel extends HttpKernel
|
||||
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
|
||||
'valid.token' => ValidateToken::class,
|
||||
'token.check' => \App\Http\Middleware\TokenCheckerMiddleware::class,
|
||||
'storage.invoice.check.byorder' => \App\Http\Middleware\CheckForStorageInvoiceByOrderId::class,
|
||||
'storage.invoice.check.bytransactions' => \App\Http\Middleware\CheckForStorageInvoiceByTransactions::class,
|
||||
'storage.invoice.check.bygroup' => \App\Http\Middleware\CheckForStorageInvoiceByGroup::class,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use App\Classes\Modules\Transactions\Processors\CheckStorageInvoiceTransactionProcessor;
|
||||
use App\Classes\Modules\Transactions\Services\ListsGroups;
|
||||
use App\Models\Order;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class CheckForStorageInvoiceByGroup
|
||||
{
|
||||
|
||||
/** @var CheckStorageInvoiceTransactionProcessor */
|
||||
private $storageInvoiceTransactionProcessor;
|
||||
|
||||
/** @var ListsGroups */
|
||||
private $listsGroups;
|
||||
|
||||
|
||||
public function __construct(CheckStorageInvoiceTransactionProcessor $storageInvoiceTransactionProcessor, ListsGroups $listsGroups)
|
||||
{
|
||||
$this->storageInvoiceTransactionProcessor = $storageInvoiceTransactionProcessor;
|
||||
$this->listsGroups = $listsGroups;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
|
||||
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
// :options="{'per_page': 10, order_by: {column: 'id', DESC: true}, 'status_in': [0, 1], 'receiver': company_module_id, order_by: {column: 'updated_at', DESC: true}}"
|
||||
$filters = json_decode($request->input('filters'), true);
|
||||
if(json_encode($filters['order_by']) == '{"column":"updated_at","DESC":true}'){
|
||||
$filters['order_by_updated_at_desc'] = true;
|
||||
}
|
||||
unset($filters['order_by']);
|
||||
$groups = $this->listsGroups->execute($filters);
|
||||
|
||||
|
||||
if(isset($filters['check_for_storage_invoice'])){
|
||||
foreach ($groups as $group){
|
||||
foreach ($group->groupTransactions as $groupTransaction) {
|
||||
$invoice = $groupTransaction->transaction;
|
||||
$packingList = $invoice->owner()->first();
|
||||
if($packingList){
|
||||
$order = $packingList->owner()->first();
|
||||
if($order instanceof Order){
|
||||
$storages = $this->storageInvoiceTransactionProcessor->executeOrder($order);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use App\Classes\Modules\Transactions\Processors\CheckStorageInvoiceTransactionProcessor;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class CheckForStorageInvoiceByOrderId
|
||||
{
|
||||
|
||||
/** @var CheckStorageInvoiceTransactionProcessor */
|
||||
private $storageInvoiceTransactionProcessor;
|
||||
|
||||
|
||||
public function __construct(CheckStorageInvoiceTransactionProcessor $storageInvoiceTransactionProcessor)
|
||||
{
|
||||
$this->storageInvoiceTransactionProcessor = $storageInvoiceTransactionProcessor;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
|
||||
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
$orderId = $request->route('id');
|
||||
$storages = $this->storageInvoiceTransactionProcessor->execute($orderId);
|
||||
$request->merge(['storages' => $storages]);
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use App\Classes\Modules\Transactions\Processors\CheckStorageInvoiceTransactionProcessor;
|
||||
use App\Classes\Modules\Transactions\Services\ListsTransactions;
|
||||
use App\Classes\Modules\Transactions\Services\ListsGroups;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Models\CompanyConnection;
|
||||
use App\Models\Order;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class CheckForStorageInvoiceByTransactions
|
||||
{
|
||||
|
||||
/** @var CheckStorageInvoiceTransactionProcessor */
|
||||
private $storageInvoiceTransactionProcessor;
|
||||
|
||||
/** @var ListsTransactions */
|
||||
private $listsTransactions;
|
||||
|
||||
/** @var ListsGroups */
|
||||
private $listsGroups;
|
||||
|
||||
|
||||
public function __construct(CheckStorageInvoiceTransactionProcessor $storageInvoiceTransactionProcessor, ListsTransactions $listsTransactions, ListsGroups $listsGroups)
|
||||
{
|
||||
$this->storageInvoiceTransactionProcessor = $storageInvoiceTransactionProcessor;
|
||||
$this->listsTransactions = $listsTransactions;
|
||||
$this->listsGroups = $listsGroups;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
|
||||
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
$results = [];
|
||||
$transactions = null;
|
||||
$marking = $request->route('marking');
|
||||
if($marking){ //for web route /customer/{marking}/payment-and-billing
|
||||
$connection = CompanyConnection::where('invitee_reference', $marking)->first();
|
||||
$company_module_id = $connection->invitee->id;
|
||||
$filters = [
|
||||
'per_page' => 999,
|
||||
'status_in' => [2],
|
||||
'receiver' => $company_module_id,
|
||||
'type_in' => [TransactionType::SHIPPING_INVOICE]
|
||||
];
|
||||
$transactions = $this->listsTransactions->execute($filters);
|
||||
}
|
||||
else{ //for api route /transactions/list
|
||||
$filters = json_decode($request->input('filters'), true);
|
||||
$filters['type_in'] = [TransactionType::SHIPPING_INVOICE];
|
||||
if(json_encode($filters['order_by']) == '{"column":"id","DESC":true}'){
|
||||
$filters['order_by_id_desc'] = true;
|
||||
}
|
||||
unset($filters['order_by']);
|
||||
$transactions = $this->listsTransactions->execute($filters);
|
||||
}
|
||||
|
||||
|
||||
if(isset($filters['check_for_storage_invoice'])){
|
||||
foreach($transactions as $transaction){
|
||||
$packingList = $transaction->owner()->first();
|
||||
if($packingList){
|
||||
$order = $packingList->owner()->first();
|
||||
if($order instanceof Order){
|
||||
$storages = $this->storageInvoiceTransactionProcessor->executeOrder($order);
|
||||
if($storages){
|
||||
$results = array_merge($results, $storages);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$filteredResults = array_values(array_filter($results, function($item, $key) {
|
||||
static $seen = array();
|
||||
$hash = md5($item['parentInvoiceId'] . $item['storageInvoiceId']);
|
||||
return !isset($seen[$hash]) && ($seen[$hash] = true);
|
||||
}, ARRAY_FILTER_USE_BOTH));
|
||||
|
||||
|
||||
$request->merge(['storages' => $filteredResults]);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\PaymentMethodType;
|
||||
use App\Models\Transaction;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class GroupForOrderV2Resource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
$payment_transaction = Transaction::where('payment_reference', $this->reference)->first();
|
||||
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'original_amount' => (float) $this->original_amount,
|
||||
'original_currency' => new CurrencyResource($this->original_currency),
|
||||
'issuer_name' => $this->issuerCompany->name,
|
||||
'issuer_id' => $this->issuerCompany->id,
|
||||
'amount' => (float) $this->amount,
|
||||
'service_charge' => (float) $this->amount,
|
||||
'currency' => new CurrencyResource($this->currency),
|
||||
'created_at' => Carbon::parse($this->created_at)->format('d-m-Y h:i:s A'),
|
||||
'currency_rate' => (float) $this->currency_rate,
|
||||
'status' => $this->status,
|
||||
'status_name' => ApprovalStatus::APPROVAL_STATUS_ID[$this->status],
|
||||
'payment_method' => (int)$this->payment_method,
|
||||
'payment_method_name' => ucwords(PaymentMethodType::PAYMENT_METHODS_ID[$this->payment_method]),
|
||||
'payment_reference' => $this->reference,
|
||||
'transactions_ids' => GroupTransactionsForOrderV2Resource::collection($this->groupTransactions),
|
||||
'payment_transaction' => $payment_transaction ? [
|
||||
'id' => $payment_transaction->id,
|
||||
'status' => $payment_transaction->status,
|
||||
'status_name' => ApprovalStatus::APPROVAL_STATUS_ID[$payment_transaction->status]
|
||||
] : []
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class GroupTransactionsForOrderV2Resource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
// 'id' => $this->id,
|
||||
'group_id' => $this->group_id,
|
||||
'transaction_id' => $this->transaction_id,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class JobResultResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'job_id' => $this->job_id,
|
||||
'result' => $this->result,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
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 App\Http\Resources\V2\PackingListV2Resource;
|
||||
|
||||
class ListPackingListJobResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
$exceptionUsers = in_array($this->userInfo ? $this->userInfo->type : Auth()->user()->type, [RoleTypes::SHADOW_ADMIN, RoleTypes::SUPER_ADMIN]);
|
||||
$packages = !$this->packingLists()->exists() || $exceptionUsers ? $this->packages : $this->packingLists->first()->packages;
|
||||
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'claimant_id' => $this->claimant_id,
|
||||
'reference' => $this->reference,
|
||||
'status' => $this->status,
|
||||
'transport' => new TransportResource($this->transports()->first()),
|
||||
'type' => $this->type,
|
||||
'receive_packing_list' => $this->when($this->type === PackingListType::SHIPPING_PACKING_LIST, new PackingListV2Resource(PackingList::where('reference', $this->reference)->where('type', PackingListType::WAREHOUSE_RECEIVE_LIST)->first(), $this->userInfo)),
|
||||
// 'packages' => PackageResource::collection($packages),
|
||||
// $this->mergeWhen($this->owner instanceof Order, [
|
||||
// 'order' => New OrderResource($this->owner)
|
||||
// ]),
|
||||
'container' => new ContainerResource($this->containers->first()),
|
||||
'packages' => PackageWithoutOrderResource::collection($packages),
|
||||
$this->mergeWhen($this->owner instanceof Order, [ 'order' => New OrderResource($this->owner) ]),
|
||||
'shipping_transaction' => new TransactionResource($this->transactions()->where('type', TransactionType::SHIPPING_INVOICE)->whereNotIn('status', [ApprovalStatus::SUSPENDED, ApprovalStatus::EXPIRED])->first()),
|
||||
'suspended_invoice' => new TransactionResource($this->transactions()->where('type', TransactionType::SHIPPING_INVOICE)->whereIn('status', [ApprovalStatus::SUSPENDED])->first()),
|
||||
// 'suspended_invoices' => TransactionResource::collection($this->transactions()->where('type', TransactionType::SHIPPING_INVOICE)->whereIn('status', [ApprovalStatus::SUSPENDED])->get()),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -37,6 +37,7 @@ class MappableTransactionResource extends JsonResource
|
||||
'owner_type' => Transaction::class,
|
||||
'owner_id'=> $this->id,
|
||||
'owner_reference'=> $reference,
|
||||
'created_at'=> $this->created_at, // invoice date
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,16 +27,19 @@ class MappableTransactionWithDetailsResource extends JsonResource
|
||||
'order_reference' => null,
|
||||
'bill_no' => null,
|
||||
'marking' => null,
|
||||
'created_at' => null
|
||||
];
|
||||
|
||||
if ($this->type === TransactionType::PAYMENT) {
|
||||
$order = $this->owner->owner->owner;
|
||||
$data['order_reference'] = $order->reference;
|
||||
$data['debtor_code'] = $order->companyModule->company->debtor;
|
||||
$data['created_at'] = $this->owner->created_at; // invoice date
|
||||
} elseif (in_array($this->type, [TransactionType::GROUP_PAYMENT, TransactionType::TOP_UP])) {
|
||||
$connection = $this->owner->owner->inviters()->withPivot('invitee_reference')->first();
|
||||
$data['marking'] = $connection ? $connection->pivot->invitee_reference : '';
|
||||
$data['bill_no'] = $this->bill_no;
|
||||
$data['created_at'] = $this->created_at;
|
||||
} else {
|
||||
$payments = $this->transactions()
|
||||
->payments()->where('status', ApprovalStatus::APPROVED)
|
||||
@@ -54,6 +57,7 @@ class MappableTransactionWithDetailsResource extends JsonResource
|
||||
'type' => $payment->type,
|
||||
'marking' => null,
|
||||
'amount' => $payment->amount,
|
||||
'created_at' => $this->created_at
|
||||
];
|
||||
})->toArray();
|
||||
} else {
|
||||
@@ -61,6 +65,7 @@ class MappableTransactionWithDetailsResource extends JsonResource
|
||||
$data['amount'] = 'Transaction Type not allowed';
|
||||
$data['transaction_type'] = $this->type;
|
||||
$data['payment_transactions'] = null;
|
||||
$data['created_at'] = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,8 +31,9 @@ class OrderV2Resource extends JsonResource
|
||||
'address' => new AddressResource($this->addresses()->where('status', '=', ApprovalStatus::APPROVED)->first()),
|
||||
'address_change_request' => new AddressResource($this->addressesPendingVerification()->first()),
|
||||
'invoices' => $this->whenLoaded('packingLists', function() {
|
||||
return TransactionResource::collection($this->transactions()->whereNotIn('transactions.status', [0, 1])->where('transactions.type', TransactionType::SHIPPING_INVOICE)->get());
|
||||
return TransactionWithStorageResource::collection($this->transactions()->whereNotIn('transactions.status', [0, 1])->whereIn('transactions.type', [TransactionType::SHIPPING_INVOICE, TransactionType::STORAGE_INVOICE])->get());
|
||||
}),
|
||||
'storages' => $this->storages ? $this->storages : null, //from middleware
|
||||
'remarks' => RemarkResource::collection($this->remarks),
|
||||
'created_at' => $this->created_at->format('d-m-Y')
|
||||
];
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use App\Models\Order;
|
||||
use App\Models\PackingList;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class PackageWithoutOrderResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'type' => $this->type,
|
||||
'description' => $this->description,
|
||||
'width' => floatval($this->width),
|
||||
'height' => floatval($this->height),
|
||||
'length' => floatval($this->length),
|
||||
'weight' => $this->weight,
|
||||
'quantity' => $this->quantity,
|
||||
'cbm' => (($this->width / 100) * ($this->height / 100) * ($this->length / 100)) * $this->quantity,
|
||||
'reference' => $this->packingList->reference,
|
||||
'status' => $this->status,
|
||||
// $this->mergeWhen($originalPackingList->owner instanceof Order, [
|
||||
// 'order' => New OrderResource($originalPackingList->owner)
|
||||
// ]),
|
||||
// 'container' => new ContainerResource($originalPackingList->containers()->first()),
|
||||
// 'transport' => new TransportResource($originalPackingList->transports()->first())
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -40,7 +40,7 @@ class TransactionResource extends JsonResource
|
||||
if ($group) {
|
||||
$groupTransactions = GroupTransactionResource::collection($group->groupTransactions);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return [
|
||||
@@ -48,7 +48,7 @@ class TransactionResource extends JsonResource
|
||||
'owner_type' => $this->owner_type,
|
||||
'order' => $order,
|
||||
'group_transactions' => $groupTransactions,
|
||||
'group_reference' => $groupTransactions ? $group->reference : null,
|
||||
'group_reference' => $groupTransactions ? ($group ? $group->reference : null ) : null,
|
||||
'documents' => $groupTransactions ? DocumentResource::collection($this->documents->where('status', ApprovalStatus::PENDING_VERIFICATION)) : DocumentResource::collection($this->documents),
|
||||
'type' => (int) $this->type,
|
||||
'bill_no' => $this->bill_no,
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Models\Group;
|
||||
use App\Models\Transaction;
|
||||
use App\Models\Wallet;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class TransactionWithStorageResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
$order = null;
|
||||
$groupTransactions = null;
|
||||
$group_payment_attempts = null;
|
||||
$groupPaymentAttemptsFiltered = [];
|
||||
$group_payment_expired = null;
|
||||
$group_payment_history = null;
|
||||
$groupTotalAmount = 0;
|
||||
|
||||
if ($this->owner instanceof Transaction) {
|
||||
if ($this->owner) {
|
||||
if ($this->owner->owner) {
|
||||
$order = new OrderResource($this->owner->owner->owner);
|
||||
}
|
||||
}
|
||||
} else if (!($this->owner instanceof Transaction) && !($this->owner instanceof Wallet)) {
|
||||
if ($this->owner) {
|
||||
$order = new OrderResource($this->owner->owner);
|
||||
}
|
||||
|
||||
if($this->groups){
|
||||
$group_payment_attempts = GroupForOrderV2Resource::collection($this->groups->whereNotIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]));
|
||||
$group_payment_expired = GroupForOrderV2Resource::collection($this->groupsWithTrashed->whereIn('status', [ApprovalStatus::EXPIRED]));
|
||||
$group_payment_history = GroupForOrderV2Resource::collection($this->groups->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::REJECTED]));
|
||||
}
|
||||
|
||||
} else {
|
||||
$group = Group::where('reference', $this->payment_reference)->first();
|
||||
if ($group) {
|
||||
$groupTransactions = GroupTransactionResource::collection($group->groupTransactions);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
$ts = $this->groups->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION])->last();
|
||||
if ($ts) {
|
||||
$paymentTransaction = Transaction::where('payment_reference', $ts->reference)->whereIn('status', [ApprovalStatus::PENDING_SUBMISSION])->first();
|
||||
if($paymentTransaction){
|
||||
$groupTotalAmount = (double) $this->amount;
|
||||
|
||||
foreach ($group_payment_history as $key => $value) {
|
||||
if ($value->id === $ts->id && $value->reference === $ts->reference) {
|
||||
unset($group_payment_history[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($group_payment_attempts as $key => $value) {
|
||||
if ($value->id === $ts->id && $value->reference == $ts->reference) {
|
||||
$groupPaymentAttemptsFiltered[$key] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'owner_type' => $this->owner_type,
|
||||
'order' => $order,
|
||||
'group_transactions' => $groupTransactions,
|
||||
'group_reference' => $groupTransactions ? ($group ? $group->reference : null ) : null,
|
||||
'groups_payment_attempts' => $groupPaymentAttemptsFiltered,
|
||||
'groups_payment_expired' => $group_payment_expired,
|
||||
'groups_payment_history' => $group_payment_history,
|
||||
'documents' => $groupTransactions ? DocumentResource::collection($this->documents->where('status', ApprovalStatus::PENDING_VERIFICATION)) : DocumentResource::collection($this->documents),
|
||||
'type' => (int) $this->type,
|
||||
'bill_no' => $this->bill_no,
|
||||
'amount' => (double) $this->amount,
|
||||
'payment_method' => (int) $this->payment_method,
|
||||
'payment_reference' => $this->payment_reference,
|
||||
'outstanding' => (double) $this->amount - ($this->transactions()->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->sum('amount')),
|
||||
'floating' => $group_payment_attempts ? $groupTotalAmount : (double) $this->transactions()->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::PENDING_SUBMISSION, ApprovalStatus::PENDING_VERIFICATION])->sum('amount'),
|
||||
'service_charge' => (double) $this->service_charge,
|
||||
'tax' => (double) $this->tax,
|
||||
'original_amount' => (double) $this->original_amount,
|
||||
'currency' => new CurrencyResource($this->currency),
|
||||
'original_currency' => new CurrencyResource($this->original_currency),
|
||||
'currency_rate' => (double) $this->currency_rate,
|
||||
'status' => (int) $this->status,
|
||||
'details' => TransactionDetailResource::collection($this->transactionDetails),
|
||||
'transactions' => TransactionResource::collection($this->transactions),
|
||||
'payment_attempts' => TransactionResource::collection(
|
||||
$this->transactions()
|
||||
->payments()->where('status', ApprovalStatus::PENDING_SUBMISSION)
|
||||
->get()
|
||||
),
|
||||
'payments_expired' => TransactionResource::collection(
|
||||
$this->transactions()
|
||||
->payments()->where('status', ApprovalStatus::EXPIRED)
|
||||
->get()
|
||||
),
|
||||
'payment_history' => TransactionResource::collection(
|
||||
$this->transactions()
|
||||
->payments()
|
||||
->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::COMPLETED, ApprovalStatus::REJECTED])
|
||||
->get()
|
||||
),
|
||||
'remarks' => RemarkResource::collection($this->remarks),
|
||||
'storages' => $this->storages ? $this->storages : null, //from middleware
|
||||
'expires_on' => Carbon::parse($this->expires_on)->format('d-m-Y h:s:i'),
|
||||
'updated_at' => Carbon::parse($this->updated_at)->format('d-m-Y'),
|
||||
'created_at' => Carbon::parse($this->created_at)->format('d-m-Y')
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources\V2;
|
||||
|
||||
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 App\Http\Resources as V1;
|
||||
|
||||
|
||||
class PackingListV2Resource extends JsonResource
|
||||
{
|
||||
private $userInfo;
|
||||
|
||||
public function __construct($resource, $userInfo = null)
|
||||
{
|
||||
parent::__construct($resource);
|
||||
$this->userInfo = $userInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
$user = $this->userInfo ? $this->userInfo : Auth()->user();
|
||||
$exceptionUsers = in_array($user->type, [RoleTypes::SHADOW_ADMIN, RoleTypes::SUPER_ADMIN]);
|
||||
$packages = !$this->packingLists()->exists() || $exceptionUsers ? $this->packages : $this->packingLists->first()->packages;
|
||||
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'claimant_id' => $this->claimant_id,
|
||||
'reference' => $this->reference,
|
||||
'status' => $this->status,
|
||||
'transport' => new V1\TransportResource($this->transports()->first()),
|
||||
'type' => $this->type,
|
||||
'receive_packing_list' => $this->when($this->type === PackingListType::SHIPPING_PACKING_LIST, new PackingListV2Resource(PackingList::where('reference', $this->reference)->where('type', PackingListType::WAREHOUSE_RECEIVE_LIST)->first(), $user)),
|
||||
'packages' => V1\PackageResource::collection($packages),
|
||||
$this->mergeWhen($this->owner instanceof Order, [
|
||||
'order' => New V1\OrderResource($this->owner)
|
||||
]),
|
||||
'shipping_transaction' => new V1\TransactionResource($this->transactions()->where('type', TransactionType::SHIPPING_INVOICE)->whereNotIn('status', [ApprovalStatus::SUSPENDED, ApprovalStatus::EXPIRED])->first()),
|
||||
'suspended_invoice' => new V1\TransactionResource($this->transactions()->where('type', TransactionType::SHIPPING_INVOICE)->whereIn('status', [ApprovalStatus::SUSPENDED])->first()),
|
||||
// 'suspended_invoices' => V1\TransactionResource::collection($this->transactions()->where('type', TransactionType::SHIPPING_INVOICE)->whereIn('status', [ApprovalStatus::SUSPENDED])->get()),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
class JobResult extends AbstractModel
|
||||
{
|
||||
protected $table = 'job_results';
|
||||
|
||||
public $fillable = [
|
||||
'job_id',
|
||||
'result'
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Carbon;
|
||||
|
||||
class PermitsReminder extends Model
|
||||
{
|
||||
use SoftDeletes;
|
||||
|
||||
protected $table = 'permits_reminders';
|
||||
|
||||
protected $dates = ['deleted_at'];
|
||||
|
||||
protected $fillable = ['model', 'expiry_date', 'reminder_date'];
|
||||
|
||||
public function getExpiryDateAttribute($value)
|
||||
{
|
||||
return $this->attributes['expiry_date'] === null ? NULL : Carbon::parse($this->attributes['expiry_date'])->format('d-m-Y');
|
||||
}
|
||||
|
||||
public function getReminderDateAttribute($value)
|
||||
{
|
||||
return $this->attributes['reminder_date'] === null ? NULL : Carbon::parse($this->attributes['reminder_date'])->format('d-m-Y');
|
||||
}
|
||||
|
||||
public function getCreatedAtAttribute($value)
|
||||
{
|
||||
return $this->attributes['created_at'] === null ? NULL : Carbon::parse($this->attributes['created_at'])->format('d-m-Y');
|
||||
}
|
||||
}
|
||||
@@ -89,6 +89,14 @@ class Transaction extends AbstractModel implements Documentable, Transactionable
|
||||
return $this->BelongsToMany(Group::class, GroupTransaction::class, 'transaction_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BelongsToMany
|
||||
*/
|
||||
public function groupsWithTrashed(): BelongsToMany
|
||||
{
|
||||
return $this->BelongsToMany(Group::class, GroupTransaction::class, 'transaction_id')->withTrashed();;
|
||||
}
|
||||
|
||||
public function convert_original_amount()
|
||||
{
|
||||
if($this->booking()->first()->fix_currency_id !== 1) {
|
||||
|
||||
@@ -54,6 +54,12 @@ return [
|
||||
'days' => 14,
|
||||
],
|
||||
|
||||
'storage_invoices' => [
|
||||
'driver' => 'single',
|
||||
'path' => storage_path('logs/laravel_storage_invoices.log'),
|
||||
'level' => 'info',
|
||||
],
|
||||
|
||||
'slack' => [
|
||||
'driver' => 'slack',
|
||||
'url' => env('LOG_SLACK_WEBHOOK_URL'),
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateJobResultsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('job_results', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('job_id', 50);
|
||||
$table->longText('result')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
// $table->foreign('job_id')->references('id')->on('jobs')->onDelete('cascade');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('job_results');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddNewColumnToJobResultsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('job_results', function (Blueprint $table) {
|
||||
$table->longText('url')->after('result')->nullable();
|
||||
$table->string('job_command_name')->after('url')->nullable();
|
||||
$table->longText('job_command')->after('job_command_name')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('job_results', function (Blueprint $table) {
|
||||
$table->dropColumn('url');
|
||||
$table->dropColumn('job_command_name');
|
||||
$table->dropColumn('job_command');
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddIsCreditTermToCompanyConnections extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('company_connections', function (Blueprint $table) {
|
||||
$table->boolean('is_credit_term')->default(false);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('company_connections', function (Blueprint $table) {
|
||||
$table->dropColumn('is_credit_term');
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddNewColumn2ToJobResultsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('job_results', function (Blueprint $table) {
|
||||
$table->string('request_signature')->after('job_id')->nullable();
|
||||
$table->string('result_signature')->after('request_signature')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('job_results', function (Blueprint $table) {
|
||||
$table->dropColumn('request_signature');
|
||||
$table->dropColumn('result_signature');
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreatePermitsRemindersTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('permits_reminders', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('model')->nullable();
|
||||
$table->timestamp('expiry_date')->nullable();
|
||||
$table->timestamp('reminder_date')->nullable();
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('permits_reminders');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddIsWaivedToTransactionsLogsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('transaction_logs', function (Blueprint $table) {
|
||||
$table->boolean('is_waived')->nullable()->after('status')->default(false);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('transaction_logs', function (Blueprint $table) {
|
||||
$table->dropColumn('is_waived');
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddIsWaivedToTransactionsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('transactions', function (Blueprint $table) {
|
||||
$table->boolean('is_waived')->nullable()->after('status')->default(false);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('transactions', function (Blueprint $table) {
|
||||
$table->dropColumn('is_waived');
|
||||
});
|
||||
}
|
||||
}
|
||||
Vendored
+2
-1
@@ -37,6 +37,7 @@ gulp.task('vendorCss', () => {
|
||||
.pipe(plugins.cleanCss())
|
||||
.pipe(plugins.replace('../../../font-awesome/', './'))
|
||||
.pipe(plugins.replace('../../jquery-ui-dist/', ''))
|
||||
//.pipe(plugins.replace(/background-image:url\(\.\.\/\.\./g, `background-image:url(`)) //cief todo: gulp
|
||||
.pipe(gulp.dest(pkg.paths.build.css));
|
||||
});
|
||||
|
||||
@@ -115,4 +116,4 @@ gulp.task('watch', (done) => {
|
||||
gulp.watch(pkg.globs.sourceJs, gulp.series('sourceJs'));
|
||||
gulp.watch(pkg.globs.sourceJs, gulp.series('sourceFonts'));
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
Binary file not shown.
+1
-1
@@ -5,7 +5,7 @@
|
||||
<div class="col-auto">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h6 class="no-margin fs-12 text-black">{{item.street_one}} {{item.street_two}}, {{item.district.name}}, {{item.post_code}} {{item.state.name}}, {{item.country.name}}</h6>
|
||||
<h6 v-if="item" class="no-margin fs-12 text-black">{{item.street_one}} {{item.street_two}}, {{item.district.name}}, {{item.post_code}} {{item.state.name}}, {{item.country.name}}</h6>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+41
-5
@@ -6,13 +6,14 @@
|
||||
<div v-show="!$store.getters.isLoading(section)">
|
||||
<list-component :section="section" :endpoint="endpoint" :options="options">
|
||||
<template slot="list" slot-scope="{data}">
|
||||
<payments-billing-components v-if="endpoint == route('api.transaction.list')" :section="section" :data="data" :selectedInvoice="selectedInvoice" v-on:input="updateList($event)"></payments-billing-components>
|
||||
<!-- <payments-billing-components v-if="endpoint == route('api.transaction.list') && !data.storages" :section="section" :data="data" :selectedInvoice="selectedInvoice" v-on:input="updateList($event)"></payments-billing-components> -->
|
||||
<payments-billing-variant-2-components v-if="endpoint == route('api.transaction.list')" :section="section" :invoices="getMergedInvoices(data, data.storages)" :selectedInvoice="selectedInvoice" :isPaidInvoices="isPaidInvoices" v-on:input="updateList($event)"></payments-billing-variant-2-components>
|
||||
<group-payments-billing-components v-else :section="section" :data="data" :selectedInvoice="selectedInvoice" v-on:input="updateList($event)"></group-payments-billing-components>
|
||||
</template>
|
||||
</list-component>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-12 col-md-4" v-if="!['customerPaidGroupInvoiceComponent', 'customerGroupPaymentInProgressInvoiceComponent'].includes(section)">
|
||||
<div class="col-12 col-sm-12 col-md-4" v-if="!['customerPaidGroupInvoiceComponent', 'customerGroupPaymentInProgressInvoiceComponent', 'customerGroupPaymentExpiredInvoiceComponent'].includes(section)">
|
||||
<div class="row align-items-center">
|
||||
<div class="col">
|
||||
<div class="row" v-if="section === 'customerPendingPaymentInvoiceComponent'">
|
||||
@@ -94,6 +95,10 @@
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
isPaidInvoices :{
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
@@ -117,7 +122,7 @@
|
||||
},
|
||||
selectedIds () {
|
||||
return this.selectedInvoice.map(s=>s.id);
|
||||
},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
generateSummaryInvoice(){
|
||||
@@ -126,9 +131,40 @@
|
||||
makePayment(){
|
||||
this.submit(this.route('api.transaction.group.create', JSON.stringify(this.selectedId)), 'post', this.section, true, false);
|
||||
},
|
||||
updateList(packageList){
|
||||
this.selectedInvoice.includes(packageList) ? this.selectedInvoice.splice(this.selectedInvoice.indexOf(packageList), 1) : this.selectedInvoice.push(packageList);
|
||||
updateList(invoices){
|
||||
invoices.forEach(invoice => {
|
||||
if (this.selectedInvoice.includes(invoice)) {
|
||||
this.selectedInvoice.splice(this.selectedInvoice.indexOf(invoice), 1);
|
||||
} else {
|
||||
this.selectedInvoice.push(invoice);
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
getMergedInvoices(shippingInvoice, storages){
|
||||
if(storages){
|
||||
const storageMap = {};
|
||||
for (const storage of storages) {
|
||||
storageMap[storage.parentInvoiceId] = storage.storageInvoiceId;
|
||||
}
|
||||
|
||||
const storageInvoiceId = storageMap[shippingInvoice.id];
|
||||
const storage = storages.find((i) => {
|
||||
return i.storageInvoiceId === storageInvoiceId;
|
||||
});
|
||||
|
||||
const mergedArray = [
|
||||
...(shippingInvoice ? [shippingInvoice] : []),
|
||||
...(storage && storage.storageInvoice.status !== 3 ? [storage.storageInvoice] : [])
|
||||
];
|
||||
return mergedArray;
|
||||
}
|
||||
|
||||
const mergedArray = [
|
||||
...(shippingInvoice ? [shippingInvoice] : [])
|
||||
];
|
||||
return mergedArray;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
+26
-5
@@ -43,6 +43,22 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col p-t-20 p-b-20 bg-master-lighter tabButton" tab-name="groupPaymentExpired">
|
||||
<div class="row justify-content-center m-b-5">
|
||||
<div class="col-auto">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
|
||||
width="35" height="35"
|
||||
viewBox="0 0 172 172"
|
||||
style=" fill:#000000;"><g fill="none" fill-rule="nonzero" stroke="none" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" font-family="none" font-weight="none" font-size="none" text-anchor="none" style="mix-blend-mode: normal"><path d="M0,172v-172h172v172z" fill="none"></path><g fill="#000000"><path d="M39.81699,21.5l-18.31699,22.89414v106.10586h129v-2.15v-103.95586l-18.31699,-22.89414zM41.88301,25.8h88.23398l13.75664,17.2h-47.12363v2.15c0,5.96338 -4.78662,10.75 -10.75,10.75c-5.96338,0 -10.75,-4.78662 -10.75,-10.75v-2.15h-47.12363zM25.8,47.3h45.58672c1.08865,7.23076 7.08802,12.9 14.61328,12.9c7.52526,0 13.52463,-5.66924 14.61328,-12.9h45.58672v98.9h-120.4zM86,68.8c-15.41089,0 -27.95,12.53911 -27.95,27.95c0,15.41089 12.53911,27.95 27.95,27.95c15.41089,0 27.95,-12.53911 27.95,-27.95c0,-15.41089 -12.53911,-27.95 -27.95,-27.95zM86,73.1c13.087,0 23.65,10.563 23.65,23.65c0,13.087 -10.563,23.65 -23.65,23.65c-13.087,0 -23.65,-10.563 -23.65,-23.65c0,-13.087 10.563,-23.65 23.65,-23.65zM85.96641,77.37061c-1.18576,0.01854 -2.13264,0.9936 -2.11641,2.17939v16.125l-7.73916,5.80332c-0.95086,0.71198 -1.1445,2.05998 -0.43252,3.01084c0.71198,0.95086 2.05998,1.1445 3.01084,0.43252l9.46084,-7.09668v-18.275c0.00796,-0.58115 -0.21968,-1.14076 -0.63105,-1.55134c-0.41137,-0.41057 -0.97142,-0.63714 -1.55255,-0.62806zM38.7,135.45c-1.18741,0 -2.15,0.96259 -2.15,2.15c0,1.18741 0.96259,2.15 2.15,2.15c1.18741,0 2.15,-0.96259 2.15,-2.15c0,-1.18741 -0.96259,-2.15 -2.15,-2.15zM47.3,135.45c-1.18741,0 -2.15,0.96259 -2.15,2.15c0,1.18741 0.96259,2.15 2.15,2.15c1.18741,0 2.15,-0.96259 2.15,-2.15c0,-1.18741 -0.96259,-2.15 -2.15,-2.15zM55.9,135.45c-1.18741,0 -2.15,0.96259 -2.15,2.15c0,1.18741 0.96259,2.15 2.15,2.15c1.18741,0 2.15,-0.96259 2.15,-2.15c0,-1.18741 -0.96259,-2.15 -2.15,-2.15zM64.5,135.45c-1.18741,0 -2.15,0.96259 -2.15,2.15c0,1.18741 0.96259,2.15 2.15,2.15c1.18741,0 2.15,-0.96259 2.15,-2.15c0,-1.18741 -0.96259,-2.15 -2.15,-2.15zM73.1,135.45c-1.18741,0 -2.15,0.96259 -2.15,2.15c0,1.18741 0.96259,2.15 2.15,2.15c1.18741,0 2.15,-0.96259 2.15,-2.15c0,-1.18741 -0.96259,-2.15 -2.15,-2.15zM81.7,135.45c-1.18741,0 -2.15,0.96259 -2.15,2.15c0,1.18741 0.96259,2.15 2.15,2.15c1.18741,0 2.15,-0.96259 2.15,-2.15c0,-1.18741 -0.96259,-2.15 -2.15,-2.15zM90.3,135.45c-1.18741,0 -2.15,0.96259 -2.15,2.15c0,1.18741 0.96259,2.15 2.15,2.15c1.18741,0 2.15,-0.96259 2.15,-2.15c0,-1.18741 -0.96259,-2.15 -2.15,-2.15zM98.9,135.45c-1.18741,0 -2.15,0.96259 -2.15,2.15c0,1.18741 0.96259,2.15 2.15,2.15c1.18741,0 2.15,-0.96259 2.15,-2.15c0,-1.18741 -0.96259,-2.15 -2.15,-2.15zM107.5,135.45c-1.18741,0 -2.15,0.96259 -2.15,2.15c0,1.18741 0.96259,2.15 2.15,2.15c1.18741,0 2.15,-0.96259 2.15,-2.15c0,-1.18741 -0.96259,-2.15 -2.15,-2.15zM116.1,135.45c-1.18741,0 -2.15,0.96259 -2.15,2.15c0,1.18741 0.96259,2.15 2.15,2.15c1.18741,0 2.15,-0.96259 2.15,-2.15c0,-1.18741 -0.96259,-2.15 -2.15,-2.15zM124.7,135.45c-1.18741,0 -2.15,0.96259 -2.15,2.15c0,1.18741 0.96259,2.15 2.15,2.15c1.18741,0 2.15,-0.96259 2.15,-2.15c0,-1.18741 -0.96259,-2.15 -2.15,-2.15zM133.3,135.45c-1.18741,0 -2.15,0.96259 -2.15,2.15c0,1.18741 0.96259,2.15 2.15,2.15c1.18741,0 2.15,-0.96259 2.15,-2.15c0,-1.18741 -0.96259,-2.15 -2.15,-2.15z"></path></g></g>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="fs-12 m-t-5 all-caps">Group Payment Expired</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col p-t-20 p-b-20 bg-master-lighter tabButton" tab-name="paidGroupInvoice">
|
||||
<div class="row justify-content-center m-b-5">
|
||||
<div class="col-auto">
|
||||
@@ -75,7 +91,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -84,22 +100,27 @@
|
||||
<div class="col bg-master-lightest p-1 p-sm-4">
|
||||
<div class="row tabsContainer tabContent" tab-name="pendingPayment">
|
||||
<div class="col">
|
||||
<customer-payment-billing-inner-component :endpoint="route('api.transaction.list')" section="customerPendingPaymentInvoiceComponent" :company_module_id="company_module_id" :options="{'per_page': 10, order_by: {column: 'id', DESC: true}, 'status_in': [2], 'receiver': company_module_id, 'type': 1, 'does_not_have_payment_status_in': [0,1] ,'does_not_have_groups': 1}"></customer-payment-billing-inner-component>
|
||||
<customer-payment-billing-inner-component :endpoint="route('api.transaction.list')" section="customerPendingPaymentInvoiceComponent" :company_module_id="company_module_id" :options="{'per_page': 10, order_by: {column: 'id', DESC: true}, 'status_in': [2], 'receiver': company_module_id, 'type_in': [1], 'does_not_have_payment_status_in': [0,1] ,'does_not_have_groups': 1, 'check_for_storage_invoice': 1}"></customer-payment-billing-inner-component>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row tabsContainer tabContent hide" tab-name="groupPaymentInProgress">
|
||||
<div class="col">
|
||||
<customer-payment-billing-inner-component :endpoint="route('api.transaction.group.list')" section="customerGroupPaymentInProgressInvoiceComponent" :company_module_id="company_module_id" :options="{'per_page': 10, order_by: {column: 'id', DESC: true}, 'status_in': [0, 1], 'receiver': company_module_id, order_by: {column: 'updated_at', DESC: true}}"></customer-payment-billing-inner-component>
|
||||
<customer-payment-billing-inner-component :endpoint="route('api.transaction.group.list')" section="customerGroupPaymentInProgressInvoiceComponent" :company_module_id="company_module_id" :options="{'per_page': 10, 'status_in': [0, 1], 'receiver': company_module_id, order_by: {column: 'updated_at', DESC: true}}"></customer-payment-billing-inner-component>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row tabsContainer tabContent hide" tab-name="groupPaymentExpired">
|
||||
<div class="col">
|
||||
<customer-payment-billing-inner-component :endpoint="route('api.transaction.group.list')" section="customerGroupPaymentExpiredInvoiceComponent" :company_module_id="company_module_id" :options="{'per_page': 10, 'status_in': [6], 'receiver': company_module_id, 'with_trashed': true, order_by: {column: 'updated_at', DESC: true}}"></customer-payment-billing-inner-component>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row tabsContainer tabContent hide" tab-name="paidGroupInvoice">
|
||||
<div class="col">
|
||||
<customer-payment-billing-inner-component :endpoint="route('api.transaction.group.list')" section="customerPaidGroupInvoiceComponent" :company_module_id="company_module_id" :options="{'per_page': 10, order_by: {column: 'id', DESC: true}, 'status_in': [2], 'receiver': company_module_id, order_by: {column: 'updated_at', DESC: true}}"></customer-payment-billing-inner-component>
|
||||
<customer-payment-billing-inner-component :endpoint="route('api.transaction.group.list')" section="customerPaidGroupInvoiceComponent" :company_module_id="company_module_id" :options="{'per_page': 10, 'status_in': [2], 'receiver': company_module_id, order_by: {column: 'updated_at', DESC: true}}"></customer-payment-billing-inner-component>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row tabsContainer tabContent hide" tab-name="paidInvoice">
|
||||
<div class="col">
|
||||
<customer-payment-billing-inner-component :endpoint="route('api.transaction.list')" section="customerPaidInvoiceComponent" :company_module_id="company_module_id" :options="{'per_page': 10, order_by: {column: 'id', DESC: true}, 'status_in': [3], 'receiver': company_module_id, 'type': 1, order_by: {column: 'updated_at', DESC: true}}"></customer-payment-billing-inner-component>
|
||||
<customer-payment-billing-inner-component :endpoint="route('api.transaction.list')" section="customerPaidInvoiceComponent" :company_module_id="company_module_id" :options="{'per_page': 10, 'status_in': [3], 'receiver': company_module_id, 'type_in': [1,16], order_by: {column: 'updated_at', DESC: true}}" :isPaidInvoices="true"></customer-payment-billing-inner-component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<div class="col bg-white padding-40 b-rad-lg">
|
||||
<div class="row m-b-10">
|
||||
<div class="col text-center">
|
||||
<p>Plese set the approximate dates of below.</p>
|
||||
<p>Please set the approximate dates of below.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
@@ -12,13 +12,13 @@
|
||||
<div class="col p-l-0 p-r-10">
|
||||
<validation-wrapper-component class="m-b-15" :validator="$v.parameters.etd">
|
||||
<label class="text-primary">Etd</label>
|
||||
<date-picker-component :parameters="parameters" :value="'etd'"></date-picker-component>
|
||||
<date-picker-component v-model.lazy="parameters.etd"></date-picker-component>
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
<div class="col p-r-0 p-l-10">
|
||||
<validation-wrapper-component class="m-b-15" :validator="$v.parameters.eta">
|
||||
<label class="text-primary">Eta</label>
|
||||
<date-picker-component :parameters="parameters" :value="'eta'"></date-picker-component>
|
||||
<date-picker-component v-model.lazy="parameters.eta"></date-picker-component>
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
</div>
|
||||
@@ -43,8 +43,8 @@
|
||||
data() {
|
||||
return {
|
||||
parameters: {
|
||||
etd: this.etd,
|
||||
eta: this.eta,
|
||||
etd: this.data.transport.current_schedule.etd,
|
||||
eta: this.data.transport.current_schedule.eta,
|
||||
}
|
||||
};
|
||||
},
|
||||
@@ -57,4 +57,4 @@
|
||||
mixins: [modalFormHandler]
|
||||
}
|
||||
|
||||
</script>
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,207 @@
|
||||
<template>
|
||||
<transition-component group enter-class="animate__animated animate__fadeInUp animate__delay-1 animate__faster p-r-30" leave-class="animate__animated animate__fadeOutDown animate__faster p-r-30" style="min-height: 300px;width:100%">
|
||||
<loading-component style="height: 200px; top: 0;" key="1" color="success" v-show="isLoading"></loading-component>
|
||||
<div class="row" key="2" v-show="!$store.getters.isLoading(section)">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row align-items-center justify-content-center p-t-50 p-b-50" v-show="!$store.getters.getListData(section).length && !isLoading && emptyListSection">
|
||||
<div class="col-10">
|
||||
<div class="row align-items-center justify-content-center hint-text">
|
||||
<div class="col-4 hint-text"><img src="/images/not-found-illustration.png" class="w-100 hint-text"/></div>
|
||||
</div>
|
||||
<div class="row text-center">
|
||||
<div class="col">
|
||||
<div class="row m-t-20">
|
||||
<div class="col">
|
||||
<p class="all-caps no-margin fs-11" style="letter-spacing: 2px;">Nothing To Show Here</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-t-5 align-items-center justify-content-center">
|
||||
<div class="col">
|
||||
<small class="fs-9 muted all-caps font-lato" style="letter-spacing: 2px">There is no results found, Try adjusting your filters to find what you are looking for.</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" v-show="!isLoading">
|
||||
<div class="col">
|
||||
<div class="list disable-text-selection" data-check-all="checkAll">
|
||||
<div class="row" ref="list" v-for="item in $store.getters.getListData(section)" v-bind:key="item.id" :data="item">
|
||||
<div class="col">
|
||||
<slot name="list" :data="item"></slot>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" v-show="!isLoading">
|
||||
<div class="col">
|
||||
<pagination-component :section="section" class="mb-5" ref="pagination"></pagination-component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</transition-component>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import requestV2 from '../../../general/mixins/aws/requestV2'
|
||||
export default {
|
||||
props: {
|
||||
section:{
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
endpoint: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
options: {
|
||||
default () {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
emptyListSection: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
filters: this.options,
|
||||
pollingInterval: null,
|
||||
isPolling: false,
|
||||
isFetchingResult: false,
|
||||
isLoading: false,
|
||||
}
|
||||
},
|
||||
created(){
|
||||
this.setDecoratorDefault();
|
||||
this.$store.dispatch('updateListQueue', {'name': this.section, 'page': 1, 'filters': this.filters}); //cief todo: Uncaught (in promise) null
|
||||
},
|
||||
computed: {
|
||||
pendingList () {
|
||||
return this.$store.getters.isInCompleteQueue(this.section);
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
pendingList(inComplete){
|
||||
if(inComplete){
|
||||
this.fetchList();
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
fetchList(){
|
||||
let listDecorators = this.$store.getters.getListDetails(this.section);
|
||||
let url = this.endpoint + '?page=' + listDecorators.page + '&filters=' + JSON.stringify(listDecorators.filters);
|
||||
this.isLoading = true;
|
||||
this.submitJob(url);
|
||||
},
|
||||
successHandler(response){
|
||||
let result = JSON.parse(response.payload.data.result);
|
||||
result.meta = {
|
||||
current_page: result.meta.current_page,
|
||||
first_page_url: result.meta.first_page_url,
|
||||
from: result.meta.from,
|
||||
last_page: result.meta.last_page,
|
||||
last_page_url: result.meta.last_page_url,
|
||||
next_page_url: result.meta.next_page_url,
|
||||
path: result.meta.path,
|
||||
per_page: result.meta.per_page,
|
||||
prev_page_url: result.meta.prev_page_url,
|
||||
to: result.meta.to,
|
||||
total: result.meta.total
|
||||
};
|
||||
|
||||
this.stopPolling();
|
||||
this.$store.dispatch('completeList', {'name': this.section, 'data': result.data});
|
||||
this.$refs.pagination.makePagination(result.meta, result.links);
|
||||
this.isLoading = false;
|
||||
},
|
||||
errorHandler(error){
|
||||
this.isFetchingResult = false;
|
||||
this.isPolling = false;
|
||||
},
|
||||
startPolling(jobId, maxAttempts = 8) {
|
||||
let attempts = 0;
|
||||
let interval = 10000; // Initial interval
|
||||
|
||||
const resetPollingInterval = (customInterval) => {
|
||||
this.pollingInterval = setInterval(pollJobResult, customInterval);
|
||||
};
|
||||
|
||||
const pollJobResult = () => {
|
||||
if (this.isPolling || this.isFetchingResult) {
|
||||
return;
|
||||
}
|
||||
this.isPolling = true;
|
||||
|
||||
attempts++;
|
||||
if(attempts === 1){
|
||||
this.stopPolling();
|
||||
resetPollingInterval(5000);
|
||||
}
|
||||
|
||||
if (attempts > maxAttempts) {
|
||||
this.stopPolling();
|
||||
this.isLoading = false;
|
||||
console.log(`Reached maximum attempts (${maxAttempts}). Polling stopped.`);
|
||||
return;
|
||||
}
|
||||
|
||||
if(attempts === maxAttempts){
|
||||
this.fetchJobResult(jobId, true);
|
||||
}
|
||||
else{
|
||||
this.fetchJobResult(jobId);
|
||||
}
|
||||
};
|
||||
|
||||
// pollJobResult(); // Initial call
|
||||
this.pollingInterval = setInterval(pollJobResult, interval);
|
||||
},
|
||||
stopPolling() {
|
||||
clearInterval(this.pollingInterval);
|
||||
this.pollingInterval = null;
|
||||
this.isPolling = false;
|
||||
this.isFetchingResult = false;
|
||||
},
|
||||
submitJob(url){
|
||||
try {
|
||||
this.$store.dispatch('crudRequestV2', {endpoint: url, method: 'get'}).then(response => {
|
||||
let success = response.ok;
|
||||
response.json().then(response => {
|
||||
if(!success){return;}
|
||||
let jobId = response.payload.data.job_id;
|
||||
if(jobId){
|
||||
this.startPolling(jobId);
|
||||
}
|
||||
});
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('Error submitJob', error);
|
||||
}
|
||||
},
|
||||
fetchJobResult(jobId, isLastAttempt = false) {
|
||||
// console.log('fetchJobResult: ', jobId);
|
||||
this.isFetchingResult = true;
|
||||
try {
|
||||
let anotherEndpoint = route('api.job.fetch', jobId);
|
||||
if(isLastAttempt){
|
||||
anotherEndpoint = route('api.job.fetch.last.attempt', jobId, isLastAttempt);
|
||||
}
|
||||
this.poll(anotherEndpoint, 'get', this.section, false, false); //cief todo: Uncaught (in promise) null
|
||||
} catch (error) {
|
||||
console.error('Error fetchJobResult', error);
|
||||
}
|
||||
}
|
||||
},
|
||||
mixins: [requestV2]
|
||||
}
|
||||
</script>
|
||||
@@ -147,8 +147,11 @@
|
||||
<p>You can view your invoices here and make payment.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row bg-master-lightest p-t-15" v-for="invoice in order.invoices">
|
||||
<div class="col">
|
||||
<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-variant-2-component :data="getMergedInvoices(invoice)" :storage="getStorageInfo(invoice)" invoice_status="Pending Payment" :section="section"></customer-payments-billing-variant-2-component>
|
||||
</div>
|
||||
<div class="col" v-else>
|
||||
<customer-payments-billing-component :data="invoice" invoice_status="Pending Payment" :section="section"></customer-payments-billing-component>
|
||||
</div>
|
||||
</div>
|
||||
@@ -180,6 +183,16 @@
|
||||
computed: {
|
||||
pendingQueue () {
|
||||
return this.$store.getters.isInCompleteQueue(this.section);
|
||||
},
|
||||
orderStorageMap() {
|
||||
// Create a map to link parent invoice IDs to storageInvoiceIds
|
||||
const storageMap = {};
|
||||
if(this.order.storages){
|
||||
for (const storage of this.order.storages) {
|
||||
storageMap[storage.parentInvoiceId] = storage.storageInvoiceId;
|
||||
}
|
||||
}
|
||||
return storageMap;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@@ -201,7 +214,36 @@
|
||||
this.$store.dispatch('completeList', {'name': this.section, 'data': []});
|
||||
this.isLoading = false;
|
||||
this.order = response.payload.data;
|
||||
}
|
||||
},
|
||||
getStorageInfo(invoice) {
|
||||
const storageObject = this.findStorageInfoObject(invoice.id);
|
||||
return storageObject;
|
||||
},
|
||||
findStorageInfoObject(shippingInvoiceId) {
|
||||
if(this.order.storages){
|
||||
return this.order.storages.find(storage => storage.parentInvoiceId === shippingInvoiceId);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
getMergedInvoices(invoice){
|
||||
const storageInvoice = this.getStorageInvoice(invoice);
|
||||
const mergedArray = [
|
||||
...(invoice ? [invoice] : []),
|
||||
...(storageInvoice ? [storageInvoice] : []),
|
||||
];
|
||||
return mergedArray;
|
||||
},
|
||||
getStorageInvoice(invoice) {
|
||||
// Retrieve the storageInvoiceId for the current shipping invoice from storage info (order.storages)
|
||||
const storageInvoiceId = this.orderStorageMap[invoice.id];
|
||||
|
||||
// Find and return the storage invoice (type 16) from order.invoices
|
||||
const storageInvoice = this.order.invoices.find((invoice) => {
|
||||
return invoice.type === 16 && invoice.id === storageInvoiceId;
|
||||
});
|
||||
|
||||
return storageInvoice;
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
+6
@@ -34,11 +34,17 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- CIEF TODO: For easy revert to old code -->
|
||||
<list-component :key="currentKey" :section="section" :endpoint="route('api.packing_list.list')" :options="options">
|
||||
<template slot="list" slot-scope="{data}">
|
||||
<admin-payments-billing-component :data="data" :invoice_status="invoice_status" :section="section" ></admin-payments-billing-component>
|
||||
</template>
|
||||
</list-component>
|
||||
<!-- <list-polling-component :key="currentKey" :section="section" :endpoint="route('api.packing_list.list.job')" :options="options">
|
||||
<template slot="list" slot-scope="{data}">
|
||||
<admin-payments-billing-component :data="data" :invoice_status="invoice_status" :section="section" ></admin-payments-billing-component>
|
||||
</template>
|
||||
</list-polling-component> -->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
<template>
|
||||
<div class="row m-t-20" @keyup.enter="search">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col-12 col-md">
|
||||
<div class="row m-b-15">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col p-r-0">
|
||||
<div class="form-group no-margin form-group-default b-rad-none">
|
||||
<label class="text-primary">Order Number Like</label>
|
||||
<input type="text" class="form-control" v-model="marking" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto p-l-0 p-r-0">
|
||||
<div class="btn btn-primary b-rad-none" @click="search">
|
||||
<i class="fa fa-search lh-40"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto p-l-0">
|
||||
<div class="btn btn-secondary b-rad-none" @click="reset">
|
||||
<i class="fa fa-remove lh-40"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-md">
|
||||
<div class="row" v-if="with_export">
|
||||
<div class="col">
|
||||
<download-billing-with-dates-component :section="section"></download-billing-with-dates-component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- CIEF TODO: For easy revert to old code -->
|
||||
<!-- <list-component :key="currentKey" :section="section" :endpoint="route('api.packing_list.list')" :options="options">
|
||||
<template slot="list" slot-scope="{data}">
|
||||
<admin-payments-billing-component :data="data" :invoice_status="invoice_status" :section="section" ></admin-payments-billing-component>
|
||||
</template>
|
||||
</list-component> -->
|
||||
<list-polling-component :key="currentKey" :section="section" :endpoint="route('api.packing_list.list.job')" :options="options">
|
||||
<template slot="list" slot-scope="{data}">
|
||||
<single-admin-payments-billing-component :data="data" :invoice_status="invoice_status" :section="section" ></single-admin-payments-billing-component>
|
||||
</template>
|
||||
</list-polling-component>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
invoice_status: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
options: {
|
||||
default () {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
section:{
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
with_export:{
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
marking: '',
|
||||
currentKey: 1,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
search() {
|
||||
this.options['order_marking_in'] = this.marking;
|
||||
this.currentKey+=1;
|
||||
},
|
||||
reset() {
|
||||
this.marking = '';
|
||||
delete(this.options['order_marking_in']);
|
||||
this.currentKey+=1;
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
+20
-6
@@ -111,6 +111,20 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row bg-master-lightest" v-if="item.payments_expired.length">
|
||||
<div class="col">
|
||||
<div class="row m-t-10 m-b-10">
|
||||
<div class="col">
|
||||
<div class="font-head fs-10 all-caps">Payment Expired</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<payment-expired-component v-for="item in item.payments_expired" v-bind:key="item.id" :data="item" ></payment-expired-component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row bg-master-lightest" v-if="item.payment_history.length">
|
||||
<div class="col">
|
||||
<div class="row m-t-10 m-b-10">
|
||||
@@ -215,12 +229,12 @@
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
cbm () {
|
||||
return (Math.ceil((this.item.packages.reduce((total, obj) => (obj.type === 2 ? 0 : obj.cbm) + total, 0)) * 1000) / 1000).toFixed(3)
|
||||
},
|
||||
overweight(){
|
||||
return (Math.ceil((this.item.packages.reduce((total, obj) => (obj.type === 2 ? obj.cbm : 0) + total, 0)) * 1000) / 1000).toFixed(3)
|
||||
},
|
||||
// cbm () {
|
||||
// return (Math.ceil((this.item.packages.reduce((total, obj) => (obj.type === 2 ? 0 : obj.cbm) + total, 0)) * 1000) / 1000).toFixed(3)
|
||||
// },
|
||||
// overweight(){
|
||||
// return (Math.ceil((this.item.packages.reduce((total, obj) => (obj.type === 2 ? obj.cbm : 0) + total, 0)) * 1000) / 1000).toFixed(3)
|
||||
// },
|
||||
latestComment() {
|
||||
let questions = this.item.remarks;
|
||||
return questions.slice().reverse()[0];
|
||||
|
||||
+316
@@ -0,0 +1,316 @@
|
||||
<template>
|
||||
<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">
|
||||
<p class="no-margin fs-10 all-caps">Invoice Date</p>
|
||||
<div> {{ item.updated_at }}</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<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">
|
||||
<p class="no-margin fs-10 all-caps">Amount</p>
|
||||
<div>MYR {{ item.amount.toFixed(2) }}</div>
|
||||
</div>
|
||||
<div class="col-2">
|
||||
<div v-if="item.remarks.length">
|
||||
<p class="no-margin fs-10 all-caps">Billing Question</p>
|
||||
<div>
|
||||
{{ getLatestComment(item).content }}
|
||||
<span class="btn requestModal no-border" v-if="item.remarks.length" size="large" data-type="chatmodal">
|
||||
<i class="fa fa-comment-o"></i>
|
||||
</span>
|
||||
</div>
|
||||
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="chatmodal">
|
||||
<remark-component :section="section" :data="item" module_type="Transaction"></remark-component>
|
||||
</modal-component>
|
||||
</div>
|
||||
<div v-else>
|
||||
<p class="no-margin fs-10 all-caps invisible">Billing Question</p>
|
||||
<div>
|
||||
<span class="btn requestModal no-border invisible">
|
||||
<i class="fa fa-edit"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-2 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>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div class="btn bg-grey no-border muted invisible">
|
||||
<i class="fa fa-file-pdf-o"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1 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="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>
|
||||
</modal-component>
|
||||
</div>
|
||||
<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 class="row">
|
||||
<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 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">
|
||||
<div class="col">
|
||||
<h6 class="all-caps m-b-5 no-margin text-underline bold">Billing question</h6>
|
||||
<remark-component :section="section" :data="item" module_type="Transaction"></remark-component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row b-t b-grey p-t-10 m-l-5 m-r-5" >
|
||||
<div class="col-12 col-md-7 padding-20">
|
||||
<div class="row bg-master-lightest">
|
||||
<div class="col">
|
||||
<div v-for="(groupItem, index) in items" class="row bg-master-lightest" v-if="groupItem.groups_payment_attempts.length && groupItem.type == 1 && groupTransactionsExist(items, groupItem.groups_payment_attempts)">
|
||||
<div class="col">
|
||||
<div class="row m-t-10 m-b-10">
|
||||
<div class="col">
|
||||
<div v-if="index === 0" class="font-head fs-10 all-caps">Payment Attempt</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<single-group-payment-transaction-details-component v-for="group in groupItem.groups_payment_attempts" v-bind:key="group.id" :data="group" :section="section"></single-group-payment-transaction-details-component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-for="(groupItem, index) in items" class="row bg-master-lightest" v-if="groupItem.groups_payment_expired.length && groupItem.type == 1 && groupTransactionsExist(items, groupItem.groups_payment_expired)">
|
||||
<div class="col">
|
||||
<div class="row m-t-10 m-b-10">
|
||||
<div class="col">
|
||||
<div v-if="index === 0" class="font-head fs-10 all-caps">Payment Expired</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<payment-expired-component v-for="group in groupItem.groups_payment_expired" v-bind:key="group.id" :data="group" :section="section"></payment-expired-component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-for="(groupItem, index) in items" class="row bg-master-lightest" v-if="groupItem.groups_payment_history.length && groupItem.type == 1 && groupTransactionsExist(items, groupItem.groups_payment_history)">
|
||||
<div class="col">
|
||||
<div class="row m-t-10 m-b-10">
|
||||
<div class="col">
|
||||
<div v-if="index === 0" class="font-head fs-10 all-caps">Payment History</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<single-group-payment-history-transaction-details-component v-for="group in groupItem.groups_payment_history" v-bind:key="group.id" :data="group" :section="section"></single-group-payment-history-transaction-details-component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-for="(paymentAttemptItem, index) in items" class="row bg-master-lightest" v-if="items.some(x => x.payment_attempts && x.payment_attempts.length > 0)">
|
||||
<div class="col">
|
||||
<div class="row m-t-10 m-b-10">
|
||||
<div class="col">
|
||||
<div v-if="index === 0" class="font-head fs-10 all-caps">Payment Attempt</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<shipping-transaction-component v-for="i in paymentAttemptItem.payment_attempts" v-bind:key="i.id" :data="i" :section="section"></shipping-transaction-component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-for="(paymentExpiredItem, index) in items" class="row bg-master-lightest" v-if="items.some(x => x.payments_expired && x.payments_expired.length > 0)">
|
||||
<div class="col">
|
||||
<div class="row m-t-10 m-b-10">
|
||||
<div class="col">
|
||||
<div v-if="index === 0" class="font-head fs-10 all-caps">Payment Expired</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<payment-expired-component v-for="i in paymentExpiredItem.payments_expired" v-bind:key="i.id" :data="i" ></payment-expired-component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-for="(paymentHistoryItem, index) in items" class="row bg-master-lightest" v-if="items.some(x => x.payment_history && x.payment_history.length > 0)">
|
||||
<div class="col">
|
||||
<div class="row m-t-10 m-b-10">
|
||||
<div class="col">
|
||||
<div v-if="index === 0" class="font-head fs-10 all-caps">Payment History</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<payment-history-component v-for="i in paymentHistoryItem.payment_history" v-bind:key="i.id" :data="i" ></payment-history-component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-md-5 padding-20 parentContainer">
|
||||
<div class="row bg-master-lightest h-100">
|
||||
<div class="col">
|
||||
<div class="row padding-10">
|
||||
<div class="col">
|
||||
<div class="row align-items-end m-b-10 text-complete">
|
||||
<div class="col">
|
||||
<div class="font-heading all-caps fs-12">Total Amount:</div>
|
||||
</div>
|
||||
<div class="col-auto text-right">
|
||||
<div class="font-heading fs-12">MYR {{(Math.round((totalAmount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row align-items-end m-b-10 text-success">
|
||||
<div class="col">
|
||||
<div class="font-heading all-caps fs-12">Paid Total:</div>
|
||||
</div>
|
||||
<div class="col-auto text-right">
|
||||
<div class="font-heading fs-12">MYR {{(Math.round((totalAmount - totalOutstanding + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row align-items-end m-b-10">
|
||||
<div class="col">
|
||||
<div class="font-heading all-caps fs-12">Floating Amount:</div>
|
||||
</div>
|
||||
<div class="col-auto text-right">
|
||||
<div class="font-heading fs-12">MYR {{(Math.round((totalFloating + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row align-items-end bold text-danger">
|
||||
<div class="col">
|
||||
<div class="font-heading all-caps fs-12">OutStanding Total:</div>
|
||||
</div>
|
||||
<div class="col-auto text-right">
|
||||
<div class="font-heading fs-12">MYR {{(Math.round((totalOutstanding + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-t-20" v-if="totalOutstanding - totalFloating > 0.009">
|
||||
<div class="col">
|
||||
<div class="btn btn-sm all-caps b-rad-none btn-success btn-block requestModal" data-type="makePayment">Make Payment</div>
|
||||
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="makePayment">
|
||||
<group-payment-form-component :section="section" :selectedIds="selectedIds" :sumAmount="totalOutstanding.toFixed(2)" :showManualPayment="true"></group-payment-form-component>
|
||||
</modal-component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
|
||||
props: {
|
||||
data: {
|
||||
type: Array,
|
||||
},
|
||||
invoice_status: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
section:{
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
storage:{
|
||||
type: Object
|
||||
},
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
items: this.data,
|
||||
parameters: {
|
||||
packing_list_id: null,
|
||||
transaction_details: [],
|
||||
},
|
||||
expanded: true,
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
data: function() {
|
||||
this.items = this.data;
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
totalAmount() {
|
||||
return this.items.reduce((sum, item) => sum + item.amount, 0);
|
||||
},
|
||||
totalOutstanding() {
|
||||
return this.items.reduce((sum, item) => sum + item.outstanding, 0);
|
||||
},
|
||||
totalFloating() {
|
||||
return this.items.reduce((sum, item) => sum + item.floating, 0);
|
||||
},
|
||||
selectedIds() {
|
||||
const ids = [];
|
||||
this.items.forEach(item => {
|
||||
ids.push(item.id);
|
||||
});
|
||||
return ids;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
getLatestComment(item) {
|
||||
let questions = item.remarks;
|
||||
return questions.slice().reverse()[0];
|
||||
},
|
||||
successHandler(response){
|
||||
this.item = response.payload.data;
|
||||
},
|
||||
groupTransactionsExist(items, groups) {
|
||||
return groups.some(group =>
|
||||
group.transactions_ids.length === items.length &&
|
||||
group.transactions_ids.every(transaction =>
|
||||
items.some(item => item.id === transaction.transaction_id)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user