mirror of
https://gitlab.com/uldvstar/exchange-2.0.git
synced 2026-08-19 04:24:16 +00:00
Merge branch 'development' of gitlab.com:CIEFWorldwideSdnBhd/exchange-2.0 into wallet-ui
# Conflicts: # resources/views/partials/header.blade.php # routes/web.php
This commit is contained in:
@@ -56,5 +56,3 @@ BILLPLZ_BASE_URL="https://www.billplz-sandbox.com"
|
||||
BILLPLZ_API_KEY="0fa4c710-761b-4a7a-a501-c2c2d02643d5"
|
||||
BILLPLZ_X_SIGNATURE_KEY="S-pbNVthVRsvnPfZlgLwqqOg"
|
||||
BILLPLZ_COLLECTION_ID="hev2wdjy"
|
||||
BILLPLZ_REDIRECT_URL="http://localhost:9003/bookings/billplz"
|
||||
BILLPLZ_CALLBACK_URL="localhost:9003/api/v1/billplz/callback"
|
||||
@@ -17,7 +17,6 @@ abstract class AbstractUpdateRecord
|
||||
*/
|
||||
public function handler(Model $model){
|
||||
try{
|
||||
|
||||
if($model->save()){ return $model; }
|
||||
|
||||
} catch (QueryException $exception){
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace App\Classes\General\Eloquent\Filters;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class isPublished implements Filter
|
||||
class IsPublished implements Filter
|
||||
{
|
||||
|
||||
/**
|
||||
|
||||
@@ -14,7 +14,7 @@ class PaymentReference implements Filter
|
||||
*/
|
||||
public static function apply(Builder $builder, $value)
|
||||
{
|
||||
return $builder->where('payment_reference', $value);
|
||||
return $builder->where('payment_reference', '=', $value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,6 +5,7 @@ namespace App\Classes\General\Eloquent\Filters;
|
||||
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Models\Booking;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
@@ -19,7 +20,7 @@ class WithTotalPayments implements Filter
|
||||
public static function apply(Builder $builder, $value)
|
||||
{
|
||||
return $builder->leftJoin('bookings', 'companies.id', '=', 'bookings.company_id')->rightJoin('transactions', function ($join) {
|
||||
$join->on('bookings.id', '=', 'transactions.booking_id')->where('transactions.type', TransactionType::PAYMENT)->whereIn('transactions.status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
|
||||
})->addSelect(['companies.*', DB::raw('SUM(transactions.amount) as total_payments')])->groupBy(['companies.id']);
|
||||
$join->on('bookings.id', '=', 'transactions.owner_id')->where('owner_type', '=', Booking::class)->where('transactions.type', TransactionType::PAYMENT)->whereIn('transactions.status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
|
||||
})->addSelect(['companies.*', DB::raw('SUM(transactions.amount) as total_payments'), DB::raw('SUM(transactions.amount / DATEDIFF(companies.created_at, CURRENT_DATE)) as spending_average_per_day'), DB::raw('SUM(transactions.amount) / count(distinct bookings.id) as spending_average_booking')])->groupBy(['companies.id']);
|
||||
}
|
||||
}
|
||||
@@ -53,24 +53,18 @@ class DeleteUserLogic extends AbstractControllerLogic
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
* @throws ErrorException
|
||||
* @throws \App\Classes\Exceptions\AccessForbiddenException
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
* @throws \App\Classes\Exceptions\RequestValidationException
|
||||
*/
|
||||
public function logic(Request $request) : JsonResponse
|
||||
{
|
||||
try {
|
||||
DB::beginTransaction();
|
||||
$user = $this->fetchesUser->execute(['id' => $request->route('id')]);
|
||||
$this->canDeleteUser->passes();
|
||||
$this->deletesUser->execute($user);
|
||||
|
||||
$user = $this->fetchesUser->execute(['id' => $request->route('id')]);
|
||||
$this->canDeleteUser->passes();
|
||||
$this->deletesUser->execute($user);
|
||||
|
||||
DB::commit();
|
||||
|
||||
return $this->resourceResponse(new UserResource($user));
|
||||
|
||||
} catch (\Exception $exception){
|
||||
throw new ErrorException($exception->getMessage(), $exception->getCode());
|
||||
}
|
||||
return $this->resourceResponse(new UserResource($user));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,7 +4,7 @@ namespace App\Classes\Modules\Accounts\DataTransferObjects;
|
||||
|
||||
use App\Classes\General\Interfaces\DataTransferObject;
|
||||
|
||||
class FullnameObject implements DataTransferObject
|
||||
class FullNameObject implements DataTransferObject
|
||||
{
|
||||
/** @var string */
|
||||
private $name;
|
||||
@@ -12,11 +12,6 @@ class FullnameObject implements DataTransferObject
|
||||
/**
|
||||
* UserObject constructor.
|
||||
* @param string $name
|
||||
* @param string $email
|
||||
* @param string $password
|
||||
* @param string $passwordConfirmation
|
||||
* @param int|null $type
|
||||
* @param int|null $status
|
||||
*/
|
||||
public function __construct(string $name)
|
||||
{
|
||||
|
||||
@@ -22,7 +22,7 @@ class AddressObject implements DataTransferObject
|
||||
/** @var int */
|
||||
private $districtId;
|
||||
|
||||
/** @var int */
|
||||
/** @var string */
|
||||
private $postCode;
|
||||
|
||||
/**
|
||||
@@ -32,9 +32,9 @@ class AddressObject implements DataTransferObject
|
||||
* @param int $countryId
|
||||
* @param int $stateId
|
||||
* @param int $districtId
|
||||
* @param int $postCode
|
||||
* @param string $postCode
|
||||
*/
|
||||
public function __construct(string $streetOne, ?string $streetTwo, int $countryId, int $stateId, int $districtId, int $postCode)
|
||||
public function __construct(string $streetOne, ?string $streetTwo, int $countryId, int $stateId, int $districtId, string $postCode)
|
||||
{
|
||||
$this->streetOne = $streetOne;
|
||||
$this->streetTwo = $streetTwo;
|
||||
@@ -85,9 +85,9 @@ class AddressObject implements DataTransferObject
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
* @return string
|
||||
*/
|
||||
public function getPostCode(): int
|
||||
public function getPostCode(): string
|
||||
{
|
||||
return $this->postCode;
|
||||
}
|
||||
|
||||
@@ -2,8 +2,12 @@
|
||||
|
||||
namespace App\Classes\Modules\Billplzs\ControllersLogic;
|
||||
|
||||
use ErrorException;
|
||||
use App\Classes\Modules\Wallets\DataTransferObjects\WalletObject;
|
||||
use App\Classes\Modules\Wallets\Services\UpdatesWallet;
|
||||
|
||||
use App\Classes\Exceptions\ResourceNotFoundException;
|
||||
use App\Http\Resources\TransactionResource;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
@@ -14,19 +18,12 @@ use App\Classes\Modules\Billplzs\DataTransferObjects\BillplzXSignatureObject;
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Transactions\Services\FetchesTransaction;
|
||||
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class CallbackBillplzLogic extends AbstractControllerLogic
|
||||
class CallbackBillplzLogic
|
||||
{
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function notification():array {
|
||||
return [
|
||||
'title' => 'Callback Billplz',
|
||||
'message' => 'You have successfully receive Billplz callback'
|
||||
];
|
||||
}
|
||||
|
||||
/** @var GetBillplzBill */
|
||||
private $getBillplzBill;
|
||||
@@ -37,44 +34,68 @@ class CallbackBillplzLogic extends AbstractControllerLogic
|
||||
/** @var UpdatesTransactionStatus */
|
||||
private $updatesTransactionStatus;
|
||||
|
||||
/** @var UpdatesWallet */
|
||||
private $updatesWallet;
|
||||
|
||||
/**
|
||||
* CreateBookingLogic constructor.
|
||||
* @param CreateGetBillplzBillsBillplzBill $getBillplzBill
|
||||
* @param GetBillplzBill $getBillplzBill
|
||||
* @param FetchesTransaction $fetchesTransaction
|
||||
* @param UpdatesTransactionStatus $updatesTransactionStatus
|
||||
*/
|
||||
public function __construct(GetBillplzBill $getBillplzBill, FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus)
|
||||
public function __construct(GetBillplzBill $getBillplzBill, FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus, UpdatesWallet $updatesWallet)
|
||||
{
|
||||
$this->getBillplzBill = $getBillplzBill;
|
||||
$this->fetchesTransaction = $fetchesTransaction;
|
||||
$this->updatesTransactionStatus = $updatesTransactionStatus;
|
||||
$this->updatesWallet = $updatesWallet;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
* @throws \App\Classes\Exceptions\AccessForbiddenException
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
* @throws \App\Classes\Exceptions\RequestValidationException
|
||||
* @return bool|\Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||
* @throws MalformedRequestException
|
||||
* @throws ResourceNotFoundException
|
||||
*/
|
||||
public function logic(Request $request) : JsonResponse
|
||||
public function execute(Request $request)
|
||||
{
|
||||
|
||||
$billplzXSignatureObject = new BillplzXSignatureObject($request);
|
||||
|
||||
if(!$billplzXSignatureObject->isValidSignature()) throw new MalformedRequestException('Unable to get correct response from billplz server.');
|
||||
if(!$billplzXSignatureObject->isValidSignature()){
|
||||
throw new MalformedRequestException('Billplz Payment validation failed.');
|
||||
}
|
||||
|
||||
$billPlz = $this->getBillplzBill->execute($billplzXSignatureObject->getBillPlzId());
|
||||
|
||||
if(!$billPlz) throw new MalformedRequestException('Unable to get correct response from billplz server.');
|
||||
if(!$billPlz) throw new ResourceNotFoundException('Billplz bill not found.');
|
||||
|
||||
$transaction = $this->fetchesTransaction->execute(['payment_reference' => $billplzXSignatureObject->getBillPlzId()]);
|
||||
|
||||
if($billPlz->state == 'paid') $this->updatesTransactionStatus->execute($transaction, ApprovalStatus::APPROVED);
|
||||
|
||||
return $this->response(['data' => $billPlz]);
|
||||
if($billPlz->state === 'paid') {
|
||||
$status = ApprovalStatus::APPROVED;
|
||||
if (
|
||||
$transaction->owner_type == 'App\Models\Wallet' &&
|
||||
$transaction->status == ApprovalStatus::PENDING_VERIFICATION
|
||||
) {
|
||||
$wallet = $transaction->owner;
|
||||
$updateWalletAmount = $wallet->amount + $transaction->amount;
|
||||
$walletOject = new WalletObject($wallet->company->id, $wallet->currency_id, $wallet->code, $updateWalletAmount);
|
||||
$wallet = $this->updatesWallet->execute($wallet, $walletOject);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if($billPlz->state === 'due') {
|
||||
$status = $billplzXSignatureObject->getStatus() === 'failed' ? ApprovalStatus::REJECTED : ApprovalStatus::PENDING_VERIFICATION;
|
||||
}
|
||||
|
||||
$this->updatesTransactionStatus->execute($transaction, $status);
|
||||
|
||||
$token = Auth::fromUser(User::find(1));
|
||||
$request->headers->set('Authorization', 'Bearer '.$token);
|
||||
|
||||
return $request->method() === 'POST' ? true : view('pages.payments_redirect', ['marking' => $transaction->booking->marking, 'payment_reference' => $transaction->payment_reference, 'status' => $status, 'amount' => $transaction->amount]);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -40,9 +40,7 @@ class CreateBillplzBillLogic extends AbstractControllerLogic
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
* @throws \App\Classes\Exceptions\AccessForbiddenException
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
* @throws \App\Classes\Exceptions\RequestValidationException
|
||||
* @throws MalformedRequestException
|
||||
*/
|
||||
public function logic(Request $request) : JsonResponse
|
||||
{
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Classes\Modules\Billplzs\DataTransferObjects;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Classes\General\Interfaces\DataTransferObject;
|
||||
use function PHPSTORM_META\map;
|
||||
|
||||
class BillplzXSignatureObject implements DataTransferObject
|
||||
{
|
||||
@@ -11,6 +12,9 @@ class BillplzXSignatureObject implements DataTransferObject
|
||||
/** @var string */
|
||||
private $billPlzId;
|
||||
|
||||
/** @var string */
|
||||
private $status;
|
||||
|
||||
/** @var array */
|
||||
private $billPlzConstructArray;
|
||||
|
||||
@@ -20,6 +24,9 @@ class BillplzXSignatureObject implements DataTransferObject
|
||||
/** @var string */
|
||||
private $billPlzComputedXSignature;
|
||||
|
||||
/** @var string */
|
||||
private $type;
|
||||
|
||||
/** @var Request */
|
||||
private $request;
|
||||
|
||||
@@ -28,22 +35,26 @@ class BillplzXSignatureObject implements DataTransferObject
|
||||
|
||||
public function __construct(Request $request)
|
||||
{
|
||||
$this->request = $request;
|
||||
|
||||
$this->billPlzId = $request->id ? $request->id : $request->{'billplz[id]'};
|
||||
$this->type = $request->exists('billplz') ? 'redirect' : 'callback';
|
||||
|
||||
$this->requestXSignature = $request->x_signature ? $request->x_signature : $request->{'billplz[x_signature]'};
|
||||
$this->request = $this->type === 'redirect' ? $request->input('billplz') : $request;
|
||||
|
||||
$this->billPlzId = $this->request['id'];
|
||||
|
||||
$this->status = $this->request['transaction_status'];
|
||||
|
||||
$this->requestXSignature = $this->request['x_signature'];
|
||||
|
||||
$this->_constructBillplzArray()->_natSortBillplzArray()->_constructBillplzString()->_computeBillplzXSignature();
|
||||
}
|
||||
|
||||
private function _constructBillplzArray(){
|
||||
foreach($this->request->all() as $key => $value){
|
||||
if($key != 'x_signature' && $key != 'billplz[x_signature]'){
|
||||
$key = str_replace(']', '', str_replace('[', '', $key));
|
||||
$this->billPlzConstructArray[] = $key.$value;
|
||||
}
|
||||
}
|
||||
|
||||
$this->billPlzConstructArray = collect($this->request)->forget('x_signature')->map(function($item, $key){
|
||||
return $this->type === 'redirect' ? 'billplz'.$key.$item : $key.$item;
|
||||
})->toArray();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -72,6 +83,11 @@ class BillplzXSignatureObject implements DataTransferObject
|
||||
return $this->billPlzId;
|
||||
}
|
||||
|
||||
public function getStatus(): string
|
||||
{
|
||||
return $this->status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
@@ -98,7 +114,7 @@ class BillplzXSignatureObject implements DataTransferObject
|
||||
|
||||
public function isValidSignature(): bool
|
||||
{
|
||||
return $this->billPlzComputedXSignature == $this->requestXSignature ? true : false;
|
||||
return $this->billPlzComputedXSignature === $this->requestXSignature ? true : false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,22 +7,30 @@ use App\Classes\Exceptions\MalformedRequestException;
|
||||
|
||||
class CreatesBillplzBill
|
||||
{
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Model
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
* @param string $name
|
||||
* @param string $email
|
||||
* @param string $description
|
||||
* @param float $amount
|
||||
* @param string $billNumber
|
||||
* @param null|string $bankCode
|
||||
* @return null|object
|
||||
* @throws MalformedRequestException
|
||||
*/
|
||||
public function execute(string $name, string $email, string $description, float $amount, string $billNumber, ?string $bankCode = null) {
|
||||
public function execute(string $name, string $email, string $description, float $amount, string $billNumber, ?string $bankCode = null) {
|
||||
try{
|
||||
$response = Http::withBasicAuth(config('billplz.api_key').':', '')->withOptions(["verify"=>false])->post(config('billplz.base_url').'/api/v3/bills', [
|
||||
// config('billplz.maybank')
|
||||
$response = Http::withBasicAuth(config('billplz.api_key').':', '')->post(config('billplz.base_url').'/api/v3/bills', [
|
||||
'collection_id' => config('billplz.collection_id'),
|
||||
'name' => $name,
|
||||
'email' => $email,
|
||||
'description' => $description,
|
||||
'amount' => $amount,
|
||||
'redirect_url' => config('billplz.redirect_url'),
|
||||
'callback_url' => config('billplz.callback_url'),
|
||||
'amount' => $this->finalizeAmount($amount),
|
||||
'redirect_url' => route('online_payment.redirect'),
|
||||
'callback_url' => route('api.online_payment.callback'),
|
||||
'reference_1_label' => 'Bank Code',
|
||||
'reference_1' => $bankCode ? $bankCode : config('billplz.maybank'),
|
||||
'reference_1' => $bankCode ? $bankCode : '',
|
||||
'reference_2_label' => 'Bill Number',
|
||||
'reference_2' => $billNumber
|
||||
]);
|
||||
@@ -40,4 +48,9 @@ class CreatesBillplzBill
|
||||
throw new MalformedRequestException('Unable to get correct response from billplz server' . $exception->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
protected function finalizeAmount($amount){
|
||||
$number = round($amount, 2) * 100;
|
||||
return (string) $number;
|
||||
}
|
||||
}
|
||||
@@ -2,13 +2,16 @@
|
||||
|
||||
namespace App\Classes\Modules\Billplzs\Services;
|
||||
|
||||
use App\Classes\Exceptions\MalformedRequestException;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
|
||||
class GetBillplzBill
|
||||
{
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Model
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
* @param string $billPlzId
|
||||
* @return null|object
|
||||
* @throws MalformedRequestException
|
||||
*/
|
||||
public function execute(string $billPlzId) {
|
||||
try{
|
||||
|
||||
@@ -61,7 +61,11 @@ class ApprovePurchaseOrderLogic extends AbstractControllerLogic
|
||||
|
||||
$booking = $this->fetchesBooking->execute(['id' => $request->route('id')]);
|
||||
|
||||
$this->updatesTransactionStatus->execute($booking->transactions()->where('type', TransactionType::PURCHASE_ORDER)->first(), ApprovalStatus::APPROVED);
|
||||
$purchaseOrder = $booking->transactions()->where('type', TransactionType::PURCHASE_ORDER)->first();
|
||||
|
||||
$booking->transactions()->where('type', TransactionType::PURCHASE_ORDER)->where('id', '!=', $purchaseOrder->id)->delete();
|
||||
|
||||
$this->updatesTransactionStatus->execute($purchaseOrder, ApprovalStatus::APPROVED);
|
||||
|
||||
$this->createInvoiceTransactionProcessor->execute($booking);
|
||||
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Bookings\ControllersLogic;
|
||||
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Transactions\ControllersLogic\CreatePurchaseOrderTransactionLogic;
|
||||
use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject;
|
||||
use App\Classes\Modules\Transactions\Processors\CreatePurchaseOrderTransactionProcessor;
|
||||
use App\Classes\Modules\Transactions\Services\GeneratesPurchaseOrderProducts;
|
||||
use App\Classes\Modules\Transactions\Services\GeneratesTransactionBillNumber;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\PaymentMethodType;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
|
||||
use App\Models\Booking;
|
||||
use App\Models\Transaction;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class AutoPurchaseOrderFillLogic extends AbstractControllerLogic
|
||||
{
|
||||
/**
|
||||
* AutoPurchaseOrderFillLogic constructor.
|
||||
* @param GeneratesPurchaseOrderProducts $generatesPurchaseOrderProducts
|
||||
* @param GeneratesTransactionBillNumber $generatesTransactionBillNumber
|
||||
* @param CreatePurchaseOrderTransactionProcessor $createPurchaseOrderTransactionProcessor
|
||||
*/
|
||||
public function __construct(GeneratesPurchaseOrderProducts $generatesPurchaseOrderProducts, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CreatePurchaseOrderTransactionProcessor $createPurchaseOrderTransactionProcessor)
|
||||
{
|
||||
$this->generatesPurchaseOrderProducts = $generatesPurchaseOrderProducts;
|
||||
$this->generatesTransactionBillNumber = $generatesTransactionBillNumber;
|
||||
$this->createPurchaseOrderTransactionProcessor = $createPurchaseOrderTransactionProcessor;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function notification():array {
|
||||
return [
|
||||
'title' => 'Purchase Order Approval',
|
||||
'message' => 'You have successfully updated the Purchase order status'
|
||||
];
|
||||
}
|
||||
|
||||
/** @var GeneratesPurchaseOrderProducts */
|
||||
private $generatesPurchaseOrderProducts;
|
||||
|
||||
/** @var GeneratesTransactionBillNumber */
|
||||
private $generatesTransactionBillNumber;
|
||||
|
||||
/** @var CreatePurchaseOrderTransactionProcessor */
|
||||
private $createPurchaseOrderTransactionProcessor;
|
||||
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
*/
|
||||
public function logic(Request $request) : JsonResponse
|
||||
{
|
||||
$bookings = Booking::whereMonth('created_at', 7)
|
||||
->whereYear('created_at', 2021)
|
||||
->whereDoesntHave('transactions', function($q){
|
||||
$q->where('type', TransactionType::PURCHASE_ORDER);
|
||||
$q->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED]);
|
||||
})->get();
|
||||
foreach ($bookings as $booking) {
|
||||
$po = Transaction::where('type', TransactionType::PURCHASE_ORDER)
|
||||
->where('status', ApprovalStatus::APPROVED)->where('issuer', $booking->company_id)
|
||||
->select('*', DB::raw('abs(amount - ' . $booking->fix_amount . ') as nearest_price'))->orderBy('nearest_price')->first();
|
||||
|
||||
|
||||
if (!$po) {
|
||||
$po = Transaction::where('type', TransactionType::PURCHASE_ORDER)
|
||||
->where('status', ApprovalStatus::APPROVED)->select('*', DB::raw('abs(amount - ' . $booking->fix_amount . ') as nearest_price'))->orderBy('nearest_price')->first();
|
||||
}
|
||||
|
||||
$products = $this->generatesPurchaseOrderProducts->execute($po, $booking->fix_amount);
|
||||
|
||||
$deference = $booking->fix_amount - $products->sum('total');
|
||||
|
||||
if($deference > -150 && $deference < 150 && $deference != 0) {
|
||||
|
||||
$products->push([
|
||||
'description' => $deference < 0 ? 'Discount':'Shipping Fee',
|
||||
'quantity' => 1,
|
||||
'stockCode' => '',
|
||||
'total' => $deference,
|
||||
'unit_price' => $deference
|
||||
]);
|
||||
}
|
||||
|
||||
$billNumber = $this->generatesTransactionBillNumber->execute('XPO-');
|
||||
|
||||
$total = $products->sum('total');
|
||||
|
||||
$object = new TransactionObject($billNumber, TransactionType::PURCHASE_ORDER, $booking->company->id, 1,
|
||||
1, PaymentMethodType::CASH,
|
||||
$total, $total, $booking->fix_currency_id, $booking->fix_currency_id,
|
||||
1, 0, 0, null, ApprovalStatus::PENDING_SUBMISSION, $products->toArray());
|
||||
|
||||
$this->createPurchaseOrderTransactionProcessor->execute($booking, $object);
|
||||
}
|
||||
|
||||
return $this->response([]);
|
||||
}
|
||||
}
|
||||
@@ -99,7 +99,7 @@ class CreateBookingPaymentLogic extends AbstractControllerLogic
|
||||
$billNumber = $this->generatesTransactionBillNumber->execute('PYMT-');
|
||||
|
||||
if(PaymentMethodType::PAYMENT_METHODS[$request->input('payment_method')] == PaymentMethodType::PAYMENT_GATEWAY){
|
||||
$billPlzBill = $this->createsBillplzBill->execute($request->user()->name, $request->user()->email, 'This payment is made on behave '.$booking->company->name, $configurations->getTotal(), $billNumber, $request->input('bank_code'));
|
||||
$billPlzBill = $this->createsBillplzBill->execute($request->user()->name, $request->user()->email, 'This payment is made for transfer ref. '.$booking->marking, $configurations->getTotal(), $billNumber, $request->input('bank_code'));
|
||||
}
|
||||
|
||||
$object = new TransactionObject($billNumber, TransactionType::PAYMENT, 1, $booking->company->id,
|
||||
@@ -109,7 +109,7 @@ class CreateBookingPaymentLogic extends AbstractControllerLogic
|
||||
$configurations->getTax(), $configurations->getServiceCharge(), Carbon::now()->addMinutes($paymentAttemptLimit), ApprovalStatus::PENDING_SUBMISSION, [], isset($billPlzBill) ? $billPlzBill->id : NULL);
|
||||
|
||||
$transaction = $this->createsTransaction->execute($booking, $object);
|
||||
|
||||
|
||||
return $this->resourceResponse(new TransactionResource($transaction));
|
||||
}
|
||||
|
||||
|
||||
@@ -3,21 +3,22 @@
|
||||
namespace App\Classes\Modules\Bookings\ControllersLogic;
|
||||
|
||||
|
||||
use App\Models\Booking;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use App\Http\Resources\TransactionResource;
|
||||
use App\Classes\Exceptions\MalformedRequestException;
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Bookings\Services\FetchesBookingQuotation;
|
||||
use App\Classes\Modules\Transactions\Services\FetchesTransaction;
|
||||
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
|
||||
use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject;
|
||||
use App\Classes\Modules\Transactions\DataTransferObjects\TransactionRefundCalculationObject;
|
||||
use App\Classes\Modules\Transactions\Services\CreatesTransaction;
|
||||
use App\Classes\Modules\Transactions\Services\GeneratesTransactionBillNumber;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Http\Resources\TransactionResource;
|
||||
use App\Models\Booking;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Transactions\Services\CreatesTransaction;
|
||||
use App\Classes\Modules\Transactions\Services\FetchesTransaction;
|
||||
use App\Classes\Modules\Bookings\Services\FetchesBookingQuotation;
|
||||
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
|
||||
use App\Classes\Modules\Bookings\Services\CalculatesBookingRefundAmount;
|
||||
use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject;
|
||||
use App\Classes\Modules\Transactions\Services\GeneratesTransactionBillNumber;
|
||||
use App\Classes\Modules\Transactions\DataTransferObjects\TransactionRefundCalculationObject;
|
||||
|
||||
class CreateBookingRefundLogic extends AbstractControllerLogic
|
||||
{
|
||||
@@ -47,6 +48,9 @@ class CreateBookingRefundLogic extends AbstractControllerLogic
|
||||
/** @var CreatesTransaction */
|
||||
private $createsTransaction;
|
||||
|
||||
/** @var CalculatesBookingRefundAmount */
|
||||
private $calculatesBookingRefundAmount;
|
||||
|
||||
/**
|
||||
* CreateBookingPaymentLogic constructor.
|
||||
* @param FetchesBookingQuotation $fetchBookingQuotation
|
||||
@@ -54,14 +58,16 @@ class CreateBookingRefundLogic extends AbstractControllerLogic
|
||||
* @param UpdatesTransactionStatus $updatesTransactionStatus
|
||||
* @param GeneratesTransactionBillNumber $generatesTransactionBillNumber
|
||||
* @param CreatesTransaction $createsTransaction
|
||||
* @param CalculatesBookingRefundAmount $calculatesBookingRefundAmount
|
||||
*/
|
||||
public function __construct(FetchesBookingQuotation $fetchBookingQuotation, FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CreatesTransaction $createsTransaction)
|
||||
public function __construct(FetchesBookingQuotation $fetchBookingQuotation, FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CreatesTransaction $createsTransaction, CalculatesBookingRefundAmount $calculatesBookingRefundAmount)
|
||||
{
|
||||
$this->fetchBookingQuotation = $fetchBookingQuotation;
|
||||
$this->fetchesTransaction = $fetchesTransaction;
|
||||
$this->updatesTransactionStatus = $updatesTransactionStatus;
|
||||
$this->generatesTransactionBillNumber = $generatesTransactionBillNumber;
|
||||
$this->createsTransaction = $createsTransaction;
|
||||
$this->calculatesBookingRefundAmount = $calculatesBookingRefundAmount;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -82,6 +88,11 @@ class CreateBookingRefundLogic extends AbstractControllerLogic
|
||||
$customerBooking = $booking->transactions()->payments()->complete()->where('original_amount', '=', $transaction->original_amount)->where('id', '<', $transaction->id)->orderByDesc('id')->first();
|
||||
}
|
||||
|
||||
$refund = $this->calculatesBookingRefundAmount->execute($booking, $booking->fix_currency_id, $transaction->bill_no);
|
||||
dd($refund);
|
||||
|
||||
if($refund + $request->input('amount') > $transaction->original_amount) throw new MalformedRequestException('Your refund must not be greater than '. $transaction->original_amount .'.');
|
||||
|
||||
$transactionRefundCalculationObject = new TransactionRefundCalculationObject($booking, (int) $transaction->type === TransactionType::BILL ? $customerBooking : $transaction, $request->input('amount'));
|
||||
$transactionRefundCalculationObject->init();
|
||||
|
||||
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Bookings\ControllersLogic;
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Bookings\Services\FetchesBooking;
|
||||
use App\Classes\Modules\Bookings\Standards\Rules\CanFetchBooking;
|
||||
use App\Classes\Modules\Transactions\Processors\CreateProformaInvoiceTransactionProcessor;
|
||||
use App\Http\Resources\BookingResource;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class CreateProformaInvoiceTransactionLogic extends AbstractControllerLogic
|
||||
{
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function notification():array {
|
||||
return [
|
||||
'title' => 'Create Proforma Invoice Transaction',
|
||||
'message' => 'You have successfully create proforma invoice transaction'
|
||||
];
|
||||
}
|
||||
|
||||
/** @var CanFetchBooking */
|
||||
private $canFetchBooking;
|
||||
|
||||
/** @var FetchesBooking */
|
||||
private $fetchesBooking;
|
||||
|
||||
/** @var CreateProformaInvoiceTransactionProcessor */
|
||||
private $CreateProformaInvoiceTransactionProcessor;
|
||||
|
||||
/**
|
||||
* FetchBookingLogic constructor.
|
||||
* @param CanFetchBooking $canFetchBooking
|
||||
* @param FetchesBooking $fetchesBooking
|
||||
* @param CreateProformaInvoiceTransactionProcessor $CreateProformaInvoiceTransactionProcessor
|
||||
*/
|
||||
public function __construct(
|
||||
CanFetchBooking $canFetchBooking,
|
||||
FetchesBooking $fetchesBooking,
|
||||
CreateProformaInvoiceTransactionProcessor $CreateProformaInvoiceTransactionProcessor
|
||||
)
|
||||
{
|
||||
$this->canFetchBooking = $canFetchBooking;
|
||||
$this->fetchesBooking = $fetchesBooking;
|
||||
$this->CreateProformaInvoiceTransactionProcessor = $CreateProformaInvoiceTransactionProcessor;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @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')]);
|
||||
|
||||
$this->CreateProformaInvoiceTransactionProcessor->execute($booking);
|
||||
|
||||
return $this->resourceResponse(new BookingResource($booking));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Bookings\ControllersLogic;
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Bookings\Services\FetchesBooking;
|
||||
use App\Classes\Modules\Bookings\Standards\Rules\CanFetchBooking;
|
||||
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\Http\Resources\BookingResource;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
|
||||
class RegenerateInvoiceBookingLogic extends AbstractControllerLogic
|
||||
{
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function notification():array {
|
||||
return [
|
||||
'title' => 'Regenerate Booking Invoice',
|
||||
'message' => 'You have successfully regenerate booking invoice'
|
||||
];
|
||||
}
|
||||
|
||||
/** @var CanFetchBooking */
|
||||
private $canFetchBooking;
|
||||
|
||||
/** @var FetchesBooking */
|
||||
private $fetchesBooking;
|
||||
|
||||
/** @var DeletesTransaction */
|
||||
private $deletesTransaction;
|
||||
|
||||
/** @var UpdatesBookingStatus */
|
||||
private $updatesBookingStatus;
|
||||
|
||||
/** @var DeletesDocument */
|
||||
private $deletesDocument;
|
||||
|
||||
/** @var CreateInvoiceTransactionProcessor */
|
||||
private $createInvoiceTransactionProcessor;
|
||||
|
||||
/**
|
||||
* FetchBookingLogic constructor.
|
||||
* @param CanFetchBooking $canFetchBooking
|
||||
* @param FetchesBooking $fetchesBooking
|
||||
* @param DeletesTransaction $deletesTransaction
|
||||
* @param UpdatesBookingStatus $updatesBookingStatus
|
||||
* @param DeletesDocument $deletesDocument
|
||||
* @param CreateInvoiceTransactionProcessor $createInvoiceTransactionProcessor
|
||||
*/
|
||||
public function __construct(
|
||||
CanFetchBooking $canFetchBooking,
|
||||
FetchesBooking $fetchesBooking,
|
||||
DeletesTransaction $deletesTransaction,
|
||||
UpdatesBookingStatus $updatesBookingStatus,
|
||||
DeletesDocument $deletesDocument,
|
||||
CreateInvoiceTransactionProcessor $createInvoiceTransactionProcessor
|
||||
)
|
||||
{
|
||||
$this->canFetchBooking = $canFetchBooking;
|
||||
$this->fetchesBooking = $fetchesBooking;
|
||||
$this->deletesTransaction = $deletesTransaction;
|
||||
$this->updatesBookingStatus = $updatesBookingStatus;
|
||||
$this->deletesDocument = $deletesDocument;
|
||||
$this->createInvoiceTransactionProcessor = $createInvoiceTransactionProcessor;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
* @throws \App\Classes\Exceptions\AccessForbiddenException
|
||||
* @throws \App\Classes\Exceptions\RequestValidationException
|
||||
*/
|
||||
public function logic(Request $request) : JsonResponse
|
||||
{
|
||||
$this->canFetchBooking->passes();
|
||||
|
||||
$booking = $this->fetchesBooking->execute([
|
||||
'id' => $request->route('id'),
|
||||
'status' => ApprovalStatus::COMPLETED,
|
||||
'with_transactions' => true]
|
||||
);
|
||||
|
||||
$this->updatesBookingStatus->execute($booking, ApprovalStatus::APPROVED);
|
||||
|
||||
$transaction = $booking->transactions()->whereIn('type', [TransactionType::INVOICE, TransactionType::SUPPLIER_DELIVER])->get();
|
||||
foreach ($transaction as $key => $row) {
|
||||
$this->deletesTransaction->execute($row);
|
||||
}
|
||||
|
||||
$document = $booking->documents()->get();
|
||||
foreach ($document as $key => $row) {
|
||||
$this->deletesDocument->execute($row);
|
||||
}
|
||||
|
||||
$this->createInvoiceTransactionProcessor->execute($booking);
|
||||
|
||||
return $this->resourceResponse(new BookingResource($booking));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Bookings\ControllersLogic;
|
||||
|
||||
use App\Classes\Modules\Bookings\Services\UpdatesBookingFixedAmount;
|
||||
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Http\Resources\BookingResource;
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
|
||||
use App\Classes\Modules\Bookings\Services\FetchesBooking;
|
||||
|
||||
use App\Classes\Modules\Bookings\Standards\Rules\CanUpdateBooking;
|
||||
use App\Classes\Modules\Bookings\DataTransferObjects\BookingObject;
|
||||
use App\Classes\Modules\Bookings\Services\CalculatesBookingOutstanding;
|
||||
|
||||
use ErrorException;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use App\Classes\Exceptions\MalformedRequestException;
|
||||
|
||||
class UpdateBookingAmountLogic extends AbstractControllerLogic
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function notification():array {
|
||||
return [
|
||||
'title' => 'Updated Booking',
|
||||
'message' => 'You have successfully updated the Booking'
|
||||
];
|
||||
}
|
||||
|
||||
/** @var CanUpdateBooking */
|
||||
private $canUpdateBooking;
|
||||
|
||||
/** @var UpdatesBookingFixedAmount */
|
||||
private $updatesBookingFixedAmount;
|
||||
|
||||
/** @var FetchesBooking */
|
||||
private $fetchesBooking;
|
||||
|
||||
/** @var CalculatesBookingOutstanding */
|
||||
private $calculatesBookingOutstanding;
|
||||
|
||||
/** @var UpdatesTransactionStatus */
|
||||
private $updatesTransactionStatus;
|
||||
|
||||
/**
|
||||
* UpdateBookingAmountLogic constructor.
|
||||
* @param CanUpdateBooking $canUpdateBooking
|
||||
* @param UpdatesBookingFixedAmount $updatesBookingFixedAmount
|
||||
* @param FetchesBooking $fetchesBooking
|
||||
* @param CalculatesBookingOutstanding $calculatesBookingOutstanding
|
||||
* @param UpdatesTransactionStatus $updatesTransactionStatus
|
||||
*/
|
||||
public function __construct(CanUpdateBooking $canUpdateBooking, UpdatesBookingFixedAmount $updatesBookingFixedAmount, FetchesBooking $fetchesBooking, CalculatesBookingOutstanding $calculatesBookingOutstanding, UpdatesTransactionStatus $updatesTransactionStatus)
|
||||
{
|
||||
$this->canUpdateBooking = $canUpdateBooking;
|
||||
$this->updatesBookingFixedAmount = $updatesBookingFixedAmount;
|
||||
$this->fetchesBooking = $fetchesBooking;
|
||||
$this->calculatesBookingOutstanding = $calculatesBookingOutstanding;
|
||||
$this->updatesTransactionStatus = $updatesTransactionStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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('fix_amount', $booking->fix_amount))), 5, '.', '');
|
||||
|
||||
$minimum_amount = $booking->fix_amount - $this->calculatesBookingOutstanding->execute($booking);
|
||||
|
||||
if ((float)$input_amount < $minimum_amount) {
|
||||
throw new MalformedRequestException('Booking Amount cannot be less than '. $minimum_amount .'.');
|
||||
}
|
||||
|
||||
$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));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,8 +11,10 @@ use Carbon\Carbon;
|
||||
class CalculatesBookingRefundAmount
|
||||
{
|
||||
|
||||
public function execute(Booking $booking){
|
||||
return $booking->transactions()->refunds()->complete()->sum('original_amount');
|
||||
public function execute(Booking $booking, int $type, ?string $payment_reference = NULL){
|
||||
return $type === 1 ?
|
||||
$booking->transactions()->refunds($payment_reference)
|
||||
->selectRaw('sum(amount - service_charge - tax) as sub_total')->get()->sum('sub_total') : $booking->transactions()->refunds($payment_reference)->sum('original_amount');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -12,7 +12,7 @@ class CalculatesBookingTransferredAmount
|
||||
{
|
||||
|
||||
public function execute(Booking $booking){
|
||||
return $booking->transactions()->bills()->transferred()->sum('original_amount');
|
||||
return $booking->transactions()->bills()->complete()->sum('original_amount');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -17,8 +17,8 @@ class UpdatesBooking extends AbstractUpdateRecord
|
||||
*/
|
||||
public function execute(Booking $model, BookingObject $object)
|
||||
{
|
||||
$model->transferable_bank_id = $object->getTransferableBankId();
|
||||
$model->reference = $object->getReference();
|
||||
$model->bank_id = $object->getTransferableBankId();
|
||||
$model->marking = $object->getMarking();
|
||||
$model->fix_amount = $object->getFixAmount();
|
||||
$model->fix_currency_id = $object->getFixCurrencyId();
|
||||
$model->convertible_currency_id = $object->getConvertibleCurrencyId();
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Bookings\Services;
|
||||
|
||||
use App\Classes\General\Eloquent\AbstractUpdateRecord;
|
||||
use App\Classes\Modules\Bookings\DataTransferObjects\BookingObject;
|
||||
use App\Models\Booking;
|
||||
|
||||
class UpdatesBookingFixedAmount extends AbstractUpdateRecord
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Booking $model
|
||||
* @param float $fixedAmount
|
||||
* @return \Illuminate\Database\Eloquent\Model
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
*/
|
||||
public function execute(Booking $model, float $fixedAmount)
|
||||
{
|
||||
$model->fix_amount = $fixedAmount;
|
||||
return $this->handler($model);
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ namespace App\Classes\Modules\Bookings\Standards\Rules;
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractRule;
|
||||
use App\Classes\Modules\Bookings\DataTransferObjects\BookingObject;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class CanDeleteBooking extends AbstractRule
|
||||
{
|
||||
@@ -14,7 +15,7 @@ class CanDeleteBooking extends AbstractRule
|
||||
{
|
||||
// TODO Set Authorization rules
|
||||
|
||||
if (!\Auth::user()->can('delete booking')) {
|
||||
if (!Auth::user()->can('delete booking')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace App\Classes\Modules\Bookings\Standards\Rules;
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractRule;
|
||||
use App\Classes\Modules\Bookings\Standards\Validators\BookingValidation;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class CanUpdateBooking extends AbstractRule
|
||||
{
|
||||
@@ -29,7 +30,7 @@ class CanUpdateBooking extends AbstractRule
|
||||
{
|
||||
// TODO Set Authorization rules
|
||||
|
||||
if (!\Auth::user()->can('edit booking')) {
|
||||
if (!Auth::user()->can('edit booking')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace App\Classes\Modules\Currencies\Standards\Rules\Rates;
|
||||
use App\Classes\General\Abstracts\AbstractRule;
|
||||
use App\Classes\Modules\Currencies\Standards\Validators\Rates\RateValidation;
|
||||
use App\Classes\Modules\Currencies\DataTransferObjects\RateObject;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class CanCreateRate extends AbstractRule
|
||||
{
|
||||
@@ -27,7 +28,7 @@ class CanCreateRate extends AbstractRule
|
||||
protected function authorized(): bool
|
||||
{
|
||||
// TODO Set Authorization rules
|
||||
if (!\Auth::user()->can('add currency_rate')) {
|
||||
if (!Auth::user()->can('add currency_rate')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Classes\Modules\Currencies\Standards\Rules\Rates;
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractRule;
|
||||
use App\Classes\Modules\Currencies\DataTransferObjects\RateObject;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class CanDeleteRate extends AbstractRule
|
||||
{
|
||||
@@ -14,7 +15,7 @@ class CanDeleteRate extends AbstractRule
|
||||
{
|
||||
// TODO Set Authorization rules
|
||||
|
||||
if (!\Auth::user()->can('delete currency_rate')) {
|
||||
if (!Auth::user()->can('delete currency_rate')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Classes\Modules\Currencies\Standards\Rules\Rates;
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractRule;
|
||||
use App\Classes\Modules\Currencies\DataTransferObjects\CurrencyObject;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class CanListRates extends AbstractRule
|
||||
{
|
||||
@@ -14,7 +15,7 @@ class CanListRates extends AbstractRule
|
||||
{
|
||||
// TODO Set Authorization rules
|
||||
|
||||
if (!\Auth::user()->can('view currency_rate')) {
|
||||
if (!Auth::user()->can('view currency_rate')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ namespace App\Classes\Modules\Currencies\Standards\Rules\Rates;
|
||||
use App\Classes\General\Abstracts\AbstractRule;
|
||||
use App\Classes\Modules\Currencies\Standards\Validators\Rates\RateValidation;
|
||||
use App\Classes\Modules\Currencies\DataTransferObjects\RateObject;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class CanUpdateRate extends AbstractRule
|
||||
{
|
||||
@@ -29,7 +30,7 @@ class CanUpdateRate extends AbstractRule
|
||||
{
|
||||
// TODO Set Authorization rules
|
||||
|
||||
if (!\Auth::user()->can('view currency_rate')) {
|
||||
if (!Auth::user()->can('view currency_rate')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Documents\Services;
|
||||
|
||||
use App\Classes\General\Eloquent\AbstractDeleteRecord;
|
||||
use App\Models\Document;
|
||||
|
||||
class DeletesDocument extends AbstractDeleteRecord
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Document $model
|
||||
* @return mixed
|
||||
*/
|
||||
public function execute(Document $model) {
|
||||
return $this->handler($model);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Exports\Services;
|
||||
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\BusinessType;
|
||||
use App\Classes\ValueObjects\Constants\CompanyType;
|
||||
use App\Models\Company;
|
||||
use Maatwebsite\Excel\Concerns\Exportable;
|
||||
use Maatwebsite\Excel\Concerns\FromQuery;
|
||||
use Maatwebsite\Excel\Concerns\WithHeadingRow;
|
||||
use Maatwebsite\Excel\Concerns\WithMapping;
|
||||
|
||||
class ExportsProducts implements FromQuery, WithHeadingRow, WithMapping
|
||||
{
|
||||
|
||||
use Exportable;
|
||||
|
||||
public function headings(): array
|
||||
{
|
||||
return [
|
||||
'HS Code',
|
||||
'Name',
|
||||
'price'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Support\Collection|mixed
|
||||
*/
|
||||
public function query()
|
||||
{
|
||||
return \App\Models\TransactionDetail::inRandomOrder()->whereHas('transaction', function($query){
|
||||
return $query->where('type', \App\Classes\ValueObjects\Constants\TransactionType::PURCHASE_ORDER)->where('status', ApprovalStatus::APPROVED);
|
||||
})->limit(50);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $product
|
||||
* @return array
|
||||
*/
|
||||
public function map($product): array
|
||||
{
|
||||
|
||||
return [
|
||||
$product->product_code,
|
||||
$product->product_name,
|
||||
$product->price,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -36,7 +36,7 @@ class ExportsTransactions implements FromQuery, WithHeadingRow, WithMapping
|
||||
1 => 'PAYMENT',
|
||||
2 => 'INVOICE',
|
||||
3 => 'BILL',
|
||||
4 => 'PERFORMA',
|
||||
4 => 'PROFORMA',
|
||||
5 => 'TOP_UP',
|
||||
6 => 'REFUND',
|
||||
7 => 'PURCHASE_ORDER',
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace App\Classes\Modules\Segments\Standards\Rules;
|
||||
use App\Classes\General\Abstracts\AbstractRule;
|
||||
use App\Classes\Modules\Segments\DataTransferObjects\SegmentObject;
|
||||
use App\Classes\Modules\Segments\Standards\Validators\SegmentValidation;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class CanCreateSegment extends AbstractRule
|
||||
{
|
||||
@@ -27,7 +28,7 @@ class CanCreateSegment extends AbstractRule
|
||||
protected function authorized(): bool
|
||||
{
|
||||
// TODO Set Authorization rules
|
||||
if (!\Auth::user()->can('add segment')) {
|
||||
if (!Auth::user()->can('add segment')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Classes\Modules\Segments\Standards\Rules;
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractRule;
|
||||
use App\Classes\Modules\Segments\DataTransferObjects\SegmentObject;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class CanDeleteSegment extends AbstractRule
|
||||
{
|
||||
@@ -14,7 +15,7 @@ class CanDeleteSegment extends AbstractRule
|
||||
{
|
||||
// TODO Set Authorization rules
|
||||
|
||||
if (!\Auth::user()->can('delete segment')) {
|
||||
if (!Auth::user()->can('delete segment')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ namespace App\Classes\Modules\Segments\Standards\Rules;
|
||||
use App\Classes\General\Abstracts\AbstractRule;
|
||||
use App\Classes\Modules\Segments\DataTransferObjects\SegmentObject;
|
||||
use App\Classes\Modules\Segments\Standards\Validators\SegmentValidation;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class CanUpdateSegment extends AbstractRule
|
||||
{
|
||||
@@ -30,7 +31,7 @@ class CanUpdateSegment extends AbstractRule
|
||||
{
|
||||
// TODO Set Authorization rules
|
||||
|
||||
if (!\Auth::user()->can('edit segment')) {
|
||||
if (!Auth::user()->can('edit segment')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
+20
-48
@@ -7,6 +7,7 @@ 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\TransactionObject;
|
||||
use App\Classes\Modules\Transactions\Processors\CreatePurchaseOrderTransactionProcessor;
|
||||
use App\Classes\Modules\Transactions\Services\CreatesTransaction;
|
||||
use App\Classes\Modules\Transactions\Services\CreatesTransactionDetail;
|
||||
use App\Classes\Modules\Transactions\Services\DeletesTransactionDetails;
|
||||
@@ -25,26 +26,6 @@ use Illuminate\Http\Request;
|
||||
|
||||
class CreatePurchaseOrderTransactionLogic extends AbstractControllerLogic
|
||||
{
|
||||
/**
|
||||
* CreatePurchaseOrderTransactionLogic constructor.
|
||||
* @param FetchesBooking $fetchesBooking
|
||||
* @param UpdatesTransactionStatus $updatesTransactionStatus
|
||||
* @param CreatesTransaction $createsTransaction
|
||||
* @param CreatesTransactionDetail $createsTransactionDetail
|
||||
* @param UpdatesTransaction $updatesTransaction
|
||||
* @param DeletesTransactionDetails $deletesTransactionDetails
|
||||
* @param GeneratesTransactionBillNumber $generatesTransactionBillNumber
|
||||
*/
|
||||
public function __construct(FetchesBooking $fetchesBooking, UpdatesTransactionStatus $updatesTransactionStatus, CreatesTransaction $createsTransaction, CreatesTransactionDetail $createsTransactionDetail, UpdatesTransaction $updatesTransaction, DeletesTransactionDetails $deletesTransactionDetails, GeneratesTransactionBillNumber $generatesTransactionBillNumber)
|
||||
{
|
||||
$this->fetchesBooking = $fetchesBooking;
|
||||
$this->updatesTransactionStatus = $updatesTransactionStatus;
|
||||
$this->createsTransaction = $createsTransaction;
|
||||
$this->createsTransactionDetail = $createsTransactionDetail;
|
||||
$this->updatesTransaction = $updatesTransaction;
|
||||
$this->deletesTransactionDetails = $deletesTransactionDetails;
|
||||
$this->generatesTransactionBillNumber = $generatesTransactionBillNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
@@ -59,37 +40,35 @@ class CreatePurchaseOrderTransactionLogic extends AbstractControllerLogic
|
||||
/** @var FetchesBooking */
|
||||
private $fetchesBooking;
|
||||
|
||||
/** @var UpdatesTransactionStatus */
|
||||
private $updatesTransactionStatus;
|
||||
|
||||
/** @var CreatesTransaction */
|
||||
private $createsTransaction;
|
||||
|
||||
/** @var CreatesTransactionDetail */
|
||||
private $createsTransactionDetail;
|
||||
|
||||
/** @var UpdatesTransaction */
|
||||
private $updatesTransaction;
|
||||
|
||||
/** @var DeletesTransactionDetails */
|
||||
private $deletesTransactionDetails;
|
||||
|
||||
/** @var GeneratesTransactionBillNumber */
|
||||
private $generatesTransactionBillNumber;
|
||||
|
||||
/** @var CreatePurchaseOrderTransactionProcessor */
|
||||
private $createPurchaseOrderTransactionProcessor;
|
||||
|
||||
/**
|
||||
* CreatePurchaseOrderTransactionLogic constructor.
|
||||
* @param FetchesBooking $fetchesBooking
|
||||
* @param GeneratesTransactionBillNumber $generatesTransactionBillNumber
|
||||
* @param CreatePurchaseOrderTransactionProcessor $createPurchaseOrderTransactionProcessor
|
||||
*/
|
||||
public function __construct(FetchesBooking $fetchesBooking, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CreatePurchaseOrderTransactionProcessor $createPurchaseOrderTransactionProcessor)
|
||||
{
|
||||
$this->fetchesBooking = $fetchesBooking;
|
||||
$this->generatesTransactionBillNumber = $generatesTransactionBillNumber;
|
||||
$this->createPurchaseOrderTransactionProcessor = $createPurchaseOrderTransactionProcessor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param string $id
|
||||
* @return JsonResponse
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
*/
|
||||
public function logic(Request $request) : JsonResponse
|
||||
public function logic(Request $request, $id = '') : JsonResponse
|
||||
{
|
||||
/** @var Booking $booking */
|
||||
$booking = $this->fetchesBooking->execute(['id' => $request->route('id')]);
|
||||
|
||||
/** @var Transaction $transaction */
|
||||
$transaction = $booking->transactions()->where('type', TransactionType::PURCHASE_ORDER)->first();
|
||||
$booking = $this->fetchesBooking->execute(['id' => $request->route('id') ?? $id]);
|
||||
|
||||
$billNumber = $this->generatesTransactionBillNumber->execute('PO-');
|
||||
|
||||
@@ -102,15 +81,8 @@ class CreatePurchaseOrderTransactionLogic extends AbstractControllerLogic
|
||||
$total, $total, $booking->fix_currency_id, $booking->fix_currency_id,
|
||||
1, 0, 0, null, ApprovalStatus::PENDING_SUBMISSION, $request->input('products'));
|
||||
|
||||
!$transaction ? $transaction = $this->createsTransaction->execute($booking, $object) : $transaction = $this->updatesTransaction->execute($transaction, $object);
|
||||
|
||||
$this->updatesTransactionStatus->execute($transaction, (float) number_format($total, 2, '.', '') === (float) number_format((float)$booking->fix_amount, 2, '.', '') ? ApprovalStatus::PENDING_VERIFICATION : ApprovalStatus::PENDING_SUBMISSION);
|
||||
|
||||
$this->deletesTransactionDetails->execute($transaction);
|
||||
|
||||
foreach ($object->getDetails() as $product){
|
||||
$this->createsTransactionDetail->execute($transaction, $product);
|
||||
}
|
||||
$transaction = $this->createPurchaseOrderTransactionProcessor->execute($booking, $object);
|
||||
|
||||
return $this->resourceResponse(new TransactionResource($transaction));
|
||||
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Transactions\ControllersLogic;
|
||||
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Transactions\Services\FetchesTransaction;
|
||||
use App\Classes\Modules\Transactions\Services\DeletesTransaction;
|
||||
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\CompanyType;
|
||||
use App\Classes\ValueObjects\Constants\DocumentType;
|
||||
use App\Models\Company;
|
||||
use App\Models\Document;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
use App\Classes\Modules\Transactions\Processors\CreateInvoiceTransactionProcessor;
|
||||
|
||||
|
||||
class DeleteTransactionLogic extends AbstractControllerLogic
|
||||
{
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function notification():array {
|
||||
return [
|
||||
'title' => 'Deleted Transaction',
|
||||
'message' => 'You have successfully deleted a transaction'
|
||||
];
|
||||
}
|
||||
|
||||
/** @var FetchesTransaction */
|
||||
private $fetchesTransaction;
|
||||
|
||||
/** @var DeletesTransaction */
|
||||
private $deletesTransaction;
|
||||
|
||||
/** @var UpdatesTransactionStatus */
|
||||
private $updatesTransactionStatus;
|
||||
|
||||
/**
|
||||
* CreatePaymentVerificationDocumentLogic constructor.
|
||||
* @param FetchesTransaction $fetchesTransaction
|
||||
* @param DeletesTransaction $deletesTransaction
|
||||
*/
|
||||
public function __construct(FetchesTransaction $fetchesTransaction, DeletesTransaction $deletesTransaction, UpdatesTransactionStatus $updatesTransactionStatus)
|
||||
{
|
||||
$this->fetchesTransaction = $fetchesTransaction;
|
||||
$this->deletesTransaction = $deletesTransaction;
|
||||
$this->updatesTransactionStatus = $updatesTransactionStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
*/
|
||||
public function logic(Request $request) : JsonResponse
|
||||
{
|
||||
$transaction = $this->fetchesTransaction->execute(['id' => $request->route('id')]);
|
||||
|
||||
$this->deletesTransaction->execute($transaction);
|
||||
|
||||
$payment_transaction = $transaction->booking->transactions()->payments()->complete()->where('original_amount', '=', $transaction->original_amount)->where('id', '<', $transaction->id)->orderByDesc('id')->first();
|
||||
|
||||
$this->updatesTransactionStatus->execute($payment_transaction, ApprovalStatus::APPROVED);
|
||||
|
||||
return $this->response([]);
|
||||
}
|
||||
}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Transactions\ControllersLogic;
|
||||
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Transactions\Services\FetchesTransaction;
|
||||
use App\Classes\Modules\Transactions\Services\DeletesTransaction;
|
||||
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\Modules\Documents\Services\DeletesDocument;
|
||||
use App\Models\Company;
|
||||
use App\Models\Document;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
use App\Classes\Modules\Transactions\Processors\CreateInvoiceTransactionProcessor;
|
||||
|
||||
|
||||
class UpdatePaymentTransactionStatusLogic extends AbstractControllerLogic
|
||||
{
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function notification():array {
|
||||
return [
|
||||
'title' => 'Updated Transaction',
|
||||
'message' => 'You have successfully updated a transaction'
|
||||
];
|
||||
}
|
||||
|
||||
/** @var FetchesTransaction */
|
||||
private $fetchesTransaction;
|
||||
|
||||
/** @var UpdatesTransactionStatus */
|
||||
private $updatesTransactionStatus;
|
||||
|
||||
/** @var DeletesDocument */
|
||||
private $deletesDocument;
|
||||
|
||||
/**
|
||||
* CreatePaymentVerificationDocumentLogic constructor.
|
||||
* @param FetchesTransaction $fetchesTransaction
|
||||
* @param UpdatesTransactionStatus $updatesTransactionStatus
|
||||
* @param DeletesDocument $deletesDocument
|
||||
*/
|
||||
public function __construct(FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus, DeletesDocument $deletesDocument)
|
||||
{
|
||||
$this->fetchesTransaction = $fetchesTransaction;
|
||||
$this->updatesTransactionStatus = $updatesTransactionStatus;
|
||||
$this->deletesDocument = $deletesDocument;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
*/
|
||||
public function logic(Request $request) : JsonResponse
|
||||
{
|
||||
$transaction = $this->fetchesTransaction->execute(['id' => $request->route('id')]);
|
||||
$status = $request->route('status');
|
||||
|
||||
$this->updatesTransactionStatus->execute($transaction, $status === 'pending' ? ApprovalStatus::PENDING_VERIFICATION : ApprovalStatus::COMPLETED);
|
||||
|
||||
if ($status == 'pending') {
|
||||
$document = $transaction->documents()->first();
|
||||
if ($document) {
|
||||
$this->deletesDocument->execute($document);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->response([]);
|
||||
}
|
||||
}
|
||||
@@ -115,7 +115,6 @@ class CreateInvoiceTransactionProcessor
|
||||
if ((float) $booking_amount > (float) $payable_amount) {
|
||||
return;
|
||||
}
|
||||
|
||||
// confirm that all payments has been transferred
|
||||
if($this->calculatesBookingTransferredAmount->execute($booking) !== $this->calculatesBookingPaidAmount->execute($booking)){
|
||||
return;
|
||||
|
||||
+188
@@ -0,0 +1,188 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Transactions\Processors;
|
||||
|
||||
use App\Classes\Modules\Bookings\Services\CalculatesBookingOutstanding;
|
||||
use App\Classes\Modules\Bookings\Services\CalculatesBookingPayableAmount;
|
||||
use App\Classes\Modules\Bookings\Services\FetchesBookingQuotation;
|
||||
use App\Classes\Modules\Bookings\Services\GeneratesBookingQuotation;
|
||||
use App\Classes\Modules\Companies\Services\FetchesCompanyPaymentAttemptLimit;
|
||||
use App\Classes\Modules\Currencies\DataTransferObjects\CurrencyConversionObject;
|
||||
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\Documents\Services\CreatesDocument;
|
||||
use App\Classes\Modules\Documents\Services\CreatesFiles;
|
||||
|
||||
use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject;
|
||||
use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\PaymentMethodType;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Classes\ValueObjects\Constants\DocumentType;
|
||||
use App\Models\Booking;
|
||||
use App\Models\Document;
|
||||
use Carbon\Carbon;
|
||||
use Meneses\LaravelMpdf\Facades\LaravelMpdf;
|
||||
|
||||
class CreateProformaInvoiceTransactionProcessor
|
||||
{
|
||||
|
||||
/** @var CreatesTransaction */
|
||||
private $createsTransaction;
|
||||
|
||||
/** @var GeneratesTransactionBillNumber */
|
||||
private $generatesTransactionBillNumber;
|
||||
|
||||
|
||||
/** @var CalculatesBookingPayableAmount */
|
||||
private $calculatesBookingPayableAmount;
|
||||
|
||||
/** @var CalculatesBookingCurrencyAverageRate */
|
||||
private $calculatesBookingCurrencyAverageRate;
|
||||
|
||||
/** @var FetchesCompany */
|
||||
private $fetchesCompany;
|
||||
|
||||
/** @var CreatesDocument */
|
||||
private $createsDocument;
|
||||
|
||||
/** @var CreatesFiles */
|
||||
private $createsFile;
|
||||
|
||||
|
||||
/** @var CalculatesBookingOutstanding */
|
||||
private $calculatesBookingOutstanding;
|
||||
|
||||
/** @var GeneratesBookingQuotation */
|
||||
private $generatesBookingQuotation;
|
||||
|
||||
/** @var FetchesBookingQuotation */
|
||||
private $fetchesBookingQuotation;
|
||||
|
||||
/** @var FetchesCompanyPaymentAttemptLimit */
|
||||
private $fetchesCompanyPaymentAttemptLimit;
|
||||
|
||||
|
||||
/**
|
||||
* CreateProformaInvoiceTransactionProcessor constructor.
|
||||
* @param CreatesTransaction $createsTransaction
|
||||
* @param GeneratesTransactionBillNumber $generatesTransactionBillNumber
|
||||
* @param CalculatesBookingPayableAmount $calculatesBookingPayableAmount
|
||||
* @param CalculatesBookingCurrencyAverageRate $calculatesBookingCurrencyAverageRate
|
||||
* @param FetchesCompany $fetchesCompany
|
||||
* @param CreatesDocument $createsDocument
|
||||
* @param CreatesFiles $createsFile
|
||||
* @param CalculatesBookingOutstanding $calculatesBookingOutstanding
|
||||
* @param GeneratesBookingQuotation $generatesBookingQuotation
|
||||
* @param FetchesBookingQuotation $fetchesBookingQuotation
|
||||
* @param FetchesCompanyPaymentAttemptLimit $fetchesCompanyPaymentAttemptLimit
|
||||
*/
|
||||
public function __construct(CreatesTransaction $createsTransaction, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CalculatesBookingPayableAmount $calculatesBookingPayableAmount, CalculatesBookingCurrencyAverageRate $calculatesBookingCurrencyAverageRate, FetchesCompany $fetchesCompany, CreatesDocument $createsDocument, CreatesFiles $createsFile, CalculatesBookingOutstanding $calculatesBookingOutstanding, GeneratesBookingQuotation $generatesBookingQuotation, FetchesBookingQuotation $fetchesBookingQuotation, FetchesCompanyPaymentAttemptLimit $fetchesCompanyPaymentAttemptLimit)
|
||||
{
|
||||
$this->createsTransaction = $createsTransaction;
|
||||
$this->generatesTransactionBillNumber = $generatesTransactionBillNumber;
|
||||
$this->calculatesBookingPayableAmount = $calculatesBookingPayableAmount;
|
||||
$this->calculatesBookingCurrencyAverageRate = $calculatesBookingCurrencyAverageRate;
|
||||
$this->fetchesCompany = $fetchesCompany;
|
||||
$this->createsDocument = $createsDocument;
|
||||
$this->createsFile = $createsFile;
|
||||
$this->calculatesBookingOutstanding = $calculatesBookingOutstanding;
|
||||
$this->generatesBookingQuotation = $generatesBookingQuotation;
|
||||
$this->fetchesBookingQuotation = $fetchesBookingQuotation;
|
||||
$this->fetchesCompanyPaymentAttemptLimit = $fetchesCompanyPaymentAttemptLimit;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Booking $booking
|
||||
* @return void
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
*/
|
||||
public function execute(Booking $booking)
|
||||
{
|
||||
|
||||
$po_order_transaction = $booking->transactions()
|
||||
->where('type', TransactionType::PURCHASE_ORDER)
|
||||
->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED])
|
||||
->first();
|
||||
|
||||
$outstanding = $this->calculatesBookingOutstanding->execute($booking);
|
||||
|
||||
$conversionObject = new CurrencyConversionObject(floatval(str_replace(',', '', $outstanding)), $booking->convertible_currency_id, $booking->service_id, $booking->fix_currency_id === 1 ? 0:1, PaymentMethodType::CASH);
|
||||
|
||||
$configurations = $this->fetchesBookingQuotation->execute($booking->company, $conversionObject);
|
||||
|
||||
$paymentAttemptLimit = $this->fetchesCompanyPaymentAttemptLimit->execute($booking->company);
|
||||
|
||||
$billNumber = $this->generatesTransactionBillNumber->execute('PYMT-');
|
||||
|
||||
|
||||
$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, [], isset($billPlzBill) ? $billPlzBill->id : NULL);
|
||||
|
||||
$this->createsTransaction->execute($booking, $object);
|
||||
|
||||
$billNumber = $this->generatesTransactionBillNumber->execute('PROFORMA-');
|
||||
|
||||
$payable_amount = $booking->transactions()->whereNotIn('status', [ApprovalStatus::REJECTED, ApprovalStatus::SUSPENDED])->payments()->sum('amount');
|
||||
$booking_amount = $booking->fix_amount;
|
||||
|
||||
$transaction = $booking->transactions()
|
||||
->where('type', TransactionType::PAYMENT)
|
||||
->first();
|
||||
|
||||
$booking_currency_average_rate = $booking_amount / $booking->transactions()->whereNotIn('status', [ApprovalStatus::REJECTED, ApprovalStatus::SUSPENDED])->payments()->selectRaw('sum(amount - service_charge - tax) as sub_total')->get()->sum('sub_total');
|
||||
|
||||
$total_service_charge = $booking->transactions()
|
||||
->where('type', TransactionType::PAYMENT)
|
||||
->whereNotIn('status', [ApprovalStatus::REJECTED, ApprovalStatus::SUSPENDED])
|
||||
->sum('service_charge');
|
||||
|
||||
$total_tax = $booking->transactions()
|
||||
->where('type', TransactionType::PAYMENT)
|
||||
->whereIn('status', [ApprovalStatus::REJECTED, ApprovalStatus::SUSPENDED])
|
||||
->sum('tax');
|
||||
|
||||
$transaction_object = new TransactionObject(
|
||||
$billNumber,
|
||||
TransactionType::PROFORMA,
|
||||
$transaction->issuer,
|
||||
$transaction->receiver,
|
||||
$transaction->recipient_bank_account_id,
|
||||
$transaction->payment_method,
|
||||
$payable_amount,
|
||||
$booking_amount,
|
||||
$transaction->currency_id,
|
||||
$transaction->original_currency_id,
|
||||
$booking_currency_average_rate,
|
||||
$total_tax,
|
||||
$total_service_charge,
|
||||
null,
|
||||
ApprovalStatus::APPROVED
|
||||
);
|
||||
|
||||
$perofrma_transaction = $this->createsTransaction->execute($po_order_transaction->booking, $transaction_object);
|
||||
|
||||
$supplier = $this->fetchesCompany->execute(['id' => $transaction->receiver]);
|
||||
|
||||
$purchase_order_pdf = LaravelMpdf::loadView('pages.pdfs.proforma_invoice', ['invoice_transaction' => $perofrma_transaction, 'po_order_transaction' => $po_order_transaction, 'supplier' => $supplier]);
|
||||
$document_object = new DocumentObject(
|
||||
DocumentType::PROFORMA_INVOICE,
|
||||
[chunk_split('data:application/pdf;base64,'.base64_encode($purchase_order_pdf->output()))],
|
||||
'',
|
||||
ApprovalStatus::COMPLETED,
|
||||
'proforma_invoices'
|
||||
);
|
||||
|
||||
/** @var Document $document */
|
||||
$document = $this->createsDocument->execute($po_order_transaction->booking, $document_object);
|
||||
$this->createsFile->execute($document, $document_object);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Transactions\Processors;
|
||||
|
||||
|
||||
use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject;
|
||||
use App\Classes\Modules\Transactions\Services\CreatesTransaction;
|
||||
use App\Classes\Modules\Transactions\Services\CreatesTransactionDetail;
|
||||
use App\Classes\Modules\Transactions\Services\DeletesTransactionDetails;
|
||||
use App\Classes\Modules\Transactions\Services\UpdatesTransaction;
|
||||
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Models\Booking;
|
||||
use App\Models\Transaction;
|
||||
|
||||
class CreatePurchaseOrderTransactionProcessor
|
||||
{
|
||||
|
||||
/** @var UpdatesTransactionStatus */
|
||||
private $updatesTransactionStatus;
|
||||
|
||||
/** @var CreatesTransaction */
|
||||
private $createsTransaction;
|
||||
|
||||
/** @var CreatesTransactionDetail */
|
||||
private $createsTransactionDetail;
|
||||
|
||||
/** @var UpdatesTransaction */
|
||||
private $updatesTransaction;
|
||||
|
||||
/** @var DeletesTransactionDetails */
|
||||
private $deletesTransactionDetails;
|
||||
|
||||
/**
|
||||
* CreatePurchaseOrderTransactionProcessor constructor.
|
||||
* @param UpdatesTransactionStatus $updatesTransactionStatus
|
||||
* @param CreatesTransaction $createsTransaction
|
||||
* @param CreatesTransactionDetail $createsTransactionDetail
|
||||
* @param UpdatesTransaction $updatesTransaction
|
||||
* @param DeletesTransactionDetails $deletesTransactionDetails
|
||||
*/
|
||||
public function __construct(UpdatesTransactionStatus $updatesTransactionStatus, CreatesTransaction $createsTransaction, CreatesTransactionDetail $createsTransactionDetail, UpdatesTransaction $updatesTransaction, DeletesTransactionDetails $deletesTransactionDetails)
|
||||
{
|
||||
$this->updatesTransactionStatus = $updatesTransactionStatus;
|
||||
$this->createsTransaction = $createsTransaction;
|
||||
$this->createsTransactionDetail = $createsTransactionDetail;
|
||||
$this->updatesTransaction = $updatesTransaction;
|
||||
$this->deletesTransactionDetails = $deletesTransactionDetails;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Booking $booking
|
||||
* @param TransactionObject $object
|
||||
* @return Transaction|\Illuminate\Database\Eloquent\Model
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
*/
|
||||
public function execute(Booking $booking, TransactionObject $object){
|
||||
/** @var Transaction $transaction */
|
||||
$transaction = $booking->transactions()->where('type', TransactionType::PURCHASE_ORDER)->first();
|
||||
|
||||
!$transaction ? $transaction = $this->createsTransaction->execute($booking, $object) : $transaction = $this->updatesTransaction->execute($transaction, $object);
|
||||
|
||||
$this->updatesTransactionStatus->execute($transaction, (float) number_format($object->getAmount(), 2, '.', '') === (float) number_format((float)$booking->fix_amount, 2, '.', '') ? ApprovalStatus::PENDING_VERIFICATION : ApprovalStatus::PENDING_SUBMISSION);
|
||||
|
||||
$this->deletesTransactionDetails->execute($transaction);
|
||||
|
||||
foreach ($object->getDetails() as $product){
|
||||
$this->createsTransactionDetail->execute($transaction, $product);
|
||||
}
|
||||
|
||||
return $transaction;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,12 +5,12 @@ namespace App\Classes\Modules\Transactions\Services;
|
||||
use App\Classes\General\Eloquent\AbstractUpdateRelationshipRecord;
|
||||
use App\Classes\General\Interfaces\Transactionable;
|
||||
use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject;
|
||||
use App\Models\Booking;
|
||||
use App\Models\Transaction;
|
||||
|
||||
class CreatesTransaction extends AbstractUpdateRelationshipRecord
|
||||
{
|
||||
/**
|
||||
* @param Transactionable $transactionable
|
||||
* @param TransactionObject $object
|
||||
* @return \Illuminate\Database\Eloquent\Model
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Transactions\Services;
|
||||
|
||||
use App\Classes\General\Eloquent\AbstractDeleteRecord;
|
||||
use App\Models\Transaction;
|
||||
|
||||
class DeletesTransaction extends AbstractDeleteRecord
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Transaction $model
|
||||
* @return mixed
|
||||
*/
|
||||
public function execute(Transaction $model) {
|
||||
return $this->handler($model);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Transactions\Services;
|
||||
|
||||
|
||||
use App\Models\Transaction;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class GeneratesPurchaseOrderProducts
|
||||
{
|
||||
|
||||
/** @var Collection */
|
||||
private $products;
|
||||
|
||||
/**
|
||||
* GeneratesPurchaseOrderProducts constructor.
|
||||
* @param Collection $products
|
||||
*/
|
||||
public function __construct(Collection $products)
|
||||
{
|
||||
$this->products = $products;
|
||||
}
|
||||
|
||||
|
||||
public function execute(Transaction $transaction, float $amount){
|
||||
|
||||
$products = collect();
|
||||
|
||||
$amountDifference = $amount - $transaction->amount;
|
||||
$transactionDetails = $transaction->transactionDetails()->select('*', DB::raw('abs(price - '.abs($amountDifference).') as nearest_price'))->orderBy('nearest_price')->get();
|
||||
foreach ($transactionDetails as $product) {
|
||||
$units = floor(abs($amountDifference) / $product->price);
|
||||
$quantity = $product->quantity;
|
||||
|
||||
if($product->price <= 0){
|
||||
$amountDifference = $amountDifference + ($product->price * $product->quantity);
|
||||
continue;
|
||||
}
|
||||
|
||||
if($amountDifference > 0){
|
||||
$quantity = $product->quantity + $units;
|
||||
$amountDifference = $amountDifference - ($product->price * $units);
|
||||
}
|
||||
|
||||
if($amountDifference < 0) {
|
||||
$units = ceil(abs($amountDifference) / $product->price);
|
||||
$quantity = $product->quantity - $units;
|
||||
|
||||
if($quantity <= 0){
|
||||
$amountDifference = $amountDifference + ($product->price * $product->quantity);
|
||||
continue;
|
||||
}
|
||||
|
||||
$amountDifference = $amountDifference + ($product->price * $quantity);
|
||||
}
|
||||
|
||||
$products->push([
|
||||
'description' => $product->product_name,
|
||||
'quantity' => (int) $quantity,
|
||||
'stockCode' => $product->product_code,
|
||||
'total' => $product->price * $quantity,
|
||||
'unit_price' => (float) $product->price,
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
return $products;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Wallets\ControllersLogic;
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Wallets\DataTransferObjects\WalletObject;
|
||||
use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject;
|
||||
use App\Classes\Modules\Wallets\Services\FetchesWallet;
|
||||
use App\Classes\Modules\Transactions\Services\GeneratesTransactionBillNumber;
|
||||
use App\Classes\Modules\Transactions\Services\CreatesTransaction;
|
||||
use App\Classes\Modules\Wallets\Services\UpdatesWallet;
|
||||
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Classes\ValueObjects\Constants\PaymentMethodType;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Http\Resources\WalletResource;
|
||||
|
||||
use ErrorException;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class CreditWalletLogic extends AbstractControllerLogic
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function notification():array {
|
||||
return [
|
||||
'title' => 'Credit into Company Wallet',
|
||||
'message' => 'You have successfully credit company wallet'
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
/** @var FetchesWallet */
|
||||
private $fetchesWallet;
|
||||
|
||||
/** @var GeneratesTransactionBillNumber */
|
||||
private $generatesTransactionBillNumber;
|
||||
|
||||
/** @var CreatesTransaction */
|
||||
private $createsTransaction;
|
||||
|
||||
/** @var UpdatesWallet */
|
||||
private $updatesWallet;
|
||||
|
||||
/**
|
||||
* CreateWalletLogic constructor.
|
||||
* @param FetchesWallet $fetchesWallet
|
||||
* @param GeneratesTransactionBillNumber $generatesTransactionBillNumber
|
||||
* @param CreatesTransaction $createsTransaction
|
||||
* @param UpdatesWallet $updatesWallet
|
||||
*/
|
||||
public function __construct(
|
||||
FetchesWallet $fetchesWallet,
|
||||
GeneratesTransactionBillNumber $generatesTransactionBillNumber,
|
||||
CreatesTransaction $createsTransaction,
|
||||
UpdatesWallet $updatesWallet
|
||||
)
|
||||
{
|
||||
$this->fetchesWallet = $fetchesWallet;
|
||||
$this->generatesTransactionBillNumber = $generatesTransactionBillNumber;
|
||||
$this->createsTransaction = $createsTransaction;
|
||||
$this->updatesWallet = $updatesWallet;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
* @throws ErrorException
|
||||
*/
|
||||
public function logic(Request $request) : JsonResponse
|
||||
{
|
||||
$wallet = $this->fetchesWallet->execute(['id' => $request->input('wallet_id')]);
|
||||
|
||||
$billNumber = $this->generatesTransactionBillNumber->execute('DEBIT-NOTE-');
|
||||
|
||||
$transaction_object = new TransactionObject(
|
||||
$billNumber,
|
||||
TransactionType::CREDIT_NOTE,
|
||||
1,
|
||||
$wallet->company->id,
|
||||
1,
|
||||
PaymentMethodType::WALLET,
|
||||
$request->input('amount'),
|
||||
$request->input('amount'),
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
null,
|
||||
ApprovalStatus::PENDING_SUBMISSION,
|
||||
[]
|
||||
);
|
||||
|
||||
$transaction = $this->createsTransaction->execute($wallet, $transaction_object);
|
||||
$updateWalletAmount = $wallet->amount + $transaction->amount;
|
||||
|
||||
$walletOject = new WalletObject($wallet->company->id, $wallet->currency_id, $wallet->code, $updateWalletAmount);
|
||||
|
||||
$wallet = $this->updatesWallet->execute($wallet, $walletOject);
|
||||
|
||||
return $this->resourceResponse(new WalletResource($wallet));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Wallets\ControllersLogic;
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Wallets\DataTransferObjects\WalletObject;
|
||||
use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject;
|
||||
use App\Classes\Modules\Wallets\Services\FetchesWallet;
|
||||
use App\Classes\Modules\Transactions\Services\GeneratesTransactionBillNumber;
|
||||
use App\Classes\Modules\Transactions\Services\CreatesTransaction;
|
||||
use App\Classes\Modules\Wallets\Services\UpdatesWallet;
|
||||
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Classes\ValueObjects\Constants\PaymentMethodType;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Http\Resources\WalletResource;
|
||||
|
||||
use ErrorException;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class DebitWalletLogic extends AbstractControllerLogic
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function notification():array {
|
||||
return [
|
||||
'title' => 'Debit into Company Wallet',
|
||||
'message' => 'You have successfully debit company wallet'
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
/** @var FetchesWallet */
|
||||
private $fetchesWallet;
|
||||
|
||||
/** @var GeneratesTransactionBillNumber */
|
||||
private $generatesTransactionBillNumber;
|
||||
|
||||
/** @var CreatesTransaction */
|
||||
private $createsTransaction;
|
||||
|
||||
/** @var UpdatesWallet */
|
||||
private $updatesWallet;
|
||||
|
||||
/**
|
||||
* CreateWalletLogic constructor.
|
||||
* @param FetchesWallet $fetchesWallet
|
||||
* @param GeneratesTransactionBillNumber $generatesTransactionBillNumber
|
||||
* @param CreatesTransaction $createsTransaction
|
||||
* @param UpdatesWallet $updatesWallet
|
||||
*/
|
||||
public function __construct(
|
||||
FetchesWallet $fetchesWallet,
|
||||
GeneratesTransactionBillNumber $generatesTransactionBillNumber,
|
||||
CreatesTransaction $createsTransaction,
|
||||
UpdatesWallet $updatesWallet
|
||||
)
|
||||
{
|
||||
$this->fetchesWallet = $fetchesWallet;
|
||||
$this->generatesTransactionBillNumber = $generatesTransactionBillNumber;
|
||||
$this->createsTransaction = $createsTransaction;
|
||||
$this->updatesWallet = $updatesWallet;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
* @throws ErrorException
|
||||
*/
|
||||
public function logic(Request $request) : JsonResponse
|
||||
{
|
||||
$wallet = $this->fetchesWallet->execute(['id' => $request->input('wallet_id')]);
|
||||
|
||||
$billNumber = $this->generatesTransactionBillNumber->execute('DEBIT-NOTE-');
|
||||
|
||||
$transaction_object = new TransactionObject(
|
||||
$billNumber,
|
||||
TransactionType::DEBIT_NOTE,
|
||||
1,
|
||||
$wallet->company->id,
|
||||
1,
|
||||
PaymentMethodType::WALLET,
|
||||
$request->input('amount'),
|
||||
$request->input('amount'),
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
null,
|
||||
ApprovalStatus::PENDING_SUBMISSION,
|
||||
[]
|
||||
);
|
||||
|
||||
$transaction = $this->createsTransaction->execute($wallet, $transaction_object);
|
||||
$updateWalletAmount = $wallet->amount - $transaction->amount;
|
||||
|
||||
$walletOject = new WalletObject($wallet->company->id, $wallet->currency_id, $wallet->code, $updateWalletAmount);
|
||||
|
||||
$wallet = $this->updatesWallet->execute($wallet, $walletOject);
|
||||
|
||||
return $this->resourceResponse(new WalletResource($wallet));
|
||||
}
|
||||
}
|
||||
@@ -3,15 +3,18 @@
|
||||
namespace App\Classes\Modules\Wallets\ControllersLogic;
|
||||
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
|
||||
use App\Classes\Modules\Wallets\DataTransferObjects\WalletObject;
|
||||
use App\Classes\Modules\Wallets\Services\ListsWallet;
|
||||
use App\Classes\Modules\Wallets\Services\FetchesWallet;
|
||||
use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject;
|
||||
use App\Classes\Modules\Companies\Services\FetchesCompany;
|
||||
use App\Classes\Modules\Wallets\Services\CreatesWallet;
|
||||
use App\Classes\Modules\Wallets\Services\GeneratesWalletCode;
|
||||
use App\Classes\Modules\Transactions\Services\GeneratesTransactionBillNumber;
|
||||
use App\Classes\Modules\Billplzs\Services\CreatesBillplzBill;
|
||||
use App\Classes\Modules\Transactions\Services\CreatesTransaction;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
|
||||
use App\Classes\Modules\Wallets\Standards\Rules\CanTopUpWallet;
|
||||
use App\Classes\ValueObjects\Constants\PaymentMethodType;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Http\Resources\WalletResource;
|
||||
use App\Classes\Modules\Transactions\Processors\CreateWalletTransactionProcessor;
|
||||
|
||||
use ErrorException;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
@@ -30,26 +33,50 @@ class TopUpWalletLogic extends AbstractControllerLogic
|
||||
];
|
||||
}
|
||||
|
||||
/** @var FetchesWallet */
|
||||
private $fetchesWallet;
|
||||
|
||||
/** @var CanTopUpWallet */
|
||||
private $canTopUpWallet;
|
||||
/** @var FetchesCompany */
|
||||
private $fetchesCompany;
|
||||
|
||||
/** @var CreateWalletTransactionProcessor */
|
||||
private $createWalletTransactionProcessor;
|
||||
/** @var GeneratesWalletCode */
|
||||
private $generatesWalletCode;
|
||||
|
||||
/** @var CreatesWallet */
|
||||
private $createsWallet;
|
||||
|
||||
/** @var GeneratesTransactionBillNumber */
|
||||
private $generatesTransactionBillNumber;
|
||||
|
||||
/** @var CreatesWalletTransaction */
|
||||
private $createsWalletTransaction;
|
||||
|
||||
/** @var CreatesBillplzBill */
|
||||
private $createsBillplzBill;
|
||||
|
||||
/** @var CreatesTransaction */
|
||||
private $createsTransaction;
|
||||
|
||||
/**
|
||||
* CreateWalletLogic constructor.
|
||||
* @param CreatesWallet $createsWallet
|
||||
* @param FetchesCompany $fetchesCompany
|
||||
* @param GeneratesWalletCode $generatesWalletCode
|
||||
* @param CanCreateCompanyWallet $canCreateCompanyWallet
|
||||
* @param CreatesWallet $createsWallet
|
||||
* @param GeneratesTransactionBillNumber $generatesTransactionBillNumber
|
||||
*/
|
||||
public function __construct(CanTopUpWallet $canTopUpWallet, FetchesWallet $fetchesWallet, CreateWalletTransactionProcessor $createWalletTransactionProcessor)
|
||||
public function __construct(
|
||||
FetchesCompany $fetchesCompany,
|
||||
GeneratesWalletCode $generatesWalletCode,
|
||||
CreatesWallet $createsWallet,
|
||||
GeneratesTransactionBillNumber $generatesTransactionBillNumber,
|
||||
CreatesBillplzBill $createsBillplzBill,
|
||||
CreatesTransaction $createsTransaction
|
||||
)
|
||||
{
|
||||
$this->canTopUpWallet = $canTopUpWallet;
|
||||
$this->fetchesWallet = $fetchesWallet;
|
||||
$this->createWalletTransactionProcessor = $createWalletTransactionProcessor;
|
||||
$this->fetchesCompany = $fetchesCompany;
|
||||
$this->generatesWalletCode = $generatesWalletCode;
|
||||
$this->createsWallet = $createsWallet;
|
||||
$this->generatesTransactionBillNumber = $generatesTransactionBillNumber;
|
||||
$this->createsBillplzBill = $createsBillplzBill;
|
||||
$this->createsTransaction = $createsTransaction;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -59,13 +86,45 @@ class TopUpWalletLogic extends AbstractControllerLogic
|
||||
*/
|
||||
public function logic(Request $request) : JsonResponse
|
||||
{
|
||||
$wallet = $this->fetchesWallet->execute(['id' => $request->input('wallet_id')]);
|
||||
$company = $this->fetchesCompany->execute(['id' => $request->input('company_id')]);
|
||||
if (!$company->wallets()->first()) {
|
||||
$object = new WalletObject($company->id, 1, $this->generatesWalletCode->execute());
|
||||
$wallet = $this->createsWallet->execute($object, $company);
|
||||
}
|
||||
|
||||
$walletOject = new WalletObject( $wallet->company->id, $wallet->currency_id, $wallet->code, $request->input('amount'));
|
||||
$user = $company->employees()->first();
|
||||
$billNumber = $this->generatesTransactionBillNumber->execute('TOPUP-');
|
||||
|
||||
$billPlzBill = $this->createsBillplzBill->execute(
|
||||
$user->name,
|
||||
$user->email,
|
||||
'This payment is made for wallet topup. ' . $company->reference,
|
||||
$request->input('amount'),
|
||||
$billNumber,
|
||||
$request->input('bank_code')
|
||||
);
|
||||
|
||||
$this->canTopUpWallet->passes($walletOject);
|
||||
$transaction_object = new TransactionObject(
|
||||
$billNumber,
|
||||
TransactionType::TOP_UP,
|
||||
1,
|
||||
$company->id,
|
||||
1,
|
||||
PaymentMethodType::PAYMENT_GATEWAY,
|
||||
$request->input('amount'),
|
||||
$request->input('amount'),
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
null,
|
||||
ApprovalStatus::PENDING_SUBMISSION,
|
||||
[],
|
||||
$billPlzBill->id
|
||||
);
|
||||
|
||||
$transaction = $this->createWalletTransactionProcessor->execute($wallet, $walletOject, TransactionType::TOP_UP);
|
||||
$transaction = $this->createsTransaction->execute($company->wallets()->first(), $transaction_object);
|
||||
|
||||
return $this->resourceResponse(new WalletResource($wallet));
|
||||
}
|
||||
|
||||
@@ -21,8 +21,6 @@ class CreatesWallet extends AbstractUpdateRelationshipRecord
|
||||
$model->code = $object->getCode();
|
||||
$model->currency_id = $object->getCurrency();
|
||||
|
||||
|
||||
return $this->handler($company->wallets(), $model);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ final class DocumentType {
|
||||
public const WALLET_TOP_UP_PAYMENT_PROOF = 'WALLET_TOP_UP_PAYMENT_PROOF';
|
||||
public const WALLET_REFUND_PAYMENT_PROOF = 'WALLET_REFUND_PAYMENT_PROOF';
|
||||
|
||||
public const PROFORMA_INVOICE = 'PROFORMA_INVOICE';
|
||||
public const PURCHASE_ORDER = 'PURCHASE_ORDER';
|
||||
public const DELIVER_ORDER = 'DELIVER_ORDER';
|
||||
public const INVOICE = 'INVOICE';
|
||||
|
||||
@@ -12,7 +12,7 @@ final class TransactionType {
|
||||
|
||||
public const BILL = 3;
|
||||
|
||||
public const PERFORMA = 4;
|
||||
public const PROFORMA = 4;
|
||||
|
||||
public const TOP_UP = 5;
|
||||
|
||||
@@ -24,5 +24,7 @@ final class TransactionType {
|
||||
|
||||
public const CREDIT_NOTE = 9;
|
||||
|
||||
public const DEBIT_NOTE = 11;
|
||||
|
||||
public const WITHDRAW = 10;
|
||||
}
|
||||
|
||||
+7
-5
@@ -1,19 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Billplzs;
|
||||
namespace App\Http\Controllers\Billplz;
|
||||
|
||||
use App\Classes\Modules\Billplzs\ControllersLogic\CallbackBillplzLogic;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class CallbackBillplzController
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param BillplzBillLogic $logic
|
||||
* @return JsonResponse
|
||||
* @param CallbackBillplzLogic $logic
|
||||
* @return bool|\Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
* @throws \App\Classes\Exceptions\ResourceNotFoundException
|
||||
*/
|
||||
public function callback(Request $request, CallbackBillplzLogic $logic): JsonResponse {
|
||||
public function callback(Request $request, CallbackBillplzLogic $logic) {
|
||||
return $logic->execute($request);
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Billplzs;
|
||||
namespace App\Http\Controllers\Billplz;
|
||||
|
||||
use App\Classes\Modules\Billplzs\ControllersLogic\CreateBillplzBillLogic;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
@@ -10,7 +10,7 @@ class CreateBillplzBillController
|
||||
{
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param BillplzBillLogic $logic
|
||||
* @param CreateBillplzBillLogic $logic
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function create(Request $request, CreateBillplzBillLogic $logic): JsonResponse {
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Bookings;
|
||||
|
||||
use App\Classes\Modules\Bookings\ControllersLogic\AutoPurchaseOrderFillLogic;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Models\Booking;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class AutoPurchaseOrderFillController
|
||||
{
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param AutoPurchaseOrderFillLogic $logic
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function auto(Request $request, AutoPurchaseOrderFillLogic $logic): JsonResponse {
|
||||
Auth()->login(User::find(1));
|
||||
return $logic->execute($request);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Bookings;
|
||||
|
||||
use App\Classes\Modules\Bookings\ControllersLogic\CreateProformaInvoiceTransactionLogic;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class CreateProformaInvoiceTransaction
|
||||
{
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param CreateProformaInvoiceTransactionLogic $logic
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function create(Request $request, CreateProformaInvoiceTransactionLogic $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 RegenerateInvoiceBookingController
|
||||
{
|
||||
/**
|
||||
* @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\UpdateBookingAmountLogic;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class UpdateBookingAmountController
|
||||
{
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param CreateBookingRefundLogic $logic
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function update(Request $request, UpdateBookingAmountLogic $logic): JsonResponse {
|
||||
return $logic->execute($request);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,6 +10,6 @@ class CreateTransactionController
|
||||
{
|
||||
|
||||
public function create(Request $request, CreateTransactionLogic $logic): JsonResponse {
|
||||
return $logic->execute($request);
|
||||
return $logic->logic($request);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Transactions;
|
||||
|
||||
use App\Classes\Modules\Transactions\ControllersLogic\DeleteTransactionLogic;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class DeletePaymentProofDocumentController
|
||||
{
|
||||
public function delete(Request $request, DeleteTransactionLogic $logic): JsonResponse {
|
||||
return $logic->execute($request);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Transactions;
|
||||
|
||||
use App\Classes\Modules\Transactions\ControllersLogic\UpdatePaymentTransactionStatusLogic;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class UpdatePaymentTransactionStatusController
|
||||
{
|
||||
public function update(Request $request, UpdatePaymentTransactionStatusLogic $logic): JsonResponse {
|
||||
return $logic->execute($request);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Wallets;
|
||||
|
||||
use App\Classes\Modules\Wallets\ControllersLogic\CreditWalletLogic;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class CreditWalletController
|
||||
{
|
||||
|
||||
public function credit(Request $request, CreditWalletLogic $logic): JsonResponse {
|
||||
return $logic->execute($request);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Wallets;
|
||||
|
||||
use App\Classes\Modules\Wallets\ControllersLogic\DebitWalletLogic;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class DebitWalletController
|
||||
{
|
||||
|
||||
public function debit(Request $request, DebitWalletLogic $logic): JsonResponse {
|
||||
return $logic->execute($request);
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ namespace App\Http\Resources;
|
||||
use App\Classes\Modules\Bookings\Services\CalculatesBookingFloatingAmount;
|
||||
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\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Classes\ValueObjects\Constants\DocumentType;
|
||||
@@ -23,7 +24,6 @@ class BookingResource extends JsonResource
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
// dd($this->service);
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'company' => new CompanyResource($this->company),
|
||||
@@ -32,8 +32,8 @@ class BookingResource extends JsonResource
|
||||
'marking' => $this->marking,
|
||||
'amount' => $this->fix_amount,
|
||||
'floating_amount' => floatval((App()->make(CalculatesBookingFloatingAmount::class))->execute($this->resource, $this->fix_currency_id)),
|
||||
'paid_amount' => floatval((App()->make(CalculatesBookingPayableAmount::class))->execute($this->resource, $this->fix_currency_id)),
|
||||
'outstanding_amount' => floatval((App()->make(CalculatesBookingOutstanding::class))->execute($this->resource)),
|
||||
'paid_amount' => floatval((App()->make(CalculatesBookingPayableAmount::class))->execute($this->resource, $this->fix_currency_id)) - floatval((App()->make(CalculatesBookingRefundAmount::class))->execute($this->resource, $this->fix_currency_id)),
|
||||
'outstanding_amount' => floatval((App()->make(CalculatesBookingOutstanding::class))->execute($this->resource)) - floatval((App()->make(CalculatesBookingRefundAmount::class))->execute($this->resource, $this->fix_currency_id)),
|
||||
'fixed_currency' => new CurrencyResource($this->fixedCurrency),
|
||||
'convertible_currency' => new CurrencyResource($this->convertibleCurrency),
|
||||
'conversion_currency' => new CurrencyResource($this->conversionCurrency),
|
||||
@@ -42,6 +42,7 @@ class BookingResource extends JsonResource
|
||||
'delivery_order' => new DocumentResource($this->documents()->where('document_type', DocumentType::DELIVER_ORDER)->first()),
|
||||
'invoice' => new DocumentResource($this->documents()->where('document_type', DocumentType::INVOICE)->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()),
|
||||
],
|
||||
'status' => $this->status,
|
||||
'created_at' => Carbon::parse($this->created_at)->format('d-m-Y'),
|
||||
@@ -56,9 +57,17 @@ class BookingResource extends JsonResource
|
||||
'expired_payment_attempts' => TransactionResource::collection($this->transactions()->payments()->where('status', ApprovalStatus::PENDING_SUBMISSION)->whereDate('expires_on', '<', Carbon::now())->get()),
|
||||
'payment_history' => TransactionResource::collection($this->transactions()->where(function($query){
|
||||
$query->where(function($query){
|
||||
$query->payments()->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::REJECTED]);
|
||||
$query->where(function($query){
|
||||
$query->payments()->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::REJECTED]);
|
||||
})->orWhere(function($query){
|
||||
$query->where('type', TransactionType::BILL)->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
|
||||
});
|
||||
})->orWhere(function($query){
|
||||
$query->where('type', TransactionType::BILL)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
|
||||
$query->where(function($query){
|
||||
$query->where('type', TransactionType::REFUND)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::REJECTED, ApprovalStatus::COMPLETED]);
|
||||
})->orWhere(function($query){
|
||||
$query->where('type', TransactionType::CREDIT_NOTE)->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
|
||||
});
|
||||
});
|
||||
})->latest()->get())
|
||||
])
|
||||
|
||||
@@ -12,6 +12,7 @@ use App\Classes\ValueObjects\Constants\SegmentConstants;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Models\Currency;
|
||||
use App\Models\SegmentConstant;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
@@ -26,6 +27,7 @@ class CompanyResource extends JsonResource
|
||||
public function toArray($request)
|
||||
{
|
||||
$lastPayment = $this->transactions()->where('transactions.type', TransactionType::PAYMENT)->whereIn('transactions.status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->orderBy('id', 'DESC')->first();
|
||||
$totalPayments = $this->transactions()->where('transactions.type', TransactionType::PAYMENT)->whereIn('transactions.status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->sum('amount');
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'name' => $this->name,
|
||||
@@ -38,7 +40,14 @@ class CompanyResource extends JsonResource
|
||||
'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)->first()),
|
||||
'bookings' => $this->whenLoaded('bookings', $this->bookings()->orderBy('id', 'DESC')->get(), []),
|
||||
'total_payments' => (float) $this->transactions()->where('transactions.type', TransactionType::PAYMENT)->whereIn('transactions.status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED])->sum('amount'),
|
||||
'confirmed_bookings' => $this->bookings()->whereHas('transactions', function ($query){
|
||||
$query->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
|
||||
})->count(),
|
||||
'total_payments' => (float) $totalPayments,
|
||||
'average_spending_per_day' => (float) $totalPayments / ($this->created_at->diff(Carbon::now())->days === 0 ? 1 : $this->created_at->diff(Carbon::now())->days),
|
||||
'average_spending_per_booking' => (float) $totalPayments > 0 ? $totalPayments / $this->bookings()->whereHas('transactions', function ($query){
|
||||
$query->where('type', TransactionType::PAYMENT)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
|
||||
})->count() : $totalPayments,
|
||||
'last_payment' => $lastPayment ? $lastPayment->created_at->diffForHumans() : 'No Payments',
|
||||
'personal_banks' => BankResource::collection($this->banks->where('type', BankAccountType::PERSONAL)),
|
||||
'recipient_banks' => [
|
||||
@@ -51,10 +60,8 @@ class CompanyResource extends JsonResource
|
||||
$segment = SegmentConstant::where('reference', SegmentConstants::SUPPLIER_CURRENCIES)->where('detail->id', $this->id)->first();
|
||||
return $segment ? CurrencyResource::collection(Currency::whereIn('id', $segment->detail->currencies)->get()) : [];
|
||||
}),
|
||||
'wallet' => WalletResource::collection($this->wallets),
|
||||
'created_at' => $this->created_at->format('d-m-Y')
|
||||
|
||||
|
||||
];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Models\Transaction;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
@@ -23,9 +22,9 @@ class TransactionResource extends JsonResource
|
||||
'type' => (int) $this->type,
|
||||
'bill_no' => $this->bill_no,
|
||||
'payment_reference' => $this->payment_reference,
|
||||
'payment_method' => $this->payment_method,
|
||||
'payment_method' => (float) $this->payment_method,
|
||||
'recipient_bank_account' => new BankResource($this->when((int) $this->type === TransactionType::BILL, $this->booking->bank)),
|
||||
'issuer_name' => $this->issuerCompany->name,
|
||||
'recipient_bank_account' => new BankResource($this->when((int) $this->type === TransactionType::BILL,$this->booking->bank)),
|
||||
'amount' => (double) $this->amount,
|
||||
'original_amount' => (double) $this->original_amount,
|
||||
'currency' => new CurrencyResource($this->currency),
|
||||
@@ -38,7 +37,11 @@ class TransactionResource extends JsonResource
|
||||
'documents' => new DocumentResource($this->documents()->first()),
|
||||
'customer_booking' => new TransactionResource($this->when((int) $this->type === TransactionType::BILL, $this->booking->transactions()->payments()->complete()->where('original_amount', '=', $this->original_amount)->where('id', '<', $this->id)->orderByDesc('id')->first())),
|
||||
'expires_on' => Carbon::parse($this->expires_on)->format('d-m-Y h:i:s A'),
|
||||
'updated_at' => Carbon::parse($this->updated_at)->format('d-m-Y h:i:s A')
|
||||
'updated_at' => Carbon::parse($this->updated_at)->format('d-m-Y h:i:s A'),
|
||||
'interval' => [
|
||||
'value' => (Carbon::parse($this->created_at)->addDays(3)->gt(Carbon::now()) ) ? '+' : '-' ,
|
||||
'duration' => Carbon::parse($this->created_at)->addDays(3)->diff(Carbon::now())->format('%d'),
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class WalletResource extends JsonResource
|
||||
@@ -19,7 +20,17 @@ class WalletResource extends JsonResource
|
||||
'code' => $this->code,
|
||||
'currency_id' => $this->currency_id,
|
||||
'amount' => (double) $this->amount,
|
||||
'company_id' => (int) $this->company_id
|
||||
'company_id' => (int) $this->owner->id,
|
||||
'transactions' => $this->transactions()->orderBy('id', 'DESC')->get(),
|
||||
'topup_transactions' => $this->transactions()->where('type', TransactionType::TOP_UP)->orderBy('id', 'DESC')->get(),
|
||||
|
||||
// 'transaction' => $this->whenLoaded('transactions', function() {
|
||||
// return [
|
||||
// 'topup' => $this->transactions
|
||||
// ];
|
||||
// }),
|
||||
// 'transaction' // all
|
||||
// 'top_transaction' // only topup
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,11 +6,8 @@ use App\Classes\General\Interfaces\Documentable;
|
||||
use App\Classes\General\Interfaces\Transactionable;
|
||||
use App\Classes\ValueObjects\Constants\RoleTypes;
|
||||
use App\Scopes\CustomerBookingsScope;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
/**
|
||||
@@ -22,8 +19,8 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
* @property string marking
|
||||
* @property string reference
|
||||
* @property float fix_amount
|
||||
* @property \App\Models\Currency convertible_currency_id
|
||||
* @property \App\Models\Currency conversion_currency_id
|
||||
* @property int convertible_currency_id
|
||||
* @property int conversion_currency_id
|
||||
*/
|
||||
class Booking extends AbstractModel implements Documentable, Transactionable
|
||||
{
|
||||
|
||||
@@ -7,6 +7,7 @@ use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||
@@ -17,6 +18,8 @@ use Illuminate\Database\Eloquent\Relations\MorphTo;
|
||||
|
||||
class Transaction extends AbstractModel implements Documentable
|
||||
{
|
||||
use SoftDeletes;
|
||||
|
||||
protected $table = 'transactions';
|
||||
|
||||
public function owner(): morphTo
|
||||
@@ -126,10 +129,15 @@ class Transaction extends AbstractModel implements Documentable
|
||||
|
||||
/**
|
||||
* @param Builder $query
|
||||
* @param string $payment_reference
|
||||
* @return Builder
|
||||
*/
|
||||
public function scopeRefunds(Builder $query)
|
||||
public function scopeRefunds(Builder $query, ?string $payment_reference = NULL)
|
||||
{
|
||||
if($payment_reference){
|
||||
$query->where('payment_reference', $payment_reference);
|
||||
}
|
||||
|
||||
return $query->where('type', TransactionType::REFUND);
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -5,6 +5,7 @@ namespace App\Models;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Spatie\Permission\Traits\HasRoles;
|
||||
|
||||
use Tymon\JWTAuth\Contracts\JWTSubject;
|
||||
@@ -23,7 +24,7 @@ class User extends AbstractModel implements
|
||||
AuthorizableContract,
|
||||
CanResetPasswordContract
|
||||
{
|
||||
use HasRoles, Notifiable, Authenticatable, Authorizable, CanResetPassword, MustVerifyEmail;
|
||||
use HasRoles, Notifiable, Authenticatable, Authorizable, CanResetPassword, MustVerifyEmail, SoftDeletes;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,13 +2,14 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Classes\General\Interfaces\Transactionable;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphTo;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphMany;
|
||||
|
||||
class Wallet extends AbstractModel
|
||||
class Wallet extends AbstractModel implements Transactionable
|
||||
{
|
||||
use SoftDeletes;
|
||||
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
"ext-zip": "*",
|
||||
"barryvdh/laravel-dompdf": "^0.9.0",
|
||||
"carlos-meneses/laravel-mpdf": "^2.1",
|
||||
"doctrine/dbal": "2.*",
|
||||
"doctrine/dbal": "^2.12.1",
|
||||
"fideloper/proxy": "^4.2",
|
||||
"fruitcake/laravel-cors": "^1.0",
|
||||
"guzzlehttp/guzzle": "^6.3",
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'base_url' => env('BILLPLZ_BASE_URL', 'https://www.billplz-sandbox.com'),
|
||||
'base_url' => env('BILLPLZ_BASE_URL', 'https://www.billplz.com'),
|
||||
'api_key' => env('BILLPLZ_API_KEY', '0fa4c710-761b-4a7a-a501-c2c2d02643d5'),
|
||||
'x_signature_key' => env('BILLPLZ_X_SIGNATURE_KEY', 'S-pbNVthVRsvnPfZlgLwqqOg'),
|
||||
'collection_id' => env('BILLPLZ_COLLECTION_ID', 'hev2wdjy'),
|
||||
|
||||
@@ -230,7 +230,7 @@ class FakeBookingTransactions extends Seeder
|
||||
Constants\TransactionType::PAYMENT,
|
||||
Constants\TransactionType::INVOICE,
|
||||
Constants\TransactionType::BILL,
|
||||
Constants\TransactionType::PERFORMA,
|
||||
Constants\TransactionType::PROFORMA,
|
||||
Constants\TransactionType::TOP_UP,
|
||||
Constants\TransactionType::REFUND,
|
||||
Constants\TransactionType::PURCHASE_ORDER,
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.6 MiB |
+4
@@ -120,6 +120,10 @@
|
||||
button:focus{
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
button:disabled {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
/*
|
||||
Alternate buttons
|
||||
--------------------------------------------------
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,79 +1,128 @@
|
||||
<template>
|
||||
<div class="row align-items-center m-b-15 parentContainer">
|
||||
<div class="col-auto p-r-0">
|
||||
<div class="padding-5 bg-master-lightest">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
|
||||
width="30" height="30"
|
||||
viewBox="0 0 172 172"
|
||||
style=" fill:#000000;"><defs><linearGradient x1="86" y1="104.14063" x2="86" y2="140.57775" gradientUnits="userSpaceOnUse" id="color-1_44825_gr1"><stop offset="0" stop-color="#4ec9ff"></stop><stop offset="1" stop-color="#2bffe6"></stop></linearGradient><linearGradient x1="86" y1="16.125" x2="86" y2="159.93044" gradientUnits="userSpaceOnUse" id="color-2_44825_gr2"><stop offset="0" stop-color="#009add"></stop><stop offset="1" stop-color="#00baa4"></stop></linearGradient></defs><g fill="none" fill-rule="nonzero" stroke="none" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" font-family="none" font-weight="none" font-size="none" text-anchor="none" style="mix-blend-mode: normal"><path d="M0,172v-172h172v172z" fill="none"></path><g><path d="M121.41588,139.75h-70.83175c-2.53431,0 -3.66575,-3.18469 -1.6985,-4.78106l33.72544,-27.40175c1.97531,-1.60444 4.80256,-1.60444 6.77787,0l33.72544,27.40175c1.96725,1.59638 0.83581,4.78106 -1.6985,4.78106z" fill="url(#color-1_44825_gr1)"></path><path d="M148.135,71.77238l-8.385,-8.385v-28.42031c0,-4.46125 -3.63081,-8.09206 -8.09206,-8.09206h-2.65794v-2.65794c0,-4.46125 -3.63081,-8.09206 -8.09206,-8.09206h-69.81587c-4.46125,0 -8.09206,3.63081 -8.09206,8.09206v2.65794h-2.65794c-4.46125,0 -8.09206,3.63081 -8.09206,8.09206v28.42031l-8.385,8.385c-1.5265,1.52381 -2.365,3.55019 -2.365,5.70825v64.95688c0,7.40944 6.02806,13.4375 13.4375,13.4375h102.125c7.40944,0 13.4375,-6.02806 13.4375,-13.4375v-64.95688c0,-2.15806 -0.84119,-4.18444 -2.365,-5.70825zM77.60156,91.96356l-0.30906,0.24725c-1.28731,-1.79525 -2.0425,-3.92375 -2.0425,-6.21081c0,-5.92862 4.82138,-10.75 10.75,-10.75c5.92863,0 10.75,4.82138 10.75,10.75c0,2.26287 -0.70413,4.41019 -2.01294,6.235l-0.34131,-0.27412c-4.93962,-3.95063 -11.84919,-3.95063 -16.79419,0.00269zM86,69.875c-8.89294,0 -16.125,7.23206 -16.125,16.125c0,3.53406 1.14487,6.85581 3.18738,9.59438l-10.578,8.46025l-3.35937,-2.6875v-55.88388c6.95256,-1.06963 12.16094,-6.28069 13.23325,-13.23325h27.2835c1.06963,6.95256 6.28069,12.16094 13.23325,13.23325v55.88656l-3.35937,2.6875l-10.56994,-8.45488c2.07744,-2.79231 3.17931,-6.10869 3.17931,-9.60244c0,-8.89294 -7.23206,-16.125 -16.125,-16.125zM58.179,107.5l-31.304,25.04481v-50.08694zM145.125,82.45519v50.08963l-31.30669,-25.04481zM144.33488,75.5725c0.11825,0.11825 0.18006,0.27412 0.27412,0.4085l-4.859,3.88612v-8.8795zM131.65794,32.25c1.49962,0 2.71706,1.21744 2.71706,2.71706v49.20275l-5.375,4.3v-56.21981zM51.09206,21.5h69.81856c1.49694,0 2.71438,1.21744 2.71438,2.71706v68.55275l-5.375,4.3v-56.75731h-2.6875c-6.22694,0 -10.75,-4.52306 -10.75,-10.75v-2.6875h-37.625v2.6875c0,6.22694 -4.52306,10.75 -10.75,10.75h-2.6875v56.75731l-5.375,-4.3v-68.55275c0,-1.49962 1.21744,-2.71706 2.71706,-2.71706zM40.34206,32.25h2.65794v56.21981l-5.375,-4.3v-49.20275c0,-1.49963 1.21744,-2.71706 2.71706,-2.71706zM32.25,70.98763v8.88219l-4.859,-3.88881c0.09406,-0.13438 0.15587,-0.29025 0.27412,-0.4085zM137.0625,150.5h-102.125c-4.44513,0 -8.0625,-3.61738 -8.0625,-8.0625v-3.00463l54.08325,-43.27144c2.96969,-2.37306 7.11381,-2.37306 10.08081,0l54.08594,43.26875v3.00731c0,4.44513 -3.61737,8.0625 -8.0625,8.0625z" fill="url(#color-2_44825_gr2)"></path></g></g></svg>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<div class="row">
|
||||
<div class="col-auto p-r-10 all-caps">
|
||||
<div class="font-heading all-caps fs-11 bold">{{this.item.marking}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="font-heading all-caps fs-10 muted">{{this.item.created_at}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col" v-if="$store.getters.isAdmin">
|
||||
<div class="font-heading fs-10 muted all-caps">Marking</div>
|
||||
<div class="font-heading fs-12">
|
||||
<a :href="route('customer.profile', item.company.reference)">{{this.item.company.reference}}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<div class="font-heading fs-10 muted all-caps">Currency</div>
|
||||
<div class="font-heading fs-12 bold">
|
||||
<span class="flag-icon fs-12" :class="'flag-icon-'+item.convertible_currency.country.short_code.toLowerCase()"></span> {{this.item.convertible_currency.short_code}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<div class="font-heading fs-10 muted all-caps">Transfer Type</div>
|
||||
<div class="font-heading fs-11">{{this.item.service.name}}</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="font-heading fs-10 muted all-caps">Payable Amount</div>
|
||||
<div class="font-heading fs-11 text-success bold">{{this.item.amount}} {{this.item.fixed_currency.short_code}}</div>
|
||||
</div>
|
||||
<div class="col-auto" v-if="$store.getters.isCustomer">
|
||||
<div class="font-heading fs-10 muted all-caps">status</div>
|
||||
<div class="font-heading fs-8 all-caps text-master btn-rounded p-l-10 p-r-10 lh-15 mt-1" :class="[{'bg-warning': item.status !== 3}, {'bg-success': item.status === 3} ]">
|
||||
{{item.status === 3 ? 'Complete' : 'In Progress'}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto hide" :class="[{'invisible': !item.service.configurations.billable}]" v-if="$store.getters.isCustomer">
|
||||
<div class="font-heading fs-10 muted all-caps">Billing</div>
|
||||
<div class="font-heading fs-8 all-caps text-danger btn-rounded bg-master-lightest p-l-10 p-r-10 lh-15 mt-1">
|
||||
Pending...
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-2 p-r-5 parentContainer">
|
||||
<div class="row align-items-center">
|
||||
<div class="col-auto ml-auto">
|
||||
<div class="btn btn-xs btn-default b-rad-none requestModal" v-if="item.status !== 5 && item.paid_amount === 0 && item.floating_amount === 0 && $store.getters.isAdmin" data-type="cancelBooking">
|
||||
<i class="fa fa-fw fa-times text-danger"></i>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="border-sm row align-items-center m-b-15 parentContainer position-relative">
|
||||
<div class="col-auto p-r-0">
|
||||
<div class="padding-5 bg-master-lightest">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
|
||||
width="30" height="30"
|
||||
viewBox="0 0 172 172"
|
||||
style=" fill:#000000;"><defs><linearGradient x1="86" y1="104.14063" x2="86" y2="140.57775" gradientUnits="userSpaceOnUse" id="color-1_44825_gr1"><stop offset="0" stop-color="#4ec9ff"></stop><stop offset="1" stop-color="#2bffe6"></stop></linearGradient><linearGradient x1="86" y1="16.125" x2="86" y2="159.93044" gradientUnits="userSpaceOnUse" id="color-2_44825_gr2"><stop offset="0" stop-color="#009add"></stop><stop offset="1" stop-color="#00baa4"></stop></linearGradient></defs><g fill="none" fill-rule="nonzero" stroke="none" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" font-family="none" font-weight="none" font-size="none" text-anchor="none" style="mix-blend-mode: normal"><path d="M0,172v-172h172v172z" fill="none"></path><g><path d="M121.41588,139.75h-70.83175c-2.53431,0 -3.66575,-3.18469 -1.6985,-4.78106l33.72544,-27.40175c1.97531,-1.60444 4.80256,-1.60444 6.77787,0l33.72544,27.40175c1.96725,1.59638 0.83581,4.78106 -1.6985,4.78106z" fill="url(#color-1_44825_gr1)"></path><path d="M148.135,71.77238l-8.385,-8.385v-28.42031c0,-4.46125 -3.63081,-8.09206 -8.09206,-8.09206h-2.65794v-2.65794c0,-4.46125 -3.63081,-8.09206 -8.09206,-8.09206h-69.81587c-4.46125,0 -8.09206,3.63081 -8.09206,8.09206v2.65794h-2.65794c-4.46125,0 -8.09206,3.63081 -8.09206,8.09206v28.42031l-8.385,8.385c-1.5265,1.52381 -2.365,3.55019 -2.365,5.70825v64.95688c0,7.40944 6.02806,13.4375 13.4375,13.4375h102.125c7.40944,0 13.4375,-6.02806 13.4375,-13.4375v-64.95688c0,-2.15806 -0.84119,-4.18444 -2.365,-5.70825zM77.60156,91.96356l-0.30906,0.24725c-1.28731,-1.79525 -2.0425,-3.92375 -2.0425,-6.21081c0,-5.92862 4.82138,-10.75 10.75,-10.75c5.92863,0 10.75,4.82138 10.75,10.75c0,2.26287 -0.70413,4.41019 -2.01294,6.235l-0.34131,-0.27412c-4.93962,-3.95063 -11.84919,-3.95063 -16.79419,0.00269zM86,69.875c-8.89294,0 -16.125,7.23206 -16.125,16.125c0,3.53406 1.14487,6.85581 3.18738,9.59438l-10.578,8.46025l-3.35937,-2.6875v-55.88388c6.95256,-1.06963 12.16094,-6.28069 13.23325,-13.23325h27.2835c1.06963,6.95256 6.28069,12.16094 13.23325,13.23325v55.88656l-3.35937,2.6875l-10.56994,-8.45488c2.07744,-2.79231 3.17931,-6.10869 3.17931,-9.60244c0,-8.89294 -7.23206,-16.125 -16.125,-16.125zM58.179,107.5l-31.304,25.04481v-50.08694zM145.125,82.45519v50.08963l-31.30669,-25.04481zM144.33488,75.5725c0.11825,0.11825 0.18006,0.27412 0.27412,0.4085l-4.859,3.88612v-8.8795zM131.65794,32.25c1.49962,0 2.71706,1.21744 2.71706,2.71706v49.20275l-5.375,4.3v-56.21981zM51.09206,21.5h69.81856c1.49694,0 2.71438,1.21744 2.71438,2.71706v68.55275l-5.375,4.3v-56.75731h-2.6875c-6.22694,0 -10.75,-4.52306 -10.75,-10.75v-2.6875h-37.625v2.6875c0,6.22694 -4.52306,10.75 -10.75,10.75h-2.6875v56.75731l-5.375,-4.3v-68.55275c0,-1.49962 1.21744,-2.71706 2.71706,-2.71706zM40.34206,32.25h2.65794v56.21981l-5.375,-4.3v-49.20275c0,-1.49963 1.21744,-2.71706 2.71706,-2.71706zM32.25,70.98763v8.88219l-4.859,-3.88881c0.09406,-0.13438 0.15587,-0.29025 0.27412,-0.4085zM137.0625,150.5h-102.125c-4.44513,0 -8.0625,-3.61738 -8.0625,-8.0625v-3.00463l54.08325,-43.27144c2.96969,-2.37306 7.11381,-2.37306 10.08081,0l54.08594,43.26875v3.00731c0,4.44513 -3.61737,8.0625 -8.0625,8.0625z" fill="url(#color-2_44825_gr2)"></path></g></g></svg>
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn btn-xs btn-default b-rad-none requestModal" v-if="item.status === 5 && item.paid_amount === 0 && item.floating_amount === 0 && $store.getters.isAdmin" data-type="restoreBooking">
|
||||
<i class="fa fa-fw fa-history text-success"></i>
|
||||
<div class="col-6 col-sm-auto">
|
||||
<div class="row">
|
||||
<div class="col-auto p-r-10 all-caps">
|
||||
<div class="font-heading all-caps fs-11 bold">{{this.item.marking}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="font-heading all-caps fs-10 muted">{{this.item.created_at}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6 col-sm d-none d-lg-block" v-if="$store.getters.isAdmin">
|
||||
<div class="font-heading fs-10 muted all-caps">Marking</div>
|
||||
<div class="font-heading fs-12">
|
||||
<a :href="route('customer.profile', item.company.reference)">{{this.item.company.reference}}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6 col-sm-auto d-none d-lg-block">
|
||||
<div class="font-heading fs-10 muted all-caps">Currency</div>
|
||||
<div class="font-heading fs-12 bold">
|
||||
<span class="flag-icon fs-12" :class="'flag-icon-'+item.convertible_currency.country.short_code.toLowerCase()"></span> {{this.item.convertible_currency.short_code}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6 col-sm-auto d-none d-lg-block">
|
||||
<div class="font-heading fs-10 muted all-caps">Transfer Type</div>
|
||||
<div class="font-heading fs-11">{{this.item.service.name}}</div>
|
||||
</div>
|
||||
<div class="col-6 col-sm d-none d-lg-block">
|
||||
<div class="font-heading fs-10 muted all-caps">Payable Amount</div>
|
||||
<div class="font-heading fs-11 text-success bold">{{this.item.amount}} {{this.item.fixed_currency.short_code}}</div>
|
||||
</div>
|
||||
<div class="col-6 col-sm-auto d-none d-lg-block" v-if="$store.getters.isCustomer">
|
||||
<div class="font-heading fs-10 muted all-caps">status</div>
|
||||
<div class="font-heading fs-8 all-caps text-master btn-rounded p-l-10 p-r-10 lh-15 mt-1" :class="[{'bg-warning': item.status !== 3}, {'bg-success': item.status === 3} ]">
|
||||
{{item.status === 3 ? 'Complete' : 'In Progress'}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto hide d-none d-lg-block" :class="[{'invisible': !item.service.configurations.billable}]" v-if="$store.getters.isCustomer">
|
||||
<div class="font-heading fs-10 muted all-caps">Billing</div>
|
||||
<div class="font-heading fs-8 all-caps text-danger btn-rounded bg-master-lightest p-l-10 p-r-10 lh-15 mt-1">
|
||||
Pending...
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-2 p-r-5 parentContainer position-static">
|
||||
<div class="row align-items-center">
|
||||
<div class="col-auto ml-auto position-static">
|
||||
<div class="btn btn-xs btn-default b-rad-none requestModal" v-if="item.status !== 5 && item.paid_amount === 0 && item.floating_amount === 0 && $store.getters.isAdmin" data-type="cancelBooking">
|
||||
<i class="fa fa-fw fa-times text-danger"></i>
|
||||
</div>
|
||||
<div class="btn btn-xs btn-default b-rad-none requestModal" v-if="item.status === 5 && item.paid_amount === 0 && item.floating_amount === 0 && $store.getters.isAdmin" data-type="restoreBooking">
|
||||
<i class="fa fa-fw fa-history text-success"></i>
|
||||
</div>
|
||||
<a class="btn btn-xs btn-info b-rad-none" :href="route('booking.details', item.marking)">
|
||||
<i class="fa fa-angle-right fa-fw"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="cancelBooking">
|
||||
<cancel-booking-form-component :data="item" section="oderList" class="text-center"></cancel-booking-form-component>
|
||||
</modal-component>
|
||||
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="restoreBooking">
|
||||
<restore-booking-form-component :data="item" section="oderList" class="text-center"></restore-booking-form-component>
|
||||
</modal-component>
|
||||
</div>
|
||||
<div class="col-2 p-r-5 parentContainer position-static d-block d-sm-none">
|
||||
<div class="btn btn-xs btn-default b-rad-none position-absolute" style="top: 7px; right: 10px;" @click="expanded = !expanded">
|
||||
<i class="fa fa-fw" :class="[{'fa-angle-up': expanded}, {'fa-angle-down': !expanded}]"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="row" v-if="expanded">
|
||||
<div class="col b-b b-grey m-l-10 m-r-10 m-b-10 p-b-10" style="margin-top:-15px">
|
||||
<div class="row">
|
||||
<div class="col-6 col-sm" v-if="$store.getters.isAdmin">
|
||||
<div class="font-heading fs-10 muted all-caps">Marking</div>
|
||||
<div class="font-heading fs-12">
|
||||
<a :href="route('customer.profile', item.company.reference)">{{this.item.company.reference}}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6 col-sm-auto">
|
||||
<div class="font-heading fs-10 muted all-caps">Currency</div>
|
||||
<div class="font-heading fs-12 bold">
|
||||
<span class="flag-icon fs-12" :class="'flag-icon-'+item.convertible_currency.country.short_code.toLowerCase()"></span> {{this.item.convertible_currency.short_code}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6 col-sm-auto">
|
||||
<div class="font-heading fs-10 muted all-caps">Transfer Type</div>
|
||||
<div class="font-heading fs-11">{{this.item.service.name}}</div>
|
||||
</div>
|
||||
<div class="col-6 col-sm">
|
||||
<div class="font-heading fs-10 muted all-caps">Payable Amount</div>
|
||||
<div class="font-heading fs-11 text-success bold">{{this.item.amount}} {{this.item.fixed_currency.short_code}}</div>
|
||||
</div>
|
||||
<div class="col-6 col-sm-auto" v-if="$store.getters.isCustomer">
|
||||
<div class="font-heading fs-10 muted all-caps">status</div>
|
||||
<div class="font-heading fs-8 all-caps text-master btn-rounded p-l-10 p-r-10 lh-15 mt-1" :class="[{'bg-warning': item.status !== 3}, {'bg-success': item.status === 3} ]">
|
||||
{{item.status === 3 ? 'Complete' : 'In Progress'}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto hide" :class="[{'invisible': !item.service.configurations.billable}]" v-if="$store.getters.isCustomer">
|
||||
<div class="font-heading fs-10 muted all-caps">Billing</div>
|
||||
<div class="font-heading fs-8 all-caps text-danger btn-rounded bg-master-lightest p-l-10 p-r-10 lh-15 mt-1">
|
||||
Pending...
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a class="btn btn-xs btn-info b-rad-none" :href="route('booking.details', item.marking)">
|
||||
<i class="fa fa-angle-right fa-fw"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="cancelBooking">
|
||||
<cancel-booking-form-component :data="item" section="oderList" class="text-center"></cancel-booking-form-component>
|
||||
</modal-component>
|
||||
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="restoreBooking">
|
||||
<restore-booking-form-component :data="item" section="oderList" class="text-center"></restore-booking-form-component>
|
||||
</modal-component>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
@@ -1,53 +1,94 @@
|
||||
<template>
|
||||
<div class="row m-l-0 m-b-10 m-r-0 parentContainer" :class="[{'b-a': item.status === 4}, {'b-danger': item.status === 4}]" >
|
||||
<div class="col">
|
||||
<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}, {'bg-white': item.status !== 1 && item.status !== 4}]">
|
||||
<div class="row m-b-5">
|
||||
<div class="col-auto">
|
||||
<div class="font-heading fs-8 muted all-caps">Status</div>
|
||||
<div class="font-heading fs-10 bold" :class="[{'text-danger': item.status === 1 || item.status === 4}, {'text-success': item.status !== 1 && item.status !== 4}]">
|
||||
{{ item.status === 1 ? 'Pending Verification' : item.status === 2 ? 'Processing Payment' : item.status === 4 ? 'Rejected' : 'Transferred'}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto p-l-0">
|
||||
<div class="font-heading fs-8 muted all-caps">Payment Amount</div>
|
||||
<div class="font-heading fs-10 bold">
|
||||
{{ item.type === 3 ? item.original_currency.short_code : item.currency.short_code}} {{(Math.round((item.type === 3 ? item.original_amount : item.amount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-b-5">
|
||||
<div class="col" v-if="$store.getters.isAdmin && item.type === 3">
|
||||
<div class="font-heading fs-8 muted all-caps">Supplier</div>
|
||||
<div class="font-heading fs-10 bold">
|
||||
{{item.issuer_name}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" v-if="item.type === 1">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="font-heading fs-8 all-caps" :class="[{'text-danger': item.status === 4}, {'text-primary': item.status !== 4}]">{{ item.status === 1 ? 'Submitted' : item.status === 2 ? 'Received' : item.status === 4 ? 'Rejected' : 'Paid'}} On: {{item.updated_at}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto" v-if="item.status !== 3" :class="[{'bg-master-light': item.status === 1}, {'bg-master-lighter': item.status === 2}]">
|
||||
<div class="row align-items-center h-100">
|
||||
<div class="col">
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto bg-success" v-if="item.status === 3">
|
||||
<document-file-viewer-component class="h-100" :file="item.documents.files[0]">
|
||||
<template slot="button">
|
||||
<div class="row align-items-center h-100">
|
||||
<div class="col">
|
||||
<i class="fa fa-cloud-download text-white"></i>
|
||||
<div class="col p-t-10 p-b-10 p-r-0 pointer" @click="clickExpand()" :class="[{'bg-master-lighter': item.status === 1}, {'bg-white': item.status !== 1 && item.status !== 4}]">
|
||||
<div class="row m-b-5">
|
||||
<div class="col-auto">
|
||||
<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 === 1 ? 'Pending Verification' : item.status === 4 ? 'Rejected' : 'Processing Payment'}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto p-l-0">
|
||||
<div class="font-heading fs-8 muted all-caps">Payment Amount</div>
|
||||
<div class="font-heading fs-10 bold">
|
||||
{{item.currency.short_code}} {{(Math.round((item.amount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</document-file-viewer-component>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="font-heading fs-8 all-caps" :class="[{'text-danger': item.status === 4}, {'text-primary': item.status !== 4}]">{{ item.status === 2 ? 'Received' : item.status === 4 ? 'Rejected' : 'Submitted'}} On: {{item.updated_at}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto" v-if="item.status !== 3" :class="[{'bg-master-light': item.status === 1}, {'bg-master-lighter': item.status === 2}]">
|
||||
<div class="row align-items-center h-100" v-if="item.status !== 1 || item.payment_method !== 5">
|
||||
<div class="col">
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row align-items-center h-100" v-if="item.payment_method === 5 && item.status === 1">
|
||||
<div class="col">
|
||||
<a :href="'https://www.billplz.com/bills/'+item.payment_reference"><i class="fa fa-repeat text-success"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" v-if="item.type === 3">
|
||||
<div class="col">
|
||||
<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}, {'bg-white': item.status !== 1 && item.status !== 4}]">
|
||||
<div class="row m-b-5">
|
||||
<div class="col-auto">
|
||||
<div class="font-heading fs-8 muted all-caps">Status</div>
|
||||
<div class="font-heading fs-10 bold" :class="[{'text-danger': item.status === 1 || item.status === 4}, {'text-success': item.status !== 1 && item.status !== 4}]">
|
||||
{{ item.status === 1 ? 'Processing Payment' : 'Transferred'}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto p-l-0">
|
||||
<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 + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto" v-if="$store.getters.isAdmin">
|
||||
<div class="font-heading fs-8 muted all-caps">Supplier</div>
|
||||
<div class="font-heading fs-10 bold">
|
||||
{{item.issuer_name}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="font-heading fs-8 all-caps" >{{ item.status === 1 ? 'Paid On: ' + customerBooking.updated_at : 'Transferred On:' + item.updated_at }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto" v-if="item.status !== 3 && item.status !== 2" :class="[{'bg-master-light': item.status === 1}, {'bg-master-lighter': item.status === 2}]">
|
||||
<div class="row align-items-center h-100">
|
||||
<div class="col">
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto bg-success" v-if="item.status === 2 || item.status === 3">
|
||||
<document-file-viewer-component class="h-100" :file="item.documents.files[0]">
|
||||
<template slot="button">
|
||||
<div class="row align-items-center h-100">
|
||||
<div class="col">
|
||||
<i class="fa fa-cloud-download text-white"></i>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</document-file-viewer-component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" v-if="expandPaymentDetails">
|
||||
@@ -57,7 +98,7 @@
|
||||
<div class="font-heading all-caps fs-10">Recipient Gets</div>
|
||||
</div>
|
||||
<div class="col-auto text-right">
|
||||
<div class="font-heading fs-10">{{this.customerBooking.original_currency.short_code}} {{(Math.round((item.type === 3 ? customerBooking.original_amount : item.original_amount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}</div>
|
||||
<div class="font-heading fs-10">{{this.customerBooking.original_currency.short_code}} {{(item.original_amount).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row align-items-end bold m-b-10 text-primary">
|
||||
@@ -95,7 +136,7 @@
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="font-heading all-caps fs-10 m-b-5">Your Payment Proof</div>
|
||||
<div class="row no-margin">
|
||||
<div class="row no-margin" v-if="customerBooking.payment_method !== 5">
|
||||
<div v-if="customerBooking.documents != null">
|
||||
<div v-for="file in customerBooking.documents.files" v-bind:key="file.id" class="col-auto no-padding m-r-5">
|
||||
<document-file-viewer-component :file="file">
|
||||
@@ -108,10 +149,17 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row no-margin" v-if="customerBooking.payment_method === 5 && (customerBooking.status === 2 || customerBooking.status === 3)">
|
||||
<a :href="'https://www.billplz.com/bills/'+customerBooking.payment_reference" target="_blank">
|
||||
<div class="icon-thumbnail fs-11 text-white icon-25 bg-primary btn-rounded float-left m-r-5">
|
||||
<i class="fa fa-file-image-o fs-10"></i>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col text-right">
|
||||
<div class="font-heading all-caps fs-10 m-b-5">Our Payment Proof</div>
|
||||
<div class="row no-margin justify-content-end" v-if="item.status === 3">
|
||||
<div class="row no-margin justify-content-end" v-if="item.type === 3 && (item.status === 2 || item.status === 3)">
|
||||
<div v-for="file in item.documents.files" v-bind:key="file.id" class="col-auto no-padding m-l-5">
|
||||
<document-file-viewer-component :file="file">
|
||||
<template slot="button">
|
||||
@@ -124,7 +172,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-t-10">
|
||||
<div class="row m-t-10 hide">
|
||||
<div class="col">
|
||||
<button class="btn btn-xs all-caps b-rad-none btn-success btn-block requestModal" data-type="transferSummary">Request Refund</button>
|
||||
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="transferSummary" size="large">
|
||||
|
||||
@@ -41,10 +41,18 @@
|
||||
</div>
|
||||
</div>
|
||||
<bank-in-component :data="item"></bank-in-component>
|
||||
<div class="row" v-if="item.status === 2">
|
||||
<div class="col">
|
||||
<span class="text-complete fs-10 pointer requestModal" data-type="topUpModal">Cancel this order?</span>
|
||||
</div>
|
||||
</div>
|
||||
<modal-component type="topUpModal">
|
||||
<delete-transaction-form-component :data="item" section="section" class="text-center"></delete-transaction-form-component>
|
||||
</modal-component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-2 b-a b-dashed b-success requestModal pointer" v-if="item.status !== 3" @click="selectedID(item.id)" data-type="paymentProofModal">
|
||||
<div class="col-2 b-a b-dashed b-success requestModal pointer" v-if="item.status === 1" @click="selectedID(item.id)" data-type="paymentProofModal">
|
||||
<div class="row align-item-center justify-content-center h-100">
|
||||
<div class="col-auto" >
|
||||
<div class="row align-items-center h-100">
|
||||
@@ -61,6 +69,20 @@
|
||||
</modal-component>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto" v-if="item.status === 2">
|
||||
<button class="btn btn-xs btn-default bg-success b-rad-none no-border requestModal" data-type="approvePaymentTransaction">
|
||||
<i class="fa fa-check text-white fa-fw"></i>
|
||||
</button>
|
||||
<modal-component type="approvePaymentTransaction">
|
||||
<approve-payment-transaction-form-component :data="item" section="section" class="text-center"></approve-payment-transaction-form-component>
|
||||
</modal-component>
|
||||
<button class="btn btn-xs btn-default bg-danger b-rad-none no-border requestModal" data-type="deletePaymentTransaction">
|
||||
<i class="fa fa-times text-white fa-fw"></i>
|
||||
</button>
|
||||
<modal-component type="deletePaymentTransaction">
|
||||
<reject-payment-transaction-form-component :data="item" section="section" class="text-center"></reject-payment-transaction-form-component>
|
||||
</modal-component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+25
-10
@@ -7,13 +7,13 @@
|
||||
<div class="row align-items-center">
|
||||
<div class="col p-t-5 p-b-5">
|
||||
<div class="row">
|
||||
<div class="col-auto">
|
||||
<div class="col-6 col-md-6 col-lg-3">
|
||||
<div class="font-heading fs-10 muted all-caps">Reference</div>
|
||||
<div class="font-heading fs-10">
|
||||
{{item.bill_no}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<div class="col-6 col-md-6 col-lg-3">
|
||||
<div class="font-heading fs-10 muted all-caps">Transfer No.</div>
|
||||
<a :href="route('booking.details', item.booking.marking)">
|
||||
<div class="font-heading fs-10">
|
||||
@@ -21,24 +21,24 @@
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<div class="col-6 col-md-auto">
|
||||
<div class="font-heading fs-10 muted all-caps">Marking</div>
|
||||
<div class="font-heading fs-10">
|
||||
{{item.booking.company.reference}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col text-right">
|
||||
<div class="col text-lg-right">
|
||||
<div class="font-heading fs-10 muted all-caps">Date</div>
|
||||
<div class="font-heading fs-10">
|
||||
{{item.documents.created_at}}
|
||||
{{item.documents ? item.documents.created_at : item.updated_at}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-t-10">
|
||||
<div class="col-auto">
|
||||
<div class="col-6 col-md-6 col-lg-3">
|
||||
<div class="font-heading fs-10 muted all-caps">Payment Proof</div>
|
||||
<div class="row no-margin" v-if="item.documents != null">
|
||||
<div v-for="file in item.documents.files" v-bind:key="file.id" class="col-auto no-padding">
|
||||
<div class="row no-margin" v-if="item.payment_method !== 5">
|
||||
<div v-for="file in item.documents.files" v-bind:key="file.id" class="col-6 col-md-auto no-padding">
|
||||
<document-file-viewer-component :file="file">
|
||||
<template slot="button">
|
||||
<div class="icon-thumbnail fs-11 text-white icon-25 bg-primary btn-rounded float-left m-r-5">
|
||||
@@ -48,8 +48,15 @@
|
||||
</document-file-viewer-component>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row no-margin" v-if="item.payment_method ===5">
|
||||
<a :href="'https://www.billplz.com/bills/'+item.payment_reference" target="_blank">
|
||||
<div class="icon-thumbnail fs-11 text-white icon-25 bg-complete btn-rounded float-left m-r-5">
|
||||
Bz
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<div class="col-6 col-md-6 col-lg-3" >
|
||||
<div class="font-heading fs-10 muted all-caps">Amount</div>
|
||||
<div class="font-heading fs-12 text-success bold">
|
||||
MYR {{(Math.round((item.amount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
|
||||
@@ -61,7 +68,15 @@
|
||||
{{item.original_currency.short_code}} {{(Math.round((item.original_amount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!no_action" class="col-auto text-right">
|
||||
<div class="col text-lg-right">
|
||||
<div class="font-heading fs-10 muted all-caps">Service</div>
|
||||
<div class="font-heading fs-10">
|
||||
{{item.booking.service.name}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-t-10">
|
||||
<div v-if="!no_action" class="col-6 col-md-auto text-right">
|
||||
<button class="btn btn-xs btn-outline-danger b-rad-none m-r-5 requestModal" data-type="rejectPayment">
|
||||
<i class="fa fa-times fa-fw"></i>
|
||||
</button>
|
||||
|
||||
+37
-2
@@ -25,12 +25,39 @@
|
||||
<a :href="route('customer.profile', item.booking.company.reference)">{{item.booking.company.reference}}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<div class="font-heading fs-10 muted all-caps">Payment Proof</div>
|
||||
<div class="row no-margin" v-if="item.payment_method !==5">
|
||||
<div v-for="file in item.documents.files" v-bind:key="file.id" class="col-auto no-padding">
|
||||
<document-file-viewer-component :file="file">
|
||||
<template slot="button">
|
||||
<div class="icon-thumbnail fs-11 text-white icon-25 bg-primary btn-rounded float-left m-r-5">
|
||||
<i class="fa fa-file-image-o fs-10"></i>
|
||||
</div>
|
||||
</template>
|
||||
</document-file-viewer-component>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row no-margin" v-if="item.payment_method ===5">
|
||||
<a :href="'https://www.billplz.com/bills/'+item.payment_reference" target="_blank">
|
||||
<div class="icon-thumbnail fs-11 text-white icon-25 bg-complete btn-rounded float-left m-r-5">
|
||||
Bz
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<div class="font-heading fs-10 muted all-caps">Service</div>
|
||||
<div class="font-heading fs-10">
|
||||
{{item.booking.service.name}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-auto">
|
||||
<div class="font-heading fs-10 muted all-caps">Date</div>
|
||||
<div class="font-heading fs-10">
|
||||
{{item.documents.created_at}}
|
||||
{{item.payment_method === 5 ? item.updated_at : item.documents.created_at}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
@@ -39,12 +66,20 @@
|
||||
<span class="flag-icon" :class="'flag-icon-'+item.original_currency.country.short_code.toLowerCase()"></span> {{item.original_currency.short_code}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="col-auto">
|
||||
<div class="font-heading fs-10 muted all-caps">Amount</div>
|
||||
<div class="font-heading fs-12 text-success bold">
|
||||
{{(Math.round((item.original_amount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="font-heading fs-10 muted all-caps">timer</div>
|
||||
<div class="font-heading fs-10" :class="[{'text-success': item.interval.value === '+'}, {'text-danger': item.interval.value === '-'}]">
|
||||
{{item.interval.value}}
|
||||
{{item.interval.duration}}
|
||||
days
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
<template>
|
||||
<tr>
|
||||
<td class="v-align-middle">
|
||||
<p>{{item.documents.created_at}}</p>
|
||||
<p>{{item.documents ? item.documents.created_at : item.updated_at}}</p>
|
||||
</td>
|
||||
<td class="v-align-middle ">
|
||||
<p v-if="item.booking.bank.bank_name.includes('浙江网商银行')">1688.com</p>
|
||||
</td>
|
||||
<td class="v-align-middle ">
|
||||
<p>{{item.booking.marking}}</p>
|
||||
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
<template>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<loading-component style="height: 300px; top: 0;" key="1" color="success" v-show="isLoading" ></loading-component>
|
||||
<div class="row justify-content-center" v-show="!isLoading">
|
||||
<div class="col">
|
||||
<div class="row m-b-20">
|
||||
<div class="col">
|
||||
<h3 class="all-caps">Are you Sure?</h3>
|
||||
<div class="fs-11">Are you sure you want to approve this transaction?</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col p-r-5">
|
||||
<div class="btn btn-sm btn-default bg-master-lighter 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="submit(route('api.transaction.bill.status', item.id, 'complete'), 'put', section, true, true)">Confirm</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import componentHandler from '../../../general/mixins/componentHandler';
|
||||
import ModalFormHandler from '../../../general/mixins/modalFormHandler';
|
||||
export default {
|
||||
mixins: [componentHandler, ModalFormHandler]
|
||||
|
||||
}
|
||||
</script>
|
||||
+144
-37
File diff suppressed because one or more lines are too long
@@ -8,12 +8,17 @@
|
||||
<div class="font-heading all-caps fs-12 bold">Congratulation, you have got great rates.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-b-25">
|
||||
<div class="row m-b-25" v-if="payment_method !== 'payment_gateway'">
|
||||
<div class="col">
|
||||
<div class="font-heading fs-11">You can proceed by bank in <span class="text-success bold">{{(Math.round((calculation.total + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}} MYR</span> to the bank account detailed below and upload your payment proof to proceed with your transfer after clicking on the confirm button below.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row align-items-center m-b-25">
|
||||
<div class="row m-b-25" v-if="payment_method === 'payment_gateway'">
|
||||
<div class="col">
|
||||
<div class="font-heading fs-11">You will be redirected to your bank to complete the payment of <span class="text-success bold">{{(Math.round((calculation.total + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}} MYR</span> after clicking on the confirm button below. please follow your bank instruction to complete the payment</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row align-items-center m-b-25" v-if="payment_method !== 'payment_gateway'">
|
||||
<div class="col-auto p-r-0">
|
||||
<div class="icon-thumbnail icon-50 bg-master-lightest">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
|
||||
@@ -42,7 +47,7 @@
|
||||
</div>
|
||||
<div class="row m-b-20">
|
||||
<div class="col">
|
||||
<div class="font-heading text-danger fs-10 m-b-5">Please upload your payment proof before the booking expires within {{calculation.payment_attempt_limit}}.</div>
|
||||
<div class="font-heading text-danger fs-10 m-b-5">Please <span v-if="payment_method !== 'payment_gateway'">upload your payment proof </span><span v-if="payment_method === 'payment_gateway'">complete your payment</span> before the booking expires within {{calculation.payment_attempt_limit}}.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-b-5">
|
||||
@@ -77,6 +82,9 @@
|
||||
payment_method: {
|
||||
required: true
|
||||
},
|
||||
bank_code: {
|
||||
required: false
|
||||
},
|
||||
id: {
|
||||
type: Number,
|
||||
required: true
|
||||
@@ -91,6 +99,7 @@
|
||||
parameters: {
|
||||
payment_method: this.payment_method,
|
||||
amount: this.amount,
|
||||
bank_code: this.bank_code,
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
<template>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<loading-component style="height: 300px; top: 0;" key="1" color="success" v-show="isLoading" ></loading-component>
|
||||
<div class="row justify-content-center" v-show="!isLoading">
|
||||
<div class="col">
|
||||
<div class="row m-b-20">
|
||||
<div class="col">
|
||||
<h3 class="all-caps">Are you Sure?</h3>
|
||||
<div class="fs-11">Are you sure you want to delete this transaction? You will not be able to recover your booking after confirming your action.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col p-r-5">
|
||||
<div class="btn btn-sm btn-success btn-block b-rad-none" data-dismiss="modal">Cancel</div>
|
||||
</div>
|
||||
<div class="col p-l-5">
|
||||
<div class="btn btn-sm btn-danger btn-block b-rad-none" @click="submit(route('api.transaction.bill.delete', item.id), 'delete', section, true, true)">Confirm</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import componentHandler from '../../../general/mixins/componentHandler';
|
||||
import ModalFormHandler from '../../../general/mixins/modalFormHandler';
|
||||
export default {
|
||||
mixins: [componentHandler, ModalFormHandler]
|
||||
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,68 @@
|
||||
<template>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-b-10">
|
||||
<div class="col">
|
||||
<validation-wrapper-component :validator="$v.fix_amount">
|
||||
<label class="muted">Booking Amount ({{data.fixed_currency.short_code}})</label>
|
||||
<input type="text" class="form-control" v-model="fix_amount" 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: '',
|
||||
fix_amount: (Math.round((this.data.amount + Number.EPSILON) * 100) / 100).toFixed(2)
|
||||
}
|
||||
},
|
||||
validations: {
|
||||
fix_amount: { required }
|
||||
},
|
||||
watch: {
|
||||
'data': function() {
|
||||
this.fix_amount = (Math.round((this.data.amount + Number.EPSILON) * 100) / 100).toFixed(2);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
submitForm(){
|
||||
this.parameters = {fix_amount : parseFloat((this.fix_amount).toString().replace(',', ''))}
|
||||
this.submit(this.route('api.booking.booking_amount.update', this.data.id), 'put', this.section, true, true)
|
||||
},
|
||||
successHandler(){
|
||||
this.closeModal();
|
||||
this.formHandler('');
|
||||
},
|
||||
},
|
||||
mixins: [FormHandler]
|
||||
}
|
||||
</script>
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,97 @@
|
||||
<template>
|
||||
<div class="row align-items-center">
|
||||
<div class="col-auto p-r-0" style="min-width: 40px;">
|
||||
<div class="font-heading all-caps fs-10">{{index + 1}}</div>
|
||||
</div>
|
||||
<div class="col p-r-5">
|
||||
<div v-if="!isEdit" class="font-heading all-caps fs-10">{{product.stockCode}}</div>
|
||||
<input v-if="isEdit" type="text" class="form-control fs-10 b-rad-none" placeholder="Stock Code" v-model="product.stockCode" />
|
||||
</div>
|
||||
<div class="col-4 p-r-5 p-l-5">
|
||||
<div v-if="!isEdit" class="font-heading all-caps fs-10">{{product.description}}</div>
|
||||
<textarea v-if="isEdit" class="form-control fs-10 b-rad-none" placeholder="Description" rows="1" @keyup="onlyEnglish($event)" v-model="product.description"></textarea>
|
||||
</div>
|
||||
<div class="col text-center p-r-5 p-l-5">
|
||||
<div v-if="!isEdit" class="font-heading all-caps fs-10">{{product.quantity}}</div>
|
||||
<input v-if="isEdit" type="text" class="form-control fs-10 b-rad-none text-center" placeholder="Quantity" v-model.lazy="product.quantity" v-mask="'#########'"/>
|
||||
</div>
|
||||
<div class="col text-center p-r-5 p-l-5">
|
||||
<div v-if="!isEdit" class="font-heading all-caps fs-10">{{product.unit_price}}</div>
|
||||
<input v-if="isEdit" type="text" class="form-control fs-10 b-rad-none text-center" placeholder="Unit Price" v-model.lazy="product.unit_price" v-money="productPrice" />
|
||||
</div>
|
||||
<div class="col-1 text-center p-r-5 p-l-5">
|
||||
<div class="font-heading all-caps fs-10">{{currency}}</div>
|
||||
</div>
|
||||
<div class="col-1 text-right p-r-5 p-l-5">
|
||||
<div class="font-heading all-caps fs-10">{{(Math.round((productTotal + Number.EPSILON) * 100) / 100).toFixed(2) }}</div>
|
||||
</div>
|
||||
<div class="col-auto" :class="[{'invisible': !editable}]">
|
||||
<button class="btn btn-xs btn-outline-danger b-rad-none" @click="$emit('remove')"><i class="fa fa-times"></i></button>
|
||||
<button v-if="!isEdit" class="btn btn-xs btn-outline-warning b-rad-none" @click="isEdit = !isEdit"><i class="fa fa-pencil"></i></button>
|
||||
<button v-if="isEdit" class="btn btn-xs btn-outline-success b-rad-none" @click="updateProduct()"><i class="fa fa-check"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import formHandler from '../../../general/mixins/formHandler';
|
||||
export default {
|
||||
props: {
|
||||
editable: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
currency:{
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
index:{
|
||||
type: Number,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
isEdit: false,
|
||||
product: {
|
||||
stockCode: '',
|
||||
description: '',
|
||||
unit_price: 0,
|
||||
},
|
||||
products: []
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.product = this.data;
|
||||
this.product.unit_price = (Math.round((this.product.unit_price+ Number.EPSILON) * 1000) / 1000).toFixed(3)
|
||||
},
|
||||
computed: {
|
||||
productTotal(){
|
||||
return this.product.quantity * parseFloat((this.product.unit_price).toString().replace(',', ''));
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
updateProduct(){
|
||||
this.isEdit = !this.isEdit;
|
||||
|
||||
this.$emit('change', {
|
||||
stockCode: this.product.stockCode,
|
||||
description: this.product.description,
|
||||
quantity: this.product.quantity,
|
||||
unit_price: parseFloat((this.product.unit_price).toString().replace(',', '')),
|
||||
total: this.productTotal
|
||||
}, this.index);
|
||||
},
|
||||
onlyEnglish(event){
|
||||
let value = event.target.value,
|
||||
regex = /^[^~`!@#$%^&*()_+=[\]\{}|;':",.\/<>?a-zA-Z0-9-]+$/;
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
if(regex.test(value)){
|
||||
this.product.description = value.replace(regex, '');
|
||||
}
|
||||
},
|
||||
},
|
||||
mixins: [formHandler]
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,33 @@
|
||||
<template>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<loading-component style="height: 300px; top: 0;" key="1" color="success" v-show="isLoading" ></loading-component>
|
||||
<div class="row justify-content-center" v-show="!isLoading">
|
||||
<div class="col">
|
||||
<div class="row m-b-20">
|
||||
<div class="col">
|
||||
<h3 class="all-caps">Are you Sure?</h3>
|
||||
<div class="fs-11">Are you sure you want to regenerate the invoices for this transfer?</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col p-r-5">
|
||||
<div class="btn btn-sm btn-success btn-block b-rad-none" data-dismiss="modal">Cancel</div>
|
||||
</div>
|
||||
<div class="col p-l-5">
|
||||
<div class="btn btn-sm btn-danger btn-block b-rad-none" @click="submit(route('api.booking.regenerate.invoice', data.id), 'post', section, true, true)">Confirm</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import componentHandler from '../../../general/mixins/componentHandler';
|
||||
import ModalFormHandler from '../../../general/mixins/modalFormHandler';
|
||||
export default {
|
||||
mixins: [componentHandler, ModalFormHandler]
|
||||
|
||||
}
|
||||
</script>
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
<template>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<loading-component style="height: 300px; top: 0;" key="1" color="success" v-show="isLoading" ></loading-component>
|
||||
<div class="row justify-content-center" v-show="!isLoading">
|
||||
<div class="col">
|
||||
<div class="row m-b-20">
|
||||
<div class="col">
|
||||
<h3 class="all-caps">Are you Sure?</h3>
|
||||
<div class="fs-11">Are you sure you want to reject this transaction?</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col p-r-5">
|
||||
<div class="btn btn-sm btn-success btn-block b-rad-none" data-dismiss="modal">Cancel</div>
|
||||
</div>
|
||||
<div class="col p-l-5">
|
||||
<div class="btn btn-sm btn-danger btn-block b-rad-none" @click="submit(route('api.transaction.bill.status', item.id, 'pending'), 'put', section, true, true)">Confirm</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import componentHandler from '../../../general/mixins/componentHandler';
|
||||
import ModalFormHandler from '../../../general/mixins/modalFormHandler';
|
||||
export default {
|
||||
mixins: [componentHandler, ModalFormHandler]
|
||||
|
||||
}
|
||||
</script>
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="row">
|
||||
<div class="row mt-3 mt-md-0">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
|
||||
+20
-7
@@ -4,7 +4,7 @@
|
||||
<loading-component style="height: 200px; top: 0;" key="1" color="success" v-show="isLoading"></loading-component>
|
||||
<div class="row" v-if="booking">
|
||||
<div class="col">
|
||||
<div class="row m-b-50" v-if="booking.status === 3 && transactionsComplete">
|
||||
<div class="row m-b-50" v-if="booking.status === 3">
|
||||
<div class="col-10 no-padding">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
@@ -29,7 +29,7 @@
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-2 p-r-0">
|
||||
<div class="col-4 col-sm-2 p-r-0 h-100">
|
||||
<document-file-viewer-component :file="booking.documents.invoice.files[0]" v-if="booking.documents.invoice">
|
||||
<template slot="button">
|
||||
<div class="bg-white text-center padding-20 pointer b-grey">
|
||||
@@ -44,7 +44,7 @@
|
||||
</template>
|
||||
</document-file-viewer-component>
|
||||
</div>
|
||||
<div class="col-2 p-r-0">
|
||||
<div class="col-4 col-sm-2 p-r-0 h-100">
|
||||
<document-file-viewer-component :file="booking.documents.purchase_order.files[0]" v-if="booking.documents.purchase_order">
|
||||
<template slot="button">
|
||||
<div class="bg-white text-center padding-20 pointer b-grey">
|
||||
@@ -59,7 +59,7 @@
|
||||
</template>
|
||||
</document-file-viewer-component>
|
||||
</div>
|
||||
<div class="col-2 p-r-0">
|
||||
<div class="col-4 col-sm-2 p-r-0 h-100">
|
||||
<document-file-viewer-component :file="booking.documents.delivery_order.files[0]" v-if="booking.documents.delivery_order">
|
||||
<template slot="button">
|
||||
<div class="bg-white text-center padding-20 pointer b-grey">
|
||||
@@ -203,8 +203,12 @@
|
||||
<purchase-order-form-component :data="booking" :section="section"></purchase-order-form-component>
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn btn-xs all-caps b-rad-none btn-danger pointer requestModal" data-type="regenerateInvoices" v-if="booking.status === 3 && $store.getters.isSuperAdmin">Regenerate Invoices</div>
|
||||
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="regenerateInvoices">
|
||||
<regenerate-booking-invoices-component :data="booking" :section="section" class="text-center"></regenerate-booking-invoices-component>
|
||||
</modal-component>
|
||||
</div>
|
||||
<div class="col-12 col-sm-12 col-md-3">
|
||||
<div class="col-12 col-sm-12 col-md-3 mt-3 mt-sm-0">
|
||||
<booking-payment-quotation-component :data="booking" :section="section"></booking-payment-quotation-component>
|
||||
<div class="row m-t-20" v-if="booking.payment_attempts.length">
|
||||
<div class="col">
|
||||
@@ -250,7 +254,16 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto p-l-5 p-r-5 bg-success requestModal pointer" data-type="identificationVerificationModal">
|
||||
<div class="col-auto p-l-5 p-r-5 bg-success pointer" v-if="item.payment_method === 5">
|
||||
<a :href="'https://www.billplz.com/bills/'+item.payment_reference">
|
||||
<div class="row align-items-center h-100">
|
||||
<div class="col">
|
||||
<i class="fa fa-repeat fs-20 text-white p-l-10 p-r-10"></i>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-auto p-l-5 p-r-5 bg-success requestModal pointer" v-if="item.payment_method !== 5" data-type="paymentProofModal">
|
||||
<div @click="selectedID(item.id)" class="row align-items-center h-100">
|
||||
<div class="col">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
|
||||
@@ -263,7 +276,7 @@
|
||||
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="deleteAttempt">
|
||||
<delete-payment-attempt-form-component :data="item" :section="section" class="text-center"></delete-payment-attempt-form-component>
|
||||
</modal-component>
|
||||
<modal-component type="identificationVerificationModal">
|
||||
<modal-component type="paymentProofModal">
|
||||
<payment-verification-form-component v-if="selected_id == item.id" :section="section" :id="booking.id" :data="item"></payment-verification-form-component>
|
||||
</modal-component>
|
||||
</div>
|
||||
|
||||
+62
-14
@@ -4,34 +4,34 @@
|
||||
<div class="row">
|
||||
<div class="col p-r-5">
|
||||
<div class="row m-b-20">
|
||||
<div class="col-7">
|
||||
<div class="col-12 col-md-7">
|
||||
<div class="row m-b-15">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col-8 p-r-0">
|
||||
<div class="btn btn-xs btn-outline-primary btn-block text-left b-rad-none p-t-0 p-b-0 p-l-15 p-r-15" @click="selectedSupplier.status = !selectedSupplier.status">
|
||||
<div class="col p-r-0">
|
||||
<div class="btn btn-xs btn-outline-primary btn-block text-left b-rad-none p-t-0 p-b-0 p-l-15 p-r-15" @click="serviceDropdownLaunch.status = ! serviceDropdownLaunch.status">
|
||||
<div class="row">
|
||||
<div class="col p-t-5 p-b-5 fs-9">
|
||||
{{selectedSupplier.name}}
|
||||
<div class="col p-t-5 p-b-5">
|
||||
{{selectedService.name}}
|
||||
</div>
|
||||
<div class="col-auto b-l b-success">
|
||||
<div class="col-auto b-l b-primary">
|
||||
<div class="row h-100 align-items-center">
|
||||
<div class="col">
|
||||
<i class="fa" :class="[{'fa-angle-down': !selectedSupplier.status}, {'fa-angle-up': selectedSupplier.status}]"></i>
|
||||
<i class="fa" :class="[{'fa-angle-down': !serviceDropdownLaunch.status}, {'fa-angle-up': serviceDropdownLaunch.status}]"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative w-100">
|
||||
<div class="absolute w-100 b-l b-b b-r b-primary" :class="[{'hide': !selectedSupplier.status}]" style="top: 100%; right: 0; z-index: 1;">
|
||||
<div class="absolute w-100 b-l b-b b-r b-success" v-show="serviceDropdownLaunch.status" style="top: 100%; right: 0; z-index: 1;">
|
||||
<div class="row text-left no-margin bg-white">
|
||||
<div class="col no-padding">
|
||||
<div class="row no-margin" v-for="supplier in suppliers" v-bind:key="supplier.id" :data="supplier">
|
||||
<div class="col b-b b-grey p-t-10 p-b-10 pointer hover-t-10 p-b-10" :class="[{'bg-primary-light': selectedSupplier.id === supplier.id}, {'text-white': selectedSupplier.id === supplier.id}, {'hover-primary': selectedSupplier.id !== supplier.id}, {'pointer': selectedSupplier.id !== supplier.id}]" @click="updateSupplier(supplier)">
|
||||
<div class="row no-margin" v-for="service in selectedSupplier.services" v-bind:key="service.id" :data="service">
|
||||
<div class="col b-b b-grey p-t-10 p-b-10 pointer hover-t-10 p-b-10" :class="[{'bg-primary-light': selectedService.id === service.id}, {'text-white': selectedService.id === service.id}, {'hover-primary': selectedService.id !== service.id}, {'pointer': selectedService.id !== service.id}]" @click="updateService(service)">
|
||||
<div class="row align-items-center justify-content-center">
|
||||
<div class="col">
|
||||
<div class="font-heading fs-10">{{supplier.name}}</div>
|
||||
<div class="font-heading fs-10">{{service.name}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -41,7 +41,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-4 p-r-0">
|
||||
<div class="col p-r-0">
|
||||
<div class="btn btn-xs btn-outline-primary btn-block text-left b-rad-none p-t-0 p-b-0 p-l-15 p-r-15" @click="currencyDropdownLaunch.status = ! currencyDropdownLaunch.status">
|
||||
<div class="row">
|
||||
<div class="col p-t-5 p-b-5">
|
||||
@@ -75,11 +75,46 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-t-5">
|
||||
<div class="col p-r-0">
|
||||
<div class="btn btn-xs btn-outline-primary btn-block text-left b-rad-none p-t-0 p-b-0 p-l-15 p-r-15" @click="selectedSupplier.status = !selectedSupplier.status">
|
||||
<div class="row">
|
||||
<div class="col p-t-5 p-b-5 fs-9">
|
||||
{{selectedSupplier.name}}
|
||||
</div>
|
||||
<div class="col-auto b-l b-success">
|
||||
<div class="row h-100 align-items-center">
|
||||
<div class="col">
|
||||
<i class="fa" :class="[{'fa-angle-down': !selectedSupplier.status}, {'fa-angle-up': selectedSupplier.status}]"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative w-100">
|
||||
<div class="absolute w-100 b-l b-b b-r b-primary" :class="[{'hide': !selectedSupplier.status}]" style="top: 100%; right: 0; z-index: 1;">
|
||||
<div class="row text-left no-margin bg-white">
|
||||
<div class="col no-padding">
|
||||
<div class="row no-margin" v-for="supplier in suppliers" v-bind:key="supplier.id" :data="supplier">
|
||||
<div class="col b-b b-grey p-t-10 p-b-10 pointer hover-t-10 p-b-10" :class="[{'bg-primary-light': selectedSupplier.id === supplier.id}, {'text-white': selectedSupplier.id === supplier.id}, {'hover-primary': selectedSupplier.id !== supplier.id}, {'pointer': selectedSupplier.id !== supplier.id}]" @click="updateSupplier(supplier)">
|
||||
<div class="row align-items-center justify-content-center">
|
||||
<div class="col">
|
||||
<div class="font-heading fs-10">{{supplier.name}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<list-component ref="pendingOrdersList" section="pendingOrdersSection" :endpoint="route('api.transaction.list')" :options="{per_page: 10000, status: 2, type: 1, original_currency_id_in: [selectedCurrency.id]}">
|
||||
<list-component ref="pendingOrdersList" section="pendingOrdersSection" :endpoint="route('api.transaction.list')" :options="{per_page: 10000, status: 2, type: 1, original_currency_id_in: [selectedCurrency.id], service_type_id_in: [selectedService.id]}">
|
||||
<template slot="list" slot-scope="{data}">
|
||||
<supplier-pending-order-component :data="data" v-on:input="updateOrder($event)"></supplier-pending-order-component>
|
||||
</template>
|
||||
@@ -87,7 +122,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="col-12 col-md">
|
||||
<supplier-place-order-form-component :payments="payments" :currency="selectedCurrency" :supplier="selectedSupplier" section="pendingOrdersSection"></supplier-place-order-form-component>
|
||||
<div class="row m-t-20">
|
||||
<div class="col">
|
||||
@@ -124,6 +159,14 @@
|
||||
currencyDropdownLaunch: {
|
||||
status: false
|
||||
},
|
||||
serviceDropdownLaunch: {
|
||||
status: false
|
||||
},
|
||||
selectedService: {
|
||||
id: 1,
|
||||
name: '',
|
||||
status: false
|
||||
},
|
||||
payments: []
|
||||
}
|
||||
},
|
||||
@@ -135,6 +178,7 @@
|
||||
this.suppliers = response.payload.data;
|
||||
this.updateSupplier(this.suppliers[0]);
|
||||
this.updateCurrency(this.suppliers[0].currencies[0]);
|
||||
this.updateService(this.suppliers[0].services[0]);
|
||||
},
|
||||
updateSupplier(supplier){
|
||||
this.selectedSupplier = supplier;
|
||||
@@ -151,6 +195,10 @@
|
||||
this.payments = [];
|
||||
|
||||
},
|
||||
updateService(service){
|
||||
this.selectedService = service;
|
||||
this.serviceDropdownLaunch.status = false;
|
||||
},
|
||||
updateOrder(payment){
|
||||
this.payments.includes(payment) ? this.payments.splice(this.payments.indexOf(payment), 1) : this.payments.push(payment);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width:20%">Date</th>
|
||||
<th style="width:20%">Label</th>
|
||||
<th style="width:20%">Reference</th>
|
||||
<th style="width:29%">Marking</th>
|
||||
<th style="width:15%">Amount</th>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="row m-b-15 align-items-end">
|
||||
<div class="col">
|
||||
<div class="col-auto">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="font-heading fs-10 muted all-caps">Marking</div>
|
||||
@@ -12,7 +12,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-3 text-center">
|
||||
<div class="col-2 text-center">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="font-heading fs-10 muted all-caps">Payments</div>
|
||||
@@ -25,6 +25,30 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-2 text-center">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="font-heading fs-10 muted all-caps">Average Daily Spending</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="font-heading fs-11">MYR {{(Math.round((this.item.average_spending_per_day + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-2 text-center">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="font-heading fs-10 muted all-caps">Average Booking Spending</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="font-heading fs-11">MYR {{(Math.round((this.item.average_spending_per_booking + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto text-center">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="font-heading fs-10 muted all-caps">Last Payment</div>
|
||||
@@ -36,7 +60,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-2 text-center">
|
||||
<div class="col-auto text-center">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="font-heading fs-10 muted all-caps">Bookings</div>
|
||||
@@ -44,7 +68,7 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="font-heading all-caps fs-11">{{this.item.bookings.length}}</div>
|
||||
<div class="font-heading all-caps fs-11"><span v-if="item.confirmed_bookings">{{this.item.confirmed_bookings}} / </span>{{this.item.bookings.length}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
<i class="fa fa-circle text-success m-r-5" :class="[{'text-success': item.status === 2}, {'text-danger-darker': item.status === 5}, {'text-danger': item.status !== 2 || item.status !== 5}]"></i>{{item.status === 2 ? 'Active' : item.status === 5 ? 'Suspended' : 'Inactive'}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col m-l-50">
|
||||
<div class="col-auto m-l-50">
|
||||
<div class="row align-items-center parentContainer">
|
||||
<div class="col-auto padding-5 b-a b-grey b-rad-lg pointer requestModal" data-type="assignSegment">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
|
||||
@@ -64,6 +64,23 @@
|
||||
</modal-component>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col m-l-50">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<p class="m-b-0 fs-11 muted bold"><b>Last Payment: </b>{{item.last_payment}}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<p class="m-b-0 fs-11 muted bold"><b>Payment Amount: </b>MYR {{(Math.round((item.total_payments + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<p class="m-b-0 fs-11 muted bold"><b>Created at: </b>{{item.created_at}}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+34
@@ -3,6 +3,40 @@
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-10 ">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row" style="background-image: url('/images/—Pngtree—2019 chinese new year lantern_951828.jpg'); background-size: cover;">
|
||||
<div class="col no-padding">
|
||||
<div class="text-white text-center p-t-25 p-l-25 p-r-25" style="background-color: rgba(0,0,0,0.4);">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row m-b-20">
|
||||
<div class="col">
|
||||
<p class="m-b-0">新年快乐!</p>
|
||||
<p class="m-b-15">CIEF祝您春节快乐,万事如意,财运亨通,虎虎生威!<br>在此想通知您公司复工日期如下 :-</p>
|
||||
<p class="m-b-15 bold">客服团队 : 2022年2月7日</p>
|
||||
<p class="bold">* 假期期间 Exchange 照常可以下单,人民币复工之后就可以安排汇款</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-b-20">
|
||||
<div class="col">
|
||||
<p class="m-b-0">Happy Chinese New Year!</p>
|
||||
<p class="m-b-15">CIEF wishes you a successful & prosperous Chinese New Year.. may your business prosper with every opportunity that comes your way. <br>We would like to also update you about our company's operation resume dates as below :-</p>
|
||||
<p class="m-b-15 bold">Customer Service : 07 February 2022</p>
|
||||
<p class="bold">* EXCHANGE bookings can be placed as usual during the holidays , RMB transfers will be arranged after operation resume.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<list-component style="min-height: auto;" section="customerAnnouncements" :emptyListSection=false :endpoint="route('api.announcement.list')" :options="{has_segments:true,is_published:true}">
|
||||
<template slot="list" slot-scope="{data}">
|
||||
<view-announcement-form-component :data="data" section="customerAnnouncements"></view-announcement-form-component>
|
||||
|
||||
+1
-1
@@ -10,8 +10,8 @@
|
||||
</div>
|
||||
<div class="row m-b-10">
|
||||
<div class="col">
|
||||
<div class="fs-12">Full Name</div>
|
||||
<validation-wrapper-component :validator="$v.parameters.name">
|
||||
<label>Full Name</label>
|
||||
<input type="text" class="form-control" v-model="parameters.name">
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
@extends('layouts.base')
|
||||
|
||||
@section('content')
|
||||
<div class="row d-md-none" v-if="$store.getters.isShowing('sideMenu')">
|
||||
<div class="col absolute bg-master w-100 h-100" style="opacity: 0.3; z-index: 9998; left: 0px;"></div>
|
||||
<div class="col-8 bg-master-lightest position-fixed h-100" style="z-index: 9999" >
|
||||
@include('partials.menu')
|
||||
</div>
|
||||
</div>
|
||||
@include('partials.header')
|
||||
<div class="page-container">
|
||||
<div class="page-content-wrapper p-b-50" style="padding-top: 70px;">
|
||||
<div class="content pt-md-auto pt-4">
|
||||
<div class="container-fluid p-l-30 p-r-30 container-fixed-lg">
|
||||
<div class="container-fluid p-0 px-sm-5 container-fixed-lg">
|
||||
<div class="row no-margin">
|
||||
<div class="col">
|
||||
@yield('inner_content')
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user