Merge branch 'master' of gitlab.com:CIEFWorldwideSdnBhd/exchange-2.0 into manual-po-segment-update

This commit is contained in:
Jia Sheng
2024-08-26 21:13:51 +08:00
65 changed files with 2263 additions and 333 deletions
@@ -2,7 +2,6 @@
namespace App\Classes\General\Eloquent\Filters;
use App\Classes\ValueObjects\Constants\RoleTypes;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Auth;
@@ -12,33 +11,17 @@ class HasActiveReward implements Filter
/**
* @param Builder $builder
* @param $value
* @return mixed
* @return Builder|mixed
*/
public static function apply(Builder $builder, $value)
{
if(in_array(Auth::user()->type, RoleTypes::ADMIN_ROLES)){
// $userId = $value !== 1 ? $value : Auth::user()->id;
$userId = $value;
return $builder->where('user_id', $userId)
->where(function ($query) {
$query->whereHas('reward', function ($subquery) {
$subquery->where('is_active', true);
})
->orWhereDoesntHave('reward');
})
->whereDoesntHave('voucher.redemptions.transaction.booking.company.employees', function ($query) use ($userId) {
$query->where('user_id', $userId);
return $builder->where('user_id', Auth::user()->id) //cief todo: should not use Auth::user()->id
->where(function ($query) {
$query->whereHas('reward', function ($subquery) {
$subquery->where('is_active', true);
});
}
else{
return $builder->where('user_id', Auth::user()->id)
->where(function ($query) {
$query->whereHas('reward', function ($subquery) {
$subquery->where('is_active', true);
})
->orWhereDoesntHave('reward');
})
->whereDoesntHave('voucher.redemptions.transaction.owner');
}
// ->orWhereDoesntHave('reward');
});
}
}
@@ -0,0 +1,26 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class HasActiveRewardForAdmin implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return Builder|mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->where('user_id', $value)
->where(function ($query) {
$query->whereHas('reward', function ($subquery) {
$subquery->where('is_active', true);
});
// ->orWhereDoesntHave('reward');
});
}
}
@@ -0,0 +1,53 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use App\Classes\ValueObjects\Constants\RoleTypes;
use App\Models\User;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Auth;
class HasVouchersAllWithCompany implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return mixed
*/
public static function apply(Builder $builder, $value)
{
if(in_array(Auth::user()->type, RoleTypes::ADMIN_ROLES)){
// $userId = $value !== 1 ? $value : Auth::user()->id;
$userId = $value;
$user = User::where('id', $userId)->first();
$users = $user->company()->first()->employees;
$userIds = $users->pluck('id');
return $builder->whereIn('user_id', $userIds)
->where(function ($query) {
$query->whereHas('reward', function ($subquery) {
$subquery->where('is_active', true);
})
->orWhereDoesntHave('reward');
})
->whereDoesntHave('voucher.redemptions.transaction.booking.company.employees', function ($query) use ($userId) {
$query->where('user_id', $userId);
});
}
else{
$user = User::where('id', Auth::user()->id)->first();
$users = $user->company()->first()->employees;
$userIds = $users->pluck('id');
return $builder->whereIn('user_id', $userIds)
->where(function ($query) {
$query->whereHas('reward', function ($subquery) {
$subquery->where('is_active', true);
})
->orWhereDoesntHave('reward');
})
->whereDoesntHave('voucher.redemptions.transaction.owner');
}
}
}
@@ -0,0 +1,44 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use App\Classes\ValueObjects\Constants\RoleTypes;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Auth;
class HasVouchersAllWithUser implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return mixed
*/
public static function apply(Builder $builder, $value)
{
if(in_array(Auth::user()->type, RoleTypes::ADMIN_ROLES)){
// $userId = $value !== 1 ? $value : Auth::user()->id;
$userId = $value;
return $builder->where('user_id', $userId)
->where(function ($query) {
$query->whereHas('reward', function ($subquery) {
$subquery->where('is_active', true);
})
->orWhereDoesntHave('reward');
})
->whereDoesntHave('voucher.redemptions.transaction.booking.company.employees', function ($query) use ($userId) {
$query->where('user_id', $userId);
});
}
else{
return $builder->where('user_id', Auth::user()->id)
->where(function ($query) {
$query->whereHas('reward', function ($subquery) {
$subquery->where('is_active', true);
})
->orWhereDoesntHave('reward');
})
->whereDoesntHave('voucher.redemptions.transaction.owner');
}
}
}
@@ -1,20 +0,0 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class RandomName implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return Builder|mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->where('is_active', $value);
}
}
+5 -1
View File
@@ -41,7 +41,11 @@ class UpdatePerfexCRMPrelude implements ShouldQueue
{
$serviceTypeName = $this->transaction->owner->company->services()->where('id', $this->transaction->owner->service_id)->first()->name;
$booking = $this->transaction->booking;
$bankDetails = $this->generateBankDetails($booking->bank);
$bank = $booking->bank; //cief todo: 66
if($this->transaction->bank){
$bank = $this->transaction->bank;
}
$bankDetails = $this->generateBankDetails($bank);
$data = [
'amount' => number_format($this->transaction->amount, 2, '.', ''),
@@ -0,0 +1,19 @@
<?php
namespace App\Classes\Modules\Accounts\Services;
use App\Classes\General\Eloquent\AbstractDeleteRecord;
use App\Models\KeyValuePair;
class DeletesKeyValuePair extends AbstractDeleteRecord
{
/**
* @param KeyValuePair $model
* @return mixed
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function execute(KeyValuePair $model) {
return $this->handler($model);
}
}
@@ -3,21 +3,17 @@
namespace App\Classes\Modules\Banks\ControllersLogic;
use App\Http\Resources\BankResource;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Banks\Services\FetchesBank;
use App\Classes\Modules\Banks\Standards\Rules\CanUpdateBank;
use App\Classes\Modules\Banks\Services\UpdatesBank;
use App\Classes\Modules\Banks\Services\CreatesOrUpdateBank;
use App\Classes\Modules\Banks\Services\CreatesBankLog;
use App\Classes\Modules\Banks\Processors\UpdateBankProcessor;
use App\Classes\Modules\Banks\DataTransferObjects\BankObject;
use ErrorException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class UpdateBankLogic extends AbstractControllerLogic
{
@@ -44,24 +40,36 @@ class UpdateBankLogic extends AbstractControllerLogic
/** @var CreatesBankLog */
private $createsBankLog;
/** @var CreatesOrUpdateBank */
private $createsOrUpdateBank;
/** @var UpdateBankProcessor */
private $updateBankProcessor;
/**
* UpdateBankLogic constructor.
* @param CanUpdateBank $canUpdateBank
* @param UpdatesBank $updatesBank
* @param FetchesBank $fetchesBank
* @param CreatesBankLog $createsBankLog
* @param CreatesOrUpdateBank $createsOrUpdateBank
* @param UpdateBankProcessor $updateBankProcessor
*/
public function __construct(
CanUpdateBank $canUpdateBank,
UpdatesBank $updatesBank,
FetchesBank $fetchesBank,
CreatesBankLog $createsBankLog
CreatesBankLog $createsBankLog,
CreatesOrUpdateBank $createsOrUpdateBank,
UpdateBankProcessor $updateBankProcessor
)
{
$this->canUpdateBank = $canUpdateBank;
$this->updatesBank = $updatesBank;
$this->fetchesBank = $fetchesBank;
$this->createsBankLog = $createsBankLog;
$this->createsOrUpdateBank = $createsOrUpdateBank;
$this->updateBankProcessor = $updateBankProcessor;
}
/**
@@ -74,15 +82,15 @@ class UpdateBankLogic extends AbstractControllerLogic
public function logic(Request $request) : JsonResponse
{
$bankObject = new BankObject(
$request->input('company_id'),
$request->input('company_id'),
$request->input('account_type'),
$request->input('bank_name'),
$request->input('holder_name'),
$request->input('holder_name'),
$request->input('account_no'),
$request->input('bank_branch'),
$request->input('swift'),
$request->input('bank_branch'),
$request->input('swift'),
$request->input('snap'),
$request->input('country_id'),
$request->input('country_id'),
$request->input('reference')
);
@@ -90,12 +98,10 @@ class UpdateBankLogic extends AbstractControllerLogic
$this->canUpdateBank->passes($bankObject);
$bank_query = $this->updatesBank->execute($bank, $bankObject);
// $bankLog = $this->createsBankLog->execute($bank_query);
$bank_query = $this->updateBankProcessor->execute($bankObject, $bank, $request->input('bill_no') ?? '', (int) $request->input('transaction_id') ?? 0 );
return $this->resourceResponse(new BankResource($bank_query));
}
}
}
@@ -0,0 +1,67 @@
<?php
namespace App\Classes\Modules\Banks\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Transactions\Services\FetchesTransaction;
use App\Classes\Modules\Banks\Standards\Rules\CanUpdateBankMetadata;
use App\Classes\Modules\Banks\DataTransferObjects\BankMetadataObject;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class UpdateBankMetadataLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Update Bank Metadata',
'message' => 'You have successfully updated the Bank metadata'
];
}
/** @var CanUpdateBankMetadata */
private $canUpdateBankMetadata;
/** @var FetchesTransaction */
private $fetchesTransaction;
/**
* UpdateBankMetadataLogic constructor.
* @param CanUpdateBankMetadata $canUpdateBankMetadata
* @param FetchesTransaction $fetchesTransaction
*/
public function __construct(
CanUpdateBankMetadata $canUpdateBankMetadata,
FetchesTransaction $fetchesTransaction
)
{
$this->canUpdateBankMetadata = $canUpdateBankMetadata;
$this->fetchesTransaction = $fetchesTransaction;
}
/**
* @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
{
$bankMetadataObject = new BankMetadataObject(
$request->input('transactionId'),
);
$this->canUpdateBankMetadata->passes($bankMetadataObject);
$transaction = $this->fetchesTransaction->execute(['id' => $request->input('transactionId')]);
$transaction->attributesKVP()->delete();
return $this->response([]);
}
}
@@ -0,0 +1,29 @@
<?php
namespace App\Classes\Modules\Banks\DataTransferObjects;
use App\Classes\General\Interfaces\DataTransferObject;
class BankMetadataObject implements DataTransferObject
{
/** @var int */
private $transaction_id;
/**
* BankMetadataObject constructor.
* @param int $transaction_id
*/
public function __construct(int $transaction_id)
{
$this->transaction_id = $transaction_id;
}
/**
* @return int
*/
public function getTransactionId(): int
{
return $this->transaction_id;
}
}
@@ -0,0 +1,97 @@
<?php
namespace App\Classes\Modules\Banks\Processors;
use App\Classes\Modules\Transactions\Services\FetchesTransaction;
use App\Classes\Modules\Banks\Services\UpdatesBank;
use App\Classes\Modules\Banks\Services\CreatesOrUpdateBank;
use App\Classes\Modules\Banks\DataTransferObjects\BankObject;
use App\Classes\Modules\Accounts\DataTransferObjects\KeyValuePairObject;
use App\Classes\Modules\Accounts\Services\CreatesKeyValuePair;
use Illuminate\Database\Eloquent\Model;
use App\Models\Bank;
class UpdateBankProcessor
{
/** @var UpdatesBank */
private $updatesBank;
/** @var CreatesOrUpdateBank */
private $createsOrUpdateBank;
/** @var CreatesKeyValuePair */
private $createsKeyValuePair;
/** @var FetchesTransaction */
private $fetchesTransaction;
/**
* UpdateBankProcessor constructor.
* @param UpdatesBank $updatesBank
* @param CreatesOrUpdateBank $createsOrUpdateBank
* @param CreatesKeyValuePair $createsKeyValuePair
* @param FetchesTransaction $fetchesTransaction
*/
public function __construct(
UpdatesBank $updatesBank,
CreatesOrUpdateBank $createsOrUpdateBank,
CreatesKeyValuePair $createsKeyValuePair,
FetchesTransaction $fetchesTransaction
)
{
$this->updatesBank = $updatesBank;
$this->createsOrUpdateBank = $createsOrUpdateBank;
$this->createsKeyValuePair = $createsKeyValuePair;
$this->fetchesTransaction = $fetchesTransaction;
}
/**
* @param BankObject $bankObject
* @param Bank $bank
* @param string $billNo
* @param int $transactionId
* @return Model
* @throws \App\Classes\Exceptions\MalformedRequestException
* @throws \App\Classes\Exceptions\JobResourceNotFoundException
*/
public function execute(BankObject $bankObject, Bank $bank, string $billNo, int $transactionId) {
$result = null;
if($billNo && $transactionId){
$transaction = $this->fetchesTransaction->execute(['id' => $transactionId]);
//If payment transaction do not have a bank yet, create one
if(!$transaction->bank){
$result = $this->createsOrUpdateBank->execute($bankObject);
// if ($result->wasRecentlyCreated) {
//Key #1 for Bank
$kvp = $bank->attributesKVP()->where('key', 'App\Models\Bank')->where('value', $result->id)->latest()->first();
if(!$kvp){
$keyValuePairObject = new KeyValuePairObject(
"App\Models\Bank",
$result->id
);
$this->createsKeyValuePair->execute($bank, $keyValuePairObject);
}
//Key #2 for Payment Transaction (owner type: booking)
$keyValuePairObject = new KeyValuePairObject(
"App\Models\Bank",
$result->id
);
$this->createsKeyValuePair->execute($transaction, $keyValuePairObject);
// }
}
else{
$result = $this->updatesBank->execute($transaction->bank, $bankObject);
}
}
else{
$result = $this->updatesBank->execute($bank, $bankObject);
}
return $result;
}
}
@@ -0,0 +1,44 @@
<?php
namespace App\Classes\Modules\Banks\Services;
use App\Classes\General\Eloquent\AbstractUpdateRecord;
use App\Classes\Modules\Banks\DataTransferObjects\BankObject;
use App\Classes\ValueObjects\Constants\RoleTypes;
use App\Models\Bank;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
class CreatesOrUpdateBank extends AbstractUpdateRecord
{
/**
* @param BankObject $object
* @return \Illuminate\Database\Eloquent\Model
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function execute(BankObject $object)
{
$user = Auth::user(); /** @var User $user */
$attributes = [
'company_id' => $object->getCompanyId(),
'account_no' => $object->getAccountNo(),
'reference' => $object->getReference(),
'bank_name' => $object->getBankName(),
'holder_name' => $object->getHolderName(),
'bank_branch' => $object->getBankBranch(),
'type' => $object->getType(),
'country_id' => $object->getCountryId(),
'created_by' => Auth::id(),
'creator_type' => in_array($user->type, RoleTypes::ADMIN_ROLES) ? RoleTypes::ADMIN : RoleTypes::USER,
];
$values = [
'swift' => $object->getSwift(),
'snap' => $object->getSnap(),
];
$model = Bank::updateOrCreate($attributes, $values); //Bank::firstOrCreate($attributes, $values);
return $model;
}
}
@@ -0,0 +1,66 @@
<?php
namespace App\Classes\Modules\Banks\Standards\Rules;
use App\Classes\General\Abstracts\AbstractRule;
use App\Classes\Modules\Banks\DataTransferObjects\BankMetadataObject;
use App\Classes\Modules\Banks\Standards\Validators\BankMetadataValidation;
use App\Classes\ValueObjects\Constants\RoleTypes;
use Illuminate\Support\Facades\Auth;
class CanUpdateBankMetadata extends AbstractRule
{
/** @var BankMetadataValidation */
private $validation;
/**
* CanUpdateBankMetadata constructor.
* @param BankMetadataValidation $validation
*/
public function __construct(BankMetadataValidation $validation)
{
$this->validation = $validation;
}
/**
* @return bool
*/
protected function authorized($object): bool
{
//cief todo: 66 - temporary workaround
// if (!Auth::user()->can('update bank_metadata')) {
// return false;
// }
// return true;
if (in_array(Auth::user()->type, RoleTypes::ADMIN_ROLES)) {
return true;
}
return false;
}
/**
* @param BankMetadataObject $object
* @return bool
* @throws \App\Classes\Exceptions\RequestValidationException
*/
protected function validators($object): bool
{
return $this->validation->validate($object);
}
/**
* @param BankMetadataObject $object
* @return bool
*/
protected function criteria($object): bool
{
return true;
}
}
@@ -0,0 +1,38 @@
<?php
namespace App\Classes\Modules\Banks\Standards\Validators;
use App\Classes\General\Abstracts\AbstractValidation;
use App\Classes\Modules\Banks\DataTransferObjects\BankMetadataObject;
class BankMetadataValidation extends AbstractValidation
{
/**
* @param BankMetadataObject $object
* @return array
*/
protected function data($object): array
{
return [
'transaction_id' => $object->getTransactionId(),
];
}
/**
* @return array
*/
protected function rules(): array
{
return [
'transaction_id' => 'required',
];
}
/**
* @return array
*/
protected function messages(): array
{
return [];
}
}
@@ -108,29 +108,36 @@ class CreateBookingRefundLogic extends AbstractControllerLogic
// $transactionRefundCalculationObject = new TransactionRefundCalculationObject($booking, $transaction, $request->input('amount'));
// $transactionRefundCalculationObject->init();
$refundAmount = bcdiv($request->input('amount'), $transaction->currency_rate, 7);
if ((float)$request->input('amount') === (float)$transaction->original_amount) {
$refundAmount = $transaction->original_amount / $transaction->currency_rate;
$service_charges_to_refund = $transaction->service_charge;
} else {
$refundAmount = bcdiv($request->input('amount'), $transaction->currency_rate, 7);
$bookingAmountBeforeCurrentRefund = $booking->fix_amount - $refundInPending;
$bookingAmountAfterRefunded = $booking->fix_amount - $refundInPending - $request->input('amount');
$isFullyRefund = ($refund + $request->input('amount')) == $transaction->original_amount;
$voucherCode = null;
if ($transaction->voucherRedemption) {
$voucherCode = $transaction->voucherRedemption->voucher->code;
$bookingAmountBeforeCurrentRefund = $booking->fix_amount - $refundInPending;
$bookingAmountAfterRefunded = $booking->fix_amount - $refundInPending - $request->input('amount');
$isFullyRefund = ($refund + $request->input('amount')) == $transaction->original_amount;
$voucherCode = null;
$redemptionId = null;
if ($transaction->voucherRedemption) {
// $voucherCode = $transaction->voucherRedemption->voucher->code;
$redemptionId = $transaction->voucherRedemption->redemption_id;
}
$conversionObjectBeforeCurrentRefund = new CurrencyConversionObject($bookingAmountBeforeCurrentRefund, $booking->convertible_currency_id, $booking->service_id, $booking->fix_currency_id === 1 ? 0:1, $transaction->payment_method);
$conversionObjectAfterRefund = new CurrencyConversionObject($isFullyRefund ? $request->input('amount') : $bookingAmountAfterRefunded, $booking->convertible_currency_id, $booking->service_id, $booking->fix_currency_id === 1 ? 0:1, $transaction->payment_method);
$quotationBeforeCurrentRefund = $this->fetchBookingQuotation->execute($booking->company, $conversionObjectBeforeCurrentRefund, $voucherCode, $redemptionId);
$quotationAfterRefund = $this->fetchBookingQuotation->execute($booking->company, $conversionObjectAfterRefund, $voucherCode, $redemptionId);
$service_charges_to_refund = $isFullyRefund ? $quotationBeforeCurrentRefund->getServiceCharge() : $quotationBeforeCurrentRefund->getServiceCharge() - $quotationAfterRefund->getServiceCharge();
}
$conversionObjectBeforeCurrentRefund = new CurrencyConversionObject($bookingAmountBeforeCurrentRefund, $booking->convertible_currency_id, $booking->service_id, $booking->fix_currency_id === 1 ? 0:1, $transaction->payment_method);
$conversionObjectAfterRefund = new CurrencyConversionObject($isFullyRefund ? $request->input('amount') : $bookingAmountAfterRefunded, $booking->convertible_currency_id, $booking->service_id, $booking->fix_currency_id === 1 ? 0:1, $transaction->payment_method);
$quotationBeforeCurrentRefund = $this->fetchBookingQuotation->execute($booking->company, $conversionObjectBeforeCurrentRefund, $voucherCode);
$quotationAfterRefund = $this->fetchBookingQuotation->execute($booking->company, $conversionObjectAfterRefund, $voucherCode);
$service_charges_to_refund = $isFullyRefund ? $quotationBeforeCurrentRefund->getServiceCharge() : $quotationBeforeCurrentRefund->getServiceCharge() - $quotationAfterRefund->getServiceCharge();
// refund service charges if booking is not E2E
$refundTotal = $refundAmount;
@@ -0,0 +1,94 @@
<?php
namespace App\Classes\Modules\Bookings\ControllersLogic;
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\Services\UpdatesBooking;
use App\Classes\Modules\Bookings\DataTransferObjects\BookingObject;
use ErrorException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class UpdateBookingRecipientLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Updated Booking',
'message' => 'You have successfully updated the Booking'
];
}
/** @var CanUpdateBooking */
private $canUpdateBooking;
/** @var UpdatesBooking */
private $updatesBooking;
/** @var FetchesBooking */
private $fetchesBooking;
/**
* UpdateBookingRecipientLogic constructor.
* @param CanUpdateBooking $canUpdateBooking
* @param UpdatesBooking $updatesBooking
* @param FetchesBooking $fetchesBooking
*/
public function __construct(
CanUpdateBooking $canUpdateBooking,
UpdatesBooking $updatesBooking,
FetchesBooking $fetchesBooking
)
{
$this->canUpdateBooking = $canUpdateBooking;
$this->updatesBooking = $updatesBooking;
$this->fetchesBooking = $fetchesBooking;
}
/**
* @param Request $request
* @return JsonResponse
* @throws ErrorException
*/
public function logic(Request $request) : JsonResponse
{
try {
DB::beginTransaction();
$booking = $this->fetchesBooking->execute(['id' => $request->route('id')]);
$booking_object = new BookingObject(
$booking->service_id,
$request->input('transferable_bank_id', $booking->transferable_bank_id),
$booking->marking,
$booking->fix_amount,
$booking->fix_currency_id,
$booking->convertible_currency_id,
$booking->conversion_currency_id
);
$this->canUpdateBooking->passes($booking_object);
$booking = $this->updatesBooking->execute($booking, $booking_object);
DB::commit();
return $this->resourceResponse(new BookingResource($booking));
} catch (\Exception $exception){
throw new ErrorException($exception->getMessage(), $exception->getCode());
}
}
}
@@ -11,6 +11,7 @@ use App\Classes\Modules\Vouchers\DataTransferObjects\ValidatedVoucherObject;
use App\Classes\Modules\Vouchers\DataTransferObjects\ValidateVoucherifyVoucherObject;
use App\Classes\Modules\Currencies\Services\FetchesCurrency;
use App\Classes\Modules\Vouchers\Services\Voucherify\ValidatesVoucherifyVoucher;
use App\Classes\Modules\Vouchers\Services\Voucherify\FetchesVoucherifyRedemption;
use App\Models\Company;
use App\Models\Currency;
use Illuminate\Support\Facades\Log;
@@ -27,27 +28,34 @@ class FetchesBookingQuotation
/** @var ValidatesVoucherifyVoucher */
private $validatesVoucherifyVoucher;
/** @var FetchesVoucherifyRedemption */
private $fetchesVoucherifyRedemption;
/**
* FetchesBookingQuotation constructor.
* @param FetchesCompanyServiceSettings $fetchesCompanyServiceSettings
* @param FetchesCurrency $fetchesCurrency
* @param ValidatesVoucherifyVoucher $validatesVoucherifyVoucher
* @param FetchesVoucherifyRedemption $fetchesVoucherifyRedemption
*/
public function __construct(FetchesCompanyServiceSettings $fetchesCompanyServiceSettings, FetchesCurrency $fetchesCurrency, ValidatesVoucherifyVoucher $validatesVoucherifyVoucher)
public function __construct(FetchesCompanyServiceSettings $fetchesCompanyServiceSettings, FetchesCurrency $fetchesCurrency, ValidatesVoucherifyVoucher $validatesVoucherifyVoucher, FetchesVoucherifyRedemption $fetchesVoucherifyRedemption)
{
$this->fetchesCompanyServiceSettings = $fetchesCompanyServiceSettings;
$this->fetchesCurrency = $fetchesCurrency;
$this->validatesVoucherifyVoucher = $validatesVoucherifyVoucher;
$this->fetchesVoucherifyRedemption = $fetchesVoucherifyRedemption;
}
/**
* @param Company $company
* @param CurrencyConversionObject $conversionObject
* @param string $voucherCode
* @param null|string $voucherCode
* @param null|string $redemptionId
* @return CalculationObject
* @throws MalformedRequestException
*/
public function execute(Company $company, CurrencyConversionObject $conversionObject, ?string $voucherCode = null){
public function execute(Company $company, CurrencyConversionObject $conversionObject, ?string $voucherCode = null, ?string $redemptionId = null){
if($conversionObject->getAmount() <= 0) throw new MalformedRequestException('Your transfer must be greater than zero.');
$configurations = $this->fetchesCompanyServiceSettings->execute($company, $conversionObject);
@@ -58,27 +66,53 @@ class FetchesBookingQuotation
$calculationObject = new CalculationObject($conversionObject, $configurations, null);
$voucher = null;
//Voucherify
if($voucherCode){
$employee = $company->employees()->first();
$validateVoucherifyVoucherObject = new ValidateVoucherifyVoucherObject($company->id, $voucherCode, $calculationObject->getSubTotal(), $employee);
$employeeWhoOwnsTheVoucher = null;
$employees = $company->first()->employees;
foreach($employees as $singleEmployee){
$userRewards = $singleEmployee->rewards;
foreach($userRewards as $userReward){
if ($userReward->voucher && $userReward->voucher->code === $voucherCode) {
Log::info('1. Company with multiple employees: ' . json_encode($singleEmployee) . ", voucher: " . $voucherCode);
$employeeWhoOwnsTheVoucher = $singleEmployee;
}
}
}
if(!$employeeWhoOwnsTheVoucher){
$employeeWhoOwnsTheVoucher = $company->employees()->first();
}
$validateVoucherifyVoucherObject = new ValidateVoucherifyVoucherObject($company->id, $voucherCode, $calculationObject->getSubTotal(), $employeeWhoOwnsTheVoucher);
$result = $this->validatesVoucherifyVoucher->execute($validateVoucherifyVoucherObject);
// //A minimum charge of RM5 applies when voucher used make price to be paid by customer RM0
// if(isset($result->order->total_amount) && $result->order->total_amount === 0){
// // $result->order->cief_original_total_amount = $result->order->total_amount;
// $result->order->total_amount = 500;
// $result->order->total_discount_amount = $result->order->total_discount_amount - $result->order->total_amount;
// Log::info('FetchesBookingQuotation order total_amount RM0 (voucher applied) for company id ' . $company->id. ' with original amount ' . $calculationObject->getSubTotal());
// }
$voucher = [
"code" => $result->code,
"discount" => property_exists($result, 'discount') ? $result->discount : null,
"metadata" => $result->metadata,
"order" => $result->order,
];
$validatedVoucherObject = new ValidatedVoucherObject(isset($voucher['metadata']->name) ? $voucher['metadata']->name: "", $voucher['code'], $voucher['discount']->type ?? 'AMOUNT', $voucher['order']->total_discount_amount, $voucher['order']->total_amount);
}
else if($redemptionId){
$result = $this->fetchesVoucherifyRedemption->execute($redemptionId);
$voucher = [
"code" => $result->voucher->code ?? null,
"discount" => null,
"metadata" => null,
"order" => $result->order ?? null,
];
}
if($voucher){
$validatedVoucherObject = new ValidatedVoucherObject(
isset($voucher['metadata']->name) ? $voucher['metadata']->name : "",
$voucher['code'],
$voucher['discount']->type ?? 'AMOUNT',
$voucher['order']->total_discount_amount,
$voucher['order']->total_amount);
$calculationObject = new CalculationObject($conversionObject, $configurations, $validatedVoucherObject);
}
@@ -65,8 +65,12 @@ class ExportsAnalyticBillingTransactions implements FromCollection, WithHeadings
$bill = $transaction;
$payment = $transaction->owner;
$booking = $payment->owner;
$bank = $booking->bank; //cief todo: 66
if($payment->bank){
$bank = $payment->bank;
}
$company = $booking->company;
$ecommerce = str::contains($booking->bank->bank_name, ['浙江网商银行']);
$ecommerce = str::contains($bank->bank_name, ['浙江网商银行']);
return [
$booking->id,
@@ -88,4 +92,4 @@ class ExportsAnalyticBillingTransactions implements FromCollection, WithHeadings
$bill->created_at
];
}
}
}
@@ -0,0 +1,112 @@
<?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 Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\Transaction;
use App\Classes\Modules\Bookings\ControllersLogic\UpdateBookingAmountLogic;
use App\Classes\Modules\Bookings\Services\CalculatesBookingRefundAmount;
use Illuminate\Support\Facades\Log;
use App\Classes\Modules\Bookings\Services\CalculatesBookingPaidAmount;
class DeleteRefundTransactionLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification(): array
{
return [
'title' => 'Deleted Refund Transaction',
'message' => 'You have successfully deleted a transaction'
];
}
/** @var FetchesTransaction */
private $fetchesTransaction;
/** @var DeletesTransaction */
private $deletesTransaction;
/** @var UpdatesTransactionStatus */
private $updatesTransactionStatus;
/** @var CalculatesBookingRefundAmount */
private $calculatesBookingRefundAmount;
/** @var CalculatesBookingPaidAmount */
private $calculatesBookingPaidAmount;
/** @var UpdateBookingAmountLogic */
private $updateBookingAmountLogic;
/**
* CreatePaymentVerificationDocumentLogic constructor.
* @param FetchesTransaction $fetchesTransaction
* @param DeletesTransaction $deletesTransaction
* @param CalculatesBookingRefundAmount $calculatesBookingRefundAmount
* @param UpdateBookingAmountLogic $updateBookingAmountLogic
* @param calculatesBookingPaidAmount $calculatesBookingPaidAmount
*/
public function __construct(FetchesTransaction $fetchesTransaction, DeletesTransaction $deletesTransaction, UpdatesTransactionStatus $updatesTransactionStatus, CalculatesBookingRefundAmount $calculatesBookingRefundAmount, UpdateBookingAmountLogic $updateBookingAmountLogic, CalculatesBookingPaidAmount $calculatesBookingPaidAmount)
{
$this->fetchesTransaction = $fetchesTransaction;
$this->deletesTransaction = $deletesTransaction;
$this->updatesTransactionStatus = $updatesTransactionStatus;
$this->calculatesBookingRefundAmount = $calculatesBookingRefundAmount;
$this->updateBookingAmountLogic = $updateBookingAmountLogic;
$this->calculatesBookingPaidAmount = $calculatesBookingPaidAmount;
}
/**
* @param Request $request
* @return JsonResponse
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function logic(Request $request): JsonResponse
{
// delete refund transaction
$transaction = $this->fetchesTransaction->execute(['id' => $request->route('id')]);
$this->deletesTransaction->execute($transaction);
// Update payment_transaction status
$payment_transaction = $transaction->owner;
$this->updatesTransactionStatus->execute($payment_transaction, ApprovalStatus::APPROVED);
// delete wallet top up transaction
$booking = $transaction->owner->owner;
Transaction::where('type', TransactionType::CREDIT_NOTE)
->where('amount', $transaction->amount)
->where('payment_reference', 'like', '%' . $booking->marking . '%')
->delete();
// update back the latest booking amount
$request['fix_amount'] = $this->calculatesBookingPaidAmount->execute($booking);
$request->route()->setParameter('id', $booking->id);
$this->updateBookingAmountLogic->execute($request);
// if have SUPPLIER_REFUND transaction
$bookingInWhiteForm = $payment_transaction->transactions()->bills()->first();
if ($bookingInWhiteForm) {
$whiteFormTransaction = Transaction::where('type', TransactionType::SUPPLIER_REFUND)
->where('payment_reference', $transaction->payment_reference)
->first();
// Log::info($whiteFormTransaction->id);
$whiteFormTransaction->delete();
}
return $this->response([]);
}
}
@@ -24,6 +24,7 @@ use App\Classes\ValueObjects\Constants\DocumentType;
use App\Models\Booking;
use App\Models\Document;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;
use Mccarlosen\LaravelMpdf\Facades\LaravelMpdf;
class CreateProformaInvoiceTransactionProcessor
@@ -102,37 +103,55 @@ class CreateProformaInvoiceTransactionProcessor
*/
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);
$transaction = $booking->transactions()
->where('type', TransactionType::PAYMENT)
->first();
$conversionObject = new CurrencyConversionObject(floatval(str_replace(',', '', $outstanding)), $booking->convertible_currency_id, $booking->service_id, $booking->fix_currency_id === 1 ? 0:1, PaymentMethodType::CASH);
if (!$transaction) {
$outstanding = $this->calculatesBookingOutstanding->execute($booking);
$configurations = $this->fetchesBookingQuotation->execute($booking->company, $conversionObject);
$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-');
$paymentAttemptLimit = $this->fetchesCompanyPaymentAttemptLimit->execute($booking->company);
$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
);
$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);
$this->createsTransaction->execute($booking, $object);
}
$billNumber = $this->generatesTransactionBillNumber->execute('PROFORMA-');
$payable_amount = $booking->transactions()->payments()->where(function($query){
return $query->where(function($query){
$payable_amount = $booking->transactions()->payments()->where(function ($query) {
return $query->where(function ($query) {
return $query->where('status', ApprovalStatus::PENDING_SUBMISSION)->whereDate('expires_on', '>=', Carbon::now())->where('expires_on', '>', Carbon::now()->toTimeString());
})->orWhere(function($query){
})->orWhere(function ($query) {
return $query->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
});
})->sum('amount');
@@ -142,14 +161,16 @@ class CreateProformaInvoiceTransactionProcessor
->where('type', TransactionType::PAYMENT)
->first();
$booking_currency_average_rate = $booking_amount / $booking->transactions()->payments()->where(function($query){
return $query->where(function($query){
$paymentAmount = $booking->transactions()->payments()->where(function ($query) {
return $query->where(function ($query) {
return $query->where('status', ApprovalStatus::PENDING_SUBMISSION)->whereDate('expires_on', '>=', Carbon::now())->where('expires_on', '>', Carbon::now()->toTimeString());
})->orWhere(function($query){
})->orWhere(function ($query) {
return $query->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
});
})->selectRaw('sum(amount - service_charge - tax) as sub_total')->get()->sum('sub_total');
$booking_currency_average_rate = $booking_amount / $paymentAmount;
$total_service_charge = $booking->transactions()
->where('type', TransactionType::PAYMENT)
->whereNotIn('status', [ApprovalStatus::REJECTED, ApprovalStatus::SUSPENDED])
@@ -160,6 +181,11 @@ class CreateProformaInvoiceTransactionProcessor
->whereIn('status', [ApprovalStatus::REJECTED, ApprovalStatus::SUSPENDED])
->sum('tax');
// delete prev proforma transactions
$booking->transactions()
->where('type', TransactionType::PROFORMA)
->delete();
$transaction_object = new TransactionObject(
$billNumber,
TransactionType::PROFORMA,
@@ -178,14 +204,14 @@ class CreateProformaInvoiceTransactionProcessor
ApprovalStatus::APPROVED
);
$perofrma_transaction = $this->createsTransaction->execute($po_order_transaction->booking, $transaction_object);
$proforma_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]);
$purchase_order_pdf = LaravelMpdf::loadView('pages.pdfs.proforma_invoice', ['invoice_transaction' => $proforma_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()))],
[chunk_split('data:application/pdf;base64,' . base64_encode($purchase_order_pdf->output()))],
'',
ApprovalStatus::COMPLETED,
'proforma_invoices'
@@ -194,7 +220,5 @@ class CreateProformaInvoiceTransactionProcessor
/** @var Document $document */
$document = $this->createsDocument->execute($po_order_transaction->booking, $document_object);
$this->createsFile->execute($document, $document_object);
}
}
@@ -11,6 +11,7 @@ use App\Classes\Modules\Vouchers\Services\Voucherify\ValidatesVoucherifyVoucher;
use App\Classes\Modules\Vouchers\Services\Voucherify\CreatesVoucherifyVoucherInACampaign;
use App\Classes\Modules\Vouchers\Services\Voucherify\ListsVoucherifyVouchers;
use App\Classes\Modules\Vouchers\Services\Voucherify\FetchesVoucherifyCampaign;
use App\Classes\Modules\Vouchers\Processors\Voucherify\NewCustomerToVoucherifyProcessor;
use App\Classes\Modules\Vouchers\Services\CreatesVoucher;
use App\Classes\Modules\Vouchers\Services\FetchesVoucher;
use App\Classes\Modules\Vouchers\Services\UpdatesVoucherCampaign;
@@ -75,6 +76,9 @@ class CreateVoucherLogic extends AbstractControllerLogic
/** @var UpdatesVoucherCampaign */
private $updatesVoucherCampaign;
/** @var NewCustomerToVoucherifyProcessor */
private $newCustomerToVoucherifyProcessor;
/**
* CreateVoucherLogic constructor.
* @param ValidatesVoucherifyVoucher $validatesVoucherifyVoucher
@@ -87,8 +91,9 @@ class CreateVoucherLogic extends AbstractControllerLogic
* @param CreatesKeyValuePair $createsKeyValuePair
* @param UpdatesKeyValuePair $updatesKeyValuePair
* @param UpdatesVoucherCampaign $updatesVoucherCampaign
* @param NewCustomerToVoucherifyProcessor $newCustomerToVoucherifyProcessor
*/
public function __construct(CreatesUserReward $createsUserReward, ValidatesVoucherifyVoucher $validatesVoucherifyVoucher, CreateVoucherProcessor $createVoucherProcessor, CreatesVoucherifyVoucherInACampaign $createsVoucherifyVoucherInACampaign, CanCreateVoucher $canCreateVoucher, ListsVoucherifyVouchers $listsVoucherifyVouchers, FetchesVoucherifyCampaign $fetchesVoucherifyCampaign, CreatesKeyValuePair $createsKeyValuePair, UpdatesKeyValuePair $updatesKeyValuePair, UpdatesVoucherCampaign $updatesVoucherCampaign)
public function __construct(CreatesUserReward $createsUserReward, ValidatesVoucherifyVoucher $validatesVoucherifyVoucher, CreateVoucherProcessor $createVoucherProcessor, CreatesVoucherifyVoucherInACampaign $createsVoucherifyVoucherInACampaign, CanCreateVoucher $canCreateVoucher, ListsVoucherifyVouchers $listsVoucherifyVouchers, FetchesVoucherifyCampaign $fetchesVoucherifyCampaign, CreatesKeyValuePair $createsKeyValuePair, UpdatesKeyValuePair $updatesKeyValuePair, UpdatesVoucherCampaign $updatesVoucherCampaign, NewCustomerToVoucherifyProcessor $newCustomerToVoucherifyProcessor)
{
$this->createsUserReward = $createsUserReward;
$this->validatesVoucherifyVoucher = $validatesVoucherifyVoucher;
@@ -100,6 +105,7 @@ class CreateVoucherLogic extends AbstractControllerLogic
$this->createsKeyValuePair = $createsKeyValuePair;
$this->updatesKeyValuePair = $updatesKeyValuePair;
$this->updatesVoucherCampaign = $updatesVoucherCampaign;
$this->newCustomerToVoucherifyProcessor = $newCustomerToVoucherifyProcessor;
}
/**
@@ -129,6 +135,12 @@ class CreateVoucherLogic extends AbstractControllerLogic
$user = $userParam ? $userParam : $user;
}
//Voucherify - To check if user exist at Voucherify, create if not exist
$voucherify_entity = $user->voucherifyEntities()->first();
if(!$voucherify_entity){
$this->newCustomerToVoucherifyProcessor->execute($user->company()->first()->id, $user, false);
}
//Voucherify - creates new voucher at voucherify
if ($voucherCodeInput === Vouchers::SORRY_50 || $voucherCodeInput === Vouchers::SORRY_100 || $voucherCodeInput === Vouchers::SORRY_200 ) {
$result = $this->newVoucherifyVoucherIssuanceHandler($voucherCodeInput);
@@ -10,6 +10,7 @@ use App\Classes\Modules\Vouchers\DataTransferObjects\ValidateVoucherifyVoucherOb
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Models\Booking;
use Illuminate\Support\Facades\Log;
class ValidateVoucherLogic extends AbstractControllerLogic
{
@@ -42,11 +43,27 @@ class ValidateVoucherLogic extends AbstractControllerLogic
*/
public function logic(Request $request) : JsonResponse
{
$employeeWhoOwnsTheVoucher = null;
$booking = Booking::find($request->input('itemId'));
$employee = $booking->company->employees()->first();
$employees = $booking->company->employees()->get();
foreach($employees as $singleEmployee){
$userRewards = $singleEmployee->rewards;
foreach($userRewards as $userReward){
if ($userReward->voucher && $userReward->voucher->code === $request->input('voucherCode')) {
Log::info('2. Company with multiple employees: ' . json_encode($singleEmployee) . ", voucher: " . $request->input('voucherCode'));
$employeeWhoOwnsTheVoucher = $singleEmployee;
}
}
}
if(!$employeeWhoOwnsTheVoucher){
$employeeWhoOwnsTheVoucher = $booking->company->employees()->first();
}
$amount = $this->floatvalue($request->input('amount'));
$validateVoucherifyVoucherObject = new ValidateVoucherifyVoucherObject($booking->company_id, $request->input('voucherCode'), $amount, $employee);
$validateVoucherifyVoucherObject = new ValidateVoucherifyVoucherObject($booking->company_id, $request->input('voucherCode'), $amount, $employeeWhoOwnsTheVoucher);
$result = $this->validatesVoucherifyVoucher->execute($validateVoucherifyVoucherObject);
return $this->response(['data' => $result]);
}
@@ -65,9 +65,9 @@ class CreateVoucherifyCustomerObject implements DataTransferObject
*/
public function getAcquisitionChannel(): string
{
if(!$this->isNew){
return "";
}
// if(!$this->isNew){
// return "";
// }
return $this->acquisitionChannel;
}
@@ -17,8 +17,8 @@ class ValidateVoucherifyVoucherObject implements DataTransferObject
/** @var float */
private $amount;
/** @var User */
private $user;
/** @var User */
private $user; //this will affect certain voucher that limit user redemption e.g. one user one redemption per campaign
/**
* ValidateVoucherifyVoucherObject constructor.
@@ -18,6 +18,7 @@ use App\Classes\ValueObjects\Constants\VoucherifyEntityType;
use App\Models\User;
use App\Models\Transaction;
use App\Models\Voucher;
use App\Models\VoucherCampaign;
use Illuminate\Support\Facades\Log;
class BookingToVoucherifyProcessor
@@ -82,7 +83,24 @@ class BookingToVoucherifyProcessor
$voucherify_customer_id = "";
$voucherify_order_id = "";
if($voucherCode){
$redeemVoucherifyVoucherObject = new RedeemVoucherifyVoucherObject($companyId, $transaction->id, $voucherCode, $amount, $user);
$employeeWhoOwnsTheVoucher = null;
$employees = $user->company()->first()->employees;
foreach($employees as $singleEmployee){
$userRewards = $singleEmployee->rewards;
foreach($userRewards as $userReward){
if ($userReward->voucher && $userReward->voucher->code === $voucherCode) {
Log::info('3. Company with multiple employees: ' . json_encode($singleEmployee) . ", voucher: " . $voucherCode);
$employeeWhoOwnsTheVoucher = $singleEmployee;
}
}
}
if(!$employeeWhoOwnsTheVoucher){
$employeeWhoOwnsTheVoucher = $user;
}
$redeemVoucherifyVoucherObject = new RedeemVoucherifyVoucherObject($companyId, $transaction->id, $voucherCode, $amount, $employeeWhoOwnsTheVoucher);
$redeemVoucherResult = $this->redeemsVoucherifyVoucher->execute($redeemVoucherifyVoucherObject);
// Log::info('redeemVoucherResult: '.json_encode($redeemVoucherResult));
@@ -98,9 +116,9 @@ class BookingToVoucherifyProcessor
$voucherify_customer_id = $redeemVoucherResult->customer->id;
}
$voucher = $this->recordVoucherInfo($redeemedVoucher, $transaction);
$voucher = $this->recordVoucherInfo($redeemedVoucher);
$this->createsVoucherRedemption->execute($transaction, $voucher, $redemptionId, $voucherDiscountAmount);
$this->recordVoucherForUserInfo($user, $voucher);
$this->recordVoucherForUserInfo($employeeWhoOwnsTheVoucher, $voucher);
}
else{
$createVoucherifyOrderObject = new CreateVoucherifyOrderObject($user, $companyId, $transaction->id, $amount, true, $transaction->type == TransactionType::TOP_UP);
@@ -126,9 +144,14 @@ class BookingToVoucherifyProcessor
//Create records at 3 tables
$voucherValue = isset($redeemedVoucher->discount->amount_off) ? $redeemedVoucher->discount->amount_off : $redeemedVoucher->discount->percent_off;
$voucherType = $redeemedVoucher->discount ? $redeemedVoucher->discount->type : null;
$voucherCampaignId = isset($redeemedVoucher->campaign_id) ? $redeemedVoucher->campaign_id : null;
$voucherifyCampaignId = isset($redeemedVoucher->campaign_id) ? $redeemedVoucher->campaign_id : null;
$voucherObject= new VoucherObject($redeemedVoucher->code, isset($redeemedVoucher->metadata->name) ? $redeemedVoucher->metadata->name : "", $voucherType, $voucherValue, $voucherCampaignId);
$voucherCampaign = null;
if($voucherifyCampaignId){
$voucherCampaign = VoucherCampaign::where('campaign_id', $voucherifyCampaignId)->first();
}
$voucherObject= new VoucherObject($redeemedVoucher->code, isset($redeemedVoucher->metadata->displayname) ? $redeemedVoucher->metadata->displayname : "", $voucherType, $voucherValue, $voucherCampaign ? $voucherCampaign->id : null);
$voucher = $this->createsVoucher->execute($voucherObject);
if(!$voucher) $voucher = $this->fetchesVoucher->execute(['code' => $voucherObject->getCode()]);
@@ -44,7 +44,9 @@ class NewCustomerToVoucherifyProcessor
$createVoucherifyCustomerObject = new CreateVoucherifyCustomerObject($companyId, $user, $isNew);
$result = $this->createsVoucherifyCustomer->execute($createVoucherifyCustomerObject);
if($result && isset($result->id)){
$voucherify_entity = $user->voucherifyEntities()->get();
if($result && isset($result->id) && count($voucherify_entity) === 0){
$voucherEntityObject = new VoucherEntityObject($result->id, VoucherifyEntityType::CUSTOMER);
$this->createsVoucherEntityMapping->execute($createVoucherifyCustomerObject->getUser(), $voucherEntityObject);
}
@@ -0,0 +1,38 @@
<?php
namespace App\Classes\Modules\Vouchers\Services\Voucherify;
use Illuminate\Support\Facades\Log;
class FetchesVoucherifyRedemption
{
/** @var VoucherifyClient */
private $voucherifyClient;
/**
* FetchesVoucherifyRedemption constructor.
*
*/
public function __construct()
{
$this->voucherifyClient = createVoucherifyClient();
}
/**
* @param string $redemptionId
* @return null|object
* @throws \Voucherify\ClientException
*/
public function execute(string $redemptionId)
{
try {
$result = $this->voucherifyClient->redemptions->get($redemptionId);
return $result;
} catch (\Voucherify\ClientException $e) {
Log::error('FetchesVoucherifyRedemption '.$e);
return null;
}
}
}
@@ -0,0 +1,126 @@
<?php
namespace App\Console\Commands;
use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
use App\Classes\Modules\Documents\Services\CreatesDocument;
use App\Classes\Modules\Documents\Services\CreatesFiles;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\DocumentType;
use App\Models\Document;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\Group;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Mccarlosen\LaravelMpdf\Facades\LaravelMpdf;
class UpdateWrongGroupCurrencyRate extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'group:update-wrong-currency-rate';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Update those group with currency rate more than 100';
/** @var CreatesDocument */
private $createsDocument;
/** @var CreatesFiles */
private $createsFile;
/**
* Create a new command instance.
*
* @return void
*/
public function __construct(CreatesDocument $createsDocument, CreatesFiles $createsFile)
{
parent::__construct();
$this->createsDocument = $createsDocument;
$this->createsFile = $createsFile;
}
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
$groups = Group::where('currency_rate', '>', 100)->get();
foreach ($groups as $group) {
$transactions = $group->transactions()->get();
$rate = DB::table('transaction_logs')->where('transaction_id', $transactions->first()->id)->latest('updated_at')->first()->currency_rate;
$supplier = $group->issuerCompany;
foreach ($transactions as $transaction) {
$transaction->currency_rate = $rate;
$transaction->amount = $transaction->original_amount / $rate;
$transaction->save();
$supplierRefundTransactions = $transaction->owner->transactions()->supplierRefunds()->whereIn('status', [ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::APPROVED])->get();
foreach ($supplierRefundTransactions as $supplierRefundTransaction) {
$claimBefore = $supplierRefundTransaction->transactions()->where('type', TransactionType::BILL_REFUND)->where('status', ApprovalStatus::APPROVED)->exists();
if (!$claimBefore) {
$supplierRefundTransaction->currency_rate = $rate;
$supplierRefundTransaction->amount = $supplierRefundTransaction->original_amount / $rate;
$supplierRefundTransaction->save();
}
}
}
$group_transfer_fee = $group->morphTransactions()->where('type', TransactionType::TRANSFER_FEE)->first();
$group_transfer_fee_original_amount = 0;
if ($group_transfer_fee) {
$group_transfer_fee_original_amount = $group_transfer_fee->original_amount;
}
$transferFeeTransactions = $group->transactions()->with([
'transactions' => function ($transaction) {
return $transaction->where('type', TransactionType::TRANSFER_FEE);
}
])->get()->pluck('transactions')->flatten();
$group->original_amount = $group->transactions()->sum('original_amount') + ((float)$transferFeeTransactions->sum('service_charge') + (float)$group_transfer_fee_original_amount);
$group->amount = $group->transactions()->sum('amount') + (((float)$transferFeeTransactions->sum('service_charge') + (float)$group_transfer_fee_original_amount) / $rate) + $group->transactions()->sum('service_charge');
$group->currency_rate = $rate;
$group->tax = $group->transactions()->sum('tax');
$group->service_charge = $group->transactions()->sum('service_charge');
$group->save();
$group->documents()->delete();
$pdf = LaravelMpdf::loadView('pages.pdfs.currency_vendor_order', ['transactions' => $group->transactions, 'transferFeeTransactions' => $transferFeeTransactions, 'supplier' => $supplier, 'groupTransferFeeOriginalAmount' => $group_transfer_fee_original_amount]);
$object = new DocumentObject(
DocumentType::CURRENCY_VENDOR_ORDER,
[chunk_split('data:application/pdf;base64,' . base64_encode($pdf->output()))],
'',
ApprovalStatus::COMPLETED,
'currency_vendor_order'
);
/** @var Document $document */
$document = $this->createsDocument->execute($group, $object);
$this->createsFile->execute($document, $object);
$this->info("Group ID: {$group->id} updated to currency rate {$rate}");
}
}
}
@@ -0,0 +1,19 @@
<?php
namespace App\Http\Controllers\Banks;
use App\Classes\Modules\Banks\ControllersLogic\UpdateBankMetadataLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class UpdateBankMetadataController
{
/**
* @param Request $request
* @param UpdateBankMetadataLogic $logic
* @return JsonResponse
*/
public function delete(Request $request, UpdateBankMetadataLogic $logic): JsonResponse {
return $logic->execute($request);
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers\Bookings;
use App\Classes\Modules\Bookings\ControllersLogic\UpdateBookingRecipientLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class UpdateBookingRecipientController
{
/**
* @param Request $request
* @param UpdateBookingRecipientLogic $logic
* @return JsonResponse
*/
public function update(Request $request, UpdateBookingRecipientLogic $logic): JsonResponse {
return $logic->execute($request);
}
}
@@ -0,0 +1,14 @@
<?php
namespace App\Http\Controllers\Transactions;
use App\Classes\Modules\Transactions\ControllersLogic\DeleteRefundTransactionLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class DeleteRefundTransactionController
{
public function delete(Request $request, DeleteRefundTransactionLogic $logic): JsonResponse {
return $logic->execute($request);
}
}
+1 -1
View File
@@ -56,7 +56,7 @@ class CompanyResource extends JsonResource
'last_payment' => $lastPayment ? $lastPayment->created_at->diffForHumans() : 'No Payments',
'personal_banks' => BankResource::collection($this->banks->where('type', BankAccountType::PERSONAL)),
'recipient_banks' => [
'accounts' => BankResource::collection($this->banks->whereIn('type', [BankAccountType::EXTERNAL, BankAccountType::ALIPAY_1688, BankAccountType::ALIPAY_RECIPIENT])),
'accounts' => BankResource::collection($this->banks->whereIn('type', [BankAccountType::EXTERNAL, BankAccountType::ALIPAY_1688, BankAccountType::ALIPAY_RECIPIENT])->whereIn('creator_type', [null])),
'default' => new BankResource($this->banks->where('type', BankAccountType::EXTERNAL)->where('default', true)->first())
],
'segments' => SegmentResource::collection($this->segments),
@@ -16,8 +16,18 @@ class ListTransactionJobResource extends JsonResource
*/
public function toArray($request)
{
$booking = in_array((int)$this->type, [TransactionType::BILL, TransactionType::REFUND])? $this->owner->owner : $this->owner;
$booking = null; //cief todo: 66
$bank = null;
//Check if Transaction of type PAYMENT has an override for recipient bank - starts
if(in_array((int)$this->type, [TransactionType::BILL, TransactionType::REFUND])){
$booking = $this->owner->owner;
$bank = $this->owner->bank ?? $booking->bank;
}
else{
$booking = $this->owner;
$bank = $this->bank ?? $booking->bank;
}
//Check if Transaction of type PAYMENT has an override for recipient bank - ends
$days = $this->created_at->endOfDay()->addWeekdays($booking->service_id === 3 ? 3 : 1);
return [
@@ -27,7 +37,7 @@ class ListTransactionJobResource extends JsonResource
'bill_no' => $this->bill_no,
'payment_reference' => $this->payment_reference,
'payment_method' => (float) $this->payment_method,
'recipient_bank_account' => new BankResource($booking->bank),
'recipient_bank_account' => new BankResource($bank),
'issuer_name' => $this->issuerCompany->name,
'issuer_id' => $this->issuerCompany->id,
'amount' => (double) $this->amount,
@@ -18,8 +18,18 @@ class PaymentTransactionResource extends JsonResource
*/
public function toArray($request)
{
$booking = in_array((int)$this->type, [TransactionType::BILL, TransactionType::REFUND])? $this->owner->owner : $this->owner;
$booking = null; //cief todo: 66
$bank = null;
//Check if Transaction of type PAYMENT has an override for recipient bank - starts
if(in_array((int)$this->type, [TransactionType::BILL, TransactionType::REFUND])){
$booking = $this->owner->owner;
$bank = $this->owner->bank ?? $booking->bank;
}
else{
$booking = $this->owner;
$bank = $this->bank ?? $booking->bank;
}
//Check if Transaction of type PAYMENT has an override for recipient bank - ends
$booking_marking = '';
switch ($this->owner_type) {
@@ -38,7 +48,7 @@ class PaymentTransactionResource extends JsonResource
'bill_no' => $this->bill_no,
'payment_reference' => $this->payment_reference,
'payment_method' => (float) $this->payment_method,
'recipient_bank_account' => new BankResource($booking->bank),
'recipient_bank_account' => new BankResource($bank),
'issuer_name' => $this->issuerCompany->name,
'issuer_id' => $this->issuerCompany->id,
'amount' => (double) $this->amount,
+15 -4
View File
@@ -19,8 +19,18 @@ class TransactionResource extends JsonResource
*/
public function toArray($request)
{
$booking = in_array((int)$this->type, [TransactionType::BILL, TransactionType::REFUND, TransactionType::SUPPLIER_REFUND])? $this->owner->owner : $this->owner;
$booking = null; //cief todo: 66
$bank = null;
//Check if Transaction of type PAYMENT has an override for recipient bank - starts
if(in_array((int)$this->type, [TransactionType::BILL, TransactionType::REFUND, TransactionType::SUPPLIER_REFUND])){
$booking = $this->owner->owner;
$bank = $this->owner->bank ?? $booking->bank;
}
else{
$booking = $this->owner;
$bank = $this->bank ?? $booking->bank;
}
//Check if Transaction of type PAYMENT has an override for recipient bank - ends
$days = $this->created_at->endOfDay()->addWeekdays($booking->service_id === 3 ? 3 : 1);
return [
@@ -30,7 +40,7 @@ class TransactionResource extends JsonResource
'bill_no' => $this->bill_no,
'payment_reference' => $this->payment_reference,
'payment_method' => (float) $this->payment_method,
'recipient_bank_account' => new BankResource($booking->bank),
'recipient_bank_account' => new BankResource($bank),
'issuer_name' => $this->issuerCompany->name,
'issuer_id' => $this->issuerCompany->id,
'amount' => (double) ($this->type === TransactionType::SUPPLIER_REFUND ? $this->amount - $this->transactions()->where('type', TransactionType::BILL_REFUND)->where('status', ApprovalStatus::APPROVED)->sum('amount') : $this->amount),
@@ -54,7 +64,8 @@ class TransactionResource extends JsonResource
'duration' => $days->diff(Carbon::now())->format('%d'),
],
'remarks' => RemarkResource::collection($this->remarks),
'redemption' => new VoucherRedemptionResource($this->voucherRedemption)
'redemption' => new VoucherRedemptionResource($this->voucherRedemption),
'bank' => ((int) $this->type === TransactionType::PAYMENT) ? new BankResource($bank) : null, //When a transaction (of type payment) has an override recipient bank details on booking, this is NOT null
];
}
}
+1 -1
View File
@@ -82,7 +82,7 @@ class CompanyV2Resource extends JsonResource
'last_payment' => $lastPayment ? $lastPayment->created_at->diffForHumans() : 'No Payments',
'personal_banks' => V1\BankResource::collection($this->banks->where('type', BankAccountType::PERSONAL)),
'recipient_banks' => [
'accounts' => V1\BankResource::collection($this->banks->where('type', BankAccountType::EXTERNAL)),
'accounts' => V1\BankResource::collection($this->banks->where('type', BankAccountType::EXTERNAL)->whereIn('creator_type', [null])),
'default' => new V1\BankResource($this->banks->where('type', BankAccountType::EXTERNAL)->where('default', true)->first())
],
'segments' => V1\SegmentResource::collection($this->segments),
+3 -1
View File
@@ -4,6 +4,7 @@ namespace App\Http\Resources;
use ArrayObject;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Support\Facades\Log;
class VoucherResource extends JsonResource
{
@@ -16,7 +17,8 @@ class VoucherResource extends JsonResource
public function toArray($request)
{
$filteredRedemptions = new ArrayObject([]);
if ($request->has('filters') && str_contains($request->input('filters'), "has_active_reward")) {
if ($request->has('filters') && (str_contains($request->input('filters'), "has_vouchers_all_with_user") )) {
//|| str_contains($request->input('filters'), "has_vouchers_all_with_company")
$filteredRedemptions = new ArrayObject([]);
}
else{
+32 -3
View File
@@ -7,6 +7,8 @@ use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\MorphMany;
use App\Classes\General\Interfaces\KeyValueInterface;
/**
* Class Bank
@@ -21,10 +23,29 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
* @property int default
* @property int status
*/
class Bank extends AbstractModel
class Bank extends AbstractModel implements KeyValueInterface
{
use SoftDeletes;
/**
*
* @var array
*/
protected $fillable = [
'company_id',
'reference',
'bank_name',
'holder_name',
'account_no',
'bank_branch',
'swift',
'snap',
'type',
'country_id',
'created_by',
'creator_type',
];
protected $table = 'banks';
/**
@@ -42,7 +63,7 @@ class Bank extends AbstractModel
{
return $this->BelongsTo(Company::class, 'company_id', 'id');
}
/**
* @return HasMany
*/
@@ -50,4 +71,12 @@ class Bank extends AbstractModel
{
return $this->HasMany(Transaction::class, 'recipient_bank_account_id');
}
/**
* @return MorphMany
*/
public function attributesKVP(): MorphMany
{
return $this->morphMany(KeyValuePair::class, 'owner');
}
}
+5 -1
View File
@@ -2,10 +2,14 @@
namespace App\Models;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Database\Eloquent\SoftDeletes;
class KeyValuePair extends AbstractModel
{
use SoftDeletes;
protected $dates = ['deleted_at'];
protected $table = 'key_value_pairs';
public function owner(): MorphTo
+23 -1
View File
@@ -3,6 +3,7 @@
namespace App\Models;
use App\Classes\General\Interfaces\Documentable;
use App\Classes\General\Interfaces\KeyValueInterface;
use App\Classes\General\Interfaces\Remarkable;
use App\Classes\General\Interfaces\Transactionable;
use App\Classes\General\Interfaces\Voucherifiable;
@@ -22,7 +23,7 @@ use Staudenmeir\EloquentHasManyDeep\HasTableAlias;
use App\Models\StatementTransactionOwner;
class Transaction extends AbstractModel implements Documentable, Transactionable, Voucherifiable, Remarkable
class Transaction extends AbstractModel implements Documentable, Transactionable, Voucherifiable, Remarkable, KeyValueInterface
{
use HasTableAlias;
use SoftDeletes;
@@ -268,4 +269,25 @@ class Transaction extends AbstractModel implements Documentable, Transactionable
return $this->morphMany(Remark::class, 'owner');
}
/**
* @return MorphMany
*/
public function attributesKVP(): MorphMany
{
return $this->morphMany(KeyValuePair::class, 'owner');
}
/**
*
* @return Model|null
*/
public function getBankAttribute()
{
$keyValuePairs = $this->attributesKVP()->where('key', 'App\Models\Bank')->latest()->first();
if($keyValuePairs){
$bank = Bank::where('id', $keyValuePairs->value)->first();
return $bank;
}
return null;
}
}
@@ -0,0 +1,35 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddCreatedByAndCreatorTypeToBanksTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('banks', function (Blueprint $table) {
$table->unsignedBigInteger('created_by')->nullable()->after('country_id');
$table->unsignedInteger('creator_type')->nullable()->after('created_by'); // 'admin' or 'customer', see RoleTypes.php for more
$table->foreign('created_by')->references('id')->on('users')->onDelete('set null');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('banks', function (Blueprint $table) {
$table->dropForeign(['created_by']);
$table->dropColumn(['created_by', 'creator_type']);
});
}
}
@@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddDeletedAtToKeyValuePairs extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('key_value_pairs', function (Blueprint $table) {
$table->softDeletes();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('key_value_pairs', function (Blueprint $table) {
$table->dropSoftDeletes();
});
}
}
@@ -73,6 +73,8 @@ class AdminUserPermissionsTableSeeder extends Seeder
['name' => 'add voucher', 'guard_name' => 'web'],
['name' => 'list voucher campaigns', 'guard_name' => 'web'],
['name' => 'update bank_metadata', 'guard_name' => 'web'],
];
foreach ($permissions as $permission){
@@ -133,12 +133,15 @@
</div>
</div>
<div class="row">
<div class="col" :class="[{'p-r-15': disabled}, {'p-r-5': !disabled}]">
<div class="col" :class="[{'p-r-15': disabled}, {'p-r-5': !disabled}]" v-if="!isCancelButtonHidden">
<div class="btn btn-sm btn-default bg-master-lightest btn-block b-rad-none" :data-dismiss="closable ? 'modal' : ''" @click="$emit('close')">{{disabled ? 'Change Recipient Account' : 'Cancel'}}</div>
</div>
<div class="col p-l-5" v-if="!disabled">
<div class="col p-l-5" v-if="!disabled && !isEditing">
<div class="btn btn-sm btn-success btn-block b-rad-none" @click="submitForm()">Add Account</div>
</div>
<div class="col p-l-5" v-if="isEditing">
<div class="btn btn-sm btn-success btn-block b-rad-none" @click="submitForm()">Update Details</div>
</div>
</div>
</div>
</div>
@@ -179,6 +182,22 @@
type: String,
required: false,
default: 'RMB'
},
isEditing: {
type: Boolean,
default: false
},
isCancelButtonHidden: {
type: Boolean,
default: false
},
billNo: {
type: String,
default: ''
},
transactionId: {
type: Number,
default: 0
}
},
data(){
@@ -194,6 +213,8 @@
swift: '',
snap: '',
country_id: this.country_id,
bill_no: this.billNo,
transaction_id: this.transactionId,
}
}
},
@@ -224,10 +245,24 @@
},
methods: {
submitForm(){
this.submit(route('api.bank.create'), 'post', this.section, true, false);
if(this.isEditing){
this.parameters.company_id = this.company_id;
this.parameters.account_type = this.type;
this.parameters.bill_no = this.billNo;
this.parameters.transaction_id = this.transactionId;
this.submit(route('api.bank.update', this.parameters.id), 'put', this.section, true, false);
}
else{
this.submit(route('api.bank.create'), 'post', this.section, true, false);
}
},
successHandler(response){
this.type !== 2 ? this.closeModal() : this.$emit('createdBank', response.payload.data);
if(this.isEditing){
this.type !== 2 ? this.closeModal() : this.$emit('updatedBankDetails', response.payload.data, this.transactionId);
}
else{
this.type !== 2 ? this.closeModal() : this.$emit('createdBank', response.payload.data);
}
this.formHandler();
this.resetForm();
},
@@ -39,12 +39,15 @@
</div>
</div>
<div class="row">
<div class="col" :class="[{'p-r-15': disabled}, {'p-r-5': !disabled}]">
<div class="col" :class="[{'p-r-15': disabled}, {'p-r-5': !disabled}]" v-if="!isCancelButtonHidden">
<div class="btn btn-sm btn-default bg-master-lightest btn-block b-rad-none" :data-dismiss="closable ? 'modal' : ''" @click="$emit('close')">{{disabled ? 'Change Recipient Account' : 'Cancel'}}</div>
</div>
<div class="col p-l-5" v-if="!disabled">
<div class="col p-l-5" v-if="!disabled && !isEditing">
<button class="btn btn-sm btn-success btn-block b-rad-none" @click="submitForm()">Add Account</button>
</div>
<div class="col p-l-5" v-if="isEditing">
<button class="btn btn-sm btn-success btn-block b-rad-none" @click="submitForm()">Update Details</button>
</div>
</div>
</div>
</div>
@@ -80,6 +83,22 @@
type: Object,
required: false,
default: null
},
isEditing: {
type: Boolean,
default: false
},
isCancelButtonHidden: {
type: Boolean,
default: false
},
billNo: {
type: String,
default: ''
},
transactionId: {
type: Number,
default: 0
}
},
data(){
@@ -93,6 +112,8 @@
account_no: '',
bank_branch: '',
country_id: this.country_id,
bill_no: this.billNo,
transaction_id: this.transactionId,
},
englishTextWarning: false,
confirmProceedEnglishText: false,
@@ -115,10 +136,24 @@
submitForm(){
this.parameters.account_type = 3;
this.parameters.bank_name = '-';
this.submit(route('api.bank.create'), 'post', this.section, true, false);
if(this.isEditing){
this.parameters.company_id = this.company_id;
this.parameters.account_type = this.type;
this.parameters.bill_no = this.billNo;
this.parameters.transaction_id = this.transactionId;
this.submit(route('api.bank.update', this.parameters.id), 'put', this.section, true, false);
}
else{
this.submit(route('api.bank.create'), 'post', this.section, true, false);
}
},
successHandler(response){
this.type !== 2 ? this.closeModal() : this.$emit('createdBank', response.payload.data);
if(this.isEditing){
this.type !== 2 ? this.closeModal() : this.$emit('updatedBankDetails', response.payload.data, this.transactionId);
}
else{
this.type !== 2 ? this.closeModal() : this.$emit('createdBank', response.payload.data);
}
this.formHandler();
this.resetForm();
},
@@ -140,4 +175,4 @@
mixins: [FormHandler]
}
</script>
</script>
@@ -14,12 +14,43 @@
</div> -->
</div>
<div class="row">
<span v-if="item.voucher.end_date">
Valid till {{ item.voucher.end_date }}
</span>
<span v-else>
No expiry date
</span>
<div class="col-12 col-md-8 text-left no-padding">
<span v-if="item.voucher.end_date">
Valid till {{ item.voucher.end_date }}
</span>
<span v-else>
No expiry date
</span>
</div>
<div class="col-12 col-md-4 text-right no-padding">
<a class="requestModal" :data-type="'showVoucherTnC-' + item.id">Terms</a>
</div>
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" size="extra-large" :type="'showVoucherTnC-' + item.id">
<div class="container">
<div class="card">
<div class="card-header">
Terms & Conditions
</div>
<div class="card-body">
<ol>
<li>Vouchers are only valid for purchases made on <a href="https://exchange.cief-malaysia.com/" target="_blank">https://exchange.cief-malaysia.com/</a>.</li>
<li>Each voucher is applicable for a single transaction (unless stated otherwise).</li>
<li>Each voucher is only applicable for new orders.</li>
<li>Voucher codes are to be entered at the checkout or cart page (unless stated otherwise).</li>
<li>Vouchers are not valid for promotions or discounted products (unless stated otherwise).</li>
<li>Customers should take note of the expiry dates of the voucher(s) that they wish to redeem. Any voucher(s) which have expired will be invalid.</li>
<li>Individual vouchers are only valid during its respective promotion period. This guideline overrides any individual voucher policy (unless stated otherwise).</li>
<li>CIEF reserves the right to cancel any order if a customers purchasing behavior appears to be suspicious or potentially fraudulent.</li>
<li>CIEF vouchers are not exchangeable for cash at <a href="https://exchange.cief-malaysia.com/" target="_blank">https://exchange.cief-malaysia.com/</a>.</li>
<li>This voucher can only be used and redeemed by a registered customer who has already logged into their account during purchase.</li>
<li>CIEF reserves the right to amend the terms & conditions or cancel any vouchers/promotions without prior notice.</li>
<li>Additional terms & conditions are stated on the respective promotion banners (e.g., duration, discount amounts, validity for campaigns/promotions or certain services).</li>
</ol>
<button type="button" class="btn btn-primary" data-dismiss="modal">OK</button>
</div>
</div>
</div>
</modal-component>
</div>
</div>
</div>
@@ -64,7 +95,7 @@
fetchVouchers(){
this.isLoading = true;
if(this.employee){
this.submit(route('api.voucher.user.list') + '?filters=' + JSON.stringify( { 'has_active_reward': this.employee.id} ), 'get', this.section, false, false);
this.submit(route('api.voucher.user.list') + '?filters=' + JSON.stringify( { 'has_vouchers_all_with_company': this.employee.id} ), 'get', this.section, false, false);
}
},
successHandler(response){
@@ -0,0 +1,177 @@
<template>
<div class="row zig-zag-top">
<div class="col bg-white padding-25">
<div class="row p-b-20 b-b b-dashed b-grey m-b-20">
<div class="col">
<div class="row m-b-10" v-if="data">
<div class="col" v-if="data.billNo && data.billNo !== ''">
<div class="font-heading all-caps bold fs-10">Edit Recipient Bank Details ({{ data.billNo }})</div>
</div>
<div class="col" v-else>
<div class="font-heading all-caps bold fs-10">Edit Recipient Bank Details (Default)</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="row m-b-10">
<div class="col">
<div class="row parentContainer">
<div class="col">
<div class="row" v-show="!createBank && !isEditing">
<div class="col-7 p-r-0">
<div class="row" id="select-list" name="select-list">
<div class="col">
<div class="form-group no-margin form-group-default">
<label>{{ data.serviceType.id === 4 ? '1688 Login Id/Email/Phone' : 'Account No.' }}</label>
<input type="text" class="form-control" v-model="account_no" @keyup="parameters.bankAccount = {}" @focus="dropdownStatus = true">
</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="relative w-100">
<div class="absolute w-100 b-l b-b b-r b-grey" :class="[{'hide': !dropdownStatus}]" 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="bank in data.recipientBanks.filter(getAccountNumber)" v-bind:key="bank.id" >
<div id="select-option" name="select-option" class="col b-b b-grey p-t-10 p-b-10 pointer p-t-10 p-b-10" :class="['bg-master-lightest','text-master', 'hover-primary', 'pointer']" @click="selectBank(bank)">
<div class="row align-items-center justify-content-center">
<div class="col">
<div class="row">
<div class="col">
<div class="font-heading bold lh-15 fs-13">{{bank.reference ? bank.reference + ' - ':''}}{{bank.holder_name}}</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="font-heading all-caps fs-13 muted"><b class="m-r-5 text-primary">{{bank.account_no}}</b> {{bank.bank_name}}</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-auto p-l-0" v-show="!createBank && account_no">
<button class="btn btn-sm h-100 btn-primary b-rad-none all-caps" @click="createBank = !createBank; dropdownStatus = false">
<i class="fa fa-plus m-r-5"></i>
Create New
</button>
</div>
</div>
<div class="row" v-show="createBank || isEditing">
<div class="col">
<bank-account-form-component v-if="data.serviceType.id !== 4"
section="bookingEditRecipientDetailSection"
:data="Object.keys(parameters.bankAccount).length ? parameters.bankAccount : {account_no: account_no, company_id: data.company.id, country_id: 2, account_type: 2}"
:company_id="data.company.id"
:country_id="2"
:type="2"
:currency="data.serviceType.selectedCurrency.short_code"
:billNo="data.billNo"
:transactionId="data.transactionId"
:serviceType="data.serviceType"
:closable=false
:isEditing="isEditing"
:isCancelButtonHidden=true
v-on:createdBank="updateBank($event)"
v-on:updatedBankDetails="updatedBankDetails"
v-on:close="clearAccount()">
</bank-account-form-component>
<phone-account-form-component v-if="data.serviceType.id === 4"
section="bookingEditRecipientDetailSection"
:data="Object.keys(parameters.bankAccount).length ? parameters.bankAccount : {account_no: account_no, company_id: data.company.id, country_id: 2, account_type: 2}"
:company_id="data.company.id"
:country_id="2" :type="2"
:billNo="data.billNo"
:transactionId="data.transactionId"
:serviceType="data.serviceType"
:closable=false
:isEditing="isEditing"
:isCancelButtonHidden=true
v-on:createdBank="updateBank($event)"
v-on:updatedBankDetails="updatedBankDetails"
v-on:close="clearAccount()" ></phone-account-form-component>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-auto" v-show="!isLoading">
<button id="cancel-new-booking" name="cancel-new-booking" class="btn btn-lg btn-default bg-master-lightest b-rad-none all-caps fs-12" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</template>
<script>
import FormHandler from '../../../general/mixins/formHandler';
// import componentHandler from '../../../general/mixins/componentHandler';
// import UpdateBookingComponent from "../forms/UpdateBookingComponent";
export default {
// components: {UpdateBookingComponent},
data(){
return {
createBank: false,
isEditing: true,
recipientBanks: [],
dropdownStatus: false,
account_no: '',
}
},
created(){
this.recipientBanks = this.data.recipientBanks;
},
methods: {
getAccountNumber(bank){
return bank.account_no.startsWith(this.account_no)
},
updateBank(bank){
this.selectBank(bank);
this.recipientBanks.push(bank);
this.parameters.bankAccount = bank;
this.parameters.bankAccountDefault = bank;
},
updatedBankDetails(bank, transactionId){
this.parameters.bankAccount = bank;
this.parameters.bankAccountDefault = bank;
var foundIndex = this.recipientBanks.findIndex(x => x.id == bank.id);
this.recipientBanks[foundIndex] = bank;
this.$emit('updatedBankDetails', bank, transactionId);
this.closeModal();
},
selectBank(bank){
this.account_no = bank.account_no;
this.isEditing = true;
this.createBank = false;
this.parameters.bankAccount = bank;
this.dropdownStatus = false;
},
clearAccount(){
this.createBank = false;
this.isEditing = false;
this.account_no = '';
this.parameters.bankAccount = {};
},
},
mixins: [FormHandler]
}
</script>
@@ -0,0 +1,168 @@
<template>
<div class="row zig-zag-top">
<div class="col bg-white padding-25">
<div class="row p-b-20 b-b b-dashed b-grey m-b-20">
<div class="col">
<div class="row m-b-10" v-if="data">
<div class="col" v-if="data.billNo && data.billNo !== ''">
<div class="font-heading all-caps bold fs-10">Edit Recipient Bank Details ({{ data.billNo }})</div>
</div>
<div class="col" v-else>
<div class="font-heading all-caps bold fs-10">Edit Recipient Bank Details (Default)</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="row m-b-10">
<div class="col">
<div class="row parentContainer">
<div class="col">
<div class="row" v-show="!createBank && !isEditing">
<div class="col-7 p-r-0">
<div class="row" id="select-list" name="select-list">
<div class="col">
<div class="form-group no-margin form-group-default">
<label>{{ data.serviceType.id === 4 ? '1688 Login Id/Email/Phone' : 'Account No.' }}</label>
<input type="text" class="form-control" v-model="account_no" @keyup="parameters.bankAccount = {}" @focus="dropdownStatus = true">
</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="relative w-100">
<div class="absolute w-100 b-l b-b b-r b-grey" :class="[{'hide': !dropdownStatus}]" 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="bank in data.recipientBanks.filter(AccountNumber)" v-bind:key="bank.id" >
<div id="select-option" name="select-option" class="col b-b b-grey p-t-10 p-b-10 pointer p-t-10 p-b-10" :class="['bg-master-lightest','text-master', 'hover-primary', 'pointer']" @click="selectBank(bank)">
<div class="row align-items-center justify-content-center">
<div class="col">
<div class="row">
<div class="col">
<div class="font-heading bold lh-15 fs-13">{{bank.reference ? bank.reference + ' - ':''}}{{bank.holder_name}}</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="font-heading all-caps fs-13 muted"><b class="m-r-5 text-primary">{{bank.account_no}}</b> {{bank.bank_name}}</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-auto p-l-0" v-show="!createBank && account_no">
<button class="btn btn-sm h-100 btn-primary b-rad-none all-caps" @click="createBank = !createBank; dropdownStatus = false">
<i class="fa fa-plus m-r-5"></i>
Create New
</button>
</div>
</div>
<div class="row" v-show="createBank || isEditing">
<div class="col">
<bank-account-form-component v-if="data.serviceType.id !== 4"
section="bookingEditRecipientDetailSection"
:data="Object.keys(parameters.bankAccount).length ? parameters.bankAccount : {account_no: account_no, company_id: data.company.id, country_id: 2, account_type: 2}"
:company_id="data.company.id"
:country_id="2" :type="2"
:currency="data.serviceType.selectedCurrency.short_code"
:serviceType="data.serviceType"
:closable=false
:isEditing="isEditing"
v-on:createdBank="updateBank($event)"
v-on:updatedBankDetails="updatedBankDetails"
v-on:close="clearAccount()">
</bank-account-form-component>
<phone-account-form-component v-if="data.serviceType.id === 4"
section="bookingEditRecipientDetailSection"
:data="Object.keys(parameters.bankAccount).length ? parameters.bankAccount : {account_no: account_no, company_id: data.company.id, country_id: 2, account_type: 2}"
:company_id="data.company.id"
:country_id="2" :type="2"
:serviceType="data.serviceType"
:closable=false
:isEditing="isEditing"
v-on:createdBank="updateBank($event)"
v-on:updatedBankDetails="updatedBankDetails"
v-on:close="clearAccount()">
</phone-account-form-component>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<update-booking-component section="bookingEditRecipientDetailSection" :data="data" v-if="parameters" v-on:updatedBooking="updatedBankDetails($event)" v-on:updateBookingCanceled="cancelUpdate()"></update-booking-component>
</div>
</div>
</template>
<script>
import FormHandler from '../../../general/mixins/formHandler';
// import UpdateBookingComponent from "../forms/UpdateBookingComponent";
export default {
// components: {UpdateBookingComponent},
data(){
return {
createBank: false,
isEditing: true,
recipientBanks: [],
dropdownStatus: false,
account_no: '',
}
},
created(){
this.recipientBanks = this.data.recipientBanks;
},
methods: {
AccountNumber(bank){
return bank.account_no.startsWith(this.account_no)
},
updateBank(bank){
this.selectBank(bank);
this.recipientBanks.push(bank);
this.parameters.bankAccount = bank;
this.parameters.bankAccountDefault = bank;
},
updatedBankDetails(bank, transactionId){
this.parameters.bankAccount = bank;
this.parameters.bankAccountDefault = bank;
var foundIndex = this.recipientBanks.findIndex(x => x.id == bank.id);
this.recipientBanks[foundIndex] = bank;
this.$emit('updatedBankDetails', bank, transactionId);
},
selectBank(bank){
this.account_no = bank.account_no;
this.isEditing = true;
this.createBank = false;
this.parameters.bankAccount = bank;
this.dropdownStatus = false;
},
clearAccount(){
this.createBank = false;
this.isEditing = false;
this.account_no = '';
this.parameters.bankAccount = {};
},
cancelUpdate(){
this.parameters.bankAccount = this.parameters.bankAccountDefault;
this.isEditing = true;
this.createBank = false;
}
},
mixins: [FormHandler]
}
</script>
@@ -76,7 +76,7 @@
fetchVouchers(){
this.isLoading = true;
if(this.employee){
this.submit(route('api.voucher.user.list') + '?filters=' + JSON.stringify( { 'has_active_reward': this.employee.id} ), 'get', this.section, false, false);
this.submit(route('api.voucher.user.list') + '?filters=' + JSON.stringify( { 'has_vouchers_all_with_company': this.employee.id} ), 'get', this.section, false, false);
}
},
successHandler(response){
@@ -33,6 +33,12 @@
<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 class="row" v-if="$store.getters.isSuperAdmin">
<div class="col">
<div class="font-heading fs-8 all-caps">Payment Method: {{ convertPaymentMethod(item.payment_method) }}</div>
<div class="font-heading fs-8 all-caps">Payment Date: {{ item.created_at }}</div>
</div>
</div>
<div class="row" v-if="$store.getters.isAdmin && item.bill_no">
<div class="col">
<div class="font-heading fs-8 all-caps m-t-5">Bill Number: <b>{{ item.bill_no }}</b></div>
@@ -386,6 +392,24 @@
</modal-component>
</div>
</div>
<div class="row m-b-15 text-right parentContainer" v-if="$store.getters.isSuperAdmin && refund.status === 2">
<div class="col">
<button class="btn btn-xs btn-outline-danger b-rad-none m-r-5 requestModal" data-type="deleteRefund">
<i class="fa fa-times fa-fw"></i>
</button>
<modal-component class="animate__animated animate__fast animate__fadeIn" type="deleteRefund">
<general-confirmation-form-component
contentText="Are you sure you want to delete this refund?"
modalType="delete"
class="text-center"
:apiRoute="route('api.transaction.refund.delete', refund.id)"
apiMethod="delete"
:section="section"
>
</general-confirmation-form-component>
</modal-component>
</div>
</div>
</div>
</div>
</div>
@@ -456,6 +480,15 @@
clickExpandRefundTransactions(){
this.expandRefundTransactions = !this.expandRefundTransactions;
},
convertPaymentMethod(paymentMethod){
var paymentMethodArray = [];
paymentMethodArray[1] = 'Cash';
paymentMethodArray[2] = 'Cheque';
paymentMethodArray[3] = 'ba';
paymentMethodArray[4] = 'Wallet';
paymentMethodArray[5] = 'Payment Gateway';
return paymentMethodArray[paymentMethod];
},
},
mixins: [componentHandler]
}
@@ -51,39 +51,32 @@
</div>
</div>
</div>
<div class="row align-items-center m-b-15 parentContainer bg-master-lighter p-t-10 p-b-10">
<div class="col">
<div class="row m-b-5">
<div class="col">
<div class="font-heading all-caps fs-10 muted">Recipient Bank Details</div>
<recipient-bank-details-component :data="item" :section="section"></recipient-bank-details-component>
<div class="row" style="margin-top: -20px" v-if="$store.getters.isAdmin">
<div class="col-auto">
<p class="text-complete text-underline m-b-0 fs-12 pointer" @click="toggleEditRecipientBankDetailsCollapsed">{{ isEditRecipientBankDetailsCollapsed ? '< Back' : 'Change recipient bank details' }}</p>
</div>
</div>
<div class="row align-items-center">
<div class="col-auto p-r-0">
<img v-if="item.service.id === 4" src="/images/1688_logo.png" alt="" width="40">
<img v-else-if="item.service.id === 11" src="/images/alipay_logo.png" alt="" width="40">
<div v-else class="padding-5 bg-master-light">
<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="38.97413" x2="86" y2="57.78663" gradientUnits="userSpaceOnUse" id="color-1_77055_gr1"><stop offset="0" stop-color="#4ec9ff"></stop><stop offset="1" stop-color="#2bffe6"></stop></linearGradient><linearGradient x1="129" y1="77.49138" x2="129" y2="121.38631" gradientUnits="userSpaceOnUse" id="color-2_77055_gr2"><stop offset="0" stop-color="#4ec9ff"></stop><stop offset="1" stop-color="#2bffe6"></stop></linearGradient><linearGradient x1="43" y1="77.49138" x2="43" y2="121.38631" gradientUnits="userSpaceOnUse" id="color-3_77055_gr3"><stop offset="0" stop-color="#4ec9ff"></stop><stop offset="1" stop-color="#2bffe6"></stop></linearGradient><linearGradient x1="86" y1="64.94881" x2="86" y2="133.92888" gradientUnits="userSpaceOnUse" id="color-4_77055_gr4"><stop offset="0" stop-color="#4ec9ff"></stop><stop offset="1" stop-color="#2bffe6"></stop></linearGradient><linearGradient x1="86" y1="16.11963" x2="86" y2="155.875" gradientUnits="userSpaceOnUse" id="color-5_77055_gr5"><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="M86,40.31787c-4.4528,0 -8.0625,3.6097 -8.0625,8.0625c0,4.4528 3.6097,8.0625 8.0625,8.0625c4.4528,0 8.0625,-3.6097 8.0625,-8.0625c0,-4.4528 -3.6097,-8.0625 -8.0625,-8.0625z" fill="url(#color-1_77055_gr1)"></path><path d="M126.3125,80.625h5.375v37.625h-5.375z" fill="url(#color-2_77055_gr2)"></path><path d="M40.3125,80.625h5.375v37.625h-5.375z" fill="url(#color-3_77055_gr3)"></path><path d="M56.4375,69.875v59.125h59.125v-59.125zM99.4375,88.6875h-21.5v8.0625h16.125c2.96431,0 5.375,2.41069 5.375,5.375v8.0625c0,2.96431 -2.41069,5.375 -5.375,5.375h-5.375v5.375h-5.375v-5.375h-10.75v-5.375h21.5v-8.0625h-16.125c-2.96431,0 -5.375,-2.41069 -5.375,-5.375v-8.0625c0,-2.96431 2.41069,-5.375 5.375,-5.375h5.375v-5.375h5.375v5.375h10.75z" fill="url(#color-4_77055_gr4)"></path><path d="M86,59.125c-5.92862,0 -10.75,-4.82138 -10.75,-10.75c0,-5.92862 4.82138,-10.75 10.75,-10.75c5.92863,0 10.75,4.82138 10.75,10.75c0,5.92862 -4.82137,10.75 -10.75,10.75zM86,43c-2.96431,0 -5.375,2.41069 -5.375,5.375c0,2.96431 2.41069,5.375 5.375,5.375c2.96431,0 5.375,-2.41069 5.375,-5.375c0,-2.96431 -2.41069,-5.375 -5.375,-5.375zM108.84375,53.75c-2.22256,0 -4.03125,-1.80869 -4.03125,-4.03125c0,-2.22256 1.80869,-4.03125 4.03125,-4.03125c2.22256,0 4.03125,1.80869 4.03125,4.03125c0,2.22256 -1.80869,4.03125 -4.03125,4.03125zM108.84375,49.71606v0.00269zM63.15625,53.75c-2.22256,0 -4.03125,-1.80869 -4.03125,-4.03125c0,-2.22256 1.80869,-4.03125 4.03125,-4.03125c2.22256,0 4.03125,1.80869 4.03125,4.03125c0,2.22256 -1.80869,4.03125 -4.03125,4.03125zM63.15625,49.71606v0.00269zM150.5,69.875c2.96431,0 5.375,-2.39456 5.375,-5.34544v-1.29806c0,-1.72269 -0.84119,-3.34862 -2.30319,-4.39138l-60.03069,-40.40925c-4.58219,-3.08256 -10.49737,-3.08256 -15.07956,0l-60.08981,40.44956c-1.40825,1.00244 -2.24675,2.62838 -2.24675,4.35106v1.29806c0,2.95088 2.41069,5.34544 5.375,5.34544h8.0625v59.13037c-4.44513,0 -8.0625,3.61738 -8.0625,8.0625v3.182c-3.12019,1.11531 -5.375,4.06888 -5.375,7.568v8.05713h139.75v-8.05712c0,-3.49913 -2.25481,-6.45269 -5.375,-7.568v-3.182c0,-4.44513 -3.61738,-8.0625 -8.0625,-8.0625v-59.13038zM150.5,147.81788v2.68212h-129v-2.68212c0,-1.4835 1.204,-2.69288 2.6875,-2.69288h123.625c1.4835,0 2.6875,1.20937 2.6875,2.69288zM145.125,137.06788v2.68212h-118.25v-2.68212c0,-1.4835 1.204,-2.69288 2.6875,-2.69288h26.875h16.125h26.875h16.125h26.875c1.4835,0 2.6875,1.20937 2.6875,2.69288zM51.0625,80.625v37.625h-16.125v-37.625zM34.9375,75.25v-5.375h16.125v5.375zM51.0625,123.625v5.375h-16.125v-5.375zM56.4375,129v-59.125h5.375h10.75h5.375h16.125h5.375h5.375h10.75v59.125h-10.75h-5.375h-5.375h-16.125h-5.375h-10.75zM137.0625,80.625v37.625h-16.125v-37.625zM120.9375,75.25v-5.375h16.125v5.375zM137.0625,123.625v5.375h-16.125v-5.375zM115.5625,64.5h-16.125h-26.875v0.0215l-16.125,0.00269v-0.02419h-26.875h-8.0625l-0.06719,-1.21475l60.03069,-40.40387c1.376,-0.92987 2.95625,-1.38944 4.5365,-1.38944c1.58025,0 3.1605,0.46494 4.5365,1.39481l59.9635,40.33938l0.00806,1.27388c0,0 -0.00269,0 -0.00806,0h-8.0625z" fill="url(#color-5_77055_gr5)"></path></g></g></svg>
</div>
</div>
<div class="row" style="margin-top: -20px" v-if="!$store.getters.isAdmin && isAnyPaymentRecipientBankEdited">
<div class="col-auto">
<div class="row">
<div class="col-auto p-r-10">
<div class="font-heading fs-12">{{item.bank.holder_name}} <span class="text-complete m-l-5 bold">{{[3, 4].includes(item.bank.type) ? item.bank.account_no : item.bank.account_no.replace(/[^\dA-Z]/g, '').replace(/(.{4})/g, '$1 ').trim()}}</span></div>
</div>
</div>
<div class="row" v-if="![3, 4].includes(item.bank.type)">
<div class="col-auto p-r-10">
<div class="font-heading fs-10 small">{{item.bank.bank_name}} <span class="m-l-5">({{item.bank.bank_branch}})</span> <span class="m-l-5">({{item.bank.swift}})</span></div>
</div>
</div>
<p class="text-complete text-underline m-b-0 fs-12 pointer" @click="toggleEditRecipientBankDetailsCollapsed">{{ isEditRecipientBankDetailsCollapsed ? '< Back' : 'Show edited recipient bank details on payment' }}</p>
</div>
</div>
</div>
</div>
<div class="collapse" :class="{ show: isEditRecipientBankDetailsCollapsed }" ref="collapseContent" v-if="$store.getters.isAdmin">
<recipient-bank-details-component :data="item" :section="section" :isEditButtonHidden="false"></recipient-bank-details-component>
<edit-payment-recipient-bank-details-component :data="item" :section="section" :isEditButtonHidden="false"></edit-payment-recipient-bank-details-component>
</div>
<div class="collapse" :class="{ show: isEditRecipientBankDetailsCollapsed }" ref="collapseContent" v-if="!$store.getters.isAdmin && isAnyPaymentRecipientBankEdited">
<edit-payment-recipient-bank-details-component :data="item" :section="section" :isEditButtonHidden="true"></edit-payment-recipient-bank-details-component>
</div>
<div class="row">
<div class="col bg-white padding-15">
<div class="row" v-if="!expandPayment">
@@ -123,7 +116,7 @@
<div class="font-heading fs-12">{{this.data.fixed_currency.short_code}} {{(Math.round((this.data.outstanding_amount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}</div>
</div>
</div>
<div class="row m-t-20" v-if="data.company.employee.status === 2 && data.company.status === 2 && data.outstanding_amount > 0">
<div class="row m-t-20" v-if="data.company.employee.status === 2 && data.company.status === 2 && (Math.round((this.data.outstanding_amount + Number.EPSILON) * 100) / 100) > 0">
<div class="col">
<button id="payment-btn" class="btn btn-sm all-caps b-rad-none btn-success btn-block" @click="makePayment()">Make Payment</button>
</div>
@@ -606,6 +599,22 @@
voucherValidated: false,
voucherIsChecking: false,
showApplyVoucher: false,
recipientBanks: {
company: this.data.company,
serviceType: {
status: false,
id: this.data.service.id,
name: this.data.service.name,
currencies: this.data.service.configurations.currencies,
selectedCurrency: this.data.service.configurations.currencies[0]
},
bankAccount: this.data.bank,
bankAccountDefault: this.data.bank,
recipientBanks: this.data.company.recipient_banks.accounts,
bookingId: this.data.id
},
isEditRecipientBankDetailsCollapsed: false,
isAnyPaymentRecipientBankEdited: this.data.payment_history.some(payment => payment.bank !== null),
}
},
validations () {
@@ -635,7 +644,6 @@
id: bankCode,
status: true,
}
},
submitForm(){
this.parameters = {
@@ -643,7 +651,6 @@
voucherCode: this.voucherCode,
amount: this.amount
};
this.submit(route('api.booking.payment.quotation', this.item.id), 'post', this.section, false, false)
this.calculation = null;
},
@@ -677,9 +684,9 @@
this.calculation = null;
this.expandPayment = false;
},
updatedBankDetails(bank){
this.item.bank = bank;
},
// updatedBankDetails(bank){ //cief todo: 66 - this need to move to vuex, too many levels of passings between parent and child
// this.item.bank = bank;
// },
removeVoucher(){
this.voucherCodeFailedReason = '';
this.voucherCode = '';
@@ -710,6 +717,14 @@
},
handleSelectedVoucher(value){
this.voucherCode = value;
},
toggleEditRecipientBankDetailsCollapsed() {
this.isEditRecipientBankDetailsCollapsed = !this.isEditRecipientBankDetailsCollapsed;
if (this.isEditRecipientBankDetailsCollapsed) {
$(this.$refs.collapseContent).collapse('show');
} else {
$(this.$refs.collapseContent).collapse('hide');
}
}
},
mixins: [componentHandler],
@@ -0,0 +1,205 @@
<template>
<div class="row align-items-center m-b-15 parentContainer p-t-10 p-b-10">
<div class="col">
<div class="row" v-if="item.payment_history.length">
<div class="col">
<div class="row m-b-15 p-b-10 bg-master-lighter" v-for="singlePayment in item.payment_history" v-bind:key="singlePayment.id" >
<div class="col">
<div class="row m-b-5">
<div class="col">
<div class="font-heading">
<span class="all-caps fs-10 muted">
Recipient Bank Details
</span>
</div>
</div>
</div>
<!-- PRIORITY If bank exist for payment -->
<div class="row align-items-center" v-if="singlePayment.bank">
<div class="col-auto p-r-0">
<img v-if="item.service.id === 4" src="/images/1688_logo.png" alt="" width="40">
<img v-else-if="item.service.id === 11" src="/images/alipay_logo.png" alt="" width="40">
<div v-else class="padding-5 bg-master-light">
<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="38.97413" x2="86" y2="57.78663" gradientUnits="userSpaceOnUse" id="color-1_77055_gr1"><stop offset="0" stop-color="#4ec9ff"></stop><stop offset="1" stop-color="#2bffe6"></stop></linearGradient><linearGradient x1="129" y1="77.49138" x2="129" y2="121.38631" gradientUnits="userSpaceOnUse" id="color-2_77055_gr2"><stop offset="0" stop-color="#4ec9ff"></stop><stop offset="1" stop-color="#2bffe6"></stop></linearGradient><linearGradient x1="43" y1="77.49138" x2="43" y2="121.38631" gradientUnits="userSpaceOnUse" id="color-3_77055_gr3"><stop offset="0" stop-color="#4ec9ff"></stop><stop offset="1" stop-color="#2bffe6"></stop></linearGradient><linearGradient x1="86" y1="64.94881" x2="86" y2="133.92888" gradientUnits="userSpaceOnUse" id="color-4_77055_gr4"><stop offset="0" stop-color="#4ec9ff"></stop><stop offset="1" stop-color="#2bffe6"></stop></linearGradient><linearGradient x1="86" y1="16.11963" x2="86" y2="155.875" gradientUnits="userSpaceOnUse" id="color-5_77055_gr5"><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="M86,40.31787c-4.4528,0 -8.0625,3.6097 -8.0625,8.0625c0,4.4528 3.6097,8.0625 8.0625,8.0625c4.4528,0 8.0625,-3.6097 8.0625,-8.0625c0,-4.4528 -3.6097,-8.0625 -8.0625,-8.0625z" fill="url(#color-1_77055_gr1)"></path><path d="M126.3125,80.625h5.375v37.625h-5.375z" fill="url(#color-2_77055_gr2)"></path><path d="M40.3125,80.625h5.375v37.625h-5.375z" fill="url(#color-3_77055_gr3)"></path><path d="M56.4375,69.875v59.125h59.125v-59.125zM99.4375,88.6875h-21.5v8.0625h16.125c2.96431,0 5.375,2.41069 5.375,5.375v8.0625c0,2.96431 -2.41069,5.375 -5.375,5.375h-5.375v5.375h-5.375v-5.375h-10.75v-5.375h21.5v-8.0625h-16.125c-2.96431,0 -5.375,-2.41069 -5.375,-5.375v-8.0625c0,-2.96431 2.41069,-5.375 5.375,-5.375h5.375v-5.375h5.375v5.375h10.75z" fill="url(#color-4_77055_gr4)"></path><path d="M86,59.125c-5.92862,0 -10.75,-4.82138 -10.75,-10.75c0,-5.92862 4.82138,-10.75 10.75,-10.75c5.92863,0 10.75,4.82138 10.75,10.75c0,5.92862 -4.82137,10.75 -10.75,10.75zM86,43c-2.96431,0 -5.375,2.41069 -5.375,5.375c0,2.96431 2.41069,5.375 5.375,5.375c2.96431,0 5.375,-2.41069 5.375,-5.375c0,-2.96431 -2.41069,-5.375 -5.375,-5.375zM108.84375,53.75c-2.22256,0 -4.03125,-1.80869 -4.03125,-4.03125c0,-2.22256 1.80869,-4.03125 4.03125,-4.03125c2.22256,0 4.03125,1.80869 4.03125,4.03125c0,2.22256 -1.80869,4.03125 -4.03125,4.03125zM108.84375,49.71606v0.00269zM63.15625,53.75c-2.22256,0 -4.03125,-1.80869 -4.03125,-4.03125c0,-2.22256 1.80869,-4.03125 4.03125,-4.03125c2.22256,0 4.03125,1.80869 4.03125,4.03125c0,2.22256 -1.80869,4.03125 -4.03125,4.03125zM63.15625,49.71606v0.00269zM150.5,69.875c2.96431,0 5.375,-2.39456 5.375,-5.34544v-1.29806c0,-1.72269 -0.84119,-3.34862 -2.30319,-4.39138l-60.03069,-40.40925c-4.58219,-3.08256 -10.49737,-3.08256 -15.07956,0l-60.08981,40.44956c-1.40825,1.00244 -2.24675,2.62838 -2.24675,4.35106v1.29806c0,2.95088 2.41069,5.34544 5.375,5.34544h8.0625v59.13037c-4.44513,0 -8.0625,3.61738 -8.0625,8.0625v3.182c-3.12019,1.11531 -5.375,4.06888 -5.375,7.568v8.05713h139.75v-8.05712c0,-3.49913 -2.25481,-6.45269 -5.375,-7.568v-3.182c0,-4.44513 -3.61738,-8.0625 -8.0625,-8.0625v-59.13038zM150.5,147.81788v2.68212h-129v-2.68212c0,-1.4835 1.204,-2.69288 2.6875,-2.69288h123.625c1.4835,0 2.6875,1.20937 2.6875,2.69288zM145.125,137.06788v2.68212h-118.25v-2.68212c0,-1.4835 1.204,-2.69288 2.6875,-2.69288h26.875h16.125h26.875h16.125h26.875c1.4835,0 2.6875,1.20937 2.6875,2.69288zM51.0625,80.625v37.625h-16.125v-37.625zM34.9375,75.25v-5.375h16.125v5.375zM51.0625,123.625v5.375h-16.125v-5.375zM56.4375,129v-59.125h5.375h10.75h5.375h16.125h5.375h5.375h10.75v59.125h-10.75h-5.375h-5.375h-16.125h-5.375h-10.75zM137.0625,80.625v37.625h-16.125v-37.625zM120.9375,75.25v-5.375h16.125v5.375zM137.0625,123.625v5.375h-16.125v-5.375zM115.5625,64.5h-16.125h-26.875v0.0215l-16.125,0.00269v-0.02419h-26.875h-8.0625l-0.06719,-1.21475l60.03069,-40.40387c1.376,-0.92987 2.95625,-1.38944 4.5365,-1.38944c1.58025,0 3.1605,0.46494 4.5365,1.39481l59.9635,40.33938l0.00806,1.27388c0,0 -0.00269,0 -0.00806,0h-8.0625z" fill="url(#color-5_77055_gr5)"></path></g></g></svg>
</div>
</div>
<div class="col-auto">
<div class="row">
<div class="col-auto p-r-10">
<div class="font-heading fs-12">{{singlePayment.bank.holder_name}}
<span class="text-complete m-l-5 bold">{{[3, 4].includes(singlePayment.bank.type) ? singlePayment.bank.account_no : singlePayment.bank.account_no.replace(/[^\dA-Z]/g, '').replace(/(.{4})/g, '$1 ').trim()}}</span>
</div>
</div>
</div>
<div class="row" v-if="![3, 4].includes(singlePayment.bank.type)">
<div class="col-auto p-r-10">
<div class="font-heading fs-10 small">{{singlePayment.bank.bank_name}} <span class="m-l-5">({{singlePayment.bank.bank_branch}})</span> <span class="m-l-5">({{singlePayment.bank.swift}})</span></div>
</div>
</div>
<div class="row">
<div class="col-auto p-r-10">
<span class="fs-10">
{{singlePayment.bill_no }} -
</span>
<span class="fs-10 bold">{{singlePayment.original_currency.short_code}} {{(Math.round((singlePayment.original_amount - singlePayment.refunded_amount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
</span>
</div>
</div>
<div class="row" v-if="!isEditButtonHidden">
<div class="col-auto p-r-10">
<span class="fs-10">
<button class="btn btn-xs btn-outline-danger b-rad-none m-r-5 requestModal" :data-type="'updateBankMetadata-' + singlePayment.bill_no">
<span>Reset to Default</span>
</button>
<modal-component class="animate__animated animate__fast animate__fadeIn" :type="'updateBankMetadata-'+ singlePayment.bill_no">
<general-confirmation-form-component
contentText="Are you sure you want to reset to default"
modalType="delete"
class="text-center"
:params="getPayloadToResetDefault(singlePayment, item)"
:apiRoute="route('api.bank.update.metadata', singlePayment.bank.id)"
apiMethod="post"
:section="section"
>
</general-confirmation-form-component>
</modal-component>
</span>
</div>
</div>
</div>
</div>
<!-- Default Recipient Bank from Booking -->
<div class="row align-items-center" v-else>
<div class="col-auto p-r-0">
<img v-if="item.service.id === 4" src="/images/1688_logo.png" alt="" width="40">
<img v-else-if="item.service.id === 11" src="/images/alipay_logo.png" alt="" width="40">
<div v-else class="padding-5 bg-master-light">
<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="38.97413" x2="86" y2="57.78663" gradientUnits="userSpaceOnUse" id="color-1_77055_gr1"><stop offset="0" stop-color="#4ec9ff"></stop><stop offset="1" stop-color="#2bffe6"></stop></linearGradient><linearGradient x1="129" y1="77.49138" x2="129" y2="121.38631" gradientUnits="userSpaceOnUse" id="color-2_77055_gr2"><stop offset="0" stop-color="#4ec9ff"></stop><stop offset="1" stop-color="#2bffe6"></stop></linearGradient><linearGradient x1="43" y1="77.49138" x2="43" y2="121.38631" gradientUnits="userSpaceOnUse" id="color-3_77055_gr3"><stop offset="0" stop-color="#4ec9ff"></stop><stop offset="1" stop-color="#2bffe6"></stop></linearGradient><linearGradient x1="86" y1="64.94881" x2="86" y2="133.92888" gradientUnits="userSpaceOnUse" id="color-4_77055_gr4"><stop offset="0" stop-color="#4ec9ff"></stop><stop offset="1" stop-color="#2bffe6"></stop></linearGradient><linearGradient x1="86" y1="16.11963" x2="86" y2="155.875" gradientUnits="userSpaceOnUse" id="color-5_77055_gr5"><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="M86,40.31787c-4.4528,0 -8.0625,3.6097 -8.0625,8.0625c0,4.4528 3.6097,8.0625 8.0625,8.0625c4.4528,0 8.0625,-3.6097 8.0625,-8.0625c0,-4.4528 -3.6097,-8.0625 -8.0625,-8.0625z" fill="url(#color-1_77055_gr1)"></path><path d="M126.3125,80.625h5.375v37.625h-5.375z" fill="url(#color-2_77055_gr2)"></path><path d="M40.3125,80.625h5.375v37.625h-5.375z" fill="url(#color-3_77055_gr3)"></path><path d="M56.4375,69.875v59.125h59.125v-59.125zM99.4375,88.6875h-21.5v8.0625h16.125c2.96431,0 5.375,2.41069 5.375,5.375v8.0625c0,2.96431 -2.41069,5.375 -5.375,5.375h-5.375v5.375h-5.375v-5.375h-10.75v-5.375h21.5v-8.0625h-16.125c-2.96431,0 -5.375,-2.41069 -5.375,-5.375v-8.0625c0,-2.96431 2.41069,-5.375 5.375,-5.375h5.375v-5.375h5.375v5.375h10.75z" fill="url(#color-4_77055_gr4)"></path><path d="M86,59.125c-5.92862,0 -10.75,-4.82138 -10.75,-10.75c0,-5.92862 4.82138,-10.75 10.75,-10.75c5.92863,0 10.75,4.82138 10.75,10.75c0,5.92862 -4.82137,10.75 -10.75,10.75zM86,43c-2.96431,0 -5.375,2.41069 -5.375,5.375c0,2.96431 2.41069,5.375 5.375,5.375c2.96431,0 5.375,-2.41069 5.375,-5.375c0,-2.96431 -2.41069,-5.375 -5.375,-5.375zM108.84375,53.75c-2.22256,0 -4.03125,-1.80869 -4.03125,-4.03125c0,-2.22256 1.80869,-4.03125 4.03125,-4.03125c2.22256,0 4.03125,1.80869 4.03125,4.03125c0,2.22256 -1.80869,4.03125 -4.03125,4.03125zM108.84375,49.71606v0.00269zM63.15625,53.75c-2.22256,0 -4.03125,-1.80869 -4.03125,-4.03125c0,-2.22256 1.80869,-4.03125 4.03125,-4.03125c2.22256,0 4.03125,1.80869 4.03125,4.03125c0,2.22256 -1.80869,4.03125 -4.03125,4.03125zM63.15625,49.71606v0.00269zM150.5,69.875c2.96431,0 5.375,-2.39456 5.375,-5.34544v-1.29806c0,-1.72269 -0.84119,-3.34862 -2.30319,-4.39138l-60.03069,-40.40925c-4.58219,-3.08256 -10.49737,-3.08256 -15.07956,0l-60.08981,40.44956c-1.40825,1.00244 -2.24675,2.62838 -2.24675,4.35106v1.29806c0,2.95088 2.41069,5.34544 5.375,5.34544h8.0625v59.13037c-4.44513,0 -8.0625,3.61738 -8.0625,8.0625v3.182c-3.12019,1.11531 -5.375,4.06888 -5.375,7.568v8.05713h139.75v-8.05712c0,-3.49913 -2.25481,-6.45269 -5.375,-7.568v-3.182c0,-4.44513 -3.61738,-8.0625 -8.0625,-8.0625v-59.13038zM150.5,147.81788v2.68212h-129v-2.68212c0,-1.4835 1.204,-2.69288 2.6875,-2.69288h123.625c1.4835,0 2.6875,1.20937 2.6875,2.69288zM145.125,137.06788v2.68212h-118.25v-2.68212c0,-1.4835 1.204,-2.69288 2.6875,-2.69288h26.875h16.125h26.875h16.125h26.875c1.4835,0 2.6875,1.20937 2.6875,2.69288zM51.0625,80.625v37.625h-16.125v-37.625zM34.9375,75.25v-5.375h16.125v5.375zM51.0625,123.625v5.375h-16.125v-5.375zM56.4375,129v-59.125h5.375h10.75h5.375h16.125h5.375h5.375h10.75v59.125h-10.75h-5.375h-5.375h-16.125h-5.375h-10.75zM137.0625,80.625v37.625h-16.125v-37.625zM120.9375,75.25v-5.375h16.125v5.375zM137.0625,123.625v5.375h-16.125v-5.375zM115.5625,64.5h-16.125h-26.875v0.0215l-16.125,0.00269v-0.02419h-26.875h-8.0625l-0.06719,-1.21475l60.03069,-40.40387c1.376,-0.92987 2.95625,-1.38944 4.5365,-1.38944c1.58025,0 3.1605,0.46494 4.5365,1.39481l59.9635,40.33938l0.00806,1.27388c0,0 -0.00269,0 -0.00806,0h-8.0625z" fill="url(#color-5_77055_gr5)"></path></g></g></svg>
</div>
</div>
<div class="col-auto">
<div class="row">
<div class="col-auto p-r-10">
<div class="font-heading fs-12">{{item.bank.holder_name}}
<span class="text-complete m-l-5 bold">{{[3, 4].includes(item.bank.type) ? item.bank.account_no : item.bank.account_no.replace(/[^\dA-Z]/g, '').replace(/(.{4})/g, '$1 ').trim()}}</span>
</div>
</div>
</div>
<div class="row" v-if="![3, 4].includes(item.bank.type)">
<div class="col-auto p-r-10">
<div class="font-heading fs-10 small">{{item.bank.bank_name}} <span class="m-l-5">({{item.bank.bank_branch}})</span> <span class="m-l-5">({{item.bank.swift}})</span></div>
</div>
</div>
<div class="row">
<div class="col-auto p-r-10">
<span class="fs-10">
{{singlePayment.bill_no }} -
</span>
<span class="fs-10 bold">{{singlePayment.original_currency.short_code}} {{(Math.round((singlePayment.original_amount - singlePayment.refunded_amount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
</span>
</div>
</div>
<div class="row">
<div class="col-auto p-r-10">
<span class="fs-10">
<span class="badge badge-secondary">DEFAULT</span>
</span>
</div>
</div>
</div>
</div>
<div class="row m-t-20" v-if="!isEditButtonHidden">
<div class="col">
<div class="btn btn-sm btn-block b-rad-none shadow-sm pointer requestModal" :data-type="'editRecipientDetailsFor-' + singlePayment.bill_no" :id="'edit-recipient-details-' + singlePayment.bill_no" :name="'edit-recipient-details-' + singlePayment.bill_no">EDIT FOR PAYMENT</div>
</div>
<modal-component id="select-account-modal" class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" :type="'editRecipientDetailsFor-' + singlePayment.bill_no" size="large">
<booking-payment-recipient-edit-component :data="getRecipientBanks(singlePayment)" :section="section" v-on:updatedBankDetails="updatedBankDetails"></booking-payment-recipient-edit-component>
</modal-component>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import componentHandler from '../../../general/mixins/componentHandler';
export default {
props : {
section: {
type: String,
required: true
},
isEditButtonHidden: {
type: Boolean,
default: true
},
},
data(){
return {
recipientBanks: {
company: this.data.company,
serviceType: {
status: false,
id: this.data.service.id,
name: this.data.service.name,
currencies: this.data.service.configurations.currencies,
selectedCurrency: this.data.service.configurations.currencies[0]
},
bankAccount: this.data.bank,
bankAccountDefault: this.data.bank,
recipientBanks: this.data.company.recipient_banks.accounts,
bookingId: this.data.id,
billNo: '',
transactionId: 0,
}
}
},
methods: {
getRecipientBanks(payment = null) {
const recipientBanksAmended = { ...this.recipientBanks };
if (payment) {
if(payment.bank){
const currentBank = { ... payment.bank };
recipientBanksAmended.bankAccount = currentBank;
}
else {
const currentBank = { ... this.data.bank };
recipientBanksAmended.bankAccount = currentBank;
}
recipientBanksAmended.billNo = payment.bill_no;
recipientBanksAmended.transactionId = payment.id;
}
return recipientBanksAmended;
},
updatedBankDetails(bank, transactionId){ //cief todo: 66 - this need to move to vuex, too many levels of passings between parent and child
const index = this.item.payment_history.findIndex(payment => payment.id === transactionId);
if (index !== -1) {
this.item.payment_history[index].bank = { ... bank };
}
},
getPayloadToResetDefault(payment, booking){
// const filter = {transactionId: payment.id, bookingBankId: booking.bank.id};
const filter = {};
filter['transactionId'] = payment.id;
filter['bookingBankId'] = booking.bank.id;
return filter;
},
},
mixins: [componentHandler]
}
</script>
@@ -176,7 +176,7 @@
</div>
</template>
</document-file-viewer-component>
<button class="btn btn-sm btn-danger b-rad-none btn-block" v-if="data.documents.proforma_invoice && data.outstanding_amount > 0" @click="submit(route('api.booking.proforma.create', data.id), 'post', section, true, true)">Regenerate Proforma Invoice</button>
<button class="btn btn-sm btn-danger b-rad-none btn-block" v-if="data.documents.proforma_invoice" @click="submit(route('api.booking.proforma.create', data.id), 'post', section, true, true)">Regenerate Proforma Invoice</button>
</div>
</div>
<div class="row m-b-15" v-if="($store.getters.isAdmin && data.purchase_order.status === 1) || ($store.getters.isCustomer && data.purchase_order.status === 1 && $store.getters.getCompanyId === 199)" >
@@ -0,0 +1,83 @@
<template>
<div class="row align-items-center m-b-15 parentContainer bg-master-lighter p-t-10 p-b-10">
<div class="col">
<div class="row m-b-5">
<div class="col">
<div class="font-heading all-caps fs-10 muted">Recipient Bank Details</div>
</div>
</div>
<div class="row align-items-center">
<div class="col-auto p-r-0">
<img v-if="item.service.id === 4" src="/images/1688_logo.png" alt="" width="40">
<img v-else-if="item.service.id === 11" src="/images/alipay_logo.png" alt="" width="40">
<div v-else class="padding-5 bg-master-light">
<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="38.97413" x2="86" y2="57.78663" gradientUnits="userSpaceOnUse" id="color-1_77055_gr1"><stop offset="0" stop-color="#4ec9ff"></stop><stop offset="1" stop-color="#2bffe6"></stop></linearGradient><linearGradient x1="129" y1="77.49138" x2="129" y2="121.38631" gradientUnits="userSpaceOnUse" id="color-2_77055_gr2"><stop offset="0" stop-color="#4ec9ff"></stop><stop offset="1" stop-color="#2bffe6"></stop></linearGradient><linearGradient x1="43" y1="77.49138" x2="43" y2="121.38631" gradientUnits="userSpaceOnUse" id="color-3_77055_gr3"><stop offset="0" stop-color="#4ec9ff"></stop><stop offset="1" stop-color="#2bffe6"></stop></linearGradient><linearGradient x1="86" y1="64.94881" x2="86" y2="133.92888" gradientUnits="userSpaceOnUse" id="color-4_77055_gr4"><stop offset="0" stop-color="#4ec9ff"></stop><stop offset="1" stop-color="#2bffe6"></stop></linearGradient><linearGradient x1="86" y1="16.11963" x2="86" y2="155.875" gradientUnits="userSpaceOnUse" id="color-5_77055_gr5"><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="M86,40.31787c-4.4528,0 -8.0625,3.6097 -8.0625,8.0625c0,4.4528 3.6097,8.0625 8.0625,8.0625c4.4528,0 8.0625,-3.6097 8.0625,-8.0625c0,-4.4528 -3.6097,-8.0625 -8.0625,-8.0625z" fill="url(#color-1_77055_gr1)"></path><path d="M126.3125,80.625h5.375v37.625h-5.375z" fill="url(#color-2_77055_gr2)"></path><path d="M40.3125,80.625h5.375v37.625h-5.375z" fill="url(#color-3_77055_gr3)"></path><path d="M56.4375,69.875v59.125h59.125v-59.125zM99.4375,88.6875h-21.5v8.0625h16.125c2.96431,0 5.375,2.41069 5.375,5.375v8.0625c0,2.96431 -2.41069,5.375 -5.375,5.375h-5.375v5.375h-5.375v-5.375h-10.75v-5.375h21.5v-8.0625h-16.125c-2.96431,0 -5.375,-2.41069 -5.375,-5.375v-8.0625c0,-2.96431 2.41069,-5.375 5.375,-5.375h5.375v-5.375h5.375v5.375h10.75z" fill="url(#color-4_77055_gr4)"></path><path d="M86,59.125c-5.92862,0 -10.75,-4.82138 -10.75,-10.75c0,-5.92862 4.82138,-10.75 10.75,-10.75c5.92863,0 10.75,4.82138 10.75,10.75c0,5.92862 -4.82137,10.75 -10.75,10.75zM86,43c-2.96431,0 -5.375,2.41069 -5.375,5.375c0,2.96431 2.41069,5.375 5.375,5.375c2.96431,0 5.375,-2.41069 5.375,-5.375c0,-2.96431 -2.41069,-5.375 -5.375,-5.375zM108.84375,53.75c-2.22256,0 -4.03125,-1.80869 -4.03125,-4.03125c0,-2.22256 1.80869,-4.03125 4.03125,-4.03125c2.22256,0 4.03125,1.80869 4.03125,4.03125c0,2.22256 -1.80869,4.03125 -4.03125,4.03125zM108.84375,49.71606v0.00269zM63.15625,53.75c-2.22256,0 -4.03125,-1.80869 -4.03125,-4.03125c0,-2.22256 1.80869,-4.03125 4.03125,-4.03125c2.22256,0 4.03125,1.80869 4.03125,4.03125c0,2.22256 -1.80869,4.03125 -4.03125,4.03125zM63.15625,49.71606v0.00269zM150.5,69.875c2.96431,0 5.375,-2.39456 5.375,-5.34544v-1.29806c0,-1.72269 -0.84119,-3.34862 -2.30319,-4.39138l-60.03069,-40.40925c-4.58219,-3.08256 -10.49737,-3.08256 -15.07956,0l-60.08981,40.44956c-1.40825,1.00244 -2.24675,2.62838 -2.24675,4.35106v1.29806c0,2.95088 2.41069,5.34544 5.375,5.34544h8.0625v59.13037c-4.44513,0 -8.0625,3.61738 -8.0625,8.0625v3.182c-3.12019,1.11531 -5.375,4.06888 -5.375,7.568v8.05713h139.75v-8.05712c0,-3.49913 -2.25481,-6.45269 -5.375,-7.568v-3.182c0,-4.44513 -3.61738,-8.0625 -8.0625,-8.0625v-59.13038zM150.5,147.81788v2.68212h-129v-2.68212c0,-1.4835 1.204,-2.69288 2.6875,-2.69288h123.625c1.4835,0 2.6875,1.20937 2.6875,2.69288zM145.125,137.06788v2.68212h-118.25v-2.68212c0,-1.4835 1.204,-2.69288 2.6875,-2.69288h26.875h16.125h26.875h16.125h26.875c1.4835,0 2.6875,1.20937 2.6875,2.69288zM51.0625,80.625v37.625h-16.125v-37.625zM34.9375,75.25v-5.375h16.125v5.375zM51.0625,123.625v5.375h-16.125v-5.375zM56.4375,129v-59.125h5.375h10.75h5.375h16.125h5.375h5.375h10.75v59.125h-10.75h-5.375h-5.375h-16.125h-5.375h-10.75zM137.0625,80.625v37.625h-16.125v-37.625zM120.9375,75.25v-5.375h16.125v5.375zM137.0625,123.625v5.375h-16.125v-5.375zM115.5625,64.5h-16.125h-26.875v0.0215l-16.125,0.00269v-0.02419h-26.875h-8.0625l-0.06719,-1.21475l60.03069,-40.40387c1.376,-0.92987 2.95625,-1.38944 4.5365,-1.38944c1.58025,0 3.1605,0.46494 4.5365,1.39481l59.9635,40.33938l0.00806,1.27388c0,0 -0.00269,0 -0.00806,0h-8.0625z" fill="url(#color-5_77055_gr5)"></path></g></g></svg>
</div>
</div>
<div class="col-auto">
<div class="row">
<div class="col-auto p-r-10">
<div class="font-heading fs-12">{{item.bank.holder_name}} <span class="text-complete m-l-5 bold">{{[3, 4].includes(item.bank.type) ? item.bank.account_no : item.bank.account_no.replace(/[^\dA-Z]/g, '').replace(/(.{4})/g, '$1 ').trim()}}</span></div>
</div>
</div>
<div class="row" v-if="![3, 4].includes(item.bank.type)">
<div class="col-auto p-r-10">
<div class="font-heading fs-10 small">{{item.bank.bank_name}} <span class="m-l-5">({{item.bank.bank_branch}})</span> <span class="m-l-5">({{item.bank.swift}})</span></div>
</div>
</div>
</div>
</div>
<div class="row m-t-20" v-if="!isEditButtonHidden">
<div class="col">
<div class="btn btn-sm btn-block b-rad-none shadow-sm pointer requestModal" data-type="transferSummary" id="transfer-now" name="transfer-now">EDIT DEFAULT</div>
</div>
<modal-component id="select-account-modal" class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="transferSummary" size="large">
<booking-recipient-edit-component :data="recipientBanks" :section="section" v-on:updatedBankDetails="updatedBankDetails($event)"></booking-recipient-edit-component>
</modal-component>
</div>
</div>
</div>
</template>
<script>
import componentHandler from '../../../general/mixins/componentHandler';
export default {
props : {
section: {
type: String,
required: true
},
isEditButtonHidden: {
type: Boolean,
default: true
},
},
data(){
return {
recipientBanks: {
company: this.data.company,
serviceType: {
status: false,
id: this.data.service.id,
name: this.data.service.name,
currencies: this.data.service.configurations.currencies,
selectedCurrency: this.data.service.configurations.currencies[0]
},
bankAccount: this.data.bank,
bankAccountDefault: this.data.bank,
recipientBanks: this.data.company.recipient_banks.accounts,
bookingId: this.data.id
}
}
},
methods:{
updatedBankDetails(bank){ //cief todo: 66 - this need to move to vuex, too many levels of passings between parent and child
this.data.bank = { ... bank };
},
},
mixins: [componentHandler]
}
</script>
@@ -0,0 +1,41 @@
<template>
<div class="row">
<div class="col-auto" v-show="!isLoading">
<button id="cancel-new-booking" name="cancel-new-booking" class="btn btn-lg btn-default bg-master-lightest b-rad-none all-caps fs-12" data-dismiss="modal" @click="cancelUpdateBooking()">Cancel</button>
</div>
<div class="col text-right" v-show="!isLoading && this.data.bankAccount">
<button id="confirm-new-booking" name="confirm-new-booking" class="btn btn-lg btn-success b-rad-none all-caps fs-12" v-if="Object.keys(data.bankAccount).length" @click="submitForm()">Update Recipient</button>
</div>
</div>
</template>
<script>
import ModalFormHandler from '../../../general/mixins/modalFormHandler';
export default {
data(){
return {
parameters: {},
isLoading: false,
}
},
methods: {
submitForm(){
this.isLoading = true;
this.parameters = {
transferable_bank_id: this.data.bankAccount.id,
};
this.submit(route('api.booking.update.recipient', this.data.bookingId), 'put', this.section, true, true);
},
successHandler(response){
this.isLoading = false;
this.$emit('updatedBooking', this.data.bankAccount);
this.formHandler();
this.closeModal();
},
cancelUpdateBooking(){
this.$emit('updateBookingCanceled');
}
},
mixins: [ModalFormHandler]
}
</script>
@@ -57,7 +57,7 @@
<div class="col">
<div class="row">
<div class="col" v-if="this.$store.getters.getUserId">
<list-component section="customerVouchersListSection" :endpoint="route('api.voucher.user.list')" :options="{ 'has_active_reward': id }">
<list-component section="customerVouchersListSection" :endpoint="route('api.voucher.user.list')" :options="{ 'has_vouchers_all_with_user': id }">
<template slot="list" slot-scope="{data}">
<single-user-reward-item-component :data="data"></single-user-reward-item-component>
</template>
@@ -74,10 +74,15 @@
<div class="col">
<div class="row">
<div class="col" v-if="this.$store.getters.getUserId">
<list-component section="customerRewardsListSection" :endpoint="route('api.reward.list.details.admin', id)" :options="{'is_active': true, order_by:{ column:'order', DESC:false}}">
<!-- <list-component section="customerRewardsListSection" :endpoint="route('api.reward.list.details.admin', id)" :options="{'is_active': true, order_by:{ column:'order', DESC:false}}">
<template slot="list" slot-scope="{data}">
<single-reward-details-item-component :data="data"></single-reward-details-item-component>
</template>
</list-component> -->
<list-component section="customerRewardsListSection" :endpoint="route('api.voucher.user.list')" :options="{'has_active_reward_for_admin': id}">
<template slot="list" slot-scope="{data}">
<single-user-reward-item-component :data="data"></single-user-reward-item-component>
</template>
</list-component>
</div>
</div>
@@ -19,7 +19,7 @@
</div>
</div>
</div>
<div class="col m-r-5 d-none d-md-inline">
<!-- <div class="col m-r-5 d-none d-md-inline">
<div class="row fs-12 text-center">
<div class="col p-t-20 p-b-20 bg-master-lighter tabButton" tab-name="rewards">
<div class="row">
@@ -29,7 +29,7 @@
</div>
</div>
</div>
</div>
</div> -->
<div class="col m-r-5 d-none d-md-inline">
<div class="row fs-12 text-center">
<div class="col p-t-20 p-b-20 bg-master-lighter tabButton" tab-name="used">
@@ -52,7 +52,7 @@
<div class="col">
<div class="row">
<div class="col" v-if="this.$store.getters.getUserId">
<list-component section="customerVouchersListSection" :endpoint="route('api.voucher.user.list')" :options="{ 'has_active_reward': true }">
<list-component section="customerVouchersListSection" :endpoint="route('api.voucher.user.list')" :options="{ 'has_vouchers_all_with_user': true }">
<template slot="list" slot-scope="{data}">
<single-user-reward-item-component :data="data"></single-user-reward-item-component>
</template>
@@ -69,11 +69,16 @@
<div class="col">
<div class="row">
<div class="col" v-if="this.$store.getters.getUserId">
<list-component section="customerRewardsListSection" :endpoint="route('api.reward.list.details')" :options="{'random_name': true, order_by:{ column:'order', DESC:false}}">
<!-- <list-component section="customerRewardsListSection" :endpoint="route('api.reward.list.details')" :options="{'is_active': true, order_by:{ column:'order', DESC:false}}">
<template slot="list" slot-scope="{data}">
<single-reward-details-item-component :data="data"></single-reward-details-item-component>
</template>
</list-component>
</list-component> -->
<!-- <list-component section="customerRewardsListSection" :endpoint="route('api.voucher.user.list')" :options="{'has_active_reward': true}">
<template slot="list" slot-scope="{data}">
<single-user-reward-item-component :data="data"></single-user-reward-item-component>
</template>
</list-component> -->
</div>
</div>
</div>
@@ -33,7 +33,7 @@
required: true
},
params: {
type: Array,
type: Object,
required: false
},
modalType: {
@@ -46,12 +46,18 @@
<td>{{$transaction->currency_rate}}</td>
<td>{{$transaction->currency->short_code}} {{number_format((float)$transaction->amount, 2, '.', '')}}</td>
<td>
Account Holder Name: {{$transaction->owner->owner->bank->holder_name}}
<br>{{$transaction->owner->owner->bank->bank_name}}: {{$transaction->owner->owner->bank->account_no}}
<br>Branch: {{$transaction->owner->owner->bank->bank_branch}}
@php
$bank = $transaction->owner->owner->bank;
if($transaction->owner->bank){
$bank = $transaction->owner->bank;
}
@endphp
Account Holder Name: {{$bank->holder_name}}
<br>{{$bank->bank_name}}: {{$bank->account_no}}
<br>Branch: {{$bank->bank_branch}}
@if($transaction->original_currency->short_code === 'USD')
<br>Account Holder Address: {{$transaction->owner->owner->bank->reference}}
<br>Swift Code: {{$transaction->owner->owner->bank->swift}}
<br>Account Holder Address: {{$bank->reference}}
<br>Swift Code: {{$bank->swift}}
@endif
<br>Bank in Amount: {{$transaction->original_currency->short_code}} {{$transaction->original_amount}}
@if ($order_reference_no)
@@ -19,12 +19,18 @@
</tr>
@foreach($transactions as $transaction)
<tr style="margin-bottom: 10px;">
@php
$bank = $transaction->owner->owner->bank;
if($transaction->owner->bank){
$bank = $transaction->owner->bank;
}
@endphp
<td>{{$transaction->owner->owner->marking}}</td>
<td>{{$transaction->owner->owner->company->reference}}</td>
<td>{{$transaction->currency_rate}}</td>
<td>{{$transaction->currency->short_code}} {{number_format((float)$transaction->amount, 2, '.', '')}}</td>
<td>Account Holder Name: {{$transaction->owner->owner->bank->holder_name}}<br>{{$transaction->owner->owner->bank->bank_name}}: {{$transaction->owner->owner->bank->account_no}}
<br>Branch: {{$transaction->owner->owner->bank->bank_branch}}@if($transaction->original_currency->short_code === 'USD')<br>Swift Code: {{$transaction->owner->owner->bank->swift}}@endif<br>Bank in Amount: {{$transaction->original_currency->short_code}} {{$transaction->original_amount}}</td>
<td>Account Holder Name: {{$bank->holder_name}}<br>{{$bank->bank_name}}: {{$bank->account_no}}
<br>Branch: {{$bank->bank_branch}}@if($transaction->original_currency->short_code === 'USD')<br>Swift Code: {{$bank->swift}}@endif<br>Bank in Amount: {{$transaction->original_currency->short_code}} {{$transaction->original_amount}}</td>
</tr>
@endforeach
</tbody>
@@ -69,100 +69,15 @@
<br>
<br>
<table class="line-table" style="overflow: wrap" autosize="1">
<thead>
<tr>
<th width="5%">No</th>
<th class="stock-code" width="10%">Stock Code</th>
<th class="description">Description</th>
<th width="10%">Quantity</th>
<th width="15%">Unit Price (RM)</th>
<th width="10%">Total Amount<br>(RM)</th>
</tr>
</thead>
<tbody>
@php
$subtotal = 0;
@endphp
@foreach ($po_order_transaction->transactionDetails as $key => $transaction_detail)
<tr>
<td width="5%" class="center top">{{ $key + 1 }}</td>
<td class="stock-code top" width="10%">{{ $transaction_detail->product_code }}</td>
<td class="description">{{ $transaction_detail->product_name }}</td>
<td width="10%" class="center top">{{ $transaction_detail->quantity }}</td>
<td width="15%" class="center top">
@if($invoice_transaction->booking()->first()->fix_currency_id !== 1)
{{ number_format( (1/$invoice_transaction->currency_rate) * $transaction_detail->price, 2) }}
@else
{{ number_format($transaction_detail->price, 2) }}
@endif
</td>
<td width="20%" class="right top">
@if($invoice_transaction->booking()->first()->fix_currency_id !== 1)
<?php
$transaction = $invoice_transaction;
$voucher_redemption = $voucher_redemption ?? null;
?>
{{ number_format((float)number_format( (1/$invoice_transaction->currency_rate) * $transaction_detail->price, 2,'.','')*$transaction_detail->quantity,2) }}
<!-- Invoice Table -->
@include('pages.pdfs.purchase_order_table')
@php
$subtotal += number_format((float)number_format( (1/$invoice_transaction->currency_rate) * $transaction_detail->price, 2,'.','')*$transaction_detail->quantity,2,'.','');
@endphp
@else
{{ number_format((float)number_format($transaction_detail->price, 2,'.','')*$transaction_detail->quantity,2) }}
@php
$subtotal += number_format((float)number_format($transaction_detail->price, 2,'.','')*$transaction_detail->quantity,2,'.','');
@endphp
@endif
</td>
</tr>
@endforeach
</tbody>
<tfoot>
<tr class="subtotal">
<td colspan="4"></td>
<td class="right middle">Subtotal</td>
<td class="right middle">
{{ number_format($subtotal, 2) }}
</td>
</tr>
<tr class="billingcharges">
<td colspan="4"></td>
<td class="right">Service Charges</td>
<td class="right">
{{ number_format($invoice_transaction->service_charge, 2) }}
</td>
</tr>
<tr class="billingcharges">
<td colspan="4"></td>
<td class="right">Adjustment</td>
<td class="right">
@if($invoice_transaction->booking()->first()->fix_currency_id !== 1)
{{ number_format((float)number_format( (1/$invoice_transaction->currency_rate) * $invoice_transaction->original_amount, 2,'.','') - (float)number_format($subtotal, 2,'.',''),2) }}
@else
{{ number_format((float)number_format($invoice_transaction->amount, 2,'.','') - (float)number_format($subtotal, 2,'.',''),2) }}
@endif
</td>
</tr>
@if($invoice_transaction->tax > 0)
<tr class="billingcharges">
<td colspan="4"></td>
<td class="right">Tax</td>
<td class="right">{{ number_format($invoice_transaction->tax, 2) }}</td>
</tr>
@endif
<tr>
<td colspan="4"></td>
<td class="right middle">Total</td>
<td class="total right middle">
@if($invoice_transaction->booking()->first()->fix_currency_id !== 1)
{{ number_format( ((1/$invoice_transaction->currency_rate) * $invoice_transaction->original_amount) + $invoice_transaction->service_charge + $invoice_transaction->tax, 2) }}
@else
{{ number_format($invoice_transaction->amount + $invoice_transaction->service_charge + $invoice_transaction->tax, 2) }}
@endif
</td>
</tr>
</tfoot>
</table>
<htmlpagefooter name="page-footer">
<table width="100%">
<tr>
+3 -1
View File
@@ -10,4 +10,6 @@ Route::group(['prefix' => 'bank', 'as' => 'bank.', 'namespace' => 'Banks'], func
Route::delete('/delete/{id}', 'DeleteBankController@delete')->name('delete');
Route::put('/update/{id}/status', 'UpdateBankStatusController@update')->name('status.update');
});
Route::post('/metadata/update/{id}', 'UpdateBankMetadataController@delete')->name('update.metadata');
});
+2 -1
View File
@@ -7,6 +7,7 @@ Route::group(['prefix' => 'booking', 'as' => 'booking.', 'namespace' => 'Booking
Route::get('/list', 'ListBookingsController@list')->name('list');
Route::post('/create', 'CreateBookingController@create')->name('create');
Route::put('/update/{id}', 'UpdateBookingController@update')->name('update');
Route::put('/recipient/update/{id}', 'UpdateBookingRecipientController@update')->name('update.recipient');
Route::put('/cancel/{id}', 'CancelBookingController@cancel')->name('cancel');
Route::put('/restore/{id}', 'RestoreBookingController@restore')->name('restore');
Route::delete('/delete/{id}', 'DeleteBookingController@delete')->name('delete');
@@ -38,4 +39,4 @@ Route::group(['prefix' => 'booking', 'as' => 'booking.', 'namespace' => 'Booking
Route::post('{id}/proforma/create', 'CreateProformaInvoiceTransaction@create')->name('proforma.create');
});
});
+2
View File
@@ -14,6 +14,8 @@ Route::group(['prefix' => 'transactions', 'namespace' => 'Transactions', 'as' =>
Route::put('/{id}/bill/{status}', 'UpdatePaymentTransactionStatusController@update')->where('status', 'pending|complete')->name('bill.status');
Route::put('/{id}/refund/status/update/{status}', 'UpdateRefundTransactionStatusController@update')->name('refund.status.update');
Route::delete('/refund/{id}/delete', 'DeleteRefundTransactionController@delete')->name('refund.delete');
route::delete('{id}/bill/delete', 'DeletePaymentProofDocumentController@delete')->name('bill.delete');
Route::post('booking/{id}/details/update', 'CreatePurchaseOrderTransactionController@create')->name('po.create');
+24 -18
View File
@@ -407,25 +407,27 @@ Route::get('/pending_orders', function(){
$i = 0;
foreach ($payments as $payment){
$booking = $payment->owner;
$bank = $payment->bank ?? $booking->bank; //cief todo: 66
$original_refunds = floatval((App()->make(CalculatesBookingRefundAmount::class))->calculateRefundAmount($payment, $booking->fix_currency_id));
$refunds = $original_refunds / $payment->currency_rate;
if(!$booking instanceof Booking){
dd($payment);
}
$bankType = str::length($booking->bank->holder_name) > 4 ? 'Company' : 'Personal';
$bankType = str::length($bank->holder_name) > 4 ? 'Company' : 'Personal';
if (!preg_match('/[^A-Za-z0-9]/', $booking->bank->holder_name))
if (!preg_match('/[^A-Za-z0-9]/', $bank->holder_name))
{
$bankType = str_word_count($booking->bank->holder_name) > 4 ? 'Company' : 'Personal';
$bankType = str_word_count($bank->holder_name) > 4 ? 'Company' : 'Personal';
}
echo '<tr>';
echo '<td>'.$payment->updated_at->format('d-M-y').'</td>';
echo '<td>'.$booking->marking.'</td>';
echo '<td>'.\App\Classes\ValueObjects\Constants\PaymentMethodType::PAYMENT_METHODS_ID[$payment->payment_method].'</td>';
echo '<td>'.$booking->company->reference.'</td>';
echo '<td>'.$payment->currency->short_code.'</td>';
echo '<td>'.number_format(bcsub($payment->amount, $refunds, 7), 5, '.', '').'</td>';
echo '<td>'.$booking->marking.'</td>';
echo '<td>'.$booking->company->reference.'</td>';
echo '<td></td>';
echo '<td>'.$payment->original_currency->short_code.'</td>';
echo '<td>'.number_format(bcsub($payment->original_amount, $original_refunds, 7), 5, '.', '').'</td>';
@@ -510,14 +512,16 @@ Route::get('/approve_refunds', function(Request $request){
foreach ($approve_refunds->orderBy('created_at', 'DESC')->get() as $index => $refund){
$payment = $refund->owner;
$booking = $refund->owner->owner;
$bank = $payment->bank ?? $booking->bank; //cief todo: 66
if(!$booking instanceof Booking){
dd($refund);
}
$bankType = str::length($booking->bank->holder_name) > 4 ? 'Company' : 'Personal';
$bankType = str::length($bank->holder_name) > 4 ? 'Company' : 'Personal';
if (!preg_match('/[^A-Za-z0-9]/', $booking->bank->holder_name))
if (!preg_match('/[^A-Za-z0-9]/', $bank->holder_name))
{
$bankType = str_word_count($booking->bank->holder_name) > 4 ? 'Company' : 'Personal';
$bankType = str_word_count($bank->holder_name) > 4 ? 'Company' : 'Personal';
}
$remark = $refund->original_amount === $refund->owner->original_amount ? 'Fully Refund' : 'Partial Refund';
@@ -546,7 +550,7 @@ Route::get('/approve_refunds', function(Request $request){
echo '<td>'.$booking->service->name.'</td>';
echo '<td>'.$payment->updated_at->diffForHumans().'</td>';
echo '<td>'.$bankType.'</td>';
echo '<td>'.$booking->bank->holder_name.'</td>';
echo '<td>'.$bank->holder_name.'</td>';
echo '<td>'.$noteRemark.'</td>';
echo '</tr>';
}
@@ -564,10 +568,12 @@ Route::get('/group/text/{id}', function($id){
foreach ($group->transactions as $transaction){
$i++;
$booking = $transaction->owner->owner;
$bank = $transaction->owner->bank ?? $booking->bank; //cief todo: 66
echo 'No.'.$i.'<br>';
echo 'Bank Details:'.$booking->bank->holder_name.'<br>';
echo $booking->bank->bank_name.' '.$booking->bank->bank_branch.'<br>';
echo 'Bank Account Number:'.$booking->bank->account_no.'<br>';
echo 'Bank Details:'.$bank->holder_name.'<br>';
echo $bank->bank_name.' '.$bank->bank_branch.'<br>';
echo 'Bank Account Number:'.$bank->account_no.'<br>';
echo 'Order Amount:'.$transaction->original_currency->short_code.' '.(round($transaction->original_amount, 2) + 0).'<br><br>';
}
@@ -577,7 +583,7 @@ Route::get('/group/invoice/{id}', function ($id) {
$group = Group::findOrFail($id);
$supplier = $group->issuerCompany;
$supplier = $group->issuerCompany;
$transferFeeTransactions = $group->transactions()
->with(['transactions' => function ($transaction) {
@@ -589,8 +595,8 @@ Route::get('/group/invoice/{id}', function ($id) {
$html = view('pages.pdfs.supplier_deliver_order_group_invoice', [
'group'=> $group,
'transactions' => $group->transactions,
'transferFeeTransactions' => $transferFeeTransactions,
'transactions' => $group->transactions,
'transferFeeTransactions' => $transferFeeTransactions,
'supplier' => $supplier
])->render();
@@ -598,7 +604,7 @@ Route::get('/group/invoice/{id}', function ($id) {
$dompdf->loadHtml($html);
$dompdf->setPaper('A4', 'portrait');
$dompdf->render();
return $dompdf->stream("invoice_pdf_{$supplier->name}.pdf");
})->name('group.invoice');
@@ -1168,7 +1174,7 @@ Route::get('check-duplicate-refunds', function () {
foreach ($results as $result) {
$booking_ref_arr = explode(' ', $result->payment_reference);
$booking_ref = end($booking_ref_arr);
echo '<tr>';
echo "<td style='border: 1px solid black;'>$result->owner_type</td>";
echo "<td style='border: 1px solid black;'>$result->owner_id</td>";
@@ -1205,7 +1211,7 @@ Route::get('check-duplicate-refunds', function () {
echo "<td style='border: 1px solid black;'>" . ($refund ? $refund : '') . "</td>";
echo '</tr>';
}
echo '</tbody>';
echo '</table>';