Vourcherify

This commit is contained in:
Dillon
2023-05-30 22:02:09 +08:00
parent 44deab4542
commit 20d6ca47dc
39 changed files with 1102 additions and 35 deletions
+7
View File
@@ -58,6 +58,13 @@ BILLPLZ_X_SIGNATURE_KEY="S-HdAU6QDubUrMErxJ-PCpgw"
BILLPLZ_COLLECTION_ID="t0cggbdd" BILLPLZ_COLLECTION_ID="t0cggbdd"
BILLPLZ_WALLET_COLLECTION_ID="t0cggbdd" BILLPLZ_WALLET_COLLECTION_ID="t0cggbdd"
PERFEXCRM_BASE_URL="" PERFEXCRM_BASE_URL=""
PERFEXCRM_API_KEY="" PERFEXCRM_API_KEY=""
PERFEXCRM_IS_ENABLED="false" PERFEXCRM_IS_ENABLED="false"
VOUCHERIFY_APPLICATION_ID=""
VOUCHERIFY_CLIENT_SECRET_KEY=""
VOUCHERIFY_VERSION="v2018-08-01"
VOUCHERIFY_URL="https://as1.api.voucherify.io"
@@ -0,0 +1,20 @@
<?php
namespace App\Classes\General\Eloquent\Filters;
use Illuminate\Database\Eloquent\Builder;
class TransactionId implements Filter
{
/**
* @param Builder $builder
* @param $value
* @return Builder|mixed
*/
public static function apply(Builder $builder, $value)
{
return $builder->where('transaction_id', $value);
}
}
+14
View File
@@ -0,0 +1,14 @@
<?php
use Voucherify\VoucherifyClient;
use Voucherify\ClientException;
function createVoucherifyClient()
{
$apiID = config('voucherify.application_id');
$apiKey = config('voucherify.client_secret_key');
$apiVersion = config('voucherify.version');
$apiUrl = config('voucherify.url');
return new VoucherifyClient($apiID, $apiKey, $apiVersion, $apiUrl);
}
@@ -9,12 +9,16 @@ use App\Classes\Modules\Bookings\Services\CalculatesBookingOutstanding;
use App\Classes\Modules\Bookings\Services\FetchesBookingQuotation; use App\Classes\Modules\Bookings\Services\FetchesBookingQuotation;
use App\Classes\Modules\Companies\Services\FetchesCompanyPaymentAttemptLimit; use App\Classes\Modules\Companies\Services\FetchesCompanyPaymentAttemptLimit;
use App\Classes\Modules\Currencies\DataTransferObjects\CurrencyConversionObject; use App\Classes\Modules\Currencies\DataTransferObjects\CurrencyConversionObject;
use App\Classes\Modules\Vouchers\DataTransferObjects\VoucherObject;
use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject; use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject;
use App\Classes\Modules\Transactions\Services\CreatesTransaction; use App\Classes\Modules\Transactions\Services\CreatesTransaction;
use App\Classes\Modules\Transactions\Services\UpdatesTransaction;
use App\Classes\Modules\Transactions\Services\GeneratesTransactionBillNumber; use App\Classes\Modules\Transactions\Services\GeneratesTransactionBillNumber;
use App\Classes\Modules\Billplzs\Services\CreatesBillplzBill; use App\Classes\Modules\Billplzs\Services\CreatesBillplzBill;
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus; use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
use App\Classes\Modules\Vouchers\Services\FetchesVoucher;
use App\Classes\Modules\Vouchers\Services\CreatesVoucher;
use App\Classes\Modules\Vouchers\Services\CreatesVoucherRedemption;
use App\Classes\Modules\Vouchers\Services\RedeemsVoucher;
use App\Classes\Modules\Wallets\Services\UpdatesWalletBalance; use App\Classes\Modules\Wallets\Services\UpdatesWalletBalance;
use App\Classes\ValueObjects\Constants\ApprovalStatus; use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\PaymentMethodType; use App\Classes\ValueObjects\Constants\PaymentMethodType;
@@ -74,6 +78,17 @@ class CreateBookingPaymentLogic extends AbstractControllerLogic
/** @var RecalculatesWalletBalance */ /** @var RecalculatesWalletBalance */
private $recalculatesWalletBalance; private $recalculatesWalletBalance;
/** @var FetchesVoucher */
private $fetchesVoucher;
/** @var CreatesVoucher */
private $createsVoucher;
/** @var CreatesVoucherRedemption */
private $createsVoucherRedemption;
/** @var RedeemsVoucher */
private $redeemsVoucher;
/** /**
* CreateBookingPaymentLogic constructor. * CreateBookingPaymentLogic constructor.
* @param FetchesBookingQuotation $fetchBookingQuotation * @param FetchesBookingQuotation $fetchBookingQuotation
@@ -86,8 +101,12 @@ class CreateBookingPaymentLogic extends AbstractControllerLogic
* @param UpdatesTransactionStatus $updatesTransactionStatus * @param UpdatesTransactionStatus $updatesTransactionStatus
* @param CreateCashBackTransactionProcessor $createCashBackTransactionProcessor * @param CreateCashBackTransactionProcessor $createCashBackTransactionProcessor
* @param RecalculatesWalletBalance $recalculatesWalletBalance * @param RecalculatesWalletBalance $recalculatesWalletBalance
* @param FetchesVoucher $fetchesVoucher
* @param CreatesVoucher $createsVoucher
* @param CreatesVoucherRedemption $createsVoucherRedemption
* @param RedeemVoucher $redeemVoucher
*/ */
public function __construct(FetchesBookingQuotation $fetchBookingQuotation, FetchesCompanyPaymentAttemptLimit $fetchesCompanyPaymentAttemptLimit, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CreatesTransaction $createsTransaction, CalculatesBookingOutstanding $calculatesBookingOutstanding, CreatesBillplzBill $createsBillplzBill, UpdatesWalletBalance $updatesWalletBalance, UpdatesTransactionStatus $updatesTransactionStatus, CreateCashBackTransactionProcessor $createCashBackTransactionProcessor, RecalculatesWalletBalance $recalculatesWalletBalance) public function __construct(FetchesBookingQuotation $fetchBookingQuotation, FetchesCompanyPaymentAttemptLimit $fetchesCompanyPaymentAttemptLimit, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CreatesTransaction $createsTransaction, CalculatesBookingOutstanding $calculatesBookingOutstanding, CreatesBillplzBill $createsBillplzBill, UpdatesWalletBalance $updatesWalletBalance, UpdatesTransactionStatus $updatesTransactionStatus, CreateCashBackTransactionProcessor $createCashBackTransactionProcessor, RecalculatesWalletBalance $recalculatesWalletBalance, FetchesVoucher $fetchesVoucher, CreatesVoucher $createsVoucher, CreatesVoucherRedemption $createsVoucherRedemption, RedeemsVoucher $redeemsVoucher)
{ {
$this->fetchBookingQuotation = $fetchBookingQuotation; $this->fetchBookingQuotation = $fetchBookingQuotation;
$this->fetchesCompanyPaymentAttemptLimit = $fetchesCompanyPaymentAttemptLimit; $this->fetchesCompanyPaymentAttemptLimit = $fetchesCompanyPaymentAttemptLimit;
@@ -99,6 +118,10 @@ class CreateBookingPaymentLogic extends AbstractControllerLogic
$this->updatesTransactionStatus = $updatesTransactionStatus; $this->updatesTransactionStatus = $updatesTransactionStatus;
$this->createCashBackTransactionProcessor = $createCashBackTransactionProcessor; $this->createCashBackTransactionProcessor = $createCashBackTransactionProcessor;
$this->recalculatesWalletBalance = $recalculatesWalletBalance; $this->recalculatesWalletBalance = $recalculatesWalletBalance;
$this->fetchesVoucher = $fetchesVoucher;
$this->createsVoucher = $createsVoucher;
$this->createsVoucherRedemption = $createsVoucherRedemption;
$this->redeemsVoucher = $redeemsVoucher;
} }
/** /**
@@ -108,6 +131,12 @@ class CreateBookingPaymentLogic extends AbstractControllerLogic
*/ */
public function logic(Request $request) : JsonResponse public function logic(Request $request) : JsonResponse
{ {
$voucherCode = $request->input('voucher_code'); //cief to, json_encode and json_decode ???
// if($voucherReqInput){
// $voucherObject = json_decode($voucherReqInput);
// $validatedVoucherObject = new ValidatedVoucherObject($voucherObject->metadata->name, $voucherObject->code, $voucherObject->discount->type, $voucherObject->discount->amount_off);
// }
$booking = Booking::find($request->route('id')); $booking = Booking::find($request->route('id'));
$conversionObject = new CurrencyConversionObject(floatval(str_replace(',', '', $request->input('amount'))), $booking->convertible_currency_id, $booking->service_id, $booking->fix_currency_id === 1 ? 0:1, PaymentMethodType::PAYMENT_METHODS[$request->input('payment_method')]); $conversionObject = new CurrencyConversionObject(floatval(str_replace(',', '', $request->input('amount'))), $booking->convertible_currency_id, $booking->service_id, $booking->fix_currency_id === 1 ? 0:1, PaymentMethodType::PAYMENT_METHODS[$request->input('payment_method')]);
@@ -116,7 +145,7 @@ class CreateBookingPaymentLogic extends AbstractControllerLogic
if($conversionObject->getAmount() > round($outstanding, 2)) throw new MalformedRequestException('Your payment must not be greater than '. $outstanding .'.'); if($conversionObject->getAmount() > round($outstanding, 2)) throw new MalformedRequestException('Your payment must not be greater than '. $outstanding .'.');
$configurations = $this->fetchBookingQuotation->execute($booking->company, $conversionObject); $configurations = $this->fetchBookingQuotation->execute($booking->company, $conversionObject, $voucherCode);
$paymentAttemptLimit = $this->fetchesCompanyPaymentAttemptLimit->execute($booking->company); $paymentAttemptLimit = $this->fetchesCompanyPaymentAttemptLimit->execute($booking->company);
@@ -164,6 +193,30 @@ class CreateBookingPaymentLogic extends AbstractControllerLogic
$this->updatesTransactionStatus->execute($transaction, ApprovalStatus::APPROVED); $this->updatesTransactionStatus->execute($transaction, ApprovalStatus::APPROVED);
} }
//Voucherify
if($voucherCode){
$employee = $booking->company->employees()->first();
$result = $this->redeemsVoucher->execute($voucherCode, $configurations->getSubTotal(), $employee);
$voucher = $result->voucher;
$redemptionId = $result->id;
//Update Database
$voucherValue = 0.00;
if(isset($voucher->discount->amount_off)){
$voucherValue =$voucher->discount->amount_off;
}
if($voucherValue == 0.00){
if(isset($voucher->discount->percent_off)){
$voucherValue =$voucher->discount->percent_off;
}
}
$voucherObject= new VoucherObject($voucher->code, isset($voucher->metadata->name) ? $voucher->metadata->name : "", $voucher->discount->type, $voucherValue);
$voucher = $this->createsVoucher->execute($voucherObject);
if(!$voucher) $voucher = $this->fetchesVoucher->execute(['code' => $voucherObject->getCode()]);
$this->createsVoucherRedemption->execute($transaction, $voucher, $redemptionId, $configurations->getVoucherDiscountAmount());
}
return $this->resourceResponse(new TransactionResource($transaction)); return $this->resourceResponse(new TransactionResource($transaction));
} }
@@ -69,8 +69,11 @@ class FetchBookingPaymentQuotationLogic extends AbstractControllerLogic
$outstanding = $this->calculatesBookingOutstanding->execute($booking); $outstanding = $this->calculatesBookingOutstanding->execute($booking);
if($conversionObject->getAmount() > round($outstanding, 2)) throw new MalformedRequestException('Your payment must not be greater than '.$booking->fixedCurrency->short_code.' '. number_format((float)$outstanding, 2, '.', ',')); if($conversionObject->getAmount() > round($outstanding, 2)) throw new MalformedRequestException('Your payment must not be greater than '.$booking->fixedCurrency->short_code.' '. number_format((float)$outstanding, 2, '.', ','));
//Voucherify
$voucherCode = $request->input('voucherCode');
return $this->response(['data' => $this->generatesBookingQuotation->execute( return $this->response(['data' => $this->generatesBookingQuotation->execute(
$this->fetchBookingQuotation->execute($booking->company, $conversionObject), $this->fetchBookingQuotation->execute($booking->company, $conversionObject, $voucherCode),
$this->fetchesCompanyPaymentAttemptLimit->execute($booking->company), $this->fetchesCompanyPaymentAttemptLimit->execute($booking->company),
$conversionObject $conversionObject
)]); )]);
@@ -5,6 +5,7 @@ namespace App\Classes\Modules\Bookings\DataTransferObjects;
use App\Classes\General\Interfaces\DataTransferObject; use App\Classes\General\Interfaces\DataTransferObject;
use App\Classes\Modules\Companies\DataTransferObjects\CompanyServiceConfigurationsObject; use App\Classes\Modules\Companies\DataTransferObjects\CompanyServiceConfigurationsObject;
use App\Classes\Modules\Currencies\DataTransferObjects\CurrencyConversionObject; use App\Classes\Modules\Currencies\DataTransferObjects\CurrencyConversionObject;
use App\Classes\Modules\Vouchers\DataTransferObjects\ValidatedVoucherObject;
class CalculationObject implements DataTransferObject class CalculationObject implements DataTransferObject
{ {
@@ -15,15 +16,20 @@ class CalculationObject implements DataTransferObject
/** @var CompanyServiceConfigurationsObject */ /** @var CompanyServiceConfigurationsObject */
private $configurations; private $configurations;
/** @var ValidatedVoucherObject */
private $voucherObject;
/** /**
* CalculationObject constructor. * CalculationObject constructor.
* @param CurrencyConversionObject $conversionObject * @param CurrencyConversionObject $conversionObject
* @param CompanyServiceConfigurationsObject $configurations * @param CompanyServiceConfigurationsObject $configurations
* @param ValidatedVoucherObject $voucherObject
*/ */
public function __construct(CurrencyConversionObject $conversionObject, CompanyServiceConfigurationsObject $configurations) public function __construct(CurrencyConversionObject $conversionObject, CompanyServiceConfigurationsObject $configurations, ?ValidatedVoucherObject $voucherObject = null)
{ {
$this->conversionObject = $conversionObject; $this->conversionObject = $conversionObject;
$this->configurations = $configurations; $this->configurations = $configurations;
$this->voucherObject = $voucherObject;
} }
/** /**
@@ -43,6 +49,15 @@ class CalculationObject implements DataTransferObject
return $this->configurations; return $this->configurations;
} }
/**
* @return ValidatedVoucherObject
*/
public function getValidatedVoucherObject(): ?ValidatedVoucherObject
{
return $this->voucherObject;
}
public function getConvertibleTotal(){ public function getConvertibleTotal(){
return $this->getConversionObject()->getType() === 1 ? $this->getConversionObject()->getAmount() : $this->getConversionTotal(); return $this->getConversionObject()->getType() === 1 ? $this->getConversionObject()->getAmount() : $this->getConversionTotal();
} }
@@ -87,9 +102,31 @@ class CalculationObject implements DataTransferObject
return ($this->getSubTotal()/100) * $this->getConfigurations()->getTax(); return ($this->getSubTotal()/100) * $this->getConfigurations()->getTax();
} }
public function getTotal(): float { public function getVoucherDiscountAmount(): float {
return $this->getSubTotal() + $this->getTax(); if($this->getValidatedVoucherObject()){
return $this->getValidatedVoucherObject()->getTotalDiscountAmount();
}
else{
return 0.00;
}
} }
public function getVoucherCode(): string {
if($this->getValidatedVoucherObject()){
return $this->getValidatedVoucherObject()->getCode();
}
else{
return "";
}
}
public function getTotal(): float {
if($this->getValidatedVoucherObject()){
return $this->getValidatedVoucherObject()->getTotalAmount() + $this->getTax();
}
else{
return $this->getSubTotal() + $this->getTax();
}
}
} }
@@ -7,7 +7,9 @@ use App\Classes\Exceptions\MalformedRequestException;
use App\Classes\Modules\Bookings\DataTransferObjects\CalculationObject; use App\Classes\Modules\Bookings\DataTransferObjects\CalculationObject;
use App\Classes\Modules\Companies\Services\FetchesCompanyServiceSettings; use App\Classes\Modules\Companies\Services\FetchesCompanyServiceSettings;
use App\Classes\Modules\Currencies\DataTransferObjects\CurrencyConversionObject; use App\Classes\Modules\Currencies\DataTransferObjects\CurrencyConversionObject;
use App\Classes\Modules\Vouchers\DataTransferObjects\ValidatedVoucherObject;
use App\Classes\Modules\Currencies\Services\FetchesCurrency; use App\Classes\Modules\Currencies\Services\FetchesCurrency;
use App\Classes\Modules\Vouchers\Services\ValidatesVoucher;
use App\Models\Company; use App\Models\Company;
use App\Models\Currency; use App\Models\Currency;
@@ -20,25 +22,30 @@ class FetchesBookingQuotation
/** @var FetchesCurrency */ /** @var FetchesCurrency */
private $fetchesCurrency; private $fetchesCurrency;
/** @var ValidatesVoucher */
private $validatesVoucher;
/** /**
* FetchesBookingQuotation constructor. * FetchesBookingQuotation constructor.
* @param FetchesCompanyServiceSettings $fetchesCompanyServiceSettings * @param FetchesCompanyServiceSettings $fetchesCompanyServiceSettings
* @param FetchesCurrency $fetchesCurrency * @param FetchesCurrency $fetchesCurrency
*/ */
public function __construct(FetchesCompanyServiceSettings $fetchesCompanyServiceSettings, FetchesCurrency $fetchesCurrency) public function __construct(FetchesCompanyServiceSettings $fetchesCompanyServiceSettings, FetchesCurrency $fetchesCurrency, ValidatesVoucher $validatesVoucher)
{ {
$this->fetchesCompanyServiceSettings = $fetchesCompanyServiceSettings; $this->fetchesCompanyServiceSettings = $fetchesCompanyServiceSettings;
$this->fetchesCurrency = $fetchesCurrency; $this->fetchesCurrency = $fetchesCurrency;
$this->validatesVoucher = $validatesVoucher;
} }
/** /**
* @param Company $company * @param Company $company
* @param CurrencyConversionObject $conversionObject * @param CurrencyConversionObject $conversionObject
* @param string $voucherCode
* @return CalculationObject * @return CalculationObject
* @throws MalformedRequestException * @throws MalformedRequestException
*/ */
public function execute(Company $company, CurrencyConversionObject $conversionObject){ public function execute(Company $company, CurrencyConversionObject $conversionObject, ?string $voucherCode = null){
if($conversionObject->getAmount() <= 0) throw new MalformedRequestException('Your transfer must be greater than zero.'); if($conversionObject->getAmount() <= 0) throw new MalformedRequestException('Your transfer must be greater than zero.');
$configurations = $this->fetchesCompanyServiceSettings->execute($company, $conversionObject); $configurations = $this->fetchesCompanyServiceSettings->execute($company, $conversionObject);
@@ -47,7 +54,22 @@ class FetchesBookingQuotation
$currency = $this->fetchesCurrency->execute(['id' => $conversionObject->getCurrencyId()]); $currency = $this->fetchesCurrency->execute(['id' => $conversionObject->getCurrencyId()]);
if($conversionObject->getAmount() > $configurations->getMaxLimit()) throw new MalformedRequestException('Your transfer can\'t be greater than '.number_format( floatval(str_replace(',', '', $configurations->getMaxLimit())), 2, '.', ',').' '.$currency->short_code); if($conversionObject->getAmount() > $configurations->getMaxLimit()) throw new MalformedRequestException('Your transfer can\'t be greater than '.number_format( floatval(str_replace(',', '', $configurations->getMaxLimit())), 2, '.', ',').' '.$currency->short_code);
$calculationObject = new CalculationObject($conversionObject, $configurations); $calculationObject = new CalculationObject($conversionObject, $configurations, null);
//Voucherify
if($voucherCode){
$employee = $company->employees()->first();
$result = $this->validatesVoucher->execute($voucherCode, $calculationObject->getSubTotal(), $employee);
$voucher = [
"code" => $result->code,
"discount" => $result->discount,
"metadata" => $result->metadata,
"order" => $result->order,
];
$validatedVoucherObject = new ValidatedVoucherObject(isset($voucher['metadata']->name) ? $voucher['metadata']->name: "", $voucher['code'], $voucher['discount']->type, $voucher['order']->total_discount_amount, $voucher['order']->total_amount);
$calculationObject = new CalculationObject($conversionObject, $configurations, $validatedVoucherObject);
}
return $calculationObject; return $calculationObject;
} }
@@ -34,7 +34,9 @@ class GeneratesBookingQuotation
'total' => $calculationObject->getTotal(), 'total' => $calculationObject->getTotal(),
'date' => Carbon::now()->timezone('Asia/Singapore')->format('h:i a, jS M, Y \G\M\T T'), 'date' => Carbon::now()->timezone('Asia/Singapore')->format('h:i a, jS M, Y \G\M\T T'),
'receive_date' => $receive_date, 'receive_date' => $receive_date,
'payment_attempt_limit' => CarbonInterval::days($days)->hours($hours)->minutes($minutes)->forHumans() 'payment_attempt_limit' => CarbonInterval::days($days)->hours($hours)->minutes($minutes)->forHumans(),
'voucher_discount_amount' => $calculationObject->getVoucherDiscountAmount(),
'voucher_code' => $calculationObject->getVoucherCode(),
]; ];
} }
} }
@@ -7,6 +7,9 @@ use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Transactions\Services\FetchesTransaction; use App\Classes\Modules\Transactions\Services\FetchesTransaction;
use App\Classes\Modules\Transactions\Services\ListsTransactions; use App\Classes\Modules\Transactions\Services\ListsTransactions;
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus; use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
use App\Classes\Modules\Vouchers\Services\FetchesVoucherRedemption;
use App\Classes\Modules\Vouchers\Services\CreatesVoucherRedemption;
use App\Classes\Modules\Vouchers\Services\RollbacksRedemption;
use App\Classes\ValueObjects\Constants\ApprovalStatus; use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Http\Resources\BookingResource; use App\Http\Resources\BookingResource;
use App\Http\Resources\TransactionResource; use App\Http\Resources\TransactionResource;
@@ -32,16 +35,27 @@ class SuspendTransactionLogic extends AbstractControllerLogic
/** @var UpdatesTransactionStatus */ /** @var UpdatesTransactionStatus */
private $updatesTransactionStatus; private $updatesTransactionStatus;
/** @var RollbacksRedemption */
private $rollbacksRedemption;
/** @var FetchesVoucherRedemption */
private $fetchesVoucherRedemption;
/** @var CreatesVoucherRedemption */
private $createsVoucherRedemption;
/** /**
* SuspendTransactionLogic constructor. * SuspendTransactionLogic constructor.
* @param FetchesTransaction $fetchesTransaction * @param FetchesTransaction $fetchesTransaction
* @param UpdatesTransactionStatus $updatesTransactionStatus * @param UpdatesTransactionStatus $updatesTransactionStatus
*/ */
public function __construct(FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus) public function __construct(FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus, RollbacksRedemption $rollbacksRedemption, FetchesVoucherRedemption $fetchesVoucherRedemption, CreatesVoucherRedemption $createsVoucherRedemption)
{ {
$this->fetchesTransaction = $fetchesTransaction; $this->fetchesTransaction = $fetchesTransaction;
$this->updatesTransactionStatus = $updatesTransactionStatus; $this->updatesTransactionStatus = $updatesTransactionStatus;
$this->rollbacksRedemption = $rollbacksRedemption;
$this->fetchesVoucherRedemption = $fetchesVoucherRedemption;
$this->createsVoucherRedemption = $createsVoucherRedemption;
} }
@@ -52,6 +66,14 @@ class SuspendTransactionLogic extends AbstractControllerLogic
$this->updatesTransactionStatus->execute($transaction, ApprovalStatus::SUSPENDED); $this->updatesTransactionStatus->execute($transaction, ApprovalStatus::SUSPENDED);
if($transaction->voucherRedemption) {
$result = $this->rollbacksRedemption->execute($transaction->voucherRedemption->redemption_id);
if($result){
$redemptionId = $result->id;
$this->createsVoucherRedemption->execute($transaction, $transaction->voucherRedemption->voucher, $redemptionId, $transaction->voucherRedemption->value);
}
}
return $this->response([]); return $this->response([]);
} }
@@ -0,0 +1,48 @@
<?php
namespace App\Classes\Modules\Vouchers\ControllersLogic;
use App\Classes\Exceptions\MalformedRequestException;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Vouchers\Services\RedeemsVoucher;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use ErrorException;
class RedeemVoucherLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Redeem Voucher',
'message' => 'You have successfully redeemed a voucher'
];
}
/** @var RedeemsVoucher */
private $redeemsVoucher;
/**
* RedeemVoucherLogic constructor.
*/
public function __construct(RedeemsVoucher $redeemVoucher)
{
$this->redeemsVoucher = $redeemVoucher;
}
/**
* @param Request $request
* @return JsonResponse
* @throws MalformedRequestException
*/
public function logic(Request $request) : JsonResponse
{
$result = $this->redeemsVoucher->execute($request->input('promoCode'), $request->input('amount'));
return $this->response(['data' => $result]);
}
}
@@ -0,0 +1,48 @@
<?php
namespace App\Classes\Modules\Vouchers\ControllersLogic;
use App\Classes\Exceptions\MalformedRequestException;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Vouchers\Services\ValidatesVoucher;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use ErrorException;
class ValidateVoucherLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Fetch Voucher',
'message' => 'You have successfully fetched a voucher'
];
}
/** @var ValidatesVoucher */
private $validatesVoucher;
/**
* ValidateVoucherLogic constructor.
*/
public function __construct(ValidatesVoucher $validatesVoucher)
{
$this->validatesVoucher = $validatesVoucher;
}
/**
* @param Request $request
* @return JsonResponse
* @throws MalformedRequestException
*/
public function logic(Request $request) : JsonResponse
{
$result = $this->validatesVoucher->execute($request->input('voucherCode'), null, null);
return $this->response(['data' => $result]);
}
}
@@ -0,0 +1,82 @@
<?php
namespace App\Classes\Modules\Vouchers\DataTransferObjects;
use App\Classes\General\Interfaces\DataTransferObject;
class ValidatedVoucherObject implements DataTransferObject
{
/** @var string */
private $voucher_name;
/** @var string */
private $code;
/** @var string */
private $discount_type;
/** @var int */
private $total_discount_amount;
/** @var int */
private $total_amount;
/**
* ValidatedVoucherObject constructor.
* @param string $voucher_name
* @param string $code
* @param string $discount_type
* @param int $total_discount_amount
* @param int $total_amount
*/
public function __construct(string $voucher_name, string $code, string $discount_type, int $total_discount_amount, int $total_amount)
{
$this->voucher_name = $voucher_name;
$this->code = $code;
$this->discount_type = $discount_type;
$this->total_discount_amount = $total_discount_amount;
$this->total_amount = $total_amount;
}
/**
* @return string
*/
public function getVoucherName(): string
{
return $this->voucher_name;
}
/**
* @return string
*/
public function getCode(): string
{
return $this->code;
}
/**
* @return string
*/
public function getDiscountType(): string
{
return $this->discount_type;
}
/**
* @return float
*/
public function getTotalDiscountAmount(): float
{
return $this->total_discount_amount / 100;
}
/**
* @return float
*/
public function getTotalAmount(): float
{
return $this->total_amount / 100;
}
}
@@ -0,0 +1,70 @@
<?php
namespace App\Classes\Modules\Vouchers\DataTransferObjects;
use App\Classes\General\Interfaces\DataTransferObject;
class VoucherObject implements DataTransferObject
{
/** @var string */
private $code;
/** @var string|null */
private $name;
/** @var string|null */
private $type;
/** @var float|null */
private $value;
/**
* VoucherObject constructor.
* @param string $code
* @param string $name
* @param string $type
* @param float $value
*/
public function __construct(string $code, ?string $name, ?string $type, ?float $value)
{
$this->code = $code;
$this->name = $name;
$this->type = $type;
$this->value = $value;
}
/**
* @return string
*/
public function getCode(): string
{
return $this->code;
}
/**
* @return string
*/
public function getName(): ?string
{
return $this->name;
}
/**
* @return string
*/
public function getType(): ?string
{
return $this->type;
}
/**
* @return float
*/
public function getValue(): ?float
{
return $this->value;
}
}
@@ -0,0 +1,27 @@
<?php
namespace App\Classes\Modules\Vouchers\Services;
use App\Models\Voucher;
class CheckIfVoucherExists
{
/** @var Voucher */
private $repository;
/**
* CheckIfVoucherExists constructor.
* @param Voucher $repository
*/
public function __construct(Voucher $repository)
{
$this->repository = $repository;
}
public function execute(string $code): bool {
return $this->repository->where('code', $code)->exists();
}
}
@@ -0,0 +1,40 @@
<?php
namespace App\Classes\Modules\Vouchers\Services;
use App\Classes\General\Eloquent\AbstractUpdateRecord;
use App\Classes\Modules\Vouchers\DataTransferObjects\VoucherObject;
use App\Models\Voucher;
class CreatesVoucher extends AbstractUpdateRecord
{
/** @var CheckIfVoucherExists */
private $voucherExists;
/**
* CreatesVoucher constructor.
* @param CheckIfVoucherExists $voucherExists
*/
public function __construct(CheckIfVoucherExists $voucherExists)
{
$this->voucherExists = $voucherExists;
}
/**
* @param VoucherObject $object
* @return \Illuminate\Database\Eloquent\Model
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function execute(VoucherObject $object) {
if(!$this->voucherExists->execute($object->getCode()))
{
$model = new Voucher();
$model->code = $object->getCode();
$model->name = $object->getName();
$model->type = $object->getType();
$model->value = $object->getValue();
return $this->handler($model);
}
return null;
}
}
@@ -0,0 +1,28 @@
<?php
namespace App\Classes\Modules\Vouchers\Services;
use App\Classes\General\Eloquent\AbstractUpdateRelationshipRecord;
use App\Models\Transaction;
use App\Models\Voucher;
use App\Models\VoucherRedemption;
class CreatesVoucherRedemption extends AbstractUpdateRelationshipRecord
{
/**
* @param Transaction $transaction
* @param Voucher $voucher
* @param string $redemptionId
* @param float $value
* @return \Illuminate\Database\Eloquent\Model
* @throws \App\Classes\Exceptions\MalformedRequestException
*/
public function execute(Transaction $transaction, Voucher $voucher, string $redemptionId, float $value) {
$model = new VoucherRedemption();
$model->voucher_id = $voucher->id;
$model->redemption_id = $redemptionId;
$model->value = $value;
return $this->handler($transaction->voucherRedemption(), $model);
}
}
@@ -0,0 +1,34 @@
<?php
namespace App\Classes\Modules\Vouchers\Services;
use App\Classes\General\Eloquent\AbstractFetchRecord;
use Illuminate\Database\Eloquent\Builder;
use App\Models\Voucher;
class FetchesVoucher extends AbstractFetchRecord
{
/** @var Voucher */
private $repository;
/**
* FetchesVoucher constructor.
* @param Voucher $repository
*/
public function __construct(Voucher $repository)
{
$this->repository = $repository;
}
/**
* @return Builder
*/
public function getRepository(): Builder
{
return $this->repository->newQuery();
}
}
@@ -0,0 +1,34 @@
<?php
namespace App\Classes\Modules\Vouchers\Services;
use App\Classes\General\Eloquent\AbstractFetchRecord;
use Illuminate\Database\Eloquent\Builder;
use App\Models\VoucherRedemption;
class FetchesVoucherRedemption extends AbstractFetchRecord
{
/** @var VoucherRedemption */
private $repository;
/**
* FetchesVoucherRedemption constructor.
* @param VoucherRedemption $repository
*/
public function __construct(VoucherRedemption $repository)
{
$this->repository = $repository;
}
/**
* @return Builder
*/
public function getRepository(): Builder
{
return $this->repository->newQuery();
}
}
@@ -0,0 +1,48 @@
<?php
namespace App\Classes\Modules\Vouchers\Services;
use ErrorException;
class RedeemsVoucher
{
/** @var VoucherifyClient */
private $voucherifyClient;
/**
* RedeemsVoucher constructor.
*
*/
public function __construct()
{
$this->voucherifyClient = createVoucherifyClient();
}
/**
* @param string $promoCode
* @param string $amount
* @param object $employee
* @return null|object
* @throws ErrorException
*/
public function execute(string $promoCode, string $amount, object $employee)
{
try {
$result = $this->voucherifyClient->redemptions->redeem($promoCode, [
"customer" => [
// "id" => $employee->id,
"name" => $employee->name,
"email" => $employee->email,
],
"order" => [
"amount" => $amount * 100 //converting it to cents
]
]);
return $result;
} catch (\Voucherify\ClientException $e) {
throw $e;
}
}
}
@@ -0,0 +1,39 @@
<?php
namespace App\Classes\Modules\Vouchers\Services;
use ErrorException;
use Illuminate\Support\Facades\Log;
class RollbacksRedemption
{
/** @var VoucherifyClient */
private $voucherifyClient;
/**
* RollbacksRedemption constructor.
*
*/
public function __construct()
{
$this->voucherifyClient = createVoucherifyClient();
}
/**
* @param string $redemptionId
* @return null|object
* @throws ErrorException
*/
public function execute(string $redemptionId)
{
try {
$result = $this->voucherifyClient->redemptions->rollback($redemptionId);
return $result;
} catch (\Voucherify\ClientException $e) {
Log::error('RollbacksRedemption error:' . $e);
return null;
}
}
}
@@ -0,0 +1,64 @@
<?php
namespace App\Classes\Modules\Vouchers\Services;
use ErrorException;
use Illuminate\Support\Facades\Log;
class ValidatesVoucher
{
/** @var VoucherifyClient */
private $voucherifyClient;
/**
* ValidatesVoucher constructor.
*
*/
public function __construct()
{
$this->voucherifyClient = createVoucherifyClient();
}
/**
* @param string $voucherCode
* @param float $amount
* @param object $employee
* @return null|object
* @throws ErrorException
*/
public function execute(string $voucherCode, ?float $amount, ?object $employee)
{
try {
if($amount){
$result = $this->voucherifyClient->validations->validateVoucher($voucherCode, [
"customer" => [
// "id" => $employee->id,
"name" => $employee->name,
"email" => $employee->email,
],
"order" => [
"amount" => $amount * 100 //converting it to cents
]
]);
}
else{
$res = $this->voucherifyClient->validations->validateVoucher($voucherCode);
$result = [
"valid" => $res->valid,
"code" => $res->code
];
if (isset($res->reason)) {
$result["reason"] = $res->reason;
}
}
return $result;
} catch (\Voucherify\ClientException $e) {
// throw $e;
Log::error('ValidatesVoucher error:' . $e);
return null;
}
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers\Vouchers;
use App\Classes\Modules\Vouchers\ControllersLogic\RedeemVoucherLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class RedeemVoucherController
{
/**
* @param Request $request
* @param RedeemVoucherLogic $logic
* @return JsonResponse
*/
public function redeem(Request $request, RedeemVoucherLogic $logic): JsonResponse {
return $logic->execute($request);
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers\Vouchers;
use App\Classes\Modules\Vouchers\ControllersLogic\ValidateVoucherLogic;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class ValidateVoucherController
{
/**
* @param Request $request
* @param ValidateVoucherLogic $logic
* @return JsonResponse
*/
public function validate(Request $request, ValidateVoucherLogic $logic): JsonResponse {
return $logic->execute($request);
}
}
+2 -1
View File
@@ -48,7 +48,8 @@ class TransactionResource extends JsonResource
'interval' => [ 'interval' => [
'value' => $days->gt(Carbon::now()) ? '+' : '-', 'value' => $days->gt(Carbon::now()) ? '+' : '-',
'duration' => $days->diff(Carbon::now())->format('%d'), 'duration' => $days->diff(Carbon::now())->format('%d'),
] ],
'redemption' => new VoucherRedemptionResource($this->voucherRedemption)
]; ];
} }
} }
@@ -0,0 +1,25 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class VoucherRedemptionResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return [
'id' => $this->id,
'voucher_id' => $this->voucher_id,
'transaction_id' => $this->transaction_id,
'redemption_id' => $this->redemption_id,
'value' => (float) $this->value
];
}
}
+8
View File
@@ -112,6 +112,14 @@ class Transaction extends AbstractModel implements Documentable, Transactionable
return $this->HasOne(GroupTransaction::class, 'transaction_id'); return $this->HasOne(GroupTransaction::class, 'transaction_id');
} }
/**
* @return HasOne
*/
public function voucherRedemption(): HasOne
{
return $this->HasOne(VoucherRedemption::class, 'transaction_id', 'id');
}
public function convert_original_amount() public function convert_original_amount()
{ {
if($this->booking()->first()->fix_currency_id !== 1) { if($this->booking()->first()->fix_currency_id !== 1) {
+9
View File
@@ -4,6 +4,7 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Database\Eloquent\SoftDeletes;
use Spatie\Permission\Traits\HasRoles; use Spatie\Permission\Traits\HasRoles;
@@ -65,4 +66,12 @@ class User extends AbstractModel implements
{ {
return $this->belongsToMany(Company::class, (new Employee())->getTable(), 'user_id', 'company_id'); return $this->belongsToMany(Company::class, (new Employee())->getTable(), 'user_id', 'company_id');
} }
/**
* @return HasMany
*/
public function redemptions(): HasMany
{
return $this->HasMany(VoucherRedemption::class, 'user_id', 'id');
}
} }
+19
View File
@@ -0,0 +1,19 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Relations\HasMany;
class Voucher extends AbstractModel
{
protected $table = 'vouchers';
/**
* @return HasMany
*/
public function redemptions(): HasMany
{
return $this->HasMany(VoucherRedemption::class, 'voucher_id', 'id');
}
}
+36
View File
@@ -0,0 +1,36 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasOne;
class VoucherRedemption extends AbstractModel
{
protected $table = 'voucher_redemptions';
/**
* @return BelongsTo
*/
public function voucher(): BelongsTo
{
return $this->BelongsTo(Voucher::class, 'voucher_id', 'id');
}
/**
* @return BelongsTo
*/
public function transaction(): BelongsTo
{
return $this->BelongsTo(Transaction::class, 'transaction_id', 'id');
}
/**
* @return BelongsTo
*/
public function user(): BelongsTo
{
return $this->BelongsTo(User::class, 'user_id', 'id');
}
}
+4
View File
@@ -24,6 +24,7 @@
"maatwebsite/excel": "^3.1", "maatwebsite/excel": "^3.1",
"mpdf/mpdf": "^8.1", "mpdf/mpdf": "^8.1",
"rinvex/countries": "^6.1", "rinvex/countries": "^6.1",
"rspective/voucherify": " v2.0.*",
"smalot/pdfparser": "^2.2", "smalot/pdfparser": "^2.2",
"spatie/laravel-activitylog": "^3.14", "spatie/laravel-activitylog": "^3.14",
"spatie/laravel-permission": "^3.17", "spatie/laravel-permission": "^3.17",
@@ -57,6 +58,9 @@
"classmap": [ "classmap": [
"database/seeds", "database/seeds",
"database/factories" "database/factories"
],
"files": [
"app/Classes/General/VoucherifyHelper.php"
] ]
}, },
"autoload-dev": { "autoload-dev": {
+8
View File
@@ -0,0 +1,8 @@
<?php
return [
'application_id' => env('VOUCHERIFY_APPLICATION_ID', ''),
'client_secret_key' => env('VOUCHERIFY_CLIENT_SECRET_KEY', ''),
'version' => env('VOUCHERIFY_VERSION', ''),
'url' => env('VOUCHERIFY_URL', ''),
];
@@ -0,0 +1,35 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateVouchersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('vouchers', function (Blueprint $table) {
$table->id();
$table->string('name')->nullable();
$table->string('code');
$table->string('type')->nullable();
$table->decimal('value', 8, 2)->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('vouchers');
}
}
@@ -0,0 +1,41 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateVoucherRedemptionsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('voucher_redemptions', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('voucher_id');
$table->unsignedBigInteger('transaction_id');
$table->string('redemption_id');
$table->decimal('value', 8, 2)->nullable();
// $table->unsignedBigInteger('user_id');
$table->timestamps();
// Define foreign key constraints
$table->foreign('voucher_id')->references('id')->on('vouchers');
$table->foreign('transaction_id')->references('id')->on('transactions');
// $table->foreign('user_id')->references('id')->on('users');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('voucher_redemptions');
}
}
@@ -269,7 +269,7 @@
<div class="font-heading text-success bold">{{(Math.round((this.parameters.calculation.total + Number.EPSILON) * 100) / 100).toFixed(2)}}</div> <div class="font-heading text-success bold">{{(Math.round((this.parameters.calculation.total + Number.EPSILON) * 100) / 100).toFixed(2)}}</div>
</div> </div>
</div> </div>
<div class="row"> <!-- <div class="row">
<div class="col-6 p-t-10 p-b-10"> <div class="col-6 p-t-10 p-b-10">
<div class="no-padding text-left"> <div class="no-padding text-left">
<div class="font-heading all-caps">Promo Code</div> <div class="font-heading all-caps">Promo Code</div>
@@ -286,7 +286,7 @@
</button> </button>
</div> </div>
</div> </div>
</div> </div> -->
</div> </div>
</div> </div>
</div> </div>
@@ -350,7 +350,8 @@
this.createBank = false; this.createBank = false;
this.account_no = ''; this.account_no = '';
this.parameters.bankAccount = {}; this.parameters.bankAccount = {};
}, }
/*
applyPromocoe(){ applyPromocoe(){
let promoRequestObj = { let promoRequestObj = {
category : 'New cat 4', category : 'New cat 4',
@@ -376,11 +377,11 @@
return fetch(url, { return fetch(url, {
method: 'POST', method: 'POST',
responseType: 'json', responseType: 'json',
body: promoRequestObj, body: JSON.stringify(promoRequestObj),
headers: { headers: {
'content-type': 'application/json', 'content-type': 'application/json',
'X-App-Token': '09a22aa9-f287-4813-9c65-6baa43091a6e', 'X-App-Token': 'b839bfa1-d8c1-4846-a367-05d466f48cfd',
'X-App-Id': 'e12347c6-b072-4318-9a2b-179a7a3b1414' 'X-App-Id': 'a180e3cb-ee34-469b-876f-d4a1139b82c6'
} }
}).then(response => { }).then(response => {
@@ -394,6 +395,7 @@
}) })
} }
*/
}, },
mixins: [FormHandler] mixins: [FormHandler]
} }
@@ -150,6 +150,17 @@
<div class="font-heading fs-10">MYR {{(Math.round((item.service_charge + Number.EPSILON) * 100) / 100).toFixed(2)}}</div> <div class="font-heading fs-10">MYR {{(Math.round((item.service_charge + Number.EPSILON) * 100) / 100).toFixed(2)}}</div>
</div> </div>
</div> </div>
<div class="row align-items-end m-b-10 hint-text">
<div class="col">
<div class="font-heading all-caps fs-10">Voucher</div>
</div>
<div class="col-auto text-right" v-if="item.redemption && item.redemption.value">
<div class="font-heading fs-10">- MYR {{(Math.round((item.redemption.value + Number.EPSILON) * 100) / 100).toFixed(2)}}</div>
</div>
<div class="col-auto text-right" v-else>
<div class="font-heading fs-10">- MYR 0.00</div>
</div>
</div>
<div class="row align-items-end m-b-5 hint-text"> <div class="row align-items-end m-b-5 hint-text">
<div class="col"> <div class="col">
<div class="font-heading all-caps fs-10">Tax</div> <div class="font-heading all-caps fs-10">Tax</div>
@@ -224,7 +224,29 @@
</div> </div>
</div> </div>
</div> </div>
<div class="row"> <div class="row m-r-0">
<div class="col p-r-0">
<validation-wrapper-component :validator="$v.amount">
<label>Enter Voucher</label>
<input class="form-control" name="voucherCode" v-model.lazy="voucherCode" @keyup="updateVoucherFlag($event)">
</validation-wrapper-component>
</div>
<div class="col-auto b-r b-t b-b b-grey">
<div class="row h-100 align-items-center">
<div class="col">
<button @click="applyVoucherCode()" class="btn btn-sm h-100 btn-primary b-rad-none all-caps">
Apply
</button>
</div>
</div>
</div>
</div>
<div class="row m-l-0 m-r-0" style="height: 20px">
<i class="fa fa-spinner fa-spin m-b-5" v-if="voucherIsChecking"></i>
<span class="text-danger" v-if="voucherCodeFailedReason">{{ voucherCodeFailedReason }}</span>
<span class="text-success" v-if="voucherCodeFailedReason === '' && voucherValidated">Voucher applied</span>
</div>
<div class="row m-t-5">
<div class="col"> <div class="col">
<div class="row p-l-15 p-r-15"> <div class="row p-l-15 p-r-15">
<div class="col m-r-5 text-center"> <div class="col m-r-5 text-center">
@@ -406,7 +428,7 @@
<button class="btn btn-xs all-caps b-rad-none btn-default bg-master-lighter btn-block" @click="expandPayment = false">Cancel</button> <button class="btn btn-xs all-caps b-rad-none btn-default bg-master-lighter btn-block" @click="expandPayment = false">Cancel</button>
</div> </div>
<div class="col p-l-0"> <div class="col p-l-0">
<button id="create-booking" class="btn btn-xs all-caps b-rad-none btn-success btn-block" :class="[{'hide': paymentMethod.name === ''}]" @click="submitForm()">Create Booking</button> <button id="create-booking" class="btn btn-xs all-caps b-rad-none btn-success btn-block" :class="[{'hide': ((paymentMethod.name === '' && !voucherValidated) || (paymentMethod.name !== '' && (!voucherValidated && voucherCode !== '')) || (paymentMethod.name === '' && voucherValidated)) }]" @click="submitForm()">Create Booking</button>
</div> </div>
</div> </div>
</div> </div>
@@ -468,6 +490,17 @@
<div class="font-heading fs-12">MYR {{(Math.round((calculation.sub_total + Number.EPSILON) * 100) / 100).toFixed(2)}}</div> <div class="font-heading fs-12">MYR {{(Math.round((calculation.sub_total + Number.EPSILON) * 100) / 100).toFixed(2)}}</div>
</div> </div>
</div> </div>
<div class="row align-items-end m-b-10 hint-text">
<div class="col">
<div class="font-heading all-caps fs-12">Voucher</div>
</div>
<div class="col-auto text-right" v-if="calculation.voucher_discount_amount">
<div class="font-heading fs-12">- MYR {{(Math.round((calculation.voucher_discount_amount + Number.EPSILON) * 100) / 100).toFixed(2)}}</div>
</div>
<div class="col-auto text-right" v-else>
<div class="font-heading fs-12">- MYR 0.00</div>
</div>
</div>
<div class="row align-items-end m-b-5 hint-text"> <div class="row align-items-end m-b-5 hint-text">
<div class="col"> <div class="col">
<div class="font-heading all-caps fs-12">Tax {{(Math.round((calculation.tax + Number.EPSILON) * 10) / 10).toFixed(1)}}%</div> <div class="font-heading all-caps fs-12">Tax {{(Math.round((calculation.tax + Number.EPSILON) * 10) / 10).toFixed(1)}}%</div>
@@ -545,7 +578,11 @@
status: false status: false
}, },
amount: (Math.round((this.data.outstanding_amount + Number.EPSILON) * 100) / 100).toFixed(2), amount: (Math.round((this.data.outstanding_amount + Number.EPSILON) * 100) / 100).toFixed(2),
calculation: null calculation: null,
voucherCode: '',
voucherCodeFailedReason: '',
voucherValidated: false,
voucherIsChecking: false
} }
}, },
validations () { validations () {
@@ -580,6 +617,7 @@
submitForm(){ submitForm(){
this.parameters = { this.parameters = {
payment_method: this.paymentMethod.id, payment_method: this.paymentMethod.id,
voucherCode: this.voucherCode,
amount: this.amount amount: this.amount
}; };
@@ -587,7 +625,22 @@
this.calculation = null; this.calculation = null;
}, },
successHandler(response){ successHandler(response){
this.calculation = response.payload.data; if(!response.payload.data){
this.voucherValidated = false;
this.voucherIsChecking = false;
this.voucherCodeFailedReason = 'Something went wrong. Please contact customer service.'
}
else if(response.payload.data.valid !== undefined && response.payload.data.code){ //applyVoucherCode()
this.voucherValidated = true;
if(response.payload.data.reason){
this.voucherCodeFailedReason = response.payload.data.reason;
this.voucherValidated = false;
}
this.voucherIsChecking = false;
}
else { //submitForm()
this.calculation = response.payload.data;
}
}, },
errorHandler(error) { errorHandler(error) {
this.error = error.message; this.error = error.message;
@@ -600,6 +653,27 @@
cancelQuotation(){ cancelQuotation(){
this.calculation = null; this.calculation = null;
this.expandPayment = false; this.expandPayment = false;
},
applyVoucherCode(){
this.voucherIsChecking = true;
this.voucherCodeFailedReason = '';
this.voucherValidated = false;
this.parameters = {
voucherCode: this.voucherCode,
amount: this.amount
};
if(this.voucherCode.trim() !== ''){
this.submit(route('api.voucher.validate'), 'post', this.section, false, false);
}
else{
this.voucherValidated = true;
this.voucherIsChecking = false;
}
},
updateVoucherFlag(event){
this.voucherCodeFailedReason = '';
this.voucherValidated = false;
this.voucherCode = event.target.value;
} }
}, },
mixins: [componentHandler], mixins: [componentHandler],
@@ -120,6 +120,8 @@
payment_method: this.payment_method, payment_method: this.payment_method,
amount: this.amount, amount: this.amount,
bank_code: this.bank_code, bank_code: this.bank_code,
voucher_code: this.calculation.voucher_code,
voucher_discount_amount: this.calculation.voucher_discount_amount
} }
} }
}, },
+2
View File
@@ -55,6 +55,8 @@ Route::group(['middleware' => 'api', 'prefix' => 'v1', 'as' => 'api.'], function
require __DIR__ . '/wallet.php'; require __DIR__ . '/wallet.php';
require __DIR__ . '/voucher.php';
// require __DIR__ . '/rate.php'; // require __DIR__ . '/rate.php';
// require __DIR__ . '/receipt.php'; // require __DIR__ . '/receipt.php';
+8
View File
@@ -0,0 +1,8 @@
<?php
use Illuminate\Support\Facades\Route;
Route::group(['prefix' => 'voucher', 'as' => 'voucher.', 'namespace' => 'Vouchers'], function () {
Route::post('fetch', 'ValidateVoucherController@validate')->name('validate');
Route::post('redeem', 'RedeemVoucherController@redeem')->name('redeem');
});