mirror of
https://gitlab.com/CIEFWorldwideSdnBhd/exchange-2.0.git
synced 2026-08-19 04:23:55 +00:00
Merge branch 'vapor/production' of https://gitlab.com/CIEFWorldwideSdnBhd/exchange-2.0 into vapor/production
This commit is contained in:
@@ -75,3 +75,8 @@ LARAVEL_VAPOR_ENABLED=false
|
||||
COMMANDS_V2_ENABLED=false
|
||||
SENDING_EMAIL_ENABLED=false
|
||||
SENDING_EMAIL_WELCOME_VOUCHER_ENABLED=false
|
||||
|
||||
|
||||
E_INVOICE_START_DATE="2025-07-01 00:00:00"
|
||||
MAINTENANCE_MESSAGE_TITLE="We'll be back online on 00:00 1/7/2025"
|
||||
MAINTENANCE_MESSAGE="Sorry for the inconvenience but we're performing some maintenance at the moment."
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Exceptions;
|
||||
|
||||
use App\Classes\ValueObjects\Constants\HttpStatus;
|
||||
|
||||
final class CriteriaNotFulfilledException extends ServiceApiException {
|
||||
public function __construct(?string $message = null) {
|
||||
parent::__construct(
|
||||
$message ?? 'One or more required criteria were not fulfilled.',
|
||||
HttpStatus::VALIDATION_FAILED
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ namespace App\Classes\General\Abstracts;
|
||||
|
||||
|
||||
use App\Classes\Exceptions\AccessForbiddenException;
|
||||
use App\Classes\Exceptions\CriteriaNotFulfilledException;
|
||||
use App\Classes\Exceptions\RequestValidationException;
|
||||
use App\Classes\General\Interfaces\DataTransferObject;
|
||||
|
||||
@@ -23,6 +24,7 @@ abstract class AbstractRule
|
||||
* @return bool
|
||||
* @throws AccessForbiddenException
|
||||
* @throws RequestValidationException
|
||||
* @throws CriteriaNotFulfilledException
|
||||
*/
|
||||
public function passes(?DataTransferObject $object = null): bool {
|
||||
try {
|
||||
@@ -35,12 +37,14 @@ abstract class AbstractRule
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
} catch(AccessForbiddenException $exception){
|
||||
throw new AccessForbiddenException('You don\'t have permission to perform this action');
|
||||
} catch(CriteriaNotFulfilledException $exception){
|
||||
throw new CriteriaNotFulfilledException($exception->getMessage());
|
||||
} catch(\Exception $exception){
|
||||
throw new RequestValidationException($exception->getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\General\Eloquent\Filters;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class IsEInvoice implements Filter
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Builder $builder
|
||||
* @param $value
|
||||
* @return Builder|mixed
|
||||
*/
|
||||
public static function apply(Builder $builder, $value)
|
||||
{
|
||||
return $builder->where('e_invoice', $value);
|
||||
}
|
||||
}
|
||||
@@ -4,8 +4,8 @@ namespace App\Classes\General;
|
||||
|
||||
use Illuminate\Http\Resources\Json\ResourceCollection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
use NumberToWords\NumberToWords;
|
||||
|
||||
class Helper
|
||||
{
|
||||
@@ -66,4 +66,25 @@ class Helper
|
||||
return json_decode($collection->response()->getContent(), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a given number to words based on the specified locale.
|
||||
*
|
||||
* @param int|float $number
|
||||
* @param string $locale The locale to use for conversion (default is 'en').
|
||||
* @return string
|
||||
*/
|
||||
static function convert($number, $locale = 'en')
|
||||
{
|
||||
$numberToWords = new NumberToWords();
|
||||
$numberTransformer = $numberToWords->getNumberTransformer($locale);
|
||||
|
||||
$number = number_format((float)$number, 2, '.', '');
|
||||
[$ringgit, $cents] = explode('.', $number);
|
||||
|
||||
$ringgitWords = $numberTransformer->toWords((int)$ringgit);
|
||||
$centsWords = $numberTransformer->toWords((int)$cents);
|
||||
|
||||
return strtoupper('ringgit ' . $ringgitWords . ' and ' . $centsWords . ' cents only');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -50,10 +50,10 @@ class ListAddressesLogic extends AbstractControllerLogic
|
||||
public function logic(Request $request) : JsonResponse
|
||||
{
|
||||
try {
|
||||
|
||||
$this->canListAddresses->passes();
|
||||
|
||||
$query = $this->listsAddresses->execute($this->listsAddresses->deserializeFilters($request->input('filters')));
|
||||
$query = $this->listsAddresses->execute(
|
||||
array_merge($this->listsAddresses->deserializeFilters($request->input('filters')), ['is_e_invoice' => false])); //exclude all addresses meant for e_invoice
|
||||
|
||||
return $this->collectionResponse(AddressResource::collection($query));
|
||||
|
||||
@@ -63,4 +63,4 @@ class ListAddressesLogic extends AbstractControllerLogic
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Addresses\ControllersLogic;
|
||||
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Addresses\Services\ListsStates;
|
||||
use App\Classes\Modules\Addresses\Standards\Rules\CanListAddresses;
|
||||
use App\Http\Resources\StateResource;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ListStatesLogic extends AbstractControllerLogic
|
||||
{
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function notification():array {
|
||||
return [
|
||||
'title' => 'Retrieved States',
|
||||
'message' => 'You have successfully retrieved a list of States'
|
||||
];
|
||||
}
|
||||
|
||||
/** @var ListsStates */
|
||||
private $listsStates;
|
||||
|
||||
/**
|
||||
* ListStatesLogic constructor.
|
||||
* @param ListsStates $listsStates
|
||||
*/
|
||||
public function __construct(ListsStates $listsStates)
|
||||
{
|
||||
$this->listsStates = $listsStates;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
*/
|
||||
public function logic(Request $request) : JsonResponse
|
||||
{
|
||||
$query = $this->listsStates->execute($this->listsStates->deserializeFilters($request->input('filters')));
|
||||
|
||||
return $this->collectionResponse(StateResource::collection($query));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Addresses\Services;
|
||||
|
||||
|
||||
use App\Classes\General\Eloquent\AbstractListRecord;
|
||||
use App\Models\State;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class ListsStates extends AbstractListRecord
|
||||
{
|
||||
|
||||
/** @var State */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* ListsStates constructor.
|
||||
* @param State $repository
|
||||
*/
|
||||
public function __construct(State $repository)
|
||||
{
|
||||
$this->repository = $repository;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return Builder
|
||||
*/
|
||||
function getRepository(): Builder
|
||||
{
|
||||
return $this->repository->newQuery();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Addresses\Services;
|
||||
|
||||
|
||||
use App\Classes\General\Eloquent\AbstractUpdateRecord;
|
||||
use App\Models\Address;
|
||||
|
||||
class UpdatesAddressMetadata extends AbstractUpdateRecord
|
||||
{
|
||||
/**
|
||||
* @param Address $model
|
||||
* @param bool $billing
|
||||
* @param bool $eInvoice
|
||||
* @return \Illuminate\Database\Eloquent\Model
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
*/
|
||||
public function execute(Address $model, bool $billing, bool $eInvoice) {
|
||||
|
||||
$model->billing = $billing;
|
||||
$model->e_invoice = $eInvoice;
|
||||
|
||||
return $this->handler($model);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Addresses\Services;
|
||||
|
||||
|
||||
use App\Classes\General\Eloquent\AbstractUpdateRelationshipRecord;
|
||||
use App\Classes\Modules\Addresses\DataTransferObjects\AddressObject;
|
||||
use App\Models\Address;
|
||||
use App\Models\Company;
|
||||
|
||||
class UpsertsAddress extends AbstractUpdateRelationshipRecord
|
||||
{
|
||||
/**
|
||||
* Create or update the company's address.
|
||||
*
|
||||
* @param Company $company
|
||||
* @param AddressObject $object
|
||||
* @param int $id
|
||||
* @return \Illuminate\Database\Eloquent\Model
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
*/
|
||||
public function execute(Company $company, AddressObject $object, int $id)
|
||||
{
|
||||
//Create new or update?
|
||||
$model = $company->addresses()->where('id', $id)->first() ?? new Address();
|
||||
|
||||
$model->street_one = $object->getStreetOne();
|
||||
$model->street_two = $object->getStreetTwo();
|
||||
$model->country_id = $object->getCountryId();
|
||||
$model->state_id = $object->getStateId();
|
||||
$model->district_id = $object->getDistrictId();
|
||||
$model->postcode = $object->getPostCode();
|
||||
|
||||
return $this->handler($company->addresses(), $model);
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ namespace App\Classes\Modules\Billplzs\ControllersLogic;
|
||||
use App\Classes\Modules\Wallets\DataTransferObjects\WalletObject;
|
||||
use App\Classes\Modules\Wallets\Services\UpdatesWallet;
|
||||
use App\Classes\Modules\Transactions\Processors\CreateCashBackTransactionProcessor;
|
||||
use App\Classes\Modules\Transactions\Processors\CreateReceiptVoucherTransactionProcessor;
|
||||
|
||||
use App\Classes\Exceptions\ResourceNotFoundException;
|
||||
use App\Classes\Modules\Wallets\Services\UpdatesWalletBalance;
|
||||
@@ -49,6 +50,9 @@ class CallbackBillplzLogic
|
||||
/** @var RecalculatesWalletBalance */
|
||||
private $recalculatesWalletBalance;
|
||||
|
||||
/** @var CreateReceiptVoucherTransactionProcessor */
|
||||
private $createReceiptVoucherTransactionProcessor;
|
||||
|
||||
/**
|
||||
* CallbackBillplzLogic constructor.
|
||||
* @param GetBillplzBill $getBillplzBill
|
||||
@@ -56,8 +60,9 @@ class CallbackBillplzLogic
|
||||
* @param UpdatesTransactionStatus $updatesTransactionStatus
|
||||
* @param UpdatesWalletBalance $updatesWalletBalance
|
||||
* @param RecalculatesWalletBalance $recalculatesWalletBalance
|
||||
* @param CreateReceiptVoucherTransactionProcessor $createReceiptVoucherTransactionProcessor
|
||||
*/
|
||||
public function __construct(GetBillplzBill $getBillplzBill, FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus, UpdatesWalletBalance $updatesWalletBalance, CreateCashBackTransactionProcessor $createCashBackTransactionProcessor, RecalculatesWalletBalance $recalculatesWalletBalance)
|
||||
public function __construct(GetBillplzBill $getBillplzBill, FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus, UpdatesWalletBalance $updatesWalletBalance, CreateCashBackTransactionProcessor $createCashBackTransactionProcessor, RecalculatesWalletBalance $recalculatesWalletBalance, CreateReceiptVoucherTransactionProcessor $createReceiptVoucherTransactionProcessor)
|
||||
{
|
||||
$this->getBillplzBill = $getBillplzBill;
|
||||
$this->fetchesTransaction = $fetchesTransaction;
|
||||
@@ -65,6 +70,7 @@ class CallbackBillplzLogic
|
||||
$this->updatesWalletBalance = $updatesWalletBalance;
|
||||
$this->createCashBackTransactionProcessor = $createCashBackTransactionProcessor;
|
||||
$this->recalculatesWalletBalance = $recalculatesWalletBalance;
|
||||
$this->createReceiptVoucherTransactionProcessor = $createReceiptVoucherTransactionProcessor;
|
||||
}
|
||||
|
||||
|
||||
@@ -105,6 +111,12 @@ class CallbackBillplzLogic
|
||||
$this->updatesWalletBalance->execute($transaction->owner, $transaction->amount);
|
||||
}
|
||||
|
||||
$booking = $transaction->owner instanceof Booking ? $transaction->booking : (count($transaction->owner->owner->bookings()->get())? $transaction->owner->owner->bookings()->orderBy('id', 'DESC')->first(): null);
|
||||
|
||||
if($transaction->owner instanceof Booking && $booking && $transaction){
|
||||
$this->createReceiptVoucherTransactionProcessor->execute($booking, $transaction);
|
||||
}
|
||||
|
||||
// if ($transaction->type == TransactionType::PAYMENT) {
|
||||
// $cash_back_transaction = $this->createCashBackTransactionProcessor->execute($transaction);
|
||||
// }
|
||||
@@ -117,4 +129,4 @@ class CallbackBillplzLogic
|
||||
return $request->method() === 'POST' ? true : view('pages.payments_redirect', ['marking' => $marking ?? null, 'transaction' => $transaction, 'status' => $status]);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
<?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::info('DeletesBillplzBill bill with id '. $billID . ' 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,42 +11,15 @@ use App\Classes\Modules\Transactions\Services\FetchesTransaction;
|
||||
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
|
||||
|
||||
use App\Classes\Modules\Transactions\Processors\CreateCashBackTransactionProcessor;
|
||||
use App\Classes\Modules\Transactions\Processors\CreateReceiptVoucherTransactionProcessor;
|
||||
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
|
||||
use App\Models\Booking;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ApprovePaymentVerificationLogic extends AbstractControllerLogic
|
||||
{
|
||||
/**
|
||||
* ApprovePaymentVerificationLogic constructor.
|
||||
* @param FetchesTransaction $fetchesTransaction
|
||||
* @param UpdatesTransactionStatus $updatesTransactionStatus
|
||||
* @param ApprovesDocument $approvesDocument
|
||||
* @param RejectsDocument $rejectsDocument
|
||||
* @param FetchesDocument $fetchesDocument
|
||||
* @param CreateCashBackTransactionProcessor $createCashBackTransactionProcessor
|
||||
*/
|
||||
public function __construct(FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus, ApprovesDocument $approvesDocument, RejectsDocument $rejectsDocument, FetchesDocument $fetchesDocument, CreateCashBackTransactionProcessor $createCashBackTransactionProcessor)
|
||||
{
|
||||
$this->fetchesTransaction = $fetchesTransaction;
|
||||
$this->updatesTransactionStatus = $updatesTransactionStatus;
|
||||
$this->approvesDocument = $approvesDocument;
|
||||
$this->rejectsDocument = $rejectsDocument;
|
||||
$this->createCashBackTransactionProcessor = $createCashBackTransactionProcessor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function notification():array {
|
||||
return [
|
||||
'title' => 'Payment Status',
|
||||
'message' => 'You have successfully updated the payment status'
|
||||
];
|
||||
}
|
||||
|
||||
/** @var FetchesTransaction */
|
||||
private $fetchesTransaction;
|
||||
|
||||
@@ -62,6 +35,39 @@ class ApprovePaymentVerificationLogic extends AbstractControllerLogic
|
||||
/** @var CreateCashBackTransactionProcessor */
|
||||
private $createCashBackTransactionProcessor;
|
||||
|
||||
/** @var CreateReceiptVoucherTransactionProcessor */
|
||||
private $createReceiptVoucherTransactionProcessor;
|
||||
|
||||
/**
|
||||
* ApprovePaymentVerificationLogic constructor.
|
||||
* @param FetchesTransaction $fetchesTransaction
|
||||
* @param UpdatesTransactionStatus $updatesTransactionStatus
|
||||
* @param ApprovesDocument $approvesDocument
|
||||
* @param RejectsDocument $rejectsDocument
|
||||
* @param FetchesDocument $fetchesDocument
|
||||
* @param CreateCashBackTransactionProcessor $createCashBackTransactionProcessor
|
||||
* @param CreateReceiptVoucherTransactionProcessor $createReceiptVoucherTransactionProcessor
|
||||
*/
|
||||
public function __construct(FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus, ApprovesDocument $approvesDocument, RejectsDocument $rejectsDocument, FetchesDocument $fetchesDocument, CreateCashBackTransactionProcessor $createCashBackTransactionProcessor, CreateReceiptVoucherTransactionProcessor $createReceiptVoucherTransactionProcessor)
|
||||
{
|
||||
$this->fetchesTransaction = $fetchesTransaction;
|
||||
$this->updatesTransactionStatus = $updatesTransactionStatus;
|
||||
$this->approvesDocument = $approvesDocument;
|
||||
$this->rejectsDocument = $rejectsDocument;
|
||||
$this->createCashBackTransactionProcessor = $createCashBackTransactionProcessor;
|
||||
$this->createReceiptVoucherTransactionProcessor = $createReceiptVoucherTransactionProcessor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function notification():array {
|
||||
return [
|
||||
'title' => 'Payment Status',
|
||||
'message' => 'You have successfully updated the payment status'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
@@ -77,9 +83,14 @@ class ApprovePaymentVerificationLogic extends AbstractControllerLogic
|
||||
|
||||
$this->updatesTransactionStatus->execute($transaction, $status === 'approve' ? ApprovalStatus::APPROVED : ApprovalStatus::REJECTED);
|
||||
|
||||
$booking = $transaction->owner instanceof Booking ? $transaction->booking : null;
|
||||
|
||||
if($booking && $transaction){
|
||||
$this->createReceiptVoucherTransactionProcessor->execute($booking, $transaction);
|
||||
}
|
||||
// $this->createCashBackTransactionProcessor->execute($transaction);
|
||||
|
||||
return $this->response([]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace App\Classes\Modules\Bookings\ControllersLogic;
|
||||
|
||||
|
||||
use App\Classes\Exceptions\CriteriaNotFulfilledException;
|
||||
use App\Classes\Exceptions\MalformedRequestException;
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Bookings\Services\CalculatesBookingOutstanding;
|
||||
@@ -16,9 +16,17 @@ use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
|
||||
use App\Classes\Modules\Wallets\Services\UpdatesWalletBalance;
|
||||
use App\Classes\Modules\Currencies\DataTransferObjects\CurrencyConversionObject;
|
||||
use App\Classes\Modules\Bookings\Services\CalculatesBookingRefundAmount;
|
||||
use App\Classes\Modules\Bookings\DataTransferObjects\ConfirmBookingDTO;
|
||||
use App\Classes\Modules\Rules\Standards\Rules\CanPassEInvoicePromptedRule;
|
||||
use App\Classes\Modules\Rules\Standards\Rules\CanPassPurchaseOrderRule;
|
||||
use App\Classes\Modules\Rules\Standards\Rules\CanPassTINRule;
|
||||
use App\Classes\Modules\Transactions\Processors\CreateCashBackTransactionProcessor;
|
||||
use App\Classes\Modules\Vouchers\Processors\Voucherify\BookingToVoucherifyProcessor;
|
||||
use App\Classes\Modules\Wallets\Services\RecalculatesWalletBalance;
|
||||
use App\Classes\Modules\Rules\Services\RuleEvaluator;
|
||||
use App\Classes\Modules\Rules\Standards\Rules\CanPassOrderDurationLimitRule;
|
||||
use App\Classes\Modules\Transactions\Processors\CreateReceiptVoucherTransactionProcessor;
|
||||
use App\Classes\Modules\Transactions\Services\CalculatesTransactionExpiryDateTime;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\PaymentMethodType;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
@@ -80,6 +88,27 @@ class CreateBookingPaymentLogic extends AbstractControllerLogic
|
||||
/** @var CalculatesBookingRefundAmount */
|
||||
private $calculatesBookingRefundAmount;
|
||||
|
||||
/** @var RuleEvaluator */
|
||||
private $ruleEvaluator;
|
||||
|
||||
/** @var CreateReceiptVoucherTransactionProcessor */
|
||||
private $createReceiptVoucherTransactionProcessor;
|
||||
|
||||
/** @var CanPassOrderDurationLimitRule */
|
||||
protected $canPassOrderDurationLimitRule;
|
||||
|
||||
/** @var CanPassEInvoicePromptedRule */
|
||||
protected $canPassEInvoicePromptedRule;
|
||||
|
||||
/** @var CanPassTINRule */
|
||||
protected $canPassTINRule;
|
||||
|
||||
/** @var CanPassPurchaseOrderRule */
|
||||
protected $canPassPurchaseOrderRule;
|
||||
|
||||
/** @var CalculatesTransactionExpiryDateTime */
|
||||
protected $calculatesTransactionExpiryDateTime;
|
||||
|
||||
/**
|
||||
* CreateBookingPaymentLogic constructor.
|
||||
* @param FetchesBookingQuotation $fetchBookingQuotation
|
||||
@@ -94,8 +123,15 @@ class CreateBookingPaymentLogic extends AbstractControllerLogic
|
||||
* @param RecalculatesWalletBalance $recalculatesWalletBalance
|
||||
* @param BookingToVoucherifyProcessor $bookingToVoucherifyProcessor
|
||||
* @param CalculatesBookingRefundAmount $calculatesBookingRefundAmount
|
||||
* @param RuleEvaluator $ruleEvaluator
|
||||
* @param CreateReceiptVoucherTransactionProcessor $createReceiptVoucherTransactionProcessor
|
||||
* @param CanPassOrderDurationLimitRule $canPassOrderDurationLimitRule
|
||||
* @param CanPassEInvoicePromptedRule $canPassEInvoicePromptedRule
|
||||
* @param CanPassTINRule $canPassTINRule
|
||||
* @param CanPassPurchaseOrderRule $canPassPurchaseOrderRule
|
||||
* @param CalculatesTransactionExpiryDateTime $calculatesTransactionExpiryDateTime
|
||||
*/
|
||||
public function __construct(FetchesBookingQuotation $fetchBookingQuotation, FetchesCompanyPaymentAttemptLimit $fetchesCompanyPaymentAttemptLimit, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CreatesTransaction $createsTransaction, CalculatesBookingOutstanding $calculatesBookingOutstanding, CreatesBillplzBill $createsBillplzBill, UpdatesWalletBalance $updatesWalletBalance, UpdatesTransactionStatus $updatesTransactionStatus, CreateCashBackTransactionProcessor $createCashBackTransactionProcessor, RecalculatesWalletBalance $recalculatesWalletBalance, BookingToVoucherifyProcessor $bookingToVoucherifyProcessor, CalculatesBookingRefundAmount $calculatesBookingRefundAmount)
|
||||
public function __construct(FetchesBookingQuotation $fetchBookingQuotation, FetchesCompanyPaymentAttemptLimit $fetchesCompanyPaymentAttemptLimit, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CreatesTransaction $createsTransaction, CalculatesBookingOutstanding $calculatesBookingOutstanding, CreatesBillplzBill $createsBillplzBill, UpdatesWalletBalance $updatesWalletBalance, UpdatesTransactionStatus $updatesTransactionStatus, CreateCashBackTransactionProcessor $createCashBackTransactionProcessor, RecalculatesWalletBalance $recalculatesWalletBalance, BookingToVoucherifyProcessor $bookingToVoucherifyProcessor, CalculatesBookingRefundAmount $calculatesBookingRefundAmount, RuleEvaluator $ruleEvaluator, CreateReceiptVoucherTransactionProcessor $createReceiptVoucherTransactionProcessor, CanPassOrderDurationLimitRule $canPassOrderDurationLimitRule, CanPassEInvoicePromptedRule $canPassEInvoicePromptedRule, CanPassTINRule $canPassTINRule, CanPassPurchaseOrderRule $canPassPurchaseOrderRule, CalculatesTransactionExpiryDateTime $calculatesTransactionExpiryDateTime)
|
||||
{
|
||||
$this->fetchBookingQuotation = $fetchBookingQuotation;
|
||||
$this->fetchesCompanyPaymentAttemptLimit = $fetchesCompanyPaymentAttemptLimit;
|
||||
@@ -109,15 +145,35 @@ class CreateBookingPaymentLogic extends AbstractControllerLogic
|
||||
$this->recalculatesWalletBalance = $recalculatesWalletBalance;
|
||||
$this->bookingToVoucherifyProcessor = $bookingToVoucherifyProcessor;
|
||||
$this->calculatesBookingRefundAmount = $calculatesBookingRefundAmount;
|
||||
$this->ruleEvaluator = $ruleEvaluator;
|
||||
$this->createReceiptVoucherTransactionProcessor = $createReceiptVoucherTransactionProcessor;
|
||||
$this->canPassOrderDurationLimitRule = $canPassOrderDurationLimitRule;
|
||||
$this->canPassEInvoicePromptedRule = $canPassEInvoicePromptedRule;
|
||||
$this->canPassTINRule = $canPassTINRule;
|
||||
$this->canPassPurchaseOrderRule = $canPassPurchaseOrderRule;
|
||||
$this->calculatesTransactionExpiryDateTime = $calculatesTransactionExpiryDateTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
* @throws MalformedRequestException
|
||||
* @throws CriteriaNotFulfilledException
|
||||
*/
|
||||
public function logic(Request $request) : JsonResponse
|
||||
{
|
||||
$dto = new ConfirmBookingDTO($request->all());
|
||||
$result = $this->ruleEvaluator->evaluate([
|
||||
$this->canPassOrderDurationLimitRule,
|
||||
$this->canPassEInvoicePromptedRule,
|
||||
$this->canPassTINRule,
|
||||
$this->canPassPurchaseOrderRule,
|
||||
], $dto);
|
||||
|
||||
if ($result->failed()) {
|
||||
throw new CriteriaNotFulfilledException("- " . implode("<br>- ", $result->messages()));
|
||||
}
|
||||
|
||||
$voucherCode = $request->input('voucher_code');
|
||||
|
||||
$booking = Booking::find($request->route('id'));
|
||||
@@ -162,11 +218,14 @@ class CreateBookingPaymentLogic extends AbstractControllerLogic
|
||||
|
||||
$billNumber = $this->generatesTransactionBillNumber->execute('PYMT-');
|
||||
|
||||
// $expiresOn = Carbon::now()->addMinutes($paymentAttemptLimit);
|
||||
$expiresOn = $this->calculatesTransactionExpiryDateTime->execute($booking->id);
|
||||
|
||||
$object = new TransactionObject($billNumber, TransactionType::PAYMENT, 1, $booking->company->id,
|
||||
$configurations->getConfigurations()->getBankId(), $configurations->getConversionObject()->getPaymentMethod(),
|
||||
$configurations->getTotal(), $configurations->getForeignTotal(), 1,
|
||||
$configurations->getConversionObject()->getCurrencyId(), $configurations->getConfigurations()->getRate(),
|
||||
$configurations->getTax(), $configurations->getServiceCharge(), Carbon::now()->addMinutes($paymentAttemptLimit), ApprovalStatus::PENDING_SUBMISSION, [], $paymentReference);
|
||||
$configurations->getTax(), $configurations->getServiceCharge(), $expiresOn, ApprovalStatus::PENDING_SUBMISSION, [], $paymentReference);
|
||||
|
||||
/** @var Transaction $transaction */
|
||||
$transaction = $this->createsTransaction->execute($booking, $object);
|
||||
@@ -176,6 +235,7 @@ class CreateBookingPaymentLogic extends AbstractControllerLogic
|
||||
|
||||
if(PaymentMethodType::PAYMENT_METHODS[$request->input('payment_method')] == PaymentMethodType::WALLET){
|
||||
$this->updatesTransactionStatus->execute($transaction, ApprovalStatus::APPROVED);
|
||||
$this->createReceiptVoucherTransactionProcessor->execute($booking, $transaction);
|
||||
}
|
||||
|
||||
return $this->resourceResponse(new TransactionResource($transaction));
|
||||
|
||||
@@ -93,9 +93,10 @@ class CreateBookingRefundLogic extends AbstractControllerLogic
|
||||
|
||||
$invoice = $booking->transactions()->where('type', TransactionType::INVOICE)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->first();
|
||||
|
||||
if(auth()->user()->type === 3) {
|
||||
throw new MalformedRequestException('You do not have the permission to refund the order.');
|
||||
}
|
||||
//cief todo: 90 - move this into rules
|
||||
// if(auth()->user()->type === 3) {
|
||||
// throw new MalformedRequestException('You do not have the permission to refund the order.');
|
||||
// }
|
||||
|
||||
$billNumber = $this->generatesTransactionBillNumber->execute('RFD-');
|
||||
|
||||
@@ -117,7 +118,7 @@ class CreateBookingRefundLogic extends AbstractControllerLogic
|
||||
$refundAmount = $transaction->original_amount / $transaction->currency_rate;
|
||||
$service_charges_to_refund = $transaction->service_charge;
|
||||
} else {
|
||||
// partial refund
|
||||
// partial refund
|
||||
$refundAmount = bcdiv($request->input('amount'), $transaction->currency_rate, 7);
|
||||
|
||||
$bookingAmountBeforeCurrentRefund = $booking->fix_amount - $refundInPending;
|
||||
@@ -159,7 +160,7 @@ class CreateBookingRefundLogic extends AbstractControllerLogic
|
||||
|
||||
$refund_transaction = $this->createsTransaction->execute($transaction, $object);
|
||||
|
||||
$bookingInWhiteForm = $transaction->transactions()->bills()->first();
|
||||
$bookingInWhiteForm = $transaction->transactions()->bills()->first(); // if no white form created yet can approve right away
|
||||
|
||||
// create supplier refund
|
||||
if ($bookingInWhiteForm) {
|
||||
|
||||
+25
-3
@@ -2,8 +2,9 @@
|
||||
|
||||
namespace App\Classes\Modules\Bookings\ControllersLogic;
|
||||
|
||||
|
||||
use App\Classes\Exceptions\CriteriaNotFulfilledException;
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Bookings\DataTransferObjects\CreatePaymentVerificationDocumentDTO;
|
||||
use App\Classes\Modules\Companies\Services\FetchesCompany;
|
||||
use App\Classes\Modules\Companies\Services\UpdatesCompanyStatus;
|
||||
use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
|
||||
@@ -11,6 +12,8 @@ use App\Classes\Modules\Documents\Services\CreatesDocument;
|
||||
use App\Classes\Modules\Documents\Services\CreatesFiles;
|
||||
use App\Classes\Modules\Transactions\Services\FetchesTransaction;
|
||||
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
|
||||
use App\Classes\Modules\Rules\Services\RuleEvaluator;
|
||||
use App\Classes\Modules\Rules\Standards\Rules\CanPassOrderDurationLimitRule;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\CompanyType;
|
||||
use App\Classes\ValueObjects\Constants\DocumentType;
|
||||
@@ -44,19 +47,29 @@ class CreatePaymentVerificationDocumentLogic extends AbstractControllerLogic
|
||||
/** @var UpdatesTransactionStatus */
|
||||
private $updatesTransactionStatus;
|
||||
|
||||
/** @var RuleEvaluator */
|
||||
private $ruleEvaluator;
|
||||
|
||||
/** @var CanPassOrderDurationLimitRule */
|
||||
private $canPassOrderDurationLimitRule;
|
||||
|
||||
/**
|
||||
* CreatePaymentVerificationDocumentLogic constructor.
|
||||
* @param FetchesTransaction $fetchesTransaction
|
||||
* @param CreatesDocument $createsDocument
|
||||
* @param CreatesFiles $createsFile
|
||||
* @param UpdatesTransactionStatus $updatesTransactionStatus
|
||||
* @param RuleEvaluator $ruleEvaluator
|
||||
* @param CanPassOrderDurationLimitRule $canPassOrderDurationLimitRule
|
||||
*/
|
||||
public function __construct(FetchesTransaction $fetchesTransaction, CreatesDocument $createsDocument, CreatesFiles $createsFile, UpdatesTransactionStatus $updatesTransactionStatus)
|
||||
public function __construct(FetchesTransaction $fetchesTransaction, CreatesDocument $createsDocument, CreatesFiles $createsFile, UpdatesTransactionStatus $updatesTransactionStatus, RuleEvaluator $ruleEvaluator, CanPassOrderDurationLimitRule $canPassOrderDurationLimitRule)
|
||||
{
|
||||
$this->fetchesTransaction = $fetchesTransaction;
|
||||
$this->createsDocument = $createsDocument;
|
||||
$this->createsFile = $createsFile;
|
||||
$this->updatesTransactionStatus = $updatesTransactionStatus;
|
||||
$this->ruleEvaluator = $ruleEvaluator;
|
||||
$this->canPassOrderDurationLimitRule = $canPassOrderDurationLimitRule;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,6 +79,15 @@ class CreatePaymentVerificationDocumentLogic extends AbstractControllerLogic
|
||||
*/
|
||||
public function logic(Request $request) : JsonResponse
|
||||
{
|
||||
$dto = new CreatePaymentVerificationDocumentDTO($request->all());
|
||||
|
||||
$result = $this->ruleEvaluator->evaluate([
|
||||
$this->canPassOrderDurationLimitRule,
|
||||
], $dto);
|
||||
|
||||
if ($result->failed()) {
|
||||
throw new CriteriaNotFulfilledException("- " . implode("<br>- ", $result->messages()));
|
||||
}
|
||||
|
||||
$transaction = $this->fetchesTransaction->execute(['id' => $request->route('payment_id')]);
|
||||
|
||||
@@ -80,4 +102,4 @@ class CreatePaymentVerificationDocumentLogic extends AbstractControllerLogic
|
||||
return $this->response([]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Bookings\ControllersLogic;
|
||||
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Bookings\Services\FetchesBooking;
|
||||
use App\Classes\Modules\Transactions\Services\FetchesTransaction;
|
||||
use App\Classes\Modules\Bookings\Standards\Rules\CanFetchBooking;
|
||||
use App\Classes\Modules\Transactions\Processors\CreateReceiptVoucherTransactionProcessor;
|
||||
use App\Http\Resources\BookingResource;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class RegenerateBookingPaymentRVLogic extends AbstractControllerLogic
|
||||
{
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function notification(): array
|
||||
{
|
||||
return [
|
||||
'title' => 'Regenerate Booking Payment Receipt Voucher',
|
||||
'message' => 'You have successfully regenerate booking payment receipt voucher'
|
||||
];
|
||||
}
|
||||
|
||||
/** @var CanFetchBooking */
|
||||
private $canFetchBooking;
|
||||
|
||||
/** @var FetchesBooking */
|
||||
private $fetchesBooking;
|
||||
|
||||
/** @var FetchesTransaction */
|
||||
private $fetchesTransaction;
|
||||
|
||||
/** @var CreateReceiptVoucherTransactionProcessor */
|
||||
private $createReceiptVoucherTransactionProcessor;
|
||||
|
||||
/**
|
||||
* RegenerateBookingPaymentRVLogic constructor.
|
||||
* @param CanFetchBooking $canFetchBooking
|
||||
* @param FetchesBooking $fetchesBooking
|
||||
* @param FetchesTransaction $fetchesTransaction
|
||||
* @param CreateReceiptVoucherTransactionProcessor $createReceiptVoucherTransactionProcessor
|
||||
*/
|
||||
public function __construct(
|
||||
CanFetchBooking $canFetchBooking,
|
||||
FetchesBooking $fetchesBooking,
|
||||
FetchesTransaction $fetchesTransaction,
|
||||
CreateReceiptVoucherTransactionProcessor $createReceiptVoucherTransactionProcessor
|
||||
) {
|
||||
$this->canFetchBooking = $canFetchBooking;
|
||||
$this->fetchesBooking = $fetchesBooking;
|
||||
$this->fetchesTransaction = $fetchesTransaction;
|
||||
$this->createReceiptVoucherTransactionProcessor = $createReceiptVoucherTransactionProcessor;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @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
|
||||
{
|
||||
$this->canFetchBooking->passes();
|
||||
|
||||
$booking = $this->fetchesBooking->execute(['id' => $request->route('id')]);
|
||||
$transaction = $this->fetchesTransaction->execute(['id' => $request->input('paymentId')]);
|
||||
|
||||
if($booking && $transaction){
|
||||
$this->createReceiptVoucherTransactionProcessor->execute($booking, $transaction, true);
|
||||
}
|
||||
|
||||
return $this->resourceResponse(new BookingResource($booking));
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,6 @@ use App\Classes\Modules\Bookings\Services\UpdatesBookingStatus;
|
||||
use App\Classes\Modules\Transactions\Services\DeletesTransaction;
|
||||
use App\Classes\Modules\Documents\Services\DeletesDocument;
|
||||
use App\Classes\Modules\Transactions\Processors\CreateInvoiceTransactionProcessor;
|
||||
use App\Classes\Modules\Transactions\Processors\CreateInvoiceTransactionWithInvoiceNoProcessor;
|
||||
use Illuminate\Support\Str;
|
||||
use App\Classes\ValueObjects\Constants\DocumentType;
|
||||
use App\Http\Resources\BookingResource;
|
||||
@@ -52,9 +51,6 @@ class RegenerateInvoiceBookingLogic extends AbstractControllerLogic
|
||||
/** @var CreateInvoiceTransactionProcessor */
|
||||
private $createInvoiceTransactionProcessor;
|
||||
|
||||
/** @var CreateInvoiceTransactionWithInvoiceNoProcessor */
|
||||
private $createInvoiceTransactionWithInvoiceNoProcessor;
|
||||
|
||||
/**
|
||||
* FetchBookingLogic constructor.
|
||||
* @param CanFetchBooking $canFetchBooking
|
||||
@@ -63,7 +59,6 @@ class RegenerateInvoiceBookingLogic extends AbstractControllerLogic
|
||||
* @param UpdatesBookingStatus $updatesBookingStatus
|
||||
* @param DeletesDocument $deletesDocument
|
||||
* @param CreateInvoiceTransactionProcessor $createInvoiceTransactionProcessor
|
||||
* @param CreateInvoiceTransactionWithInvoiceNoProcessor $createInvoiceTransactionWithInvoiceNoProcessor
|
||||
*/
|
||||
public function __construct(
|
||||
CanFetchBooking $canFetchBooking,
|
||||
@@ -71,8 +66,7 @@ class RegenerateInvoiceBookingLogic extends AbstractControllerLogic
|
||||
DeletesTransaction $deletesTransaction,
|
||||
UpdatesBookingStatus $updatesBookingStatus,
|
||||
DeletesDocument $deletesDocument,
|
||||
CreateInvoiceTransactionProcessor $createInvoiceTransactionProcessor,
|
||||
CreateInvoiceTransactionWithInvoiceNoProcessor $createInvoiceTransactionWithInvoiceNoProcessor
|
||||
CreateInvoiceTransactionProcessor $createInvoiceTransactionProcessor
|
||||
) {
|
||||
$this->canFetchBooking = $canFetchBooking;
|
||||
$this->fetchesBooking = $fetchesBooking;
|
||||
@@ -80,7 +74,6 @@ class RegenerateInvoiceBookingLogic extends AbstractControllerLogic
|
||||
$this->updatesBookingStatus = $updatesBookingStatus;
|
||||
$this->deletesDocument = $deletesDocument;
|
||||
$this->createInvoiceTransactionProcessor = $createInvoiceTransactionProcessor;
|
||||
$this->createInvoiceTransactionWithInvoiceNoProcessor = $createInvoiceTransactionWithInvoiceNoProcessor;
|
||||
}
|
||||
|
||||
|
||||
@@ -119,8 +112,10 @@ class RegenerateInvoiceBookingLogic extends AbstractControllerLogic
|
||||
|
||||
// update currentInvoice bill_no to '-deleted-'
|
||||
$currentInvoice = $booking->transactions()->where('type', TransactionType::INVOICE)->first();
|
||||
$currentInvoice->bill_no = $currentInvoice->bill_no ."-deleted-" . (string)(Carbon::now()->timestamp);
|
||||
$currentInvoice->save();
|
||||
if($currentInvoice){
|
||||
$currentInvoice->bill_no = $currentInvoice->bill_no ."-deleted-" . (string)(Carbon::now()->timestamp);
|
||||
$currentInvoice->save();
|
||||
}
|
||||
|
||||
$transactionWithSameBillNo = Transaction::where('bill_no', $firstBillNo)->withTrashed()->get();
|
||||
if ($transactionWithSameBillNo) {
|
||||
@@ -140,7 +135,7 @@ class RegenerateInvoiceBookingLogic extends AbstractControllerLogic
|
||||
$this->deletesDocument->execute($row);
|
||||
}
|
||||
|
||||
$this->createInvoiceTransactionWithInvoiceNoProcessor->execute($booking, $firstBillNo);
|
||||
$this->createInvoiceTransactionProcessor->execute($booking, $firstBillNo, true);
|
||||
|
||||
return $this->resourceResponse(new BookingResource($booking));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Bookings\ControllersLogic;
|
||||
|
||||
use App\Classes\Modules\Bookings\Services\UpdatesBookingFixedAmount;
|
||||
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
|
||||
use App\Classes\Modules\Bookings\Services\FetchesBooking;
|
||||
use App\Classes\Modules\Bookings\Standards\Rules\CanUpdateBooking;
|
||||
use App\Classes\Modules\Accounts\Services\CreatesKeyValuePair;
|
||||
use App\Classes\Modules\Accounts\Services\UpdatesKeyValuePair;
|
||||
use App\Classes\Modules\Bookings\Services\CalculatesBookingOutstanding;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Classes\Exceptions\MalformedRequestException;
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Accounts\DataTransferObjects\KeyValuePairObject;
|
||||
use App\Http\Resources\BookingResource;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use ErrorException;
|
||||
|
||||
class UpdateBookingAmountOnHoldLogic extends AbstractControllerLogic
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function notification():array {
|
||||
return [
|
||||
'title' => 'Recorded Booking Amount',
|
||||
'message' => 'You have successfully recorded the Booking Amount to be updated'
|
||||
];
|
||||
}
|
||||
|
||||
/** @var CanUpdateBooking */
|
||||
private $canUpdateBooking;
|
||||
|
||||
/** @var UpdatesBookingFixedAmount */
|
||||
private $updatesBookingFixedAmount;
|
||||
|
||||
/** @var FetchesBooking */
|
||||
private $fetchesBooking;
|
||||
|
||||
/** @var CalculatesBookingOutstanding */
|
||||
private $calculatesBookingOutstanding;
|
||||
|
||||
/** @var UpdatesTransactionStatus */
|
||||
private $updatesTransactionStatus;
|
||||
|
||||
/** @var CreatesKeyValuePair */
|
||||
private $createsKeyValuePair;
|
||||
|
||||
/** @var UpdatesKeyValuePair */
|
||||
private $updatesKeyValuePair;
|
||||
|
||||
/**
|
||||
* UpdateBookingAmountLogic constructor.
|
||||
* @param CanUpdateBooking $canUpdateBooking
|
||||
* @param UpdatesBookingFixedAmount $updatesBookingFixedAmount
|
||||
* @param FetchesBooking $fetchesBooking
|
||||
* @param CalculatesBookingOutstanding $calculatesBookingOutstanding
|
||||
* @param UpdatesTransactionStatus $updatesTransactionStatus
|
||||
* @param CreatesKeyValuePair $createsKeyValuePair
|
||||
* @param UpdatesKeyValuePair $updatesKeyValuePair
|
||||
*/
|
||||
public function __construct(CanUpdateBooking $canUpdateBooking, UpdatesBookingFixedAmount $updatesBookingFixedAmount, FetchesBooking $fetchesBooking, CalculatesBookingOutstanding $calculatesBookingOutstanding, UpdatesTransactionStatus $updatesTransactionStatus, CreatesKeyValuePair $createsKeyValuePair, UpdatesKeyValuePair $updatesKeyValuePair)
|
||||
{
|
||||
$this->canUpdateBooking = $canUpdateBooking;
|
||||
$this->updatesBookingFixedAmount = $updatesBookingFixedAmount;
|
||||
$this->fetchesBooking = $fetchesBooking;
|
||||
$this->calculatesBookingOutstanding = $calculatesBookingOutstanding;
|
||||
$this->updatesTransactionStatus = $updatesTransactionStatus;
|
||||
$this->createsKeyValuePair = $createsKeyValuePair;
|
||||
$this->updatesKeyValuePair = $updatesKeyValuePair;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
* @throws MalformedRequestException
|
||||
*/
|
||||
public function logic(Request $request) : JsonResponse
|
||||
{
|
||||
$booking = $this->fetchesBooking->execute(['id' => $request->route('id')]);
|
||||
|
||||
$input_amount = number_format( floatval(str_replace(',', '', $request->input('amount_to_edit', $booking->fix_amount))), 5, '.', '');
|
||||
|
||||
$minimum_amount = $booking->fix_amount - $this->calculatesBookingOutstanding->execute($booking);
|
||||
|
||||
if (((float)$input_amount + 0.01) < (float)$minimum_amount) {
|
||||
throw new MalformedRequestException('Booking Amount cannot be less than '. $minimum_amount .'.');
|
||||
}
|
||||
|
||||
$key = "BOOKING_AMOUNT_UPDATE";
|
||||
$keyValuePairObject = new KeyValuePairObject($key, $input_amount);
|
||||
$metadata = $booking->attributesKVP()->where('key', $key)->first();
|
||||
if($metadata){
|
||||
$this->updatesKeyValuePair->execute($metadata, $keyValuePairObject);
|
||||
}
|
||||
else{
|
||||
$this->createsKeyValuePair->execute($booking, $keyValuePairObject);
|
||||
}
|
||||
|
||||
$poTransaction = $booking->transactions()->where('type', TransactionType::PURCHASE_ORDER)->first();
|
||||
// $booking->transactions()->where('type', TransactionType::PROFORMA)->delete();
|
||||
|
||||
if($poTransaction) {
|
||||
$this->updatesTransactionStatus->execute($poTransaction, ApprovalStatus::PENDING_SUBMISSION);
|
||||
}
|
||||
|
||||
// $booking = $this->updatesBookingFixedAmount->execute($booking, $input_amount);
|
||||
|
||||
return $this->resourceResponse(new BookingResource($booking));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace App\Classes\Modules\Bookings\ControllersLogic;
|
||||
|
||||
use App\Classes\Exceptions\MalformedRequestException;
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Bookings\Services\FetchesBooking;
|
||||
use App\Classes\Modules\Bookings\Services\UpdatesBookingFixedAmount;
|
||||
use App\Classes\Modules\Bookings\Services\CalculatesBookingOutstanding;
|
||||
use App\Classes\Modules\Bookings\Services\CalculatesBookingPayableAmount;
|
||||
use App\Classes\Modules\Bookings\Services\CalculatesBookingRefundAmount;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Http\Resources\BookingResource;
|
||||
use App\Models\Booking;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class UpdateBookingAmountWithPOLogic extends AbstractControllerLogic
|
||||
{
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function notification():array {
|
||||
return [
|
||||
'title' => 'Update Purchase Order With Booking Amount Update',
|
||||
'message' => 'You have successfully updated booking amount'
|
||||
];
|
||||
}
|
||||
|
||||
/** @var FetchesBooking */
|
||||
private $fetchesBooking;
|
||||
|
||||
/** @var UpdatesBookingFixedAmount */
|
||||
private $updatesBookingFixedAmount;
|
||||
|
||||
/** @var CalculatesBookingOutstanding */
|
||||
private $calculatesBookingOutstanding;
|
||||
|
||||
/** @var CalculatesBookingPayableAmount */
|
||||
private $calculatesBookingPayableAmount;
|
||||
|
||||
/** @var CalculatesBookingRefundAmount */
|
||||
private $calculatesBookingRefundAmount;
|
||||
|
||||
/**
|
||||
* UpdateBookingAmountWithPOLogic constructor.
|
||||
* @param FetchesBooking $fetchesBooking
|
||||
* @param UpdatesBookingFixedAmount $updatesBookingFixedAmount
|
||||
* @param CalculatesBookingOutstanding $calculatesBookingOutstanding
|
||||
* @param CalculatesBookingPayableAmount $calculatesBookingPayableAmount
|
||||
* @param CalculatesBookingRefundAmount $calculatesBookingRefundAmount
|
||||
*/
|
||||
public function __construct(FetchesBooking $fetchesBooking, UpdatesBookingFixedAmount $updatesBookingFixedAmount, CalculatesBookingOutstanding $calculatesBookingOutstanding, CalculatesBookingPayableAmount $calculatesBookingPayableAmount, CalculatesBookingRefundAmount $calculatesBookingRefundAmount)
|
||||
{
|
||||
$this->fetchesBooking = $fetchesBooking;
|
||||
$this->updatesBookingFixedAmount = $updatesBookingFixedAmount;
|
||||
$this->calculatesBookingOutstanding = $calculatesBookingOutstanding;
|
||||
$this->calculatesBookingPayableAmount = $calculatesBookingPayableAmount;
|
||||
$this->calculatesBookingRefundAmount = $calculatesBookingRefundAmount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param string $id
|
||||
* @return JsonResponse
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
* @throws \App\Classes\Exceptions\CriteriaNotFulfilledException
|
||||
*/
|
||||
public function logic(Request $request, $id = '') : JsonResponse
|
||||
{
|
||||
/** @var Booking $booking */
|
||||
$booking = $this->fetchesBooking->execute(['id' => $request->route('id') ?? $id]);
|
||||
$outstandingAmount = $this->calculatesBookingOutstanding->execute($booking);
|
||||
$bookingAttribute = $booking->attributesKVP()->where('key', "BOOKING_AMOUNT_UPDATE")->first();
|
||||
$paidAmount = floatval($this->calculatesBookingPayableAmount->execute($booking, $booking->fix_currency_id)) - floatval($this->calculatesBookingRefundAmount->execute($booking, $booking->fix_currency_id));
|
||||
|
||||
if($paidAmount > 0 && $outstandingAmount > 0 && !$bookingAttribute){
|
||||
throw new MalformedRequestException('Purchase Order at this point can only be edited after editing the booking amount');
|
||||
}
|
||||
|
||||
if($bookingAttribute){
|
||||
$total = collect($request->input('products'))->sum(function($product){
|
||||
return $product['quantity'] * floatval(str_replace(',', '', $product['unit_price']));
|
||||
});
|
||||
$bookingAmountUpdate = (float)$bookingAttribute->value;
|
||||
$isTally = $total === $bookingAmountUpdate ? true : false;
|
||||
if(!$isTally){
|
||||
throw new MalformedRequestException('Purchase Order total not tally with updated booking amount of ' . $bookingAmountUpdate);
|
||||
}
|
||||
$booking->transactions()->where('type', TransactionType::PROFORMA)->delete();
|
||||
$booking = $this->updatesBookingFixedAmount->execute($booking, $bookingAmountUpdate);
|
||||
|
||||
$request->merge(['is_privilleged_update' => true]);
|
||||
|
||||
$bookingAttribute->delete();
|
||||
}
|
||||
|
||||
return $this->resourceResponse(new BookingResource($booking));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Bookings\DataTransferObjects;
|
||||
|
||||
use App\Classes\General\Interfaces\DataTransferObject;
|
||||
|
||||
class ConfirmBookingDTO implements DataTransferObject
|
||||
{
|
||||
public int $bookingId;
|
||||
public int $companyId;
|
||||
|
||||
public function __construct(array $data)
|
||||
{
|
||||
$this->bookingId = $data['booking_id'];
|
||||
$this->companyId = $data['company_id'];
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'booking_id' => $this->bookingId,
|
||||
'company_id' => $this->companyId,
|
||||
];
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Bookings\DataTransferObjects;
|
||||
|
||||
use App\Classes\General\Interfaces\DataTransferObject;
|
||||
|
||||
class CreatePaymentVerificationDocumentDTO implements DataTransferObject
|
||||
{
|
||||
public int $bookingId;
|
||||
public int $companyId;
|
||||
public int $paymentId;
|
||||
|
||||
public function __construct(array $data)
|
||||
{
|
||||
$this->bookingId = $data['booking_id'];
|
||||
$this->companyId = $data['company_id'];
|
||||
$this->paymentId = $data['payment_id'];
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'booking_id' => $this->bookingId,
|
||||
'company_id' => $this->companyId,
|
||||
'payment_id' => $this->paymentId,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Companies\ControllersLogic;
|
||||
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Companies\Services\FetchesCompany;
|
||||
use App\Classes\Modules\Companies\Standards\Rules\CanFetchCompany;
|
||||
use App\Http\Resources\EInvoiceInfoResource;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class FetchCompanyEInvoiceInfoLogic extends AbstractControllerLogic
|
||||
{
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function notification():array {
|
||||
return [
|
||||
'title' => 'Retrieved Company E-Invoice Info',
|
||||
'message' => 'You have successfully retrieved a Company E-Invoice Info'
|
||||
];
|
||||
}
|
||||
|
||||
/** @var CanFetchCompany */
|
||||
private $canFetchCompany;
|
||||
|
||||
/** @var FetchesCompany */
|
||||
private $fetchesCompany;
|
||||
|
||||
/**
|
||||
* FetchCompanyEInvoiceInfoLogic constructor.
|
||||
* @param CanFetchCompany $canFetchCompany
|
||||
* @param FetchesCompany $fetchesCompany
|
||||
*/
|
||||
public function __construct(CanFetchCompany $canFetchCompany, FetchesCompany $fetchesCompany)
|
||||
{
|
||||
$this->canFetchCompany = $canFetchCompany;
|
||||
$this->fetchesCompany = $fetchesCompany;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
* @throws \App\Classes\Exceptions\AccessForbiddenException
|
||||
* @throws \App\Classes\Exceptions\RequestValidationException
|
||||
*/
|
||||
public function logic(Request $request) : JsonResponse
|
||||
{
|
||||
$this->canFetchCompany->passes();
|
||||
|
||||
$company = $this->fetchesCompany->execute(['id' => $request->route('id')]);
|
||||
$eInvoiceInfo = $company->addresses()->where('billing', '=', false)->where('e_invoice', '=', true)->latest()->first();
|
||||
|
||||
if($eInvoiceInfo){
|
||||
$eInvoiceInfo->tin = $company->tin;
|
||||
$eInvoiceInfo->msic_code = $company->msic_code;
|
||||
$eInvoiceInfo->e_invoice = $company->e_invoice;
|
||||
}
|
||||
else{
|
||||
return $this->response([]);
|
||||
}
|
||||
|
||||
return $this->resourceResponse(new EInvoiceInfoResource($eInvoiceInfo));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
namespace App\Classes\Modules\Companies\ControllersLogic;
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Companies\DataTransferObjects\CompanyObject;
|
||||
use App\Classes\Modules\Companies\Services\FetchesCompany;
|
||||
use App\Classes\Modules\Companies\Services\UpdatesCompany;
|
||||
use App\Classes\Modules\Companies\Services\UpdatesCompanyDebtor;
|
||||
use App\Classes\Modules\Addresses\Services\UpsertsAddress;
|
||||
use App\Classes\Modules\Addresses\Services\FetchesDistrict;
|
||||
use App\Classes\Modules\Addresses\Services\UpdatesAddressMetadata;
|
||||
use App\Classes\Modules\Addresses\Standards\Rules\CanCreateAddress;
|
||||
use App\Classes\Modules\Addresses\DataTransferObjects\AddressObject;
|
||||
use App\Classes\Modules\Companies\Services\UpdatesCompanyEInvoiceInfo;
|
||||
use App\Classes\Modules\Companies\Standards\Rules\CanUpdateCompany;
|
||||
use App\Classes\Modules\Companies\DataTransferObjects\UpdateCompanyDetailsDTO;
|
||||
use App\Http\Resources\CompanyResource;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class UpdateCompanyDetailsLogic extends AbstractControllerLogic
|
||||
{
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function notification():array {
|
||||
return [
|
||||
'title' => 'Update Company Details',
|
||||
'message' => 'You have successfully updated the Company Details'
|
||||
];
|
||||
}
|
||||
/** @var CanUpdateCompany */
|
||||
private $canUpdateCompany;
|
||||
|
||||
/** @var UpdatesCompany */
|
||||
private $updatesCompany;
|
||||
|
||||
/** @var FetchesCompany */
|
||||
private $fetchesCompany;
|
||||
|
||||
/** @var UpdatesCompanyDebtor */
|
||||
private $updatesCompanyDebtor;
|
||||
|
||||
/** @var CanCreateAddress */
|
||||
private $canCreateAddress;
|
||||
|
||||
/** @var FetchesDistrict */
|
||||
private $fetchesDistrict;
|
||||
|
||||
/** @var UpsertsAddress */
|
||||
private $upsertsAddress;
|
||||
|
||||
/** @var UpdatesCompanyEInvoiceInfo */
|
||||
private $updatesCompanyEInvoiceInfo;
|
||||
|
||||
/** @var UpdatesAddressMetadata */
|
||||
private $updatesAddressMetadata;
|
||||
|
||||
|
||||
/**
|
||||
* UpdateCompanyDetailsLogic constructor.
|
||||
* @param CanUpdateCompany $canUpdateCompany
|
||||
* @param UpdatesCompany $updatesCompany
|
||||
* @param FetchesCompany $fetchesCompany
|
||||
* @param UpdatesCompanyDebtor $updatesCompanyDebtor
|
||||
* @param CanCreateAddress $canCreateAddress
|
||||
* @param FetchesDistrict $fetchesDistrict
|
||||
* @param FetchesCompany $fetchesCompany
|
||||
* @param UpsertsAddress $upsertsAddress
|
||||
* @param UpdatesCompanyEInvoiceInfo $updatesCompanyEInvoiceInfo;
|
||||
* @param UpdatesAddressMetadata $updatesAddressMetadata
|
||||
*/
|
||||
public function __construct(
|
||||
CanUpdateCompany $canUpdateCompany,
|
||||
UpdatesCompany $updatesCompany,
|
||||
FetchesCompany $fetchesCompany,
|
||||
UpdatesCompanyDebtor $updatesCompanyDebtor,
|
||||
CanCreateAddress $canCreateAddress,
|
||||
FetchesDistrict $fetchesDistrict,
|
||||
UpsertsAddress $upsertsAddress,
|
||||
UpdatesCompanyEInvoiceInfo $updatesCompanyEInvoiceInfo,
|
||||
UpdatesAddressMetadata $updatesAddressMetadata
|
||||
)
|
||||
{
|
||||
$this->canUpdateCompany = $canUpdateCompany;
|
||||
$this->updatesCompany = $updatesCompany;
|
||||
$this->fetchesCompany = $fetchesCompany;
|
||||
$this->updatesCompanyDebtor = $updatesCompanyDebtor;
|
||||
$this->canCreateAddress = $canCreateAddress;
|
||||
$this->fetchesDistrict = $fetchesDistrict;
|
||||
$this->fetchesCompany = $fetchesCompany;
|
||||
$this->upsertsAddress = $upsertsAddress;
|
||||
$this->updatesCompanyEInvoiceInfo = $updatesCompanyEInvoiceInfo;
|
||||
$this->updatesAddressMetadata = $updatesAddressMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
* @throws ErrorException
|
||||
*/
|
||||
public function logic(Request $request) : JsonResponse
|
||||
{
|
||||
$dto = new UpdateCompanyDetailsDTO($request->all());
|
||||
|
||||
$company = $this->fetchesCompany->execute(['id' => $request->route('id')]);
|
||||
$object = new CompanyObject($dto->name, $dto->reference, $company->business_type, $dto->type);
|
||||
|
||||
$this->canUpdateCompany->passes($object);
|
||||
|
||||
//Update Name and Debtor
|
||||
$company = $this->updatesCompany->execute($company, $object);
|
||||
if ($dto->debtor|| $company->first()->debtor !== null) {
|
||||
$this->updatesCompanyDebtor->execute($company, $dto->debtor);
|
||||
}
|
||||
|
||||
//Update EInvoice Related Info
|
||||
if($company->e_invoice){
|
||||
$district = $this->fetchesDistrict->execute(['id' => $dto->districtId]);
|
||||
$addObj = new AddressObject($dto->streetOne, $dto->streetTwo, $district->country_id, $dto->stateId, $district->id, $dto->postCode);
|
||||
$this->canCreateAddress->passes($addObj);
|
||||
|
||||
$address = $this->upsertsAddress->execute($company, $addObj, $dto->addressId);
|
||||
$query = $this->updatesAddressMetadata->execute($address, false, true);
|
||||
$this->updatesCompanyEInvoiceInfo->execute($company, $dto->tin, $dto->msicCode);
|
||||
}
|
||||
|
||||
return $this->resourceResponse(new CompanyResource($company));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Companies\ControllersLogic;
|
||||
|
||||
|
||||
use App\Classes\Exceptions\CriteriaNotFulfilledException;
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Addresses\Services\CreatesAddress;
|
||||
use App\Classes\Modules\Addresses\Services\FetchesDistrict;
|
||||
use App\Classes\Modules\Addresses\Services\UpdatesAddressMetadata;
|
||||
use App\Classes\Modules\Addresses\Standards\Rules\CanCreateAddress;
|
||||
use App\Classes\Modules\Addresses\DataTransferObjects\AddressObject;
|
||||
use App\Classes\Modules\Companies\Services\FetchesCompany;
|
||||
use App\Classes\Modules\Companies\Services\UpdatesCompanyEInvoiceInfo;
|
||||
use App\Classes\Modules\Companies\DataTransferObjects\EInvoiceInfoDTO;
|
||||
use App\Classes\Modules\Rules\Services\RuleEvaluator;
|
||||
use App\Classes\Modules\Rules\Standards\Rules\CanPassEInvoicePromptedRule;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class UpdateCompanyEInvoiceInfoLogic extends AbstractControllerLogic
|
||||
{
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function notification():array {
|
||||
return [
|
||||
'title' => 'EInvoice Info Update',
|
||||
'message' => 'You have successfully updated company E-Invoice information'
|
||||
];
|
||||
}
|
||||
|
||||
/** @var CanCreateAddress */
|
||||
private $canCreateAddress;
|
||||
|
||||
/** @var FetchesDistrict */
|
||||
private $fetchesDistrict;
|
||||
|
||||
/** @var FetchesCompany */
|
||||
private $fetchesCompany;
|
||||
|
||||
/** @var CreatesAddress */
|
||||
private $createsAddress;
|
||||
|
||||
/** @var RuleEvaluator */
|
||||
private $ruleEvaluator;
|
||||
|
||||
/** @var UpdatesCompanyEInvoiceInfo */
|
||||
private $updatesCompanyEInvoiceInfo;
|
||||
|
||||
/** @var UpdatesAddressMetadata */
|
||||
private $updatesAddressMetadata;
|
||||
|
||||
/** @var CanPassEInvoicePromptedRule */
|
||||
private $canPassEInvoicePromptedRule;
|
||||
|
||||
/**
|
||||
* UpdateCompanyEInvoiceInfoLogic constructor.
|
||||
* @param CanCreateAddress $canCreateAddress
|
||||
* @param FetchesDistrict $fetchesDistrict
|
||||
* @param FetchesCompany $fetchesCompany
|
||||
* @param CreatesAddress $createsAddress
|
||||
* @param RuleEvaluator $ruleEvaluator;
|
||||
* @param UpdatesCompanyEInvoiceInfo $updatesCompanyEInvoiceInfo;
|
||||
* @param UpdatesAddressMetadata $updatesAddressMetadata
|
||||
* @param CanPassEInvoicePromptedRule $canPassEInvoicePromptedRule
|
||||
*/
|
||||
public function __construct(CanCreateAddress $canCreateAddress, FetchesDistrict $fetchesDistrict, FetchesCompany $fetchesCompany, CreatesAddress $createsAddress, RuleEvaluator $ruleEvaluator, UpdatesCompanyEInvoiceInfo $updatesCompanyEInvoiceInfo, UpdatesAddressMetadata $updatesAddressMetadata, CanPassEInvoicePromptedRule $canPassEInvoicePromptedRule)
|
||||
{
|
||||
$this->canCreateAddress = $canCreateAddress;
|
||||
$this->fetchesDistrict = $fetchesDistrict;
|
||||
$this->fetchesCompany = $fetchesCompany;
|
||||
$this->createsAddress = $createsAddress;
|
||||
$this->ruleEvaluator = $ruleEvaluator;
|
||||
$this->updatesCompanyEInvoiceInfo = $updatesCompanyEInvoiceInfo;
|
||||
$this->updatesAddressMetadata = $updatesAddressMetadata;
|
||||
$this->canPassEInvoicePromptedRule = $canPassEInvoicePromptedRule;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
* @throws \App\Classes\Exceptions\AccessForbiddenException
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
* @throws \App\Classes\Exceptions\RequestValidationException
|
||||
* @throws \App\Classes\Exceptions\CriteriaNotFulfilledException
|
||||
*/
|
||||
public function logic(Request $request) : JsonResponse
|
||||
{
|
||||
$dto = new EInvoiceInfoDTO($request->all());
|
||||
$result = $this->ruleEvaluator->evaluate([
|
||||
$this->canPassEInvoicePromptedRule,
|
||||
], $dto);
|
||||
|
||||
if ($result->failed()) {
|
||||
throw new CriteriaNotFulfilledException("- " . implode("<br>- ", $result->messages()));
|
||||
}
|
||||
|
||||
$district = $this->fetchesDistrict->execute(['id' => $dto->districtId]);
|
||||
$object = new AddressObject($dto->streetOne, $dto->streetTwo, $district->country_id, $dto->stateId, $district->id, $dto->postCode);
|
||||
|
||||
//Update Address
|
||||
$this->canCreateAddress->passes($object);
|
||||
$company = $this->fetchesCompany->execute(['id' => $dto->companyId]);
|
||||
$address = $this->createsAddress->execute($company, $object);
|
||||
$query = $this->updatesAddressMetadata->execute($address, false, true);
|
||||
|
||||
//Update tin, msic code
|
||||
$this->updatesCompanyEInvoiceInfo->execute($company, $dto->tin, $dto->msicCode);
|
||||
|
||||
return $this->response([]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Companies\ControllersLogic;
|
||||
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Companies\Services\UpdatesCompanyEInvoiceRequest;
|
||||
use App\Classes\Modules\Companies\Services\FetchesCompany;
|
||||
use App\Classes\Modules\Companies\DataTransferObjects\EInvoiceRequestDTO;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class UpdateCompanyEInvoiceRequestLogic extends AbstractControllerLogic
|
||||
{
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function notification():array {
|
||||
return [
|
||||
'title' => 'Updated EInvoice Request',
|
||||
'message' => 'You have successfully updated company E-Invoice request'
|
||||
];
|
||||
}
|
||||
|
||||
/** @var FetchesCompany */
|
||||
private $fetchesCompany;
|
||||
|
||||
/** @var UpdatesCompanyEInvoiceRequest */
|
||||
private $updatesCompanyEInvoiceRequest;
|
||||
|
||||
|
||||
/**
|
||||
* UpdateCompanyEInvoiceRequestLogic constructor.
|
||||
* @param FetchesCompany $fetchesCompany
|
||||
* @param UpdatesCompanyEInvoiceRequest $updatesCompanyEInvoiceRequest
|
||||
*/
|
||||
public function __construct(FetchesCompany $fetchesCompany, UpdatesCompanyEInvoiceRequest $updatesCompanyEInvoiceRequest)
|
||||
{
|
||||
$this->fetchesCompany = $fetchesCompany;
|
||||
$this->updatesCompanyEInvoiceRequest = $updatesCompanyEInvoiceRequest;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
{
|
||||
$dto = new EInvoiceRequestDTO($request->all());
|
||||
$company = $this->fetchesCompany->execute(['id' => $dto->companyId]);
|
||||
$this->updatesCompanyEInvoiceRequest->execute($company, $dto->eInvoiceRequest);
|
||||
|
||||
return $this->response([]);
|
||||
}
|
||||
}
|
||||
@@ -20,8 +20,8 @@ class UpdateCompanyNameAndDebtorLogic extends AbstractControllerLogic
|
||||
*/
|
||||
protected function notification():array {
|
||||
return [
|
||||
'title' => 'Update Company Account Status',
|
||||
'message' => 'You have successfully updated the Company Account Status'
|
||||
'title' => 'Update Company Details',
|
||||
'message' => 'You have successfully updated the Company Details'
|
||||
];
|
||||
}
|
||||
/** @var CanUpdateCompany */
|
||||
@@ -77,6 +77,4 @@ class UpdateCompanyNameAndDebtorLogic extends AbstractControllerLogic
|
||||
|
||||
return $this->resourceResponse(new CompanyResource($query));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Companies\DataTransferObjects;
|
||||
|
||||
use App\Classes\General\Interfaces\DataTransferObject;
|
||||
|
||||
class EInvoiceInfoDTO implements DataTransferObject
|
||||
{
|
||||
public string $tin;
|
||||
public string $msicCode;
|
||||
public int $districtId;
|
||||
public int $stateId;
|
||||
public int $companyId;
|
||||
public string $streetOne;
|
||||
public string $streetTwo;
|
||||
public int $postCode;
|
||||
|
||||
public function __construct(array $data)
|
||||
{
|
||||
$this->tin = (string) ($data['tin'] ?? '');
|
||||
$this->msicCode = (string) ($data['msic_code'] ?? '');
|
||||
$this->districtId = (int) ($data['district_id'] ?? 0);
|
||||
$this->stateId = (int) ($data['state_id'] ?? 0);
|
||||
$this->companyId = (int) ($data['company_id'] ?? 0);
|
||||
$this->streetOne = (string) ($data['street_one'] ?? '');
|
||||
$this->streetTwo = (string) ($data['street_two'] ?? '');
|
||||
$this->postCode = (int) ($data['post_code'] ?? 0);
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'tin' => $this->tin,
|
||||
'msic_code' => $this->msicCode,
|
||||
'district_id' => $this->districtId,
|
||||
'state_id' => $this->stateId,
|
||||
'company_id' => $this->companyId,
|
||||
'street_one' => $this->streetOne,
|
||||
'street_two' => $this->streetTwo,
|
||||
'post_code' => $this->postCode,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Companies\DataTransferObjects;
|
||||
|
||||
use App\Classes\General\Interfaces\DataTransferObject;
|
||||
|
||||
class EInvoiceRequestDTO implements DataTransferObject
|
||||
{
|
||||
public bool $eInvoiceRequest;
|
||||
public int $companyId;
|
||||
|
||||
public function __construct(array $data)
|
||||
{
|
||||
$this->eInvoiceRequest = $data['e_invoice_request'];
|
||||
$this->companyId = $data['company_id'];
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'e_invoice_request' => $this->eInvoiceRequest,
|
||||
'company_id' => $this->companyId,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Companies\DataTransferObjects;
|
||||
|
||||
use App\Classes\General\Interfaces\DataTransferObject;
|
||||
|
||||
class UpdateCompanyDetailsDTO implements DataTransferObject
|
||||
{
|
||||
public int $id;
|
||||
public string $name;
|
||||
public string $debtor;
|
||||
public string $reference;
|
||||
public int $type;
|
||||
|
||||
public string $tin;
|
||||
public string $msicCode;
|
||||
public int $addressId;
|
||||
public int $districtId;
|
||||
public int $stateId;
|
||||
public int $companyId;
|
||||
public string $streetOne;
|
||||
public string $streetTwo;
|
||||
public int $postCode;
|
||||
|
||||
public function __construct(array $data)
|
||||
{
|
||||
$this->id = (int) ($data['id'] ?? 0);
|
||||
$this->name = (string) ($data['name'] ?? '');
|
||||
$this->debtor = (string) ($data['debtor'] ?? '');
|
||||
$this->reference = (string) ($data['reference'] ?? '');
|
||||
$this->type = (int) ($data['type'] ?? 0);
|
||||
|
||||
$this->tin = (string) ($data['tin'] ?? 0);
|
||||
$this->msicCode = (string) ($data['msic_code'] ?? '');
|
||||
$this->addressId = (int) ($data['address_id'] ?? 0);
|
||||
$this->districtId = (int) ($data['district_id'] ?? 0);
|
||||
$this->stateId = (int) ($data['state_id'] ?? 0);
|
||||
$this->companyId = (int) ($data['company_id'] ?? 0);
|
||||
$this->streetOne = (string) ($data['street_one'] ?? '');
|
||||
$this->streetTwo = (string) ($data['street_two'] ?? '');
|
||||
$this->postCode = (int) ($data['post_code'] ?? 0);
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'name' => $this->name,
|
||||
'debtor' => $this->debtor,
|
||||
'reference' => $this->reference,
|
||||
'type' => $this->type,
|
||||
|
||||
'tin' => $this->tin,
|
||||
'msic_code' => $this->msicCode,
|
||||
'address_id' => $this->addressId,
|
||||
'district_id' => $this->districtId,
|
||||
'state_id' => $this->stateId,
|
||||
'company_id' => $this->companyId,
|
||||
'street_one' => $this->streetOne,
|
||||
'street_two' => $this->streetTwo,
|
||||
'post_code' => $this->postCode,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Companies\Services;
|
||||
|
||||
use App\Classes\General\Eloquent\AbstractUpdateRecord;
|
||||
use App\Models\Company;
|
||||
|
||||
class UpdatesCompanyEInvoiceInfo extends AbstractUpdateRecord
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Company $model
|
||||
* @param string $tin
|
||||
* @param string $msicCode
|
||||
* @return \Illuminate\Database\Eloquent\Model
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
*/
|
||||
public function execute(Company $model, string $tin, string $msicCode)
|
||||
{
|
||||
$model->tin = $tin;
|
||||
$model->msic_code = $msicCode;
|
||||
|
||||
return $this->handler($model);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Companies\Services;
|
||||
|
||||
|
||||
use App\Classes\General\Eloquent\AbstractUpdateRecord;
|
||||
use App\Models\Company;
|
||||
|
||||
class UpdatesCompanyEInvoiceRequest extends AbstractUpdateRecord
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Company $model
|
||||
* @param bool $eInvoice
|
||||
* @return \Illuminate\Database\Eloquent\Model
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
*/
|
||||
public function execute(Company $model, bool $eInvoice)
|
||||
{
|
||||
if (is_null($model->e_invoice_requested_at)) {
|
||||
if($eInvoice){
|
||||
$model->e_invoice_requested_at = now();
|
||||
}
|
||||
}
|
||||
$model->e_invoice = $eInvoice;
|
||||
|
||||
return $this->handler($model);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Exports\Services;
|
||||
|
||||
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\BusinessType;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Models\Company;
|
||||
use Maatwebsite\Excel\Concerns\Exportable;
|
||||
use Maatwebsite\Excel\Concerns\FromQuery;
|
||||
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
|
||||
use Maatwebsite\Excel\Concerns\WithHeadingRow;
|
||||
use Maatwebsite\Excel\Concerns\WithHeadings;
|
||||
use Maatwebsite\Excel\Concerns\WithMapping;
|
||||
|
||||
class ExportsEInvoiceDebtorSummary implements FromQuery, WithHeadings, WithHeadingRow, WithMapping, ShouldAutoSize
|
||||
{
|
||||
|
||||
use Exportable;
|
||||
|
||||
|
||||
public function headings(): array
|
||||
{
|
||||
return [
|
||||
'Code',
|
||||
'Need Tax INV?',
|
||||
'Request Date',
|
||||
'TIN NO.',
|
||||
'DebtorControlAcc',
|
||||
'ControlAccount',
|
||||
'CompanyName',
|
||||
'Desc2',
|
||||
'DebtorType',
|
||||
'DisplayTerm',
|
||||
'CurrencyCode',
|
||||
'RegisterNo',
|
||||
'Address1',
|
||||
'Address2',
|
||||
'Address3',
|
||||
'PostCode',
|
||||
'DeliverAddr1',
|
||||
'DeliverAddr2',
|
||||
'DeliverAddr3',
|
||||
'DeliverPostCode',
|
||||
'EmailAddress',
|
||||
'Attention',
|
||||
'Phone1',
|
||||
'Phone2',
|
||||
'Fax1'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Support\Collection|mixed
|
||||
*/
|
||||
public function query()
|
||||
{
|
||||
return Company::where(function($query){
|
||||
// $query->whereNull('debtor')->orWhere('debtor', '');
|
||||
$query->whereNotNull('e_invoice');
|
||||
})->whereNotIn('id', [2207, 2248, 2029])->where('business_type', BusinessType::IMPORTER)->where('status', ApprovalStatus::APPROVED)->where(function($query){
|
||||
$query->whereHas('transactions', function($query){
|
||||
return $query->whereIn('type', [TransactionType::PAYMENT, TransactionType::TOP_UP])->whereIn('transactions.status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED, ApprovalStatus::PENDING_VERIFICATION]);
|
||||
})->orWhereHas('wallets', function($query){
|
||||
return $query->whereHas('transactions');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Company $company
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function map($company): array
|
||||
{
|
||||
return [
|
||||
'<<New>>', // Code
|
||||
$company->e_invoice, // Need Tax INV?
|
||||
$company->e_invoice_requested_at, // Request Date
|
||||
$company->tin, // TIN NO.
|
||||
'300-0000', // DebtorControlAcc
|
||||
'300-0000', // ControlAccount
|
||||
$company->name.' (PURCHASE)', // CompanyName
|
||||
$company->reference, // Desc2
|
||||
'', // DebtorType
|
||||
'PIA', // DisplayTerm
|
||||
'MYR', // CurrencyCode
|
||||
'', // RegisterNo
|
||||
'', // Address1
|
||||
'', // Address2
|
||||
'', // Address3
|
||||
'', // PostCode
|
||||
'', // DeliverAddr1
|
||||
'', // DeliverAddr2
|
||||
'', // DeliverAddr3
|
||||
'', // DeliverPostCode
|
||||
'', // EmailAddress
|
||||
'', // Attention
|
||||
'', // Phone1
|
||||
'', // Phone2
|
||||
'', // Fax1
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -72,28 +72,28 @@ class ExportsNullDebtors implements FromQuery, WithHeadings, WithHeadingRow, Wit
|
||||
public function map($company): array
|
||||
{
|
||||
return [
|
||||
'<<New>>',
|
||||
'300-0000',
|
||||
'300-0000',
|
||||
$company->name.' (PURCHASE)',
|
||||
$company->reference,
|
||||
'',
|
||||
'PIA',
|
||||
'MYR',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',//EmailAddress
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
''
|
||||
'<<New>>', // Code
|
||||
'300-0000', // DebtorControlAcc
|
||||
'300-0000', // ControlAccount
|
||||
$company->name.' (PURCHASE)', // CompanyName
|
||||
$company->reference, // Desc2
|
||||
'', // DebtorType
|
||||
'PIA', // DisplayTerm
|
||||
'MYR', // CurrencyCode
|
||||
'', // RegisterNo
|
||||
'', // Address1
|
||||
'', // Address2
|
||||
'', // Address3
|
||||
'', // PostCode
|
||||
'', // DeliverAddr1
|
||||
'', // DeliverAddr2
|
||||
'', // DeliverAddr3
|
||||
'', // DeliverPostCode
|
||||
'', // EmailAddress
|
||||
'', // Attention
|
||||
'', // Phone1
|
||||
'', // Phone2
|
||||
'', // Fax1
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Rules\ControllersLogic;
|
||||
|
||||
|
||||
use App\Classes\Exceptions\CriteriaNotFulfilledException;
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Rules\DataTransferObjects\CheckEInvoiceRuleDTO;
|
||||
use App\Classes\Modules\Rules\Services\RuleEvaluator;
|
||||
use App\Classes\Modules\Rules\Standards\Rules\CanPassEInvoicePromptedRule;
|
||||
use App\Classes\Modules\Rules\Standards\Rules\CanPassTINRule;
|
||||
use App\Http\Resources\RuleResource;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class CheckEInvoiceRuleLogic extends AbstractControllerLogic
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function notification():array {
|
||||
return [
|
||||
'title' => 'Rule Check E-Invoice',
|
||||
'message' => 'You have successfully passed all rules evaluated'
|
||||
];
|
||||
}
|
||||
|
||||
/** @var RuleEvaluator */
|
||||
private $ruleEvaluator;
|
||||
|
||||
/** @var CanPassEInvoicePromptedRule */
|
||||
private $canPassEInvoicePromptedRule;
|
||||
|
||||
/** @var CanPassTINRule */
|
||||
private $canPassTINRule;
|
||||
|
||||
/**
|
||||
* CheckEInvoiceRuleLogic constructor.
|
||||
*/
|
||||
public function __construct(RuleEvaluator $ruleEvaluator, CanPassEInvoicePromptedRule $canPassEInvoicePromptedRule, CanPassTINRule $canPassTINRule)
|
||||
{
|
||||
$this->ruleEvaluator = $ruleEvaluator;
|
||||
$this->canPassEInvoicePromptedRule = $canPassEInvoicePromptedRule;
|
||||
$this->canPassTINRule = $canPassTINRule;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
* @throws \App\Classes\Exceptions\AccessForbiddenException
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
* @throws \App\Classes\Exceptions\RequestValidationException
|
||||
* @throws \App\Classes\Exceptions\CriteriaNotFulfilledException
|
||||
*/
|
||||
public function logic(Request $request) : JsonResponse
|
||||
{
|
||||
$dto = new CheckEInvoiceRuleDTO($request->all());
|
||||
|
||||
$result = $this->ruleEvaluator->evaluate([
|
||||
$this->canPassEInvoicePromptedRule,
|
||||
$this->canPassTINRule,
|
||||
], $dto);
|
||||
|
||||
if ($result->failed()) {
|
||||
throw new CriteriaNotFulfilledException("- " . implode("<br>- ", $result->messages()));
|
||||
}
|
||||
|
||||
return $this->resourceResponse(new RuleResource((object)$result));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Rules\ControllersLogic;
|
||||
|
||||
|
||||
use App\Classes\Exceptions\CriteriaNotFulfilledException;
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Rules\DataTransferObjects\CheckPurchaseOrderRuleDTO;
|
||||
use App\Classes\Modules\Rules\Services\RuleEvaluator;
|
||||
use App\Classes\Modules\Rules\Standards\Rules\CanPassEInvoicePromptedRule;
|
||||
use App\Classes\Modules\Rules\Standards\Rules\CanPassOrderDurationLimitRule;
|
||||
use App\Classes\Modules\Rules\Standards\Rules\CanPassPurchaseOrderRule;
|
||||
use App\Http\Resources\RuleResource;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class CheckPurchaseOrderRuleLogic extends AbstractControllerLogic
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function notification():array {
|
||||
return [
|
||||
'title' => 'Rule Check Purchase Order',
|
||||
'message' => 'You have successfully passed all rules evaluated'
|
||||
];
|
||||
}
|
||||
|
||||
/** @var RuleEvaluator */
|
||||
private $ruleEvaluator;
|
||||
|
||||
/** @var CanPassOrderDurationLimitRule */
|
||||
private $canPassOrderDurationLimitRule;
|
||||
|
||||
/** @var CanPassEInvoicePromptedRule */
|
||||
private $canPassEInvoicePromptedRule;
|
||||
|
||||
/** @var CanPassPurchaseOrderRule */
|
||||
private $canPassPurchaseOrderRule;
|
||||
|
||||
|
||||
/**
|
||||
* CheckPurchaseOrderRuleLogic constructor.
|
||||
* @param RuleEvaluator $ruleEvaluator
|
||||
* @param CanPassOrderDurationLimitRule $canPassOrderDurationLimitRule
|
||||
* @param CanPassEInvoicePromptedRule $canPassEInvoicePromptedRule
|
||||
* @param CanPassPurchaseOrderRule $canPassPurchaseOrderRule
|
||||
|
||||
*/
|
||||
public function __construct(RuleEvaluator $ruleEvaluator, CanPassOrderDurationLimitRule $canPassOrderDurationLimitRule, CanPassEInvoicePromptedRule $canPassEInvoicePromptedRule, CanPassPurchaseOrderRule $canPassPurchaseOrderRule)
|
||||
{
|
||||
$this->ruleEvaluator = $ruleEvaluator;
|
||||
$this->canPassOrderDurationLimitRule = $canPassOrderDurationLimitRule;
|
||||
$this->canPassEInvoicePromptedRule = $canPassEInvoicePromptedRule;
|
||||
$this->canPassPurchaseOrderRule = $canPassPurchaseOrderRule;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
* @throws \App\Classes\Exceptions\AccessForbiddenException
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
* @throws \App\Classes\Exceptions\RequestValidationException
|
||||
* @throws \App\Classes\Exceptions\CriteriaNotFulfilledException
|
||||
*/
|
||||
public function logic(Request $request) : JsonResponse
|
||||
{
|
||||
$dto = new CheckPurchaseOrderRuleDTO($request->all());
|
||||
|
||||
$result = $this->ruleEvaluator->evaluate([
|
||||
$this->canPassOrderDurationLimitRule,
|
||||
$this->canPassEInvoicePromptedRule,
|
||||
$this->canPassPurchaseOrderRule,
|
||||
], $dto);
|
||||
|
||||
if ($result->failed()) {
|
||||
throw new CriteriaNotFulfilledException("- " . implode("<br>- ", $result->messages()));
|
||||
}
|
||||
|
||||
return $this->resourceResponse(new RuleResource((object)$result));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Rules\ControllersLogic;
|
||||
|
||||
|
||||
use App\Classes\Exceptions\CriteriaNotFulfilledException;
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Rules\DataTransferObjects\CheckTransferRuleDTO;
|
||||
use App\Classes\Modules\Rules\Services\RuleEvaluator;
|
||||
use App\Classes\Modules\Rules\Standards\Rules\CanPassOrderDurationLimitRule;
|
||||
use App\Http\Resources\RuleResource;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class CheckTransferRuleLogic extends AbstractControllerLogic
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function notification():array {
|
||||
return [
|
||||
'title' => 'Rule Check Transfer',
|
||||
'message' => 'You have successfully passed all rules evaluated'
|
||||
];
|
||||
}
|
||||
|
||||
/** @var RuleEvaluator */
|
||||
private $ruleEvaluator;
|
||||
|
||||
/** @var CanPassOrderDurationLimitRule */
|
||||
private $canPassOrderDurationLimitRule;
|
||||
|
||||
/**
|
||||
* CheckTransferRuleLogic constructor.
|
||||
* @param RuleEvaluator $ruleEvaluator
|
||||
* @param CanPassOrderDurationLimitRule $canPassOrderDurationLimitRule
|
||||
*/
|
||||
public function __construct(RuleEvaluator $ruleEvaluator, CanPassOrderDurationLimitRule $canPassOrderDurationLimitRule)
|
||||
{
|
||||
$this->ruleEvaluator = $ruleEvaluator;
|
||||
$this->canPassOrderDurationLimitRule = $canPassOrderDurationLimitRule;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
* @throws \App\Classes\Exceptions\AccessForbiddenException
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
* @throws \App\Classes\Exceptions\RequestValidationException
|
||||
* @throws \App\Classes\Exceptions\CriteriaNotFulfilledException
|
||||
*/
|
||||
public function logic(Request $request) : JsonResponse
|
||||
{
|
||||
$dto = new CheckTransferRuleDTO($request->all());
|
||||
|
||||
$result = $this->ruleEvaluator->evaluate([
|
||||
$this->canPassOrderDurationLimitRule,
|
||||
], $dto);
|
||||
|
||||
if ($result->failed()) {
|
||||
throw new CriteriaNotFulfilledException("- " . implode("<br>- ", $result->messages()));
|
||||
}
|
||||
|
||||
return $this->resourceResponse(new RuleResource((object)$result));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Rules\DataTransferObjects;
|
||||
|
||||
use App\Classes\General\Interfaces\DataTransferObject;
|
||||
|
||||
class CheckEInvoiceRuleDTO implements DataTransferObject
|
||||
{
|
||||
public int $companyId;
|
||||
|
||||
public function __construct(array $data)
|
||||
{
|
||||
$this->companyId = $data['company_id'];
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'company_id' => $this->companyId,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Rules\DataTransferObjects;
|
||||
|
||||
use App\Classes\General\Interfaces\DataTransferObject;
|
||||
|
||||
class CheckPurchaseOrderRuleDTO implements DataTransferObject
|
||||
{
|
||||
public int $bookingId;
|
||||
public int $companyId;
|
||||
|
||||
public function __construct(array $data)
|
||||
{
|
||||
$this->bookingId = $data['booking_id'];
|
||||
$this->companyId = $data['company_id'];
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'booking_id' => $this->bookingId,
|
||||
'company_id' => $this->companyId,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Rules\DataTransferObjects;
|
||||
|
||||
use App\Classes\General\Interfaces\DataTransferObject;
|
||||
|
||||
class CheckTransferRuleDTO implements DataTransferObject
|
||||
{
|
||||
public int $bookingId;
|
||||
public int $companyId;
|
||||
public string $paymentReference;
|
||||
|
||||
public function __construct(array $data)
|
||||
{
|
||||
$this->bookingId = $data['booking_id'];
|
||||
$this->companyId = $data['company_id'];
|
||||
$this->paymentReference = $data['payment_reference'] ?? '';
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'booking_id' => $this->bookingId,
|
||||
'company_id' => $this->companyId,
|
||||
'payment_reference' => $this->paymentReference,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Rules\Services;
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractRule;
|
||||
use App\Classes\General\Interfaces\DataTransferObject;
|
||||
use App\Classes\Exceptions\AccessForbiddenException;
|
||||
use App\Classes\Exceptions\CriteriaNotFulfilledException;
|
||||
use App\Classes\Exceptions\RequestValidationException;
|
||||
use App\Classes\ValueObjects\Response\RuleEvaluationResult;
|
||||
|
||||
class RuleEvaluator //For using AbstractRule
|
||||
{
|
||||
/**
|
||||
* Evaluate multiple rules.
|
||||
*
|
||||
* @param AbstractRule[] $rules
|
||||
* @param DataTransferObject|null $object
|
||||
* @return RuleEvaluationResult
|
||||
*/
|
||||
public function evaluate(array $rules, ?DataTransferObject $object = null): RuleEvaluationResult
|
||||
{
|
||||
$messages = [];
|
||||
$success = true;
|
||||
|
||||
foreach ($rules as $rule) {
|
||||
try {
|
||||
if (!$rule->passes($object)) {
|
||||
$success = false;
|
||||
$messages[] = get_class($rule) . ' failed without exception';
|
||||
}
|
||||
} catch (AccessForbiddenException | RequestValidationException | CriteriaNotFulfilledException $e) {
|
||||
$success = false;
|
||||
$messages[] = $e->getMessage();
|
||||
} catch (\Exception $e) {
|
||||
$success = false;
|
||||
$messages[] = 'Unexpected error in ' . get_class($rule) . ': ' . $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
return new RuleEvaluationResult($success, $messages);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Rules\Standards\Rules;
|
||||
|
||||
use App\Classes\Exceptions\CriteriaNotFulfilledException;
|
||||
use App\Classes\General\Abstracts\AbstractRule;
|
||||
use App\Classes\Modules\Companies\Services\FetchesCompany;
|
||||
|
||||
class CanPassEInvoicePromptedRule extends AbstractRule
|
||||
{
|
||||
|
||||
/** @var FetchesCompany */
|
||||
private $fetchesCompany;
|
||||
|
||||
/**
|
||||
* CanPassEInvoicePromptedRule constructor.
|
||||
* @param FetchesCompany $fetchesCompany
|
||||
*/
|
||||
public function __construct(FetchesCompany $fetchesCompany)
|
||||
{
|
||||
$this->fetchesCompany = $fetchesCompany;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function authorized($object): bool
|
||||
{
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function validators($object): bool
|
||||
{
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function criteria($object): bool
|
||||
{
|
||||
//Check if account requires E-Invoice
|
||||
$company = $this->fetchesCompany->execute(['id' => $object->companyId]);
|
||||
if($company->e_invoice === null){
|
||||
throw new CriteriaNotFulfilledException("Please refresh page and click 'Make Payment' first to answer question related to E-Invoice.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Rules\Standards\Rules;
|
||||
|
||||
use App\Classes\Exceptions\CriteriaNotFulfilledException;
|
||||
use App\Classes\General\Abstracts\AbstractRule;
|
||||
use App\Classes\Modules\Bookings\Services\FetchesBooking;
|
||||
use App\Classes\Modules\Companies\Services\FetchesCompany;
|
||||
use App\Classes\Modules\Bookings\Services\CalculatesBookingPayableAmount;
|
||||
use App\Classes\Modules\Bookings\Services\CalculatesBookingRefundAmount;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
|
||||
class CanPassEditingPORule extends AbstractRule
|
||||
{
|
||||
|
||||
/** @var FetchesBooking */
|
||||
private $fetchesBooking;
|
||||
|
||||
/** @var FetchesCompany */
|
||||
private $fetchesCompany;
|
||||
|
||||
/**
|
||||
* CanPassEditingPORule constructor.
|
||||
* @param FetchesBooking $fetchesBooking
|
||||
* @param FetchesCompany $fetchesCompany
|
||||
*/
|
||||
public function __construct(FetchesBooking $fetchesBooking, FetchesCompany $fetchesCompany)
|
||||
{
|
||||
$this->fetchesBooking = $fetchesBooking;
|
||||
$this->fetchesCompany = $fetchesCompany;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function authorized($object): bool
|
||||
{
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function validators($object): bool
|
||||
{
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function criteria($object): bool
|
||||
{
|
||||
//Check if user is allow to edit purchase order
|
||||
$booking = $this->fetchesBooking->execute(['id' => $object->bookingId]);
|
||||
|
||||
$paidAmount = floatval((App()->make(CalculatesBookingPayableAmount::class))->execute($booking, $booking->fix_currency_id)) - floatval((App()->make(CalculatesBookingRefundAmount::class))->execute($booking, $booking->fix_currency_id));
|
||||
|
||||
if($paidAmount > 0){
|
||||
throw new CriteriaNotFulfilledException("Purchase order form is no longer allow to be edited.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Rules\Standards\Rules;
|
||||
|
||||
use App\Classes\Exceptions\CriteriaNotFulfilledException;
|
||||
use App\Classes\General\Abstracts\AbstractRule;
|
||||
use App\Classes\Modules\Bookings\Services\FetchesBooking;
|
||||
use App\Classes\Modules\Companies\Services\FetchesCompanyPaymentAttemptLimit;
|
||||
use App\Classes\Modules\Transactions\Services\CalculatesTransactionExpiryDateTime;
|
||||
use App\Classes\Modules\Billplzs\Services\DeletesBillplzBill;
|
||||
use App\Classes\Modules\Transactions\Services\FetchesTransaction;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\PaymentMethodType;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class CanPassOrderDurationLimitRule extends AbstractRule
|
||||
{
|
||||
|
||||
/** @var FetchesBooking */
|
||||
private $fetchesBooking;
|
||||
|
||||
/** @var FetchesCompanyPaymentAttemptLimit */
|
||||
private $fetchesCompanyPaymentAttemptLimit;
|
||||
|
||||
/** @var CalculatesTransactionExpiryDateTime */
|
||||
private $calculatesTransactionExpiryDateTime;
|
||||
|
||||
/** @var DeletesBillplzBill */
|
||||
private $deletesBillplzBill;
|
||||
|
||||
/** @var FetchesTransaction */
|
||||
private $fetchesTransaction;
|
||||
|
||||
/**
|
||||
* CanPassOrderDurationLimitRule constructor.
|
||||
* @param FetchesBooking $fetchesBooking
|
||||
* @param FetchesCompanyPaymentAttemptLimit $fetchesCompanyPaymentAttemptLimit
|
||||
* @param CalculatesTransactionExpiryDateTime $calculatesTransactionExpiryDateTime
|
||||
* @param DeletesBillplzBill $deletesBillplzBill
|
||||
* @param FetchesTransaction $fetchesTransaction
|
||||
*/
|
||||
public function __construct(FetchesBooking $fetchesBooking, FetchesCompanyPaymentAttemptLimit $fetchesCompanyPaymentAttemptLimit, CalculatesTransactionExpiryDateTime $calculatesTransactionExpiryDateTime, DeletesBillplzBill $deletesBillplzBill, FetchesTransaction $fetchesTransaction)
|
||||
{
|
||||
$this->fetchesBooking = $fetchesBooking;
|
||||
$this->fetchesCompanyPaymentAttemptLimit = $fetchesCompanyPaymentAttemptLimit;
|
||||
$this->calculatesTransactionExpiryDateTime = $calculatesTransactionExpiryDateTime;
|
||||
$this->deletesBillplzBill = $deletesBillplzBill;
|
||||
$this->fetchesTransaction = $fetchesTransaction;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function authorized($object): bool
|
||||
{
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function validators($object): bool
|
||||
{
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function criteria($object): bool
|
||||
{
|
||||
//Check if order is still valid (within duration limit, reused PAYMENT_ATTEMPT_DURATION_LIMIT)
|
||||
$expiresOn = $this->calculatesTransactionExpiryDateTime->execute($object->bookingId);
|
||||
$isExpired = Carbon::now()->greaterThan($expiresOn);
|
||||
if($isExpired){
|
||||
|
||||
if($object->paymentReference){
|
||||
$transaction = $this->fetchesTransaction->execute(['payment_reference' => $object->paymentReference]);
|
||||
if($transaction->status === ApprovalStatus::PENDING_SUBMISSION && $transaction->payment_method == PaymentMethodType::PAYMENT_GATEWAY){
|
||||
$this->deletesBillplzBill->execute($object->paymentReference);
|
||||
}
|
||||
}
|
||||
|
||||
throw new CriteriaNotFulfilledException("Transfer has already expired.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Rules\Standards\Rules;
|
||||
|
||||
use App\Classes\Exceptions\CriteriaNotFulfilledException;
|
||||
use App\Classes\General\Abstracts\AbstractRule;
|
||||
use App\Classes\Modules\Bookings\Services\FetchesBooking;
|
||||
use App\Classes\Modules\Companies\Services\FetchesCompany;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\SegmentNameConstants;
|
||||
use App\Classes\ValueObjects\Constants\ServiceTypeNameConstants;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Models\ServiceType;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class CanPassPurchaseOrderRule extends AbstractRule
|
||||
{
|
||||
|
||||
/** @var FetchesBooking */
|
||||
private $fetchesBooking;
|
||||
|
||||
/** @var FetchesCompany */
|
||||
private $fetchesCompany;
|
||||
|
||||
/**
|
||||
* CanPassPurchaseOrderRule constructor.
|
||||
* @param FetchesBooking $fetchesBooking
|
||||
* @param FetchesCompany $fetchesCompany
|
||||
*/
|
||||
public function __construct(FetchesBooking $fetchesBooking, FetchesCompany $fetchesCompany)
|
||||
{
|
||||
$this->fetchesBooking = $fetchesBooking;
|
||||
$this->fetchesCompany = $fetchesCompany;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function authorized($object): bool
|
||||
{
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function validators($object): bool
|
||||
{
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function criteria($object): bool
|
||||
{
|
||||
//Check if the transfer/booking already has purchase order filled
|
||||
$booking = $this->fetchesBooking->execute(['id' => $object->bookingId]);
|
||||
$purchaseOrder = $booking->transactions()->where('type', TransactionType::PURCHASE_ORDER)->first();
|
||||
|
||||
$isPOEmptyException = false;
|
||||
if (!$purchaseOrder || $purchaseOrder->status === ApprovalStatus::PENDING_SUBMISSION) {
|
||||
$isPOEmptyException = true;
|
||||
}
|
||||
|
||||
if($isPOEmptyException){ //If PO is indeed empty, there are some scenarios where PO actually can be left empty
|
||||
$ids = ServiceType::whereIn('name', [
|
||||
ServiceTypeNameConstants::PAYMENT_1688,
|
||||
ServiceTypeNameConstants::VIP_1688,
|
||||
])->get()->pluck('id');
|
||||
|
||||
//It can be left empty when booking is of type 1688: specifcally: 1688 Payment and 1688 VIP
|
||||
if (in_array($booking->service_id, $ids->all())) {
|
||||
$isPOEmptyException = false;
|
||||
}
|
||||
|
||||
//However when the customer falls under the segment '1688 Manual PO Periodic', even if their booking is of type 1688 (1688 Payment and 1688 VIP),
|
||||
//they still must fill up the PO. Confusing?? IKR
|
||||
$company = $this->fetchesCompany->execute(['id' => $object->companyId]);
|
||||
$filteredSegments = $company->segments()->whereIn('name', [SegmentNameConstants::MANUAL_PO_PERIODIC_1688, SegmentNameConstants::MANUAL_PO_1688])->get();
|
||||
if(!$isPOEmptyException){
|
||||
if (!$filteredSegments->isEmpty()) {
|
||||
$isPOEmptyException = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($isPOEmptyException){
|
||||
throw new CriteriaNotFulfilledException("Please complete the purchase order form.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Rules\Standards\Rules;
|
||||
|
||||
|
||||
use App\Classes\Exceptions\CriteriaNotFulfilledException;
|
||||
use App\Classes\General\Abstracts\AbstractRule;
|
||||
use App\Classes\Modules\Companies\Services\FetchesCompany;
|
||||
|
||||
class CanPassTINRule extends AbstractRule
|
||||
{
|
||||
|
||||
/** @var FetchesCompany */
|
||||
private $fetchesCompany;
|
||||
|
||||
/**
|
||||
* CanPassTINRule constructor.
|
||||
* @param FetchesCompany $fetchesCompany
|
||||
*/
|
||||
public function __construct(FetchesCompany $fetchesCompany)
|
||||
{
|
||||
$this->fetchesCompany = $fetchesCompany;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function authorized($object): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function validators($object): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function criteria($object): bool
|
||||
{
|
||||
//Check if TIN already provided if account requires E-Invoice
|
||||
$company = $this->fetchesCompany->execute(['id' => $object->companyId]);
|
||||
if($company->e_invoice === 1 && !$company->tin){
|
||||
throw new CriteriaNotFulfilledException("Please provide all requested E-Invoice Info.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
+31
-5
@@ -3,9 +3,11 @@
|
||||
|
||||
namespace App\Classes\Modules\Transactions\ControllersLogic;
|
||||
|
||||
use App\Classes\Exceptions\CriteriaNotFulfilledException;
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Bookings\Services\FetchesBooking;
|
||||
use App\Classes\Modules\Companies\Services\FetchesCompany;
|
||||
use App\Classes\Modules\Transactions\DataTransferObjects\CreatePurchaseOrderDTO;
|
||||
use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject;
|
||||
use App\Classes\Modules\Transactions\Processors\CreatePurchaseOrderTransactionProcessor;
|
||||
use App\Classes\Modules\Transactions\Services\CreatesTransaction;
|
||||
@@ -15,14 +17,18 @@ use App\Classes\Modules\Transactions\Services\FetchesTransaction;
|
||||
use App\Classes\Modules\Transactions\Services\GeneratesTransactionBillNumber;
|
||||
use App\Classes\Modules\Transactions\Services\UpdatesTransaction;
|
||||
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
|
||||
use App\Classes\Modules\Rules\Services\RuleEvaluator;
|
||||
use App\Classes\Modules\Rules\Standards\Rules\CanPassEditingPORule;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\PaymentMethodType;
|
||||
use App\Classes\ValueObjects\Constants\RoleTypes;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Http\Resources\TransactionResource;
|
||||
use App\Models\Booking;
|
||||
use App\Models\Transaction;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class CreatePurchaseOrderTransactionLogic extends AbstractControllerLogic
|
||||
{
|
||||
@@ -33,7 +39,7 @@ class CreatePurchaseOrderTransactionLogic extends AbstractControllerLogic
|
||||
protected function notification():array {
|
||||
return [
|
||||
'title' => 'Update Purchase Order',
|
||||
'message' => 'You have successfully updated you booking\'s purchase order'
|
||||
'message' => 'You have successfully updated your booking\'s purchase order'
|
||||
];
|
||||
}
|
||||
|
||||
@@ -46,17 +52,27 @@ class CreatePurchaseOrderTransactionLogic extends AbstractControllerLogic
|
||||
/** @var CreatePurchaseOrderTransactionProcessor */
|
||||
private $createPurchaseOrderTransactionProcessor;
|
||||
|
||||
/** @var RuleEvaluator */
|
||||
private $ruleEvaluator;
|
||||
|
||||
/** @var CanPassEditingPORule */
|
||||
private $canPassEditingPORule;
|
||||
|
||||
/**
|
||||
* CreatePurchaseOrderTransactionLogic constructor.
|
||||
* @param FetchesBooking $fetchesBooking
|
||||
* @param GeneratesTransactionBillNumber $generatesTransactionBillNumber
|
||||
* @param CreatePurchaseOrderTransactionProcessor $createPurchaseOrderTransactionProcessor
|
||||
* @param RuleEvaluator $ruleEvaluator
|
||||
* @param CanPassEditingPORule $canPassEditingPORule
|
||||
*/
|
||||
public function __construct(FetchesBooking $fetchesBooking, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CreatePurchaseOrderTransactionProcessor $createPurchaseOrderTransactionProcessor)
|
||||
public function __construct(FetchesBooking $fetchesBooking, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CreatePurchaseOrderTransactionProcessor $createPurchaseOrderTransactionProcessor, RuleEvaluator $ruleEvaluator, CanPassEditingPORule $canPassEditingPORule)
|
||||
{
|
||||
$this->fetchesBooking = $fetchesBooking;
|
||||
$this->generatesTransactionBillNumber = $generatesTransactionBillNumber;
|
||||
$this->createPurchaseOrderTransactionProcessor = $createPurchaseOrderTransactionProcessor;
|
||||
$this->ruleEvaluator = $ruleEvaluator;
|
||||
$this->canPassEditingPORule = $canPassEditingPORule;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -64,9 +80,22 @@ class CreatePurchaseOrderTransactionLogic extends AbstractControllerLogic
|
||||
* @param string $id
|
||||
* @return JsonResponse
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
* @throws \App\Classes\Exceptions\CriteriaNotFulfilledException
|
||||
*/
|
||||
public function logic(Request $request, $id = '') : JsonResponse
|
||||
{
|
||||
//This checking is excluded for (1) Admin, (2) Update of booking amount post payment as user
|
||||
if(!in_array(Auth::user()->type, RoleTypes::ADMIN_ROLES) && !$request->has('is_privilleged_update')){
|
||||
$dto = new CreatePurchaseOrderDTO($request->all());
|
||||
$result = $this->ruleEvaluator->evaluate([
|
||||
$this->canPassEditingPORule
|
||||
], $dto);
|
||||
|
||||
if ($result->failed()) {
|
||||
throw new CriteriaNotFulfilledException("- " . implode("<br>- ", $result->messages()));
|
||||
}
|
||||
}
|
||||
|
||||
/** @var Booking $booking */
|
||||
$booking = $this->fetchesBooking->execute(['id' => $request->route('id') ?? $id]);
|
||||
|
||||
@@ -87,7 +116,4 @@ class CreatePurchaseOrderTransactionLogic extends AbstractControllerLogic
|
||||
return $this->resourceResponse(new TransactionResource($transaction));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -13,6 +13,10 @@ use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Classes\General\AWSS3Helper;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
/**
|
||||
* @deprecated This class is deprecated and should not be used.
|
||||
* Use `GenerateCreditNotePdfV2Logic` instead
|
||||
*/
|
||||
class GenerateCreditNotePdfLogic
|
||||
{
|
||||
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace App\Classes\Modules\Transactions\ControllersLogic;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Mccarlosen\LaravelMpdf\Facades\LaravelMpdf;
|
||||
use App\Classes\Modules\Companies\Services\FetchesCompany;
|
||||
use App\Classes\Modules\Transactions\Services\FetchesTransaction;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Classes\General\AWSS3Helper;
|
||||
use App\Classes\ValueObjects\Constants\DocumentType;
|
||||
use App\Models\KeyValuePair;
|
||||
use App\Models\Transaction;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class GenerateCreditNotePdfV2Logic
|
||||
{
|
||||
|
||||
/** @var FetchesTransaction */
|
||||
private $fetchesTransaction;
|
||||
|
||||
/** @var FetchesCompany */
|
||||
private $fetchesCompany;
|
||||
|
||||
/**
|
||||
* GenerateCreditNotePdfV2Logic constructor.
|
||||
* @param FetchesTransaction $fetchesTransaction
|
||||
* @param FetchesCompany $fetchesCompany
|
||||
*/
|
||||
public function __construct(FetchesTransaction $fetchesTransaction, FetchesCompany $fetchesCompany)
|
||||
{
|
||||
$this->fetchesTransaction = $fetchesTransaction;
|
||||
$this->fetchesCompany = $fetchesCompany;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return string|\Symfony\Component\HttpFoundation\Response
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
*/
|
||||
public function execute(Request $request)
|
||||
{
|
||||
$pdfTemplateName = 'pages.pdfs.credit_note_v2'; //default since e-invoice implementation
|
||||
$transaction = $this->fetchesTransaction->execute(['id' => $request->route('id')]);
|
||||
|
||||
if($transaction->type === TransactionType::REFUND){
|
||||
//Retrieve TransactionType::CREDIT_NOTE
|
||||
$booking = $transaction->owner->booking;
|
||||
$kvp = $transaction->attributesKVP()->latest()->first();
|
||||
if($kvp){
|
||||
if($kvp->key === 'App\Models\Transaction'){
|
||||
$transaction = $this->fetchesTransaction->execute(['id' => $kvp->value ]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
//For Old Cases
|
||||
$booking = $transaction->booking;
|
||||
$pdfTemplateName = 'pages.pdfs.credit_note'; //default
|
||||
|
||||
//For New Cases with e-invoice: Retrieve the refund transaction for this credit note
|
||||
$kvp = KeyValuePair::where('key', 'App\Models\Transaction')->where('value', $transaction->id)->first();
|
||||
if($kvp){
|
||||
$kvpOwner = $kvp->owner;
|
||||
if($kvpOwner && $kvpOwner instanceof Transaction && $kvpOwner->type === TransactionType::REFUND){
|
||||
$booking = $kvpOwner->owner->booking;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$date = $transaction->created_at;
|
||||
$supplier = $this->fetchesCompany->execute(['id' => $transaction->receiver]);
|
||||
$brn = $supplier->documents->where('document_type', DocumentType::SSM_REGISTRATION)->first();
|
||||
|
||||
$eInvoiceStarted = false;
|
||||
$eInvoiceStartDate = Carbon::parse(env('E_INVOICE_START_DATE', '2025-07-01 00:00:00'));
|
||||
$bookingCreatedDate = Carbon::parse($booking->created_at);
|
||||
|
||||
if ($bookingCreatedDate->isAfter($eInvoiceStartDate)) {
|
||||
$eInvoiceStarted = true;
|
||||
}
|
||||
// $eInvoiceStarted = false; //cief todo: 90 - for testing
|
||||
|
||||
if($eInvoiceStarted)
|
||||
{
|
||||
if($supplier->e_invoice === 1){
|
||||
Log::info('Based on booking created date, E-Credit Note started and company wants e-invoice ' . json_encode($booking));
|
||||
$date = $booking->updated_at->copy()->endOfMonth();
|
||||
$pdfTemplateName = 'pages.pdfs.e_credit_note';
|
||||
}
|
||||
else{
|
||||
Log::info('Based on booking created date, E-Credit Note started and company do not wants e-invoice');
|
||||
$pdfTemplateName = 'pages.pdfs.credit_note_v2';
|
||||
}
|
||||
}
|
||||
else{
|
||||
Log::info('Based on booking created date, E-Credit Note not yet started');
|
||||
}
|
||||
|
||||
$pdf = LaravelMpdf::loadView($pdfTemplateName, ['transaction' => $transaction, 'booking' => $booking, 'supplier' => $supplier, 'date' => $date, 'brn' => $brn,]);
|
||||
|
||||
$exportFileName = 'CreditNote.pdf';
|
||||
$filesystemDriver = Storage::getDefaultDriver();
|
||||
if($filesystemDriver === 's3'){
|
||||
$pdfContent = $pdf->output();
|
||||
return response([ 'src' => AWSS3Helper::S3PDF($exportFileName, $pdfContent) ]);
|
||||
}
|
||||
else{
|
||||
return $pdf->stream($exportFileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
+16
-9
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace App\Classes\Modules\Transactions\ControllersLogic;
|
||||
|
||||
use App\Classes\Exceptions\MalformedRequestException;
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Bookings\ControllersLogic\UpdateBookingAmountLogic;
|
||||
use App\Classes\Modules\Companies\Services\FetchesCompany;
|
||||
@@ -12,12 +11,11 @@ use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\Modules\Documents\Services\DeletesDocument;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
use App\Classes\Modules\Wallets\Processors\CreditWalletProcessor;
|
||||
use App\Classes\Modules\Bookings\Services\CalculatesBookingPayableAmount;
|
||||
use App\Classes\Modules\Bookings\Services\CalculatesBookingRefundAmount;
|
||||
use App\Classes\ValueObjects\Constants\RemarkRefundReason;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class UpdateRefundTransactionStatusLogic extends AbstractControllerLogic
|
||||
{
|
||||
@@ -86,9 +84,10 @@ class UpdateRefundTransactionStatusLogic extends AbstractControllerLogic
|
||||
*/
|
||||
public function logic(Request $request) : JsonResponse
|
||||
{
|
||||
if(auth()->user()->type === 3) {
|
||||
throw new MalformedRequestException('You do not have the permission to refund the order.');
|
||||
}
|
||||
//cief todo: 90 - move this into rules
|
||||
// if(auth()->user()->type === 3) {
|
||||
// throw new MalformedRequestException('You do not have the permission to refund the order.');
|
||||
// }
|
||||
|
||||
$refundTransaction = $this->fetchesTransaction->execute(['id' => $request->route('id')]);
|
||||
|
||||
@@ -100,14 +99,22 @@ class UpdateRefundTransactionStatusLogic extends AbstractControllerLogic
|
||||
|
||||
$booking = $paymentTransaction->owner;
|
||||
|
||||
$reference = $paymentTransaction->amount - $refundTransaction->amount < 0.01 ? 'Fully Refund for Ref. ' . $booking->marking : 'Partially Refund for Ref. ' . $booking->marking;
|
||||
// $reference = $paymentTransaction->amount - $refundTransaction->amount < 0.01 ? 'Fully Refund for Ref. ' . $booking->marking : 'Partially Refund for Ref. ' . $booking->marking;
|
||||
if ($paymentTransaction->amount - $refundTransaction->amount < 0.01) {
|
||||
$reference = 'Return Inward for Ref. ' . $booking->marking;
|
||||
} else {
|
||||
$refundRemark = $refundTransaction->remarks && $refundTransaction->remarks->first() ? $refundTransaction->remarks->first()->content : $request->input('refundRemark') ;
|
||||
$remarkGroup = RemarkRefundReason::REFUND_REASONS[$refundRemark] ?? null;
|
||||
$reference = $remarkGroup ? $remarkGroup . ' for Ref. ' . $booking->marking : $refundRemark . ' for Ref. ' . $booking->marking;
|
||||
}
|
||||
|
||||
$refundAmount = $this->calculatesBookingRefundAmount->calculateRefundAmount($paymentTransaction, $booking->fix_currency_id);
|
||||
|
||||
$paidAmount = $paymentTransaction->original_amount - $refundAmount;
|
||||
|
||||
if ($refundTransaction->status == ApprovalStatus::APPROVED) {
|
||||
$this->creditWalletProcessor->execute($booking->company, $refundTransaction->type, $refundTransaction->amount, $reference);
|
||||
$this->creditWalletProcessor->execute($booking->company, $refundTransaction->type, $refundTransaction->amount, $reference, $refundTransaction);
|
||||
|
||||
$po_transaction = $booking->transactions()->where('type', TransactionType::PURCHASE_ORDER)->first();
|
||||
|
||||
if ($po_transaction) {
|
||||
@@ -129,4 +136,4 @@ class UpdateRefundTransactionStatusLogic extends AbstractControllerLogic
|
||||
|
||||
return $this->response([]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Transactions\DataTransferObjects;
|
||||
|
||||
use App\Classes\General\Interfaces\DataTransferObject;
|
||||
|
||||
class CreatePurchaseOrderDTO implements DataTransferObject
|
||||
{
|
||||
public int $bookingId;
|
||||
public int $companyId;
|
||||
|
||||
public function __construct(array $data)
|
||||
{
|
||||
$this->bookingId = $data['booking_id'];
|
||||
$this->companyId = $data['company_id'];
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'booking_id' => $this->bookingId,
|
||||
'company_id' => $this->companyId,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ use App\Classes\ValueObjects\Constants\DocumentType;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Models\Booking;
|
||||
use App\Models\Document;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Mccarlosen\LaravelMpdf\Facades\LaravelMpdf;
|
||||
use Webklex\PDFMerger\Facades\PDFMergerFacade as PDFMerger;
|
||||
@@ -45,9 +46,26 @@ class CreateInvoiceDocumentProcessor
|
||||
public function execute($transaction, $purchaseOrder, $supplier, $document_type, $voucherRedemption = null)
|
||||
{
|
||||
// calculate current Paid Amount
|
||||
$booking = $transaction->owner_type == Booking::class ? $transaction->owner : null;
|
||||
$booking = $transaction->owner_type == Booking::class ? $transaction->owner : null;
|
||||
$currentPaidAmount = null;
|
||||
$brn = $supplier->documents->where('document_type', DocumentType::SSM_REGISTRATION)->first();
|
||||
$documentDate = $supplier->segments->whereIn('id', [23])->first() ? \Carbon\Carbon::now() : $purchaseOrder->booking->created_at;
|
||||
$eInvoiceStartDate = Carbon::parse(env('E_INVOICE_START_DATE', '2025-07-01 00:00:00'));
|
||||
|
||||
if ($booking) {
|
||||
$bookingCreatedDate = Carbon::parse($booking->created_at);
|
||||
if ($bookingCreatedDate->isAfter($eInvoiceStartDate)) {
|
||||
$lastPaymentTransaction = $booking->transactions()->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::COMPLETED, ApprovalStatus::APPROVED])->latest()->first();
|
||||
$documentDate = $lastPaymentTransaction->created_at;
|
||||
if(Carbon::parse($booking->updated_at)->isAfter($lastPaymentTransaction->created_at)){
|
||||
$documentDate = $booking->updated_at;
|
||||
}
|
||||
}
|
||||
|
||||
if($document_type === DocumentType::EINVOICE){
|
||||
$lastDayOfMonth = $documentDate->copy()->endOfMonth();
|
||||
$documentDate = $lastDayOfMonth;
|
||||
}
|
||||
$payment = $booking->transactions()->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::COMPLETED, ApprovalStatus::APPROVED])->first();
|
||||
$refundAmount = $payment->transactions()->refunds()->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED])->sum('amount');
|
||||
$paymentAmount = $payment->amount;
|
||||
@@ -56,9 +74,9 @@ class CreateInvoiceDocumentProcessor
|
||||
|
||||
$lowercaseDocumentType = strtolower($document_type);
|
||||
|
||||
$order_pdf = LaravelMpdf::loadView('pages.pdfs.' . $lowercaseDocumentType, ['transaction' => $transaction, 'po_order_transaction' => $purchaseOrder, 'supplier' => $supplier, 'voucher_redemption' => $voucherRedemption, 'current_paid_amount' => $currentPaidAmount]);
|
||||
$order_pdf = LaravelMpdf::loadView('pages.pdfs.' . $lowercaseDocumentType, ['transaction' => $transaction, 'po_order_transaction' => $purchaseOrder, 'supplier' => $supplier, 'voucher_redemption' => $voucherRedemption, 'current_paid_amount' => $currentPaidAmount, 'document_date' => $documentDate, 'brn' => $brn, 'autocountId' => null]); //cief todo: 90 - autocount id to be updated
|
||||
|
||||
if($purchaseOrder->booking->service_id === 4) {
|
||||
if($purchaseOrder && $purchaseOrder->booking->service_id === 4) {
|
||||
$purchaseOrderDocuments = $purchaseOrder->booking->documents()->where('document_type', DocumentType::ECOMMERCE_PURCHASE_ORDER)->get();
|
||||
|
||||
|
||||
@@ -112,8 +130,12 @@ class CreateInvoiceDocumentProcessor
|
||||
);
|
||||
|
||||
/** @var Document $document */
|
||||
$document = $this->createsDocument->execute($purchaseOrder->booking, $document_object);
|
||||
if($document_type === DocumentType::RECEIPT_VOUCHER){
|
||||
$document = $this->createsDocument->execute($transaction, $document_object);
|
||||
}
|
||||
else{
|
||||
$document = $this->createsDocument->execute($purchaseOrder->booking, $document_object);
|
||||
}
|
||||
$this->createsFile->execute($document, $document_object);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Classes\ValueObjects\Constants\DocumentType;
|
||||
use App\Models\Booking;
|
||||
use App\Models\SegmentConstant;
|
||||
use Carbon\Carbon;
|
||||
|
||||
class CreateInvoiceTransactionProcessor
|
||||
{
|
||||
@@ -83,10 +84,12 @@ class CreateInvoiceTransactionProcessor
|
||||
|
||||
/**
|
||||
* @param Booking $booking
|
||||
* @param String $invoiceNo
|
||||
* @param bool $isAllowEInvoice
|
||||
* @return void
|
||||
* @throws MalformedRequestException
|
||||
*/
|
||||
public function execute(Booking $booking)
|
||||
public function execute(Booking $booking, String $invoiceNo= "", bool $isAllowEInvoice = false)
|
||||
{
|
||||
|
||||
if ($booking->status === ApprovalStatus::COMPLETED) {
|
||||
@@ -121,10 +124,26 @@ class CreateInvoiceTransactionProcessor
|
||||
// ->first();
|
||||
|
||||
$transaction = $booking->transactions()
|
||||
->where('type', TransactionType::PAYMENT)
|
||||
->latest()->get()[0];
|
||||
->where('type', TransactionType::PAYMENT)
|
||||
->latest()->get()[0];
|
||||
$supplier = $this->fetchesCompany->execute(['id' => $transaction->receiver]);
|
||||
|
||||
$billNumber = $this->generatesTransactionBillNumber->execute('INV-');
|
||||
// Check if eInvoice implementation has started and company opted in for eInvoice
|
||||
$eInvoice = false;
|
||||
$eInvoiceStartDate = Carbon::parse(env('E_INVOICE_START_DATE', '2025-07-01 00:00:00'));
|
||||
$bookingCreatedDate = Carbon::parse($booking->created_at);
|
||||
if ($bookingCreatedDate->isAfter($eInvoiceStartDate) && $supplier->e_invoice === 1) {
|
||||
$eInvoice = true;
|
||||
}
|
||||
// $eInvoice = true; //cief todo: 90 - for testing
|
||||
|
||||
if($invoiceNo){
|
||||
$billNumber = $invoiceNo;
|
||||
}
|
||||
else{
|
||||
$billNUmberPrefix = $eInvoice ? 'EINV-' : 'INV-';
|
||||
$billNumber = $this->generatesTransactionBillNumber->execute($billNUmberPrefix);
|
||||
}
|
||||
|
||||
$booking_currency_average_rate = $this->calculatesBookingCurrencyAverageRate->execute($booking, TransactionType::PAYMENT);
|
||||
|
||||
@@ -138,6 +157,7 @@ class CreateInvoiceTransactionProcessor
|
||||
->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])
|
||||
->sum('tax');
|
||||
|
||||
|
||||
$transaction_object = new TransactionObject(
|
||||
$billNumber,
|
||||
TransactionType::INVOICE,
|
||||
@@ -159,16 +179,24 @@ class CreateInvoiceTransactionProcessor
|
||||
|
||||
$voucherRedemption = $transaction->voucherRedemption;
|
||||
|
||||
$supplier = $this->fetchesCompany->execute(['id' => $transaction->receiver]);
|
||||
|
||||
// purchase order
|
||||
$this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::PURCHASE_ORDER, $voucherRedemption);
|
||||
|
||||
// deliver order
|
||||
$this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::DELIVER_ORDER, $voucherRedemption);
|
||||
|
||||
// e-invoice
|
||||
if ($eInvoice)
|
||||
{
|
||||
if($isAllowEInvoice){
|
||||
$this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::EINVOICE, $voucherRedemption);
|
||||
}
|
||||
}
|
||||
// invoice
|
||||
$this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::INVOICE, $voucherRedemption);
|
||||
else
|
||||
{
|
||||
$this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::INVOICE, $voucherRedemption);
|
||||
}
|
||||
|
||||
$billNumber = $this->generatesTransactionBillNumber->execute('SPDO-');
|
||||
|
||||
|
||||
+5
-1
@@ -21,6 +21,10 @@ use App\Classes\ValueObjects\Constants\DocumentType;
|
||||
use App\Models\Booking;
|
||||
use App\Models\SegmentConstant;
|
||||
|
||||
/**
|
||||
* @deprecated This class is deprecated and should not be used.
|
||||
* Use `CreateInvoiceTransactionProcessor` instead or write a new one based on CreateInvoiceTransactionProcessor
|
||||
*/
|
||||
class CreateInvoiceTransactionWithInvoiceNoProcessor
|
||||
{
|
||||
|
||||
@@ -53,7 +57,7 @@ class CreateInvoiceTransactionWithInvoiceNoProcessor
|
||||
|
||||
|
||||
/**
|
||||
* CreateInvoiceTransactionProcessor constructor.
|
||||
* CreateInvoiceTransactionWithInvoiceNoProcessor constructor.
|
||||
* @param ListsTransactions $listsTransactions
|
||||
* @param CreatesTransaction $createsTransaction
|
||||
* @param GeneratesTransactionBillNumber $generatesTransactionBillNumber
|
||||
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Transactions\Processors;
|
||||
|
||||
use App\Classes\Exceptions\MalformedRequestException;
|
||||
use App\Classes\Modules\Transactions\Services\CreatesTransaction;
|
||||
use App\Classes\Modules\Transactions\Services\GeneratesTransactionBillNumber;
|
||||
use App\Classes\Modules\Bookings\Services\CalculatesBookingCurrencyAverageRate;
|
||||
use App\Classes\Modules\Companies\Services\FetchesCompany;
|
||||
use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Classes\ValueObjects\Constants\DocumentType;
|
||||
use App\Models\Booking;
|
||||
use App\Models\Transaction;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class CreateReceiptVoucherTransactionProcessor
|
||||
{
|
||||
|
||||
/** @var CreatesTransaction */
|
||||
private $createsTransaction;
|
||||
|
||||
/** @var GeneratesTransactionBillNumber */
|
||||
private $generatesTransactionBillNumber;
|
||||
|
||||
/** @var CalculatesBookingCurrencyAverageRate */
|
||||
private $calculatesBookingCurrencyAverageRate;
|
||||
|
||||
/** @var FetchesCompany */
|
||||
private $fetchesCompany;
|
||||
|
||||
/** @var CreateInvoiceDocumentProcessor */
|
||||
private $invoiceDocumentProcessor;
|
||||
|
||||
|
||||
/**
|
||||
* CreateReceiptVoucherTransactionProcessor constructor.
|
||||
* @param CreatesTransaction $createsTransaction
|
||||
* @param GeneratesTransactionBillNumber $generatesTransactionBillNumber
|
||||
* @param CalculatesBookingCurrencyAverageRate $calculatesBookingCurrencyAverageRate
|
||||
* @param FetchesCompany $fetchesCompany
|
||||
* @param CreateInvoiceDocumentProcessor $invoiceDocumentProcessor
|
||||
*/
|
||||
public function __construct(CreatesTransaction $createsTransaction, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CalculatesBookingCurrencyAverageRate $calculatesBookingCurrencyAverageRate, FetchesCompany $fetchesCompany, CreateInvoiceDocumentProcessor $invoiceDocumentProcessor)
|
||||
{
|
||||
$this->createsTransaction = $createsTransaction;
|
||||
$this->generatesTransactionBillNumber = $generatesTransactionBillNumber;
|
||||
$this->calculatesBookingCurrencyAverageRate = $calculatesBookingCurrencyAverageRate;
|
||||
$this->fetchesCompany = $fetchesCompany;
|
||||
$this->invoiceDocumentProcessor = $invoiceDocumentProcessor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Booking $booking
|
||||
* @param Transaction $transaction
|
||||
* @param bool $isRegenerate
|
||||
* @return void
|
||||
* @throws MalformedRequestException
|
||||
*/
|
||||
public function execute(Booking $booking, Transaction $transaction, bool $isRegenerate = false)
|
||||
{
|
||||
$purchaseOrder = $booking->transactions()
|
||||
->where('type', TransactionType::PURCHASE_ORDER)
|
||||
// ->complete()
|
||||
->first();
|
||||
|
||||
if(!$transaction->type === TransactionType::PAYMENT){
|
||||
return;
|
||||
}
|
||||
|
||||
if(!($transaction->status === ApprovalStatus::APPROVED || $transaction->status === ApprovalStatus::COMPLETED)){
|
||||
return;
|
||||
}
|
||||
Log::info('CreateReceiptVoucherTransactionProcessor booking id: '. $booking->id);
|
||||
Log::info('CreateReceiptVoucherTransactionProcessor transaction: '. json_encode($transaction));
|
||||
|
||||
//If payment receipt voucher already exists, return (unless you want to regenerate)
|
||||
if($transaction->transactions()->where('type', TransactionType::RECEIPT_VOUCHER)->exists() && !$isRegenerate){
|
||||
return;
|
||||
}
|
||||
|
||||
$billNumber = $this->generatesTransactionBillNumber->execute('RV-');
|
||||
|
||||
$booking_currency_average_rate = $this->calculatesBookingCurrencyAverageRate->execute($booking, TransactionType::PAYMENT);
|
||||
|
||||
$transaction_object = new TransactionObject(
|
||||
$billNumber,
|
||||
TransactionType::RECEIPT_VOUCHER,
|
||||
$transaction->issuer,
|
||||
$transaction->receiver,
|
||||
$transaction->recipient_bank_account_id,
|
||||
$transaction->payment_method,
|
||||
$transaction->amount,
|
||||
$transaction->original_amount,
|
||||
$transaction->currency_id,
|
||||
$transaction->original_currency_id,
|
||||
$booking_currency_average_rate,
|
||||
0,
|
||||
0,
|
||||
null,
|
||||
ApprovalStatus::APPROVED
|
||||
);
|
||||
$invoice_transaction = $this->createsTransaction->execute($transaction, $transaction_object);
|
||||
|
||||
$voucherRedemption = $transaction->voucherRedemption;
|
||||
|
||||
$supplier = $this->fetchesCompany->execute(['id' => $transaction->receiver]);
|
||||
|
||||
// receipt voucher - Receipt is mandatory for customer who wants e-invoice and those who does not
|
||||
$this->invoiceDocumentProcessor->execute($invoice_transaction, $purchaseOrder, $supplier, DocumentType::RECEIPT_VOUCHER, $voucherRedemption);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Transactions\Services;
|
||||
|
||||
use App\Classes\Modules\Bookings\Services\FetchesBooking;
|
||||
use App\Classes\Modules\Companies\Services\FetchesCompanyPaymentAttemptLimit;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class CalculatesTransactionExpiryDateTime
|
||||
{
|
||||
/** @var FetchesBooking */
|
||||
private $fetchesBooking;
|
||||
|
||||
/** @var FetchesCompanyPaymentAttemptLimit */
|
||||
private $fetchesCompanyPaymentAttemptLimit;
|
||||
|
||||
/**
|
||||
* CalculatesTransactionExpiryDateTime constructor.
|
||||
* @param FetchesBooking $fetchesBooking
|
||||
* @param FetchesCompanyPaymentAttemptLimit $fetchesCompanyPaymentAttemptLimit
|
||||
*/
|
||||
public function __construct(FetchesBooking $fetchesBooking, FetchesCompanyPaymentAttemptLimit $fetchesCompanyPaymentAttemptLimit)
|
||||
{
|
||||
$this->fetchesBooking = $fetchesBooking;
|
||||
$this->fetchesCompanyPaymentAttemptLimit = $fetchesCompanyPaymentAttemptLimit;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param int $bookingId
|
||||
* @return Carbon|null $returnDateTime
|
||||
*/
|
||||
public function execute(int $bookingId)
|
||||
{
|
||||
$isExpired = false;
|
||||
$booking = $this->fetchesBooking->execute(['id' => $bookingId]);
|
||||
$paymentAttemptLimit = $this->fetchesCompanyPaymentAttemptLimit->execute($booking->company);
|
||||
|
||||
$createdAt = Carbon::parse($booking->created_at);
|
||||
Log::info("1. Booking created at {$createdAt}.");
|
||||
$bookingExpiresAt = $createdAt->addMinutes($paymentAttemptLimit);
|
||||
Log::info("1. Booking expires at {$bookingExpiresAt}. (original)");
|
||||
$newBookingExpiresAt = null;
|
||||
$now = Carbon::now();
|
||||
|
||||
if ($now->greaterThan($bookingExpiresAt)) {
|
||||
$isExpired = true;
|
||||
}
|
||||
|
||||
$allPayments = $booking->transactions()
|
||||
->payments()
|
||||
->get();
|
||||
|
||||
// if ($isExpired) {
|
||||
$filteredPayments = $allPayments->filter(function ($payment) use ($bookingExpiresAt) {
|
||||
return Carbon::parse($payment->created_at)->lessThanOrEqualTo($bookingExpiresAt);
|
||||
});
|
||||
|
||||
if ($filteredPayments->isNotEmpty()) {
|
||||
// Use the earlier payment to recalculate bookingExpiresAt
|
||||
$earliestPayment = $filteredPayments->sortBy('created_at')->first();
|
||||
Log::info("2. Booking earliest payment : {$earliestPayment->id}, {$earliestPayment->created_at}");
|
||||
$newBookingExpiresAt = Carbon::parse($earliestPayment->created_at)->addMinutes($paymentAttemptLimit);
|
||||
Log::info("2. Booking expires at : {$newBookingExpiresAt}. (new)");
|
||||
$logDetails = [
|
||||
'booking_id' => $booking->id,
|
||||
'initial_created_at' => $booking->created_at,
|
||||
'original_expiry' => $bookingExpiresAt->toDateTimeString(),
|
||||
'new_expiry' => $newBookingExpiresAt->toDateTimeString(),
|
||||
'valid_payments' => []
|
||||
];
|
||||
foreach ($filteredPayments as $payment) {
|
||||
$logDetails['valid_payments'][] = [
|
||||
'payment_id' => $payment->id,
|
||||
'created_at' => $payment->created_at,
|
||||
'amount' => $payment->amount,
|
||||
];
|
||||
}
|
||||
Log::info("2. Booking initially expired, but found valid pending payment(s).", $logDetails);
|
||||
|
||||
$isExpired = Carbon::now()->greaterThan($newBookingExpiresAt);
|
||||
Log::info("2. Booking expired: {$isExpired}");
|
||||
} else {
|
||||
Log::info("Booking expired and no valid pending payments for booking ID: {$booking->id}");
|
||||
}
|
||||
// }
|
||||
$returnDateTime = $newBookingExpiresAt ? $newBookingExpiresAt : $bookingExpiresAt;
|
||||
return $returnDateTime;
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Classes\Modules\Wallets\Processors;
|
||||
|
||||
use App\Classes\Modules\Accounts\DataTransferObjects\KeyValuePairObject;
|
||||
use App\Models\Wallet;
|
||||
use App\Models\Company;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
@@ -14,6 +15,8 @@ use App\Classes\Modules\Transactions\Services\CreatesTransaction;
|
||||
use App\Classes\Modules\Wallets\DataTransferObjects\WalletObject;
|
||||
use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject;
|
||||
use App\Classes\Modules\Transactions\Services\GeneratesTransactionBillNumber;
|
||||
use App\Classes\Modules\Accounts\Services\CreatesKeyValuePair;
|
||||
use App\Models\Transaction;
|
||||
|
||||
class CreditWalletProcessor
|
||||
{
|
||||
@@ -32,6 +35,9 @@ class CreditWalletProcessor
|
||||
/** @var UpdatesWallet */
|
||||
private $updatesWallet;
|
||||
|
||||
/** @var CreatesKeyValuePair */
|
||||
private $createsKeyValuePair;
|
||||
|
||||
/**
|
||||
* CreateWalletLogic constructor.
|
||||
* @param GeneratesWalletCode $generatesWalletCode
|
||||
@@ -39,13 +45,15 @@ class CreditWalletProcessor
|
||||
* @param GeneratesTransactionBillNumber $generatesTransactionBillNumber
|
||||
* @param CreatesTransaction $createsTransaction
|
||||
* @param UpdatesWallet $updatesWallet
|
||||
* @param CreatesKeyValuePair $createsKeyValuePair
|
||||
*/
|
||||
public function __construct(
|
||||
GeneratesWalletCode $generatesWalletCode,
|
||||
CreatesWallet $createsWallet,
|
||||
GeneratesTransactionBillNumber $generatesTransactionBillNumber,
|
||||
CreatesTransaction $createsTransaction,
|
||||
UpdatesWallet $updatesWallet
|
||||
UpdatesWallet $updatesWallet,
|
||||
CreatesKeyValuePair $createsKeyValuePair
|
||||
)
|
||||
{
|
||||
$this->generatesWalletCode = $generatesWalletCode;
|
||||
@@ -53,6 +61,7 @@ class CreditWalletProcessor
|
||||
$this->generatesTransactionBillNumber = $generatesTransactionBillNumber;
|
||||
$this->createsTransaction = $createsTransaction;
|
||||
$this->updatesWallet = $updatesWallet;
|
||||
$this->createsKeyValuePair = $createsKeyValuePair;
|
||||
}
|
||||
|
||||
|
||||
@@ -61,10 +70,11 @@ class CreditWalletProcessor
|
||||
* @param int $transactionType
|
||||
* @param float $amount
|
||||
* @param string $reference
|
||||
* @param $relatedTransaction
|
||||
* @return \Illuminate\Database\Eloquent\Model
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
*/
|
||||
public function execute(Company $company, int $transactionType, float $amount, string $reference)
|
||||
public function execute(Company $company, int $transactionType, float $amount, string $reference, $relatedTransaction = null)
|
||||
{
|
||||
if (!$company->wallets()->first()) {
|
||||
$object = new WalletObject($company->id, 1, $this->generatesWalletCode->execute());
|
||||
@@ -75,16 +85,26 @@ class CreditWalletProcessor
|
||||
$wallet = $company->wallets()->first();
|
||||
|
||||
$billNumber = $this->generatesTransactionBillNumber->execute($transactionType === 2 ? 'DEBIT-NOTE-' : 'CREDIT-NOTE-');
|
||||
|
||||
|
||||
$transaction_object = new TransactionObject($billNumber, $transactionType === 2 ? TransactionType::DEBIT_NOTE : TransactionType::CREDIT_NOTE, 1, $wallet->owner->id, 1, PaymentMethodType::CASH, $amount, $amount, 1, 1, 1, 0, 0, null, ApprovalStatus::APPROVED, [], $reference);
|
||||
$transaction = $this->createsTransaction->execute($wallet, $transaction_object);
|
||||
|
||||
|
||||
$updateWalletAmount = $transactionType === 2 ? ($wallet->amount - $transaction->amount) : ($wallet->amount + $transaction->amount);
|
||||
|
||||
$walletObject = new WalletObject($wallet->owner->id, $wallet->currency_id, $wallet->code, $updateWalletAmount);
|
||||
|
||||
$wallet = $this->updatesWallet->execute($wallet, $walletObject);
|
||||
|
||||
if($relatedTransaction && $relatedTransaction instanceof Transaction){
|
||||
$kvp = $relatedTransaction->attributesKVP()->where('key', 'App\Models\Transaction')->where('value', $transaction->id)->latest()->first();
|
||||
if(!$kvp){
|
||||
$keyValuePairObject = new KeyValuePairObject(
|
||||
"App\Models\Transaction",
|
||||
$transaction->id
|
||||
);
|
||||
$this->createsKeyValuePair->execute($relatedTransaction, $keyValuePairObject);
|
||||
}
|
||||
}
|
||||
return $wallet;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,4 +27,7 @@ final class DocumentType {
|
||||
public const BULK_PURCHASE_ORDER = 'BULK_PURCHASE_ORDER';
|
||||
|
||||
public const BILL_GROUP_PAYMENT_PROOF = 'BILL_GROUP_PAYMENT_PROOF';
|
||||
|
||||
public const RECEIPT_VOUCHER = 'RECEIPT_VOUCHER';
|
||||
public const EINVOICE = 'E_INVOICE'; //cief todo: 90 - why is there no E-CREDITNOTE
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\ValueObjects\Constants;
|
||||
|
||||
class RemarkRefundReason
|
||||
{
|
||||
public const REFUND_REASONS = [
|
||||
'Not enough stock' => 'Return Inward',
|
||||
'Goods Damage/ Loss Compensation' => 'Return Inward',
|
||||
'Cancel Partial Order' => 'Return Inward',
|
||||
'Overpaid due to Supplier amend price' => 'Discount Allowed',
|
||||
'Defective Item' => 'Discount Allowed',
|
||||
'Cancel Full Order' => 'Return Inward',
|
||||
'Others' => '',
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\ValueObjects\Constants;
|
||||
|
||||
final class SegmentNameConstants {
|
||||
public const MANUAL_PO_PERIODIC_1688 = "1688 Manual PO Periodic";
|
||||
public const MANUAL_PO_1688 = "1688 Manual PO";
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\ValueObjects\Constants;
|
||||
|
||||
final class ServiceTypeNameConstants {
|
||||
|
||||
public const PAYMENT_1688 = '1688 PAYMENT';
|
||||
public const VIP_1688 = '1688 VIP';
|
||||
}
|
||||
@@ -38,6 +38,8 @@ final class TransactionType {
|
||||
|
||||
public const BILL_REFUND = 16;
|
||||
|
||||
public const RECEIPT_VOUCHER = 17;
|
||||
|
||||
public const ID_TO_NAME = [
|
||||
self::PAYMENT_ATTEMPT => "PAYMENT_ATTEMPT",
|
||||
self::PAYMENT => "PAYMENT",
|
||||
@@ -56,5 +58,5 @@ final class TransactionType {
|
||||
self::SUPPLIER_PAYMENT => "SUPPLIER_PAYMENT",
|
||||
self::SUPPLIER_REFUND => "SUPPLIER_REFUND",
|
||||
];
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\ValueObjects\Response;
|
||||
|
||||
class RuleEvaluationResult
|
||||
{
|
||||
public bool $success = true;
|
||||
public array $messages = [];
|
||||
|
||||
public function __construct(bool $success = true, array $messages = [])
|
||||
{
|
||||
$this->success = $success;
|
||||
$this->messages = $messages;
|
||||
}
|
||||
|
||||
public function failed(): bool
|
||||
{
|
||||
return ! $this->success;
|
||||
}
|
||||
|
||||
public function passed(): bool
|
||||
{
|
||||
return $this->success;
|
||||
}
|
||||
|
||||
public function messages(): array
|
||||
{
|
||||
return $this->messages;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Addresses;
|
||||
|
||||
use App\Classes\Modules\Addresses\ControllersLogic\ListStatesLogic;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ListStatesController
|
||||
{
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param ListStatesLogic $logic
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function list(Request $request, ListStatesLogic $logic): JsonResponse {
|
||||
return $logic->execute($request);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Bookings;
|
||||
|
||||
use App\Classes\Modules\Bookings\ControllersLogic\RegenerateInvoiceBookingLogic;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
|
||||
class RegenerateBookingEInvoiceController
|
||||
{
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param RegenerateInvoiceBookingLogic $logic
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function regenerate(Request $request, RegenerateInvoiceBookingLogic $logic): JsonResponse {
|
||||
return $logic->execute($request);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Bookings;
|
||||
|
||||
use App\Classes\Modules\Bookings\ControllersLogic\RegenerateBookingPaymentRVLogic;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
|
||||
class RegenerateBookingPaymentRVController
|
||||
{
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param RegenerateBookingPaymentRVLogic $logic
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function regenerate(Request $request, RegenerateBookingPaymentRVLogic $logic): JsonResponse {
|
||||
return $logic->execute($request);
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Http\Controllers\Bookings;
|
||||
|
||||
use App\Classes\Modules\Bookings\ControllersLogic\UpdateBookingAmountLogic;
|
||||
use App\Classes\Modules\Bookings\ControllersLogic\UpdateBookingAmountOnHoldLogic;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
@@ -17,4 +18,12 @@ class UpdateBookingAmountController
|
||||
return $logic->execute($request);
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param UpdateBookingAmountOnHoldLogic $logic
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function updateOnHold(Request $request, UpdateBookingAmountOnHoldLogic $logic): JsonResponse {
|
||||
return $logic->execute($request);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Companies;
|
||||
|
||||
|
||||
use App\Classes\Modules\Companies\ControllersLogic\FetchCompanyEInvoiceInfoLogic;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class FetchCompanyEInvoiceInfoController
|
||||
{
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param FetchCompanyEInvoiceInfoLogic $logic
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function fetch(Request $request, FetchCompanyEInvoiceInfoLogic $logic): JsonResponse {
|
||||
return $logic->execute($request);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Companies;
|
||||
|
||||
use App\Classes\Modules\Companies\ControllersLogic\UpdateCompanyDetailsLogic;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class UpdateCompanyDetailsController extends Controller
|
||||
{
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param UpdateCompanyDetailsLogic $logic
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function update(Request $request, UpdateCompanyDetailsLogic $logic) : JsonResponse
|
||||
{
|
||||
return $logic->execute($request);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Companies;
|
||||
|
||||
use App\Classes\Modules\Companies\ControllersLogic\UpdateCompanyEInvoiceInfoLogic;
|
||||
use App\Classes\Modules\Companies\ControllersLogic\UpdateCompanyEInvoiceRequestLogic;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class UpdateCompanyEInvoiceInfoController
|
||||
{
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param UpdateCompanyEInvoiceInfoLogic $logic
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function updateInfo(Request $request, UpdateCompanyEInvoiceInfoLogic $logic): JsonResponse {
|
||||
return $logic->execute($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param UpdateCompanyEInvoiceRequestLogic $logic
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function updateRequest(Request $request, UpdateCompanyEInvoiceRequestLogic $logic): JsonResponse {
|
||||
return $logic->execute($request);
|
||||
}
|
||||
}
|
||||
@@ -13,15 +13,16 @@ use App\Classes\Modules\Exports\Services\ExportsNullDebtors;
|
||||
use App\Classes\Modules\Exports\Services\ExportsPaymentTransactions;
|
||||
use App\Classes\Modules\Exports\Services\ExportsWalletTransactions;
|
||||
use App\Classes\Modules\Exports\Services\ExportsInvoiceTransactions;
|
||||
use App\Classes\Modules\Exports\Services\ExportsReceiptTransactions;
|
||||
use App\Classes\Modules\Exports\Services\ExportsImportedReceiptMappeds;
|
||||
use App\Classes\Modules\Exports\Services\ExportsWhiteFormTransactions;
|
||||
use App\Classes\Modules\Exports\Services\ExportsImportedInvoiceMappeds;
|
||||
use App\Classes\Modules\Exports\Services\ExportsEInvoiceDebtorSummary;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Maatwebsite\Excel\Excel;
|
||||
use App\Classes\Modules\Exports\Services\ExportsImportedInvoiceMappeds;
|
||||
use App\Models\TransactionMappingLog;
|
||||
use App\Classes\Modules\Exports\Services\ExportsReceiptTransactions;
|
||||
use App\Classes\Modules\Exports\Services\ExportsImportedReceiptMappeds;
|
||||
use App\Classes\Modules\Exports\Services\ExportsWhiteFormTransactions;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use App\Classes\General\AWSS3Helper;
|
||||
use App\Classes\Modules\Exports\Services\ExportsAllCustomersInfoForLarkSystem;
|
||||
@@ -249,7 +250,7 @@ class ExportCustomersToExcelController
|
||||
if ($password !== 'all_customers_data') {
|
||||
return response()->json(['error' => 'Invalid password'], 403);
|
||||
}
|
||||
|
||||
|
||||
$exportsAllCustomersInfoForLarkSystem = new ExportsAllCustomersInfoForLarkSystem($request);
|
||||
$exportFileName = 'exchange_all_customers_info_for_lark_system.xls';
|
||||
|
||||
@@ -262,5 +263,17 @@ class ExportCustomersToExcelController
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function eInvoiceDebtorSummary(ExportsEInvoiceDebtorSummary $exportsEInvoiceDebtorSummary, Request $request){
|
||||
$exportFileName = 'EINV_DEBTOR_SUMMARY.xls';
|
||||
$filesystemDriver = Storage::getDefaultDriver();
|
||||
if($filesystemDriver === 's3'){
|
||||
return response([ 'src' => AWSS3Helper::S3Exportable($exportFileName, $exportsEInvoiceDebtorSummary) ]);
|
||||
}
|
||||
else{
|
||||
$response = $exportsEInvoiceDebtorSummary->download($exportFileName, Excel::XLS, ['Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet']);
|
||||
ob_end_clean();
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Remarks;
|
||||
|
||||
use App\Classes\ValueObjects\Constants\RemarkRefundReason;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ListRefundRemarksController
|
||||
{
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function list(Request $request): JsonResponse {
|
||||
// $allReasons = RemarkRefundReason::REFUND_REASONS;
|
||||
// $returnArray = [];
|
||||
// foreach ($allReasons as $reason => $category) {
|
||||
// $returnArray[] = [
|
||||
// 'name' => $reason
|
||||
// ];
|
||||
// }
|
||||
// $row['payload']["data"] = $returnArray;
|
||||
|
||||
$allReasons = RemarkRefundReason::REFUND_REASONS;
|
||||
$row['payload']['data'] = array_keys($allReasons);
|
||||
return response()->json($row);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Rules;
|
||||
|
||||
use App\Classes\Modules\Rules\ControllersLogic\CheckEInvoiceRuleLogic;
|
||||
use App\Classes\Modules\Rules\ControllersLogic\CheckPurchaseOrderRuleLogic;
|
||||
use App\Classes\Modules\Rules\ControllersLogic\CheckTransferRuleLogic;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class CheckRuleController
|
||||
{
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param CheckEInvoiceRuleLogic $logic
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function checkEInvoiceRule(Request $request, CheckEInvoiceRuleLogic $logic): JsonResponse {
|
||||
return $logic->execute($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param CheckPurchaseOrderRuleLogic $logic
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function checkPurchaseOrderRule(Request $request, CheckPurchaseOrderRuleLogic $logic): JsonResponse {
|
||||
return $logic->execute($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param CheckTransferRuleLogic $logic
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function checkTransferRule(Request $request, CheckTransferRuleLogic $logic): JsonResponse {
|
||||
return $logic->execute($request);
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,8 @@ namespace App\Http\Controllers\Transactions;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Classes\Modules\Transactions\ControllersLogic\CreatePurchaseOrderTransactionLogic;
|
||||
use App\Classes\Modules\Bookings\ControllersLogic\UpdateBookingAmountWithPOLogic;
|
||||
|
||||
|
||||
|
||||
class CreatePurchaseOrderTransactionController
|
||||
@@ -15,7 +17,13 @@ class CreatePurchaseOrderTransactionController
|
||||
* @param CreatePurchaseOrderTransactionLogic $logic
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function create(Request $request, CreatePurchaseOrderTransactionLogic $logic) : JsonResponse {
|
||||
return $logic->execute($request);
|
||||
public function create(Request $request, CreatePurchaseOrderTransactionLogic $createLogic, UpdateBookingAmountWithPOLogic $updateLogic) : JsonResponse {
|
||||
// return $logic->execute($request);
|
||||
$updateResult = $updateLogic->execute($request);
|
||||
|
||||
if ($updateResult instanceof JsonResponse && $updateResult->getStatusCode() !== 200) {
|
||||
return $updateResult;
|
||||
}
|
||||
return $createLogic->execute($request);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,11 +5,15 @@ namespace App\Http\Controllers\Transactions;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Classes\Modules\Transactions\ControllersLogic\GenerateCreditNotePdfLogic;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use App\Classes\Modules\Transactions\ControllersLogic\GenerateCreditNotePdfV2Logic;
|
||||
|
||||
class GenerateCreditNotePdfController
|
||||
{
|
||||
public function download(Request $request, GenerateCreditNotePdfLogic $logic) {
|
||||
return $logic->execute($request);
|
||||
}
|
||||
|
||||
public function downloadV2(Request $request, GenerateCreditNotePdfV2Logic $logic) {
|
||||
return $logic->execute($request);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,5 +80,6 @@ class Kernel extends HttpKernel
|
||||
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
|
||||
'valid.token' => ValidateToken::class,
|
||||
'token.check' => \App\Http\Middleware\TokenCheckerMiddleware::class,
|
||||
'admin' => \App\Http\Middleware\EnsureUserIsAdmin::class, //cief todo: 90 - maintenance
|
||||
];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Classes\ValueObjects\Constants\RoleTypes;
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Tymon\JWTAuth\Facades\JWTAuth;
|
||||
|
||||
class EnsureUserIsAdmin
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\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)
|
||||
{
|
||||
$user = JWTAuth::parseToken()->authenticate();
|
||||
if(!in_array($user->type, RoleTypes::ADMIN_ROLES)){
|
||||
return response()->view('errors.503', [], 503);
|
||||
}
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class AddressEInvoiceResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'street_one' => $this->street_one,
|
||||
'street_two' => $this->street_two,
|
||||
'district' => $this->district,
|
||||
'state' => $this->state,
|
||||
'post_code' => (int) $this->postcode,
|
||||
'country' => $this->country,
|
||||
'billing' => (int) $this->billing
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,17 @@ class BookingResource extends JsonResource
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
$eInvoice = false;
|
||||
$eInvoiceStartDate = Carbon::parse(env('E_INVOICE_START_DATE', '2025-07-01 00:00:00'));
|
||||
$bookingCreatedDate = Carbon::parse($this->created_at);
|
||||
$eInvoiceRequestedDate = Carbon::parse($this->company->e_invoice_requested_at);
|
||||
//cief todo: 90 - for testing
|
||||
if ($bookingCreatedDate->isAfter($eInvoiceStartDate) && $this->company->e_invoice === 1) { //&& $bookingCreatedDate->diffInMinutes($eInvoiceRequestedDate) <= 480 cief todo: 90
|
||||
$eInvoice = true;
|
||||
}
|
||||
// if ($this->company->e_invoice === 1) {
|
||||
// $eInvoice = true;
|
||||
// }
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'company' => new CompanyResource($this->company),
|
||||
@@ -42,6 +53,7 @@ class BookingResource extends JsonResource
|
||||
'purchase_order' => new DocumentResource($this->documents()->where('document_type', DocumentType::PURCHASE_ORDER)->first()),
|
||||
'delivery_order' => new DocumentResource($this->documents()->where('document_type', DocumentType::DELIVER_ORDER)->first()),
|
||||
'invoice' => new DocumentResource($this->documents()->where('document_type', DocumentType::INVOICE)->first()),
|
||||
'e_invoice' => new DocumentResource($this->documents()->where('document_type', DocumentType::EINVOICE)->latest()->first()),
|
||||
'supplier_delivery_order' => new DocumentResource($this->documents()->where('document_type', DocumentType::SUPPLIER_DELIVER_ORDER)->first()),
|
||||
'proforma_invoice' => new DocumentResource($this->documents()->where('document_type', DocumentType::PROFORMA_INVOICE)->whereNotIn('status', [ApprovalStatus::REJECTED, ApprovalStatus::EXPIRED])->orderByDesc('id')->first()),
|
||||
'ecommerce_purchase_order' => new DocumentResource($this->documents()->where('document_type', DocumentType::ECOMMERCE_PURCHASE_ORDER)->first()),
|
||||
@@ -76,7 +88,8 @@ class BookingResource extends JsonResource
|
||||
});
|
||||
});
|
||||
})->latest()->get())
|
||||
])
|
||||
]),
|
||||
'einvoice' => $eInvoice,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,11 +37,15 @@ class CompanyResource extends JsonResource
|
||||
'name' => $this->name,
|
||||
'reference' => $this->reference,
|
||||
'debtor' => $this->debtor,
|
||||
'e_invoice' => $this->e_invoice,
|
||||
'tin' => $this->tin,
|
||||
'msic_code' => $this->msic_code,
|
||||
'type' => (int) $this->type,
|
||||
'business_type' => (int) $this->business_type,
|
||||
'status' => (int) $this->status,
|
||||
'contact' => new ContactResource ($this->when($this->has('contacts'), $this->contacts->first())),
|
||||
'address' => new AddressResource($this->when($this->has('addresses'), $this->addresses->where('billing', true)->first())),
|
||||
'address_einvoice' => $this->e_invoice ? new AddressEInvoiceResource($this->when($this->has('addresses'), $this->addresses->where('billing', false)->where('e_invoice', true)->sortByDesc('created_at')->first())) : null,
|
||||
'employee' => new UserResource(Auth::user()->type === RoleTypes::USER ? $this->employees()->where('email', '=', Auth::user()->email)->first() : $this->employees()->orderBy('id', 'DESC')->first()),
|
||||
'identification' => new DocumentResource($this->documents->whereIn('document_type', DocumentType::IDENTIFICATION_DOCUMENTS)->sortByDesc('created_at')->first()),
|
||||
'bookings' => $this->whenLoaded('bookings', $this->bookings()->orderBy('id', 'DESC')->get(), []),
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class EInvoiceInfoResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'street_one' => $this->street_one,
|
||||
'street_two' => $this->street_two,
|
||||
'district' => $this->district,
|
||||
'state' => $this->state,
|
||||
'post_code' => (int) $this->postcode,
|
||||
'country' => $this->country,
|
||||
'billing' => (int) $this->billing,
|
||||
'msic_code' => (string) $this->msic_code,
|
||||
'tin' => (string) $this->tin,
|
||||
'e_invoice' => (int) $this->e_invoice,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class RuleResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'isPassed' => $this->success,
|
||||
'messages' => $this->messages,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class StateResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'state' => $this->name,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Models\Booking;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class TransactionResource extends JsonResource
|
||||
{
|
||||
@@ -56,6 +57,7 @@ class TransactionResource extends JsonResource
|
||||
'currency_rate' => (double) $this->currency_rate,
|
||||
'status' => (int) $this->status,
|
||||
'details' => TransactionDetailResource::collection($this->transactionDetails),
|
||||
'receipt_voucher' => $this->type === TransactionType::PAYMENT && $this->transactions()->where('type', TransactionType::RECEIPT_VOUCHER)->latest()->first() ? new DocumentResource($this->transactions()->where('type', TransactionType::RECEIPT_VOUCHER)->latest()->first()->documents()->first()) : null,
|
||||
'documents' => new DocumentResource($this->documents()->first()),
|
||||
'transaction_bill' => new TransactionResource($this->when((int) $this->type === TransactionType::PAYMENT, $this->transactions()->bills()->first())),
|
||||
'transaction_refunds' => TransactionResource::collection($this->when((int) $this->type === TransactionType::PAYMENT, $this->transactions()->refunds()->get())),
|
||||
|
||||
@@ -53,15 +53,19 @@ class BookingV2Resource extends JsonResource
|
||||
'created_at' => Carbon::parse($this->created_at)->format('d-m-Y'),
|
||||
'created_at_with_time' => Carbon::parse($this->created_at)->format('d-m-Y h:i:s A'),
|
||||
$this->mergeWhen($this->relationLoaded('transactions'), [
|
||||
'purchase_order' => new V2\TransactionV2Resource($this->transactions()->where('type', TransactionType::PURCHASE_ORDER)->first()),
|
||||
'purchase_order' => new V2\TransactionV2Resource(
|
||||
$this->transactions()->where('type', TransactionType::PURCHASE_ORDER)->first()),
|
||||
'payment_attempts' => V2\TransactionV2Resource::collection(
|
||||
$this->transactions()
|
||||
->payments()->where('status', ApprovalStatus::PENDING_SUBMISSION)
|
||||
->whereDate('expires_on', '>=', Carbon::now())
|
||||
->get()
|
||||
),
|
||||
'expired_payment_attempts' => V2\TransactionV2Resource::collection($this->transactions()->payments()->where('status', ApprovalStatus::PENDING_SUBMISSION)->whereDate('expires_on', '>=', Carbon::now())->where('expires_on', '>', Carbon::now()->toTimeString())->get()),
|
||||
'payment_history' => V2\TransactionV2Resource::collection($this->transactions()->where(function($query){
|
||||
'expired_payment_attempts' => V2\TransactionV2Resource::collection(
|
||||
$this->transactions()->payments()->where('status', ApprovalStatus::PENDING_SUBMISSION)->whereDate('expires_on', '>=', Carbon::now())->where('expires_on', '>', Carbon::now()->toTimeString())->get()
|
||||
),
|
||||
'payment_history' => V2\TransactionV2Resource::collection(
|
||||
$this->transactions()->where(function($query){
|
||||
$query->where(function($query){
|
||||
$query->payments()->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::COMPLETED, ApprovalStatus::REJECTED]);
|
||||
})->orWhere(function($query){
|
||||
|
||||
+10
-1
@@ -3,6 +3,7 @@
|
||||
namespace App\Models;
|
||||
|
||||
use App\Classes\General\Interfaces\Documentable;
|
||||
use App\Classes\General\Interfaces\KeyValueInterface;
|
||||
use App\Classes\General\Interfaces\Transactionable;
|
||||
use App\Classes\General\Interfaces\Voucherifiable;
|
||||
use App\Classes\General\Traits\LogData;
|
||||
@@ -26,7 +27,7 @@ use Staudenmeir\EloquentHasManyDeep\HasRelationships;
|
||||
* @property int convertible_currency_id
|
||||
* @property int conversion_currency_id
|
||||
*/
|
||||
class Booking extends AbstractModel implements Documentable, Transactionable, Voucherifiable
|
||||
class Booking extends AbstractModel implements Documentable, Transactionable, Voucherifiable, KeyValueInterface
|
||||
{
|
||||
use HasRelationships;
|
||||
use SoftDeletes;
|
||||
@@ -130,4 +131,12 @@ class Booking extends AbstractModel implements Documentable, Transactionable, Vo
|
||||
return $this->morphMany(VoucherEntityMapping::class, 'owner');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MorphMany
|
||||
*/
|
||||
public function attributesKVP(): MorphMany
|
||||
{
|
||||
return $this->morphMany(KeyValuePair::class, 'owner');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
"fruitcake/laravel-cors": "^1.0",
|
||||
"guzzlehttp/guzzle": "^7.0.1",
|
||||
"intervention/image": "^2.5",
|
||||
"kwn/number-to-words": "^2.11",
|
||||
"laravel/framework": "^8.0",
|
||||
"laravel/tinker": "^2.0",
|
||||
"laravel/vapor-cli": "^1.55",
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'title' => env('MAINTENANCE_MESSAGE_TITLE', "We'll be back soon!"),
|
||||
'message' => env('MAINTENANCE_MESSAGE', "Sorry for the inconvenience but we're performing some maintenance at the moment."),
|
||||
];
|
||||
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'qr_code_img_url' => 'https://api.qrserver.com/v1/create-qr-code/?size=150x150&data=',
|
||||
];
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddEinvoiceToAddressesTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('addresses', function (Blueprint $table) {
|
||||
$table->boolean('e_invoice')->default(false)->after('billing');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('addresses', function (Blueprint $table) {
|
||||
$table->dropColumn('e_invoice');
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddTinToCompaniesTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('companies', function (Blueprint $table) {
|
||||
$table->string('tin')->nullable()->after('debtor');
|
||||
$table->string('msic_code')->nullable()->after('debtor')->comment("5-digit code representing business activity");
|
||||
$table->timestamp('e_invoice_requested_at')->nullable()->after('debtor');
|
||||
$table->boolean('e_invoice')->nullable()->default(null)->after('debtor');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('companies', function (Blueprint $table) {
|
||||
$table->dropColumn('tin');
|
||||
$table->dropColumn('msic_code');
|
||||
$table->dropColumn('e_invoice_requested_at');
|
||||
$table->dropColumn('e_invoice');
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,258 @@
|
||||
<template>
|
||||
<div class="row p-t-25 text-left">
|
||||
<div class="col bg-white padding-40 b-rad-lg">
|
||||
<div class="row" v-if="step === 1">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row m-b-15">
|
||||
<div class="col text-danger">
|
||||
Please check carefully, you will not be able to edit this after confirm
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-b-15">
|
||||
<div class="col-6 p-r-5">
|
||||
<validation-wrapper-component :validator="$v.parameters.tin">
|
||||
<label>TIN</label>
|
||||
<input class="form-control" name="tin" v-model="parameters.tin">
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
<div class="col-6 p-l-5">
|
||||
<validation-wrapper-component :validator="$v.parameters.msic_code">
|
||||
<label>
|
||||
MSIC Code
|
||||
<a href="https://sdk.myinvois.hasil.gov.my/codes/msic-codes/" target="_blank" rel="noopener noreferrer">
|
||||
(View List)
|
||||
</a>
|
||||
</label>
|
||||
<input class="form-control" name="msic_code" v-model="parameters.msic_code">
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-b-15">
|
||||
<div class="col">
|
||||
<validation-wrapper-component :validator="$v.parameters.street_one">
|
||||
<label>Billing Address Line 1</label>
|
||||
<input class="form-control" name="street_one" v-model="parameters.street_one">
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-b-15">
|
||||
<div class="col">
|
||||
<validation-wrapper-component :validator="$v.parameters.street_two">
|
||||
<label>Billing Address Line 2</label>
|
||||
<input class="form-control" name="street_two" v-model="parameters.street_two">
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-b-15">
|
||||
<div class="col-7 p-r-5">
|
||||
<validation-wrapper-component selectable :validator="$v.parameters.district_id">
|
||||
<label>District</label>
|
||||
<selectable-component :endpoint="route('api.address.district.list')" section="districtListSection" valueColumn="id" :labelColumn="['city']" v-model="parameters.district_id"></selectable-component>
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
<div class="col-5 p-l-5">
|
||||
<validation-wrapper-component :validator="$v.parameters.post_code" v-money="integer">
|
||||
<label>Post Code</label>
|
||||
<input class="form-control" name="post_code" v-model="parameters.post_code">
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-b-15">
|
||||
<div class="col-6 p-r-5">
|
||||
<validation-wrapper-component selectable :validator="$v.parameters.state_id">
|
||||
<label>State</label>
|
||||
<selectable-component :endpoint="route('api.address.state.list')" section="stateListSection" valueColumn="id" :labelColumn="['state']" v-model="parameters.state_id"></selectable-component>
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-b-15">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
<button type="button"
|
||||
class="btn btn-success btn-block b-rad-none"
|
||||
@click="updateStep(2)">Update E-Invoice Info</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" v-if="step === 2">
|
||||
<div class="col">
|
||||
<div class="row m-b-15">
|
||||
<div class="col">
|
||||
<div class="row m-b-15">
|
||||
<div class="col text-danger">
|
||||
Please check carefully, you will not be able to edit this after confirm
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="padding-15 bg-master-lightest">
|
||||
<p class="muted">TIN</p>
|
||||
<p class="m-b-0">{{parameters.tin}}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="padding-15 bg-master-lightest" v-if="parameters.msic_code !== 0">
|
||||
<p class="muted">MSIC Code</p>
|
||||
<p class="m-b-0">{{parameters.msic_code}}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="padding-15 bg-master-lightest">
|
||||
<p class="muted">Billing Address</p>
|
||||
<p class="m-b-0">{{parameters.street_one}} {{parameters.street_two}}, {{districts[parseFloat(parameters.district_id) - 1].city}} {{parameters.post_code}} {{states[parseFloat(parameters.state_id) - 1].state}}, {{districts[parseFloat(parameters.district_id) - 1].country.name}}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-b-15">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col-auto p-r-5">
|
||||
<button type="button" class="btn bg-master-lighter b-rad-none" @click="updateStep(1)">Edit E-Invoice Info</button>
|
||||
</div>
|
||||
<div class="col p-l-0">
|
||||
<button type="button" class="btn btn-success btn-block b-rad-none" @click="submitForm()">Confirm E-Invoice Info</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import ModalFormHandler from '../../../general/mixins/modalFormHandler';
|
||||
import { required, minLength, maxLength, alphaNum, helpers } from 'vuelidate/lib/validators'
|
||||
|
||||
function mustContainLetterAndNumber(value) {
|
||||
if (!value) return true;
|
||||
const hasLetter = /[a-zA-Z]/.test(value);
|
||||
const hasNumber = /\d/.test(value);
|
||||
return hasLetter && hasNumber;
|
||||
}
|
||||
|
||||
function notZero(value) {
|
||||
return value !== 0 && value !== '0' && value !== null && value !== undefined
|
||||
}
|
||||
|
||||
function fiveDigits(value) {
|
||||
return /^\d{5}$/.test(value)
|
||||
}
|
||||
|
||||
export default {
|
||||
props: {
|
||||
companyId: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
companyType: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
'id': function() {
|
||||
this.parameters.company_id = this.companyId;
|
||||
},
|
||||
// 'eInvoiceData': function() { //cief todo: 90
|
||||
// this.resetForm();
|
||||
// this.parameters = {
|
||||
// company_id: this.companyId,
|
||||
// street_one: this.eInvoiceData.street_one,
|
||||
// street_two: this.eInvoiceData.street_two,
|
||||
// district_id: this.eInvoiceData.district.id,
|
||||
// state_id: this.eInvoiceData.state.id,
|
||||
// post_code: this.eInvoiceData.post_code,
|
||||
// tin: this.eInvoiceData.tin,
|
||||
// msic_code: this.eInvoiceData.msic_code,
|
||||
// }
|
||||
// }
|
||||
},
|
||||
computed: {
|
||||
districts () { //cief todo: 90
|
||||
return this.$store.getters.getSelectableList('original_districtListSection');
|
||||
},
|
||||
states () {
|
||||
return this.$store.getters.getSelectableList('original_stateListSection');
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
step: 1,
|
||||
parameters : {
|
||||
company_id: this.companyId,
|
||||
street_one: '',
|
||||
street_two: '',
|
||||
district_id: '',
|
||||
state_id: '',
|
||||
post_code: 0,
|
||||
tin: '',
|
||||
msic_code: 0,
|
||||
}
|
||||
}
|
||||
},
|
||||
validations() {
|
||||
const companyType = this.companyType
|
||||
return {
|
||||
parameters: {
|
||||
street_one: { required },
|
||||
street_two: {},
|
||||
district_id: { required },
|
||||
state_id: { required },
|
||||
post_code: { notZero, fiveDigits},
|
||||
tin: {
|
||||
...(companyType === 0
|
||||
? {
|
||||
required,
|
||||
alphaNum,
|
||||
minLength: minLength(10), //was 11
|
||||
maxLength: maxLength(13)
|
||||
}
|
||||
: {}),
|
||||
...(companyType === 1
|
||||
? {
|
||||
required,
|
||||
alphaNum,
|
||||
minLength: minLength(10),
|
||||
maxLength: maxLength(13) //was 12
|
||||
}
|
||||
: {})
|
||||
},
|
||||
msic_code: companyType === 1 ? {
|
||||
notZero, fiveDigits
|
||||
}: {},
|
||||
}
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
updateStep(step){
|
||||
if(step === 2){
|
||||
if(!this.validate()){ return; }
|
||||
}
|
||||
this.step = step
|
||||
},
|
||||
submitForm(){
|
||||
this.submit((this.route('api.company.einvoice.info.update')), 'post', this.section, true, true);
|
||||
},
|
||||
successHandler(response){
|
||||
this.$emit('eInvoiceInfoUpdated', response.payload.data);
|
||||
this.closeModal();
|
||||
}
|
||||
},
|
||||
mixins: [ModalFormHandler],
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,68 @@
|
||||
<template>
|
||||
<div class="row p-t-20 text-left">
|
||||
<div class="col bg-white padding-30 b-rad-lg">
|
||||
<div class="row">
|
||||
<div class="col text-center">
|
||||
<h3>E-Invoice Info</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" v-if="eInvoiceData && eInvoiceData.district">
|
||||
<div class="col">
|
||||
<div class="padding-15 bg-master-lightest m-b-10">
|
||||
<p class="muted">TIN</p>
|
||||
<p class="m-b-0">{{ eInvoiceData.tin }}</p>
|
||||
</div>
|
||||
<div class="padding-15 bg-master-lightest m-b-10" v-if="eInvoiceData.msic_code !== '0'">
|
||||
<p class="muted">MSIC Code</p>
|
||||
<p class="m-b-0">{{ eInvoiceData.msic_code }}</p>
|
||||
</div>
|
||||
<div class="padding-15 bg-master-lightest">
|
||||
<p class="muted">Billing Address</p>
|
||||
<p class="mb-0">
|
||||
<a data-toggle="collapse" href="#billingDetails" role="button" aria-expanded="false" aria-controls="billingDetails">
|
||||
{{eInvoiceData.street_one}} {{eInvoiceData.street_two}}, {{eInvoiceData.district.name}}, {{eInvoiceData.post_code}} {{eInvoiceData.state.name}}, {{eInvoiceData.country.name}}
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<div class="collapse mt-2" id="billingDetails">
|
||||
<ul class="list-unstyled mb-0">
|
||||
<li><strong>Street 1:</strong> {{eInvoiceData.street_one}}</li>
|
||||
<li><strong>Street 2:</strong> {{eInvoiceData.street_two}}</li>
|
||||
<li><strong>District:</strong> {{eInvoiceData.district.name}}</li>
|
||||
<li><strong>Postcode:</strong> {{eInvoiceData.post_code}}</li>
|
||||
<li><strong>State:</strong> {{eInvoiceData.state.name}}</li>
|
||||
<li><strong>Country:</strong> {{eInvoiceData.country.name}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
companyId: {
|
||||
type: Number,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
eInvoiceData: null,
|
||||
}
|
||||
},
|
||||
created(){
|
||||
this.fetchData();
|
||||
},
|
||||
methods: {
|
||||
fetchData(){
|
||||
this.submit(route('api.company.einvoice.info', this.companyId), 'get', 'eInvoiceInfoViewOnlySection', false, true)
|
||||
},
|
||||
successHandler(response){
|
||||
this.eInvoiceData = response.payload.data;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -6,7 +6,7 @@
|
||||
<div class="row">
|
||||
<div class="col p-t-10 p-b-10 p-r-0 pointer" @click="clickExpand()" :class="[{'bg-master-lighter': item.status === 1 && item.type !== 6}, {'bg-white': item.status !== 1 && item.status !== 4}, {'bg-warning-lighter': item.status === 7}, {'bg-warning-lighter': item.type === 6}]">
|
||||
<div class="row m-b-5">
|
||||
<div class="col-auto">
|
||||
<div class="col-auto p-r-0">
|
||||
<div class="font-heading fs-8 muted all-caps">Status</div>
|
||||
<div class="font-heading fs-10 bold" v-if="item.type === 1" :class="[{'text-danger': item.status === 1 || item.status === 4}, {'text-success': item.status !== 1 && item.status !== 4 && item.status !== 7}, {'text-danger': item.status === 7}]">
|
||||
{{ item.status === 7 ? 'Refunded' : (item.status === 1 ? 'Pending Verification' : item.status === 4 ? 'Rejected' : 'Payment Approved')}}
|
||||
@@ -15,13 +15,13 @@
|
||||
{{ item.status === 1 ? 'Pending Verification' : item.status === 4 ? 'Rejected' : 'Processing Payment'}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto p-l-0">
|
||||
<div class="col-auto">
|
||||
<div class="font-heading fs-8 muted all-caps">Payment Amount</div>
|
||||
<div class="font-heading fs-10 bold">
|
||||
{{item.original_currency.short_code}} {{(Math.round((item.original_amount - item.refunded_amount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto p-l-0" v-if="totalRefunds !== 0">
|
||||
<div class="col-auto" v-if="totalRefunds !== 0">
|
||||
<div class="font-heading fs-8 muted all-caps">Refunded Amount</div>
|
||||
<div class="font-heading fs-10 bold text-danger">
|
||||
{{item.original_currency.short_code}} {{(Math.round((item.refunded_amount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
|
||||
@@ -45,10 +45,23 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto bg-success" v-if="item.receipt_voucher">
|
||||
<document-file-viewer-component class="h-100" :file="item.receipt_voucher.files[0]">
|
||||
<template slot="button">
|
||||
<div class="row align-items-center h-100">
|
||||
<div class="col p-r-0 p-l-0 text-center">
|
||||
<i class="fa fa-cloud-download text-white"></i>
|
||||
<p class="fs-7 text-white bold" style="width: 50px;">Receipt</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</document-file-viewer-component>
|
||||
</div>
|
||||
<div class="col-auto" v-if="item.status !== 3" :class="[{'bg-master-light': item.status === 1 && item.type !== 6}, {'bg-master-lighter': item.status === 2}, {'bg-warning-lighter': item.status === 7}, {'bg-warning-light': item.type === 6}]">
|
||||
<div class="row align-items-center h-100" v-if="item.status !== 1 || item.payment_method !== 5">
|
||||
<div class="col">
|
||||
<div class="col p-r-0 p-l-0 text-center">
|
||||
<i class="fa" :class="[{'fa-cloud-download': item.status === 1 || item.status === 2}, {'fa-ban': item.status === 4}, {'muted': item.status === 1 || item.status === 2}, {'text-danger': item.status === 4}]"></i>
|
||||
<p class="fs-7" style="width: 50px;">Payment Slip</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row align-items-center h-100" v-if="item.payment_method === 5 && item.status === 1">
|
||||
@@ -71,19 +84,19 @@
|
||||
{{ item.transaction_bill.status === 1 ? 'Processing Payment' : 'Transferred'}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto p-l-0">
|
||||
<div class="col-auto">
|
||||
<div class="font-heading fs-8 muted all-caps">Payment Amount</div>
|
||||
<div class="font-heading fs-10 bold">
|
||||
{{item.original_currency.short_code}} {{(Math.round((item.original_amount - item.refunded_amount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto p-l-0 text-danger" v-if="totalRefunds !== 0">
|
||||
<div class="col-auto text-danger" v-if="totalRefunds !== 0">
|
||||
<div class="font-heading fs-8 muted all-caps">Refunded Amount</div>
|
||||
<div class="font-heading fs-10 bold">
|
||||
{{item.original_currency.short_code}} {{(Math.round((totalRefunds + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto p-l-0" v-if="$store.getters.isSuperAdmin">
|
||||
<div class="col-auto" v-if="$store.getters.isSuperAdmin">
|
||||
<div class="font-heading fs-8 muted all-caps">Service Type</div>
|
||||
<div class="font-heading fs-10 bold">
|
||||
{{item.booking.service.name}} ({{item.booking.service.id}})
|
||||
@@ -114,12 +127,25 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto bg-success m-r-5" v-if="item.receipt_voucher">
|
||||
<document-file-viewer-component class="h-100" :file="item.receipt_voucher.files[0]">
|
||||
<template slot="button">
|
||||
<div class="row align-items-center h-100">
|
||||
<div class="col p-r-0 p-l-0 text-center">
|
||||
<i class="fa fa-cloud-download text-white"></i>
|
||||
<p class="fs-7 text-white bold" style="width: 50px;">Receipt</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</document-file-viewer-component>
|
||||
</div>
|
||||
<div class="col-auto bg-success" v-if="item.transaction_bill.status === 2 || item.transaction_bill.status === 3">
|
||||
<document-file-viewer-component class="h-100" :file="item.transaction_bill.documents.files[0]">
|
||||
<template slot="button">
|
||||
<div class="row align-items-center h-100">
|
||||
<div class="col">
|
||||
<div class="col p-r-0 p-l-0 text-center">
|
||||
<i class="fa fa-cloud-download text-white"></i>
|
||||
<p class="fs-7 text-white bold" style="width: 50px;">Payment Slip</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -220,6 +246,7 @@
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="font-heading all-caps fs-10 m-b-5">Your Payment Proof</div>
|
||||
<!-- NOT Payment Gateway -->
|
||||
<div class="row no-margin" v-if="item.payment_method !== 5">
|
||||
<div v-if="item.documents != null">
|
||||
<div v-for="file in item.documents.files" v-bind:key="file.id" class="col-auto no-padding m-r-5">
|
||||
@@ -233,6 +260,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Payment Gateway -->
|
||||
<div class="row no-margin" v-if="item.payment_method === 5 && (item.status === 2 || item.status === 3)">
|
||||
<a :href="route('billplz.bill', item.payment_reference)" target="_blank">
|
||||
<div class="icon-thumbnail fs-11 text-white icon-25 bg-primary btn-rounded float-left m-r-5">
|
||||
@@ -301,11 +329,32 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-t-10" v-show="showEditBookingAmount">
|
||||
<div class="col">
|
||||
<button class="btn btn-xs all-caps b-rad-none bg-master-lighter btn-block no-border requestModal" data-type="editBookingAmount">Edit Booking Amount</button>
|
||||
<!-- <div class="col-auto text-right">
|
||||
<div class="font-heading fs-12"><i class="fa fa-edit fs-12 pointer fa-fw requestModal" data-type="editBookingAmount" v-if="$store.getters.isSuperAdmin || ($store.getters.isCustomer && $store.getters.getCompanyId === 199)"></i> {{this.data.fixed_currency.short_code}} {{(Math.round((this.data.amount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}</div>
|
||||
</div> -->
|
||||
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="editBookingAmount">
|
||||
<!-- <edit-booking-amount-form-component :data="this.data.booking" :section="section"></edit-booking-amount-form-component> -->
|
||||
<edit-booking-amount-form-v2-component :data="this.data.booking" :section="section"></edit-booking-amount-form-v2-component>
|
||||
</modal-component>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-t-10" v-show="[2, 3].includes(item.status) && (totalRequestedRefund + totalRefunds) < data.original_amount">
|
||||
<div class="col" v-if="$store.getters.isAdmin">
|
||||
<button class="btn btn-xs all-caps b-rad-none bg-master-lighter btn-block no-border requestModal" data-type="transferSummary">Request Refund</button>
|
||||
<div class="col">
|
||||
<button class="btn btn-xs all-caps b-rad-none bg-master-lighter btn-block no-border requestModal" data-type="transferSummary">REFUND / RETURN (CREDIT NOTE)</button>
|
||||
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="transferSummary" size="large">
|
||||
<refund-confirmation-component :data="data" :section="section" :totalRefunds="totalRequestedRefund + totalRefunds"></refund-confirmation-component>
|
||||
<!-- <refund-confirmation-component :data="data" :section="section" :totalRefunds="totalRequestedRefund + totalRefunds"></refund-confirmation-component> -->
|
||||
<request-credit-note-component :data="data" :section="section" :totalRefunds="totalRequestedRefund + totalRefunds"></request-credit-note-component>
|
||||
</modal-component>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-t-10" v-show="[2, 3].includes(item.status)">
|
||||
<div class="col" v-if="$store.getters.isAdmin">
|
||||
<button class="btn btn-xs all-caps b-rad-none bg-master-lighter btn-block no-border requestModal" data-type="regenerateReceiptVoucher">Regenerate Receipt Voucher</button>
|
||||
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="regenerateReceiptVoucher">
|
||||
<regenerate-receipt-voucher-component :data="data" :section="section" class="text-center"></regenerate-receipt-voucher-component>
|
||||
</modal-component>
|
||||
</div>
|
||||
</div>
|
||||
@@ -332,38 +381,47 @@
|
||||
<div class="col bg-white padding-15">
|
||||
<div class="b-b b-grey m-b-5" v-for="(refund, index) in data.transaction_refunds">
|
||||
<div class="row m-b-10 parentContainer">
|
||||
<div class="col-auto">
|
||||
<div class="col-3">
|
||||
<div class="font-heading fs-10 muted all-caps">Created At</div>
|
||||
<div class="font-heading fs-10">
|
||||
{{ refund.created_at }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<div class="col-2">
|
||||
<div class="font-heading fs-10 muted all-caps">Status</div>
|
||||
<div class="font-heading fs-10">
|
||||
<div class="font-heading fs-10 bold" :class="[{'text-warning': refund.status === 1}, {'text-success': refund.status === 2}, {'text-danger': refund.status === 4}]">{{ refund.status === 1 ? 'Pending Verification' : refund.status === 2 ? 'Approved' : 'Rejected'}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto" v-if="$store.getters.isAdmin">
|
||||
<span class="btn requestModal no-border" size="large" data-type="chatmodal">
|
||||
<i class="fa fa-comment-o"></i>
|
||||
</span>
|
||||
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="chatmodal">
|
||||
<remark-component :section="section" :data="refund" module_type="Transaction"></remark-component>
|
||||
</modal-component>
|
||||
<div class="col-2">
|
||||
<div class="row m-l-0 m-r-0" v-if="$store.getters.isAdmin">
|
||||
<span class="btn requestModal no-border" size="large" data-type="chatmodal">
|
||||
<i class="fa fa-comment-o"></i>
|
||||
</span>
|
||||
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="chatmodal">
|
||||
<remark-component :section="section" :data="refund" module_type="Transaction"></remark-component>
|
||||
</modal-component>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col text-right">
|
||||
<div :class="['text-right', showDownloadCreditNote && refund.status === 2 ? 'col-3' : 'col-5']">
|
||||
<div class="font-heading fs-10 muted all-caps">Amount</div>
|
||||
<div class="font-heading fs-10">
|
||||
<div class="font-heading fs-10">{{refund.currency.short_code}} {{(Math.round((refund.amount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto text-right">
|
||||
<div class="font-heading fs-10 muted all-caps">Amount</div>
|
||||
<div class="font-heading fs-14 text-success bold">
|
||||
<div class="font-heading fs-10">{{refund.original_currency.short_code}} {{(Math.round((refund.original_amount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-2" v-if="showDownloadCreditNote && refund.status === 2">
|
||||
<div class="row no-margin justify-content-end">
|
||||
<div class="font-heading all-caps fs-10 m-b-5 text-right">Credit Note</div>
|
||||
<a target=”_blank” @click="downloadCreditNote(refund.id)">
|
||||
<div class="icon-thumbnail fs-11 text-white icon-25 bg-primary btn-rounded float-left m-r-0 pointer">
|
||||
<i class="fa fa-file-image-o fs-10"></i>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-b-15 text-right parentContainer" v-if="$store.getters.isSuperAdmin && refund.status === 1">
|
||||
<div class="col">
|
||||
@@ -436,6 +494,7 @@
|
||||
bank_id: 1
|
||||
},
|
||||
section: 'bookingDetailSection',
|
||||
eInvoiceStartDate: window.E_INVOICE_START_DATE || ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -476,6 +535,14 @@
|
||||
hasRefundInProgress() {
|
||||
var refundTransactionsStatus = this.data.transaction_refunds.length > 0 ? this.data.transaction_refunds.map(refund => refund.status) : [];
|
||||
return refundTransactionsStatus.includes(0) || refundTransactionsStatus.includes(1)
|
||||
},
|
||||
showEditBookingAmount(){
|
||||
return this.data.booking.company.employee.status === 2 && this.data.booking.company.status === 2 && (Math.round((this.data.booking.outstanding_amount + Number.EPSILON) * 100) / 100) > 0;
|
||||
},
|
||||
showDownloadCreditNote() {
|
||||
const today = new Date();
|
||||
const einvoiceStartDate = new Date(this.eInvoiceStartDate);
|
||||
return today > einvoiceStartDate;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -495,6 +562,26 @@
|
||||
paymentMethodArray[5] = 'Payment Gateway';
|
||||
return paymentMethodArray[paymentMethod];
|
||||
},
|
||||
downloadCreditNote(transactionId) {
|
||||
let url = this.route('transaction.credit_note.download.v2', transactionId);
|
||||
if(window.LARAVEL_VAPOR_ENABLED){
|
||||
this.$store.dispatch('crudRequest', {endpoint: url, method: 'get'})
|
||||
.then(response =>
|
||||
{
|
||||
let success = response.ok;
|
||||
response.json().then(response => {
|
||||
if(!success){return;}
|
||||
if (response.src) {
|
||||
window.open(response.src, '_blank');
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
else{
|
||||
window.open(url, '_blank');
|
||||
}
|
||||
},
|
||||
},
|
||||
mixins: [componentHandler]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,175 @@
|
||||
<template>
|
||||
<div class="row zig-zag-top" v-if="refund_reasons">
|
||||
<div class="col bg-white padding-25">
|
||||
<div class="row p-b-10">
|
||||
<div class="col">
|
||||
<div class="font-heading all-caps bold fs-10">Request Credit Note</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-b-10">
|
||||
<div class="col-7">
|
||||
<div class="row p-l-15">
|
||||
<div v-for="(method, index) in refundMethods" :key="index"
|
||||
class="col p-t-20 p-b-20 bg-master-lightest text-center b-grey pointer all-caps"
|
||||
:class="{ 'bg-complete text-white': method.name === refundMethod.name }"
|
||||
@click="updateRefundType(method)">
|
||||
{{ method.name }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-r-0 m-b-10" v-if="refundMethod.name === 'Partial Amount'">
|
||||
<div class="col">
|
||||
<validation-wrapper-component :validator="$v.refundAmount">
|
||||
<label>Credit Note Amount</label>
|
||||
<input class="form-control" name="amount" v-model="refundAmount"
|
||||
:disabled="refundMethod.name === 'Full Amount'" v-money="moneyV2">
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
<div class="col-auto b-r b-t b-b b-grey">
|
||||
<div class="row h-100 align-items-center">
|
||||
<div class="col">
|
||||
<div class="font-heading fs-10 muted">{{ data.booking.fixed_currency.short_code }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-t-5 m-b-5" v-if="refundMethod.name === 'Partial Amount'">
|
||||
<div class="col">
|
||||
<validation-wrapper-component selectable :validator="$v.refundRemark">
|
||||
<label>Reason for refund</label>
|
||||
<select-component :options="refund_reasons" v-model="refundRemark"></select-component>
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-t-5 m-b-5" v-else>
|
||||
<div class="col">
|
||||
<validation-wrapper-component :validator="$v.refundRemark">
|
||||
<label>Remarks</label>
|
||||
<input class="form-control" name="amount" v-model="refundRemark" >
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-t-5 m-b-5" v-if="refundMethod.name === 'Partial Amount' && refundRemark === 'Others'">
|
||||
<div class="col">
|
||||
<validation-wrapper-component :validator="$v.refundRemarkOthers">
|
||||
<label>Reason Others</label>
|
||||
<input class="form-control" name="amount" v-model="refundRemarkOthers">
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-t-10 m-b-10">
|
||||
<div class="col">
|
||||
<div class="font-heading all-caps fs-10 m-b-5">Paid Amount: {{ paidAmount }}</div>
|
||||
<div class="font-heading all-caps fs-10 m-b-5" v-if="this.data.refunded_amount > 0">Refunded Amount: {{ (Math.round((this.data.refunded_amount + Number.EPSILON) * 100) / 100).toFixed(2) }}</div>
|
||||
<div class="font-heading all-caps fs-10 m-b-5">Refund Amount Requested: {{ refundAmount }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-auto">
|
||||
<button class="btn btn-lg btn-default bg-master-lightest b-rad-none all-caps fs-12"
|
||||
data-dismiss="modal">Cancel</button>
|
||||
</div>
|
||||
<div class="col text-right">
|
||||
<button class="btn btn-lg btn-success b-rad-none all-caps fs-12" @click="submitForm()">Confirm &
|
||||
Proceed</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import FormHandler from '../../../general/mixins/formHandler';
|
||||
import ModalFormHandler from '../../../general/mixins/modalFormHandler';
|
||||
import { requiredIf, maxValue} from "vuelidate/lib/validators";
|
||||
|
||||
export default {
|
||||
props: {
|
||||
totalRefunds: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
refundAmount: (Math.round((this.data.original_amount - this.data.refunded_amount + Number.EPSILON) * 100) / 100).toFixed(2),
|
||||
refundRemark: '',
|
||||
refundRemarkOthers: '',
|
||||
refundMethod: { name: 'Full Amount', status: false },
|
||||
refundMethods: [
|
||||
{ name: 'Full Amount' },
|
||||
{ name: 'Partial Amount' }
|
||||
],
|
||||
refund_reasons: [],
|
||||
validateRefundRemark: false,
|
||||
}
|
||||
},
|
||||
validations() {
|
||||
return {
|
||||
refundAmount: {
|
||||
maxValue: maxValue(this.refundMaxValue)
|
||||
},
|
||||
refundRemark: {
|
||||
required: requiredIf(function () { return this.validateRefundRemark; })
|
||||
},
|
||||
refundRemarkOthers: {
|
||||
required: requiredIf(function () { return this.refundRemark === 'Others'; })
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
refundMaxValue() {
|
||||
return (Math.round((this.data.original_amount - this.data.refunded_amount + Number.EPSILON) * 100) / 100).toFixed(2);
|
||||
},
|
||||
paidAmount() {
|
||||
return this.data.original_amount;
|
||||
},
|
||||
},
|
||||
created(){
|
||||
this.fetchRefundReasons();
|
||||
},
|
||||
methods: {
|
||||
fetchRefundReasons(){
|
||||
this.submit(route('api.remark.list.refund_reasons'), 'get', 'refundReasonListSection', false, false);
|
||||
},
|
||||
successHandler(response, section){
|
||||
if(section === 'refundReasonListSection'){
|
||||
const reasons = Array.isArray(response.payload.data) ? [...response.payload.data] : [];
|
||||
|
||||
if (!this.$store.getters.isAdmin) {
|
||||
const index = reasons.indexOf("Others");
|
||||
if (index !== -1) {
|
||||
reasons.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
this.refund_reasons = reasons;
|
||||
this.validateRefundRemark = true;
|
||||
}
|
||||
else{
|
||||
this.closeModal();
|
||||
this.formHandler();
|
||||
}
|
||||
},
|
||||
submitForm() {
|
||||
this.parameters.amount = this.refundAmount;
|
||||
if (this.refundRemark === 'Others') {
|
||||
this.parameters.refundRemark = `${this.refundRemarkOthers}`; //`${this.refundRemark}: ${this.refundRemarkOthers}`;
|
||||
} else {
|
||||
this.parameters.refundRemark = this.refundRemark;
|
||||
}
|
||||
this.submit(this.route('api.booking.refund.create', this.data.booking.id, this.data.id), 'post', this.section, true, true)
|
||||
},
|
||||
updateRefundType(refund) {
|
||||
this.refundMethod = { ...refund, status: !this.refundMethod.status };
|
||||
if (this.refundMethod.name === 'Full Amount') {
|
||||
this.refundAmount = this.refundMaxValue;
|
||||
}
|
||||
this.refundRemark = '';
|
||||
this.refundRemarkOthers = '';
|
||||
},
|
||||
},
|
||||
mixins: [FormHandler, ModalFormHandler]
|
||||
}
|
||||
</script>
|
||||
+845
File diff suppressed because one or more lines are too long
@@ -111,7 +111,11 @@
|
||||
section: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
companyId: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
@@ -121,14 +125,16 @@
|
||||
amount: this.amount,
|
||||
bank_code: this.bank_code,
|
||||
voucher_code: this.calculation.voucher_code,
|
||||
voucher_discount_amount: this.calculation.voucher_discount_amount
|
||||
voucher_discount_amount: this.calculation.voucher_discount_amount,
|
||||
booking_id: this.id,
|
||||
company_id: this.companyId,
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
submitForm(){
|
||||
this.isLoading = true;
|
||||
this.submit(route('api.booking.payment.create', this.id), 'post', this.section, false, false);
|
||||
this.submit(route('api.booking.payment.create', this.id), 'post', this.section, false, true);
|
||||
},
|
||||
successHandler(response){
|
||||
if (response.payload.data.payment_method === 5) {
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
<template>
|
||||
<div class="row">
|
||||
<div class="col bg-white padding-40 b-rad-lg">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row m-b-10">
|
||||
<div class="col">
|
||||
<h3 class="all-caps m-b-5 bold no-margin">Edit Booking Amount</h3>
|
||||
<p>To ensure both updates take effect, please update the purchase order details with the equivalent booking amount immediately after this update. If not done in sequence, neither update will be applied.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-b-10">
|
||||
<div class="col">
|
||||
<validation-wrapper-component :validator="$v.amount_to_edit">
|
||||
<label class="muted">Booking Amount ({{data.fixed_currency.short_code}})</label>
|
||||
<input type="text" class="form-control" v-model="amount_to_edit" v-money="money">
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-b-5 animate__animated animate__fadeInUpBig animate__fast" v-if="error">
|
||||
<div class="col">
|
||||
<small class="bold fs-10 text-danger">{{error}}</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col p-r-5">
|
||||
<div class="btn btn-sm btn-default bg-master-lightest btn-block b-rad-none" data-dismiss="modal">Cancel</div>
|
||||
</div>
|
||||
<div class="col p-l-5">
|
||||
<div class="btn btn-sm btn-success btn-block b-rad-none" @click="submitForm()">Update</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { required } from "vuelidate/lib/validators";
|
||||
import FormHandler from '../../../general/mixins/formHandler';
|
||||
|
||||
export default {
|
||||
data(){
|
||||
return {
|
||||
error: '',
|
||||
amount_to_edit: (Math.round((this.data.paid_amount + Number.EPSILON) * 100) / 100).toFixed(2)
|
||||
}
|
||||
},
|
||||
validations: {
|
||||
amount_to_edit: { required }
|
||||
},
|
||||
// watch: {
|
||||
// 'data': function() {
|
||||
// this.amount_to_edit = (Math.round((this.data.paid_amount + Number.EPSILON) * 100) / 100).toFixed(2);
|
||||
// }
|
||||
// },
|
||||
methods: {
|
||||
submitForm(){
|
||||
this.parameters = {amount_to_edit : parseFloat((this.amount_to_edit).toString().replace(',', ''))}
|
||||
this.submit(this.route('api.booking.amount.update', this.data.id), 'put', this.section, true, true)
|
||||
},
|
||||
successHandler(){
|
||||
this.closeModal();
|
||||
this.formHandler('');
|
||||
},
|
||||
},
|
||||
mixins: [FormHandler]
|
||||
}
|
||||
</script>
|
||||
@@ -118,15 +118,17 @@
|
||||
},
|
||||
methods: {
|
||||
submitForm(){
|
||||
|
||||
this.parameters = {
|
||||
files: this.files
|
||||
files: this.files,
|
||||
booking_id: this.id,
|
||||
company_id: this.data.booking.company.id,
|
||||
payment_id: this.data.id,
|
||||
};
|
||||
|
||||
this.submit(this.route('api.booking.payment.verification.create', this.id, this.data.id), 'post', this.section, true, false)
|
||||
this.submit(this.route('api.booking.payment.verification.create', this.id, this.data.id), 'post', this.section, true, true);
|
||||
}
|
||||
},
|
||||
mixins: [ModalFromHandler]
|
||||
|
||||
}
|
||||
</script>
|
||||
</script>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<div class="row" v-if="!submitted">
|
||||
<div class="col-auto">
|
||||
<div class="bg-danger p-l-15 p-r-15 p-t-5 p-b-5 m-b-10">
|
||||
<p class="m-b-0 text-white fs-12" >Any Purchase Orders that aren't submitted within 60 days will be closed for editing.</p>
|
||||
<p class="m-b-0 text-white fs-12" >Ensure PO details are fill in correctly — NO changes allowed after submission.</p>
|
||||
</div>
|
||||
<div class="bg-danger p-l-15 p-r-15 p-t-5 p-b-5" v-if="$store.getters.isAdmin && companySegmentIds.includes(24)">
|
||||
<p class="m-b-0 text-white fs-12" >Please note that this customer request to manual fill up the PO.</p>
|
||||
@@ -150,8 +150,15 @@
|
||||
<div class="col">
|
||||
<div class="row m-b-10">
|
||||
<div class="col">
|
||||
<button id="save-purchase-order" name="save-purchase-order" class="btn btn-xs all-caps b-rad-none btn-primary btn-block" @click="submitForm()">{{(Math.round((poTotal + Number.EPSILON) * 1000) / 1000).toFixed(3) !== (Math.round((data.amount + Number.EPSILON) * 1000) / 1000).toFixed(3) ? 'Save Purchase Order' : 'Save & Confirm'}}</button>
|
||||
<button id="save-purchase-order" name="save-purchase-order" class="btn btn-xs all-caps b-rad-none btn-primary btn-block requestModal" data-type="submitPOConfirmation">{{(Math.round((poTotal + Number.EPSILON) * 1000) / 1000).toFixed(3) !== (Math.round((data.amount + Number.EPSILON) * 1000) / 1000).toFixed(3) ? 'Save Purchase Order' : 'Save & Confirm'}}</button>
|
||||
</div>
|
||||
<modal-component
|
||||
id="modal-submit-po"
|
||||
class="animate__animated animate__fast animate__fadeIn"
|
||||
styleType="fill-in" type="submitPOConfirmation" size="large">
|
||||
<purchase-order-submit-confirmation-component class="text-center" v-on:confirm-submit="handleConfirmed" :section="section">
|
||||
</purchase-order-submit-confirmation-component>
|
||||
</modal-component>
|
||||
</div>
|
||||
<div class="row" v-if="(Math.round((poTotal + Number.EPSILON) * 1000) / 1000).toFixed(3) !== data.amount">
|
||||
<div class="col">
|
||||
@@ -188,12 +195,13 @@
|
||||
<div class="col" v-if="submitted">
|
||||
<div class="alert alert-success padding-15" role="alert">
|
||||
<div class="font-heading fs-12 all-caps bold m-b-15">Your Purchase Order {{data.purchase_order.status === 1 ? 'is Being Processed for Verification' : 'has been Approved' }}</div>
|
||||
<div class="row m-b-15">
|
||||
<div class="row m-b-15" v-if="allowPOEditing">
|
||||
<div class="col">
|
||||
<div class="font-heading fs-10">If you would like to still edit your Purchase Order you can do that by clicking on the edit button below, but your purchase order verification request will be reset.</div>
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn btn-xs all-caps b-rad-none btn-default bg-master-lightest w-100" @click="submitted = false">Edit Purchase Order</button>
|
||||
<button class="btn btn-xs all-caps b-rad-none btn-default bg-master-lightest w-100" @click="submitted = false" v-if="allowPOEditing">Edit Purchase Order</button>
|
||||
<!-- <button class="btn btn-xs all-caps b-rad-none btn-default bg-master-lightest w-100" @click="submitted = false" >Edit Purchase Order</button> -->
|
||||
<button class="btn btn-xs all-caps b-rad-none btn-complete w-100 m-t-5" v-if="!data.documents.proforma_invoice && data.outstanding_amount != 0" @click="submit(route('api.booking.proforma.create', data.id), 'post', section, true, true)">Generate Proforma Invoice</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -235,7 +243,8 @@
|
||||
},
|
||||
created() {
|
||||
this.products = this.data.purchase_order ? this.data.purchase_order.details : [];
|
||||
this.submitted = this.data.purchase_order ? this.data.purchase_order.status === 1 || this.data.purchase_order.status === 2: false;
|
||||
this.submitted = this.data.purchase_order ? true : false;
|
||||
// this.submitted = this.data.purchase_order ? this.data.purchase_order.status === 1 || this.data.purchase_order.status === 2: false;
|
||||
},
|
||||
computed: {
|
||||
productTotal(){
|
||||
@@ -245,13 +254,29 @@
|
||||
return this.products.reduce(function(last, product) {
|
||||
return last + product.total;
|
||||
}, 0);
|
||||
},
|
||||
allowPOEditing() {
|
||||
//Condition 1
|
||||
const noPaymentsMade = Math.round((this.data.paid_amount + Number.EPSILON) * 100) / 100 === 0;
|
||||
const noPaymentPendingVerifications = this.data.payment_history.every(payment => payment.status !== 1);
|
||||
|
||||
//Condition 2
|
||||
const paymentsMade = Math.round((this.data.paid_amount + Number.EPSILON) * 100) / 100 > 0;
|
||||
const outstandingAmount = Math.round((this.data.outstanding_amount + Number.EPSILON) * 100) / 100 > 0;
|
||||
const allPaymentApproved = this.data.payment_history.every(payment => payment.status === 2);
|
||||
|
||||
//Condition 3
|
||||
const adminBeforeApproval = this.$store.getters.isAdmin && !(this.data.purchase_order.status === 2);
|
||||
|
||||
return (noPaymentsMade && noPaymentPendingVerifications) || (paymentsMade && outstandingAmount && allPaymentApproved) || adminBeforeApproval;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'data': function () {
|
||||
if (this.data && this.data.purchase_order && this.data.purchase_order.details) {
|
||||
this.products = this.data.purchase_order.details;
|
||||
this.submitted = this.data.purchase_order ? this.data.purchase_order.status === 1 || this.data.purchase_order.status === 2: false;
|
||||
this.submitted = this.data.purchase_order ? true : false;
|
||||
// this.submitted = this.data.purchase_order ? this.data.purchase_order.status === 1 || this.data.purchase_order.status === 2: false;
|
||||
} else {
|
||||
this.products = [];
|
||||
}
|
||||
@@ -278,10 +303,12 @@
|
||||
}
|
||||
|
||||
},
|
||||
submitForm(){
|
||||
handleConfirmed(value) {
|
||||
this.uploadFiles = false;
|
||||
this.parameters = {
|
||||
products: this.products
|
||||
products: this.products,
|
||||
booking_id: this.data.id,
|
||||
company_id: this.data.company.id,
|
||||
};
|
||||
|
||||
this.submit(route('api.transaction.po.create', this.data.id), 'post', this.section, true, true);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user