Merge branch 'dillon/63.8-new-promo-voucher-50-percent' into 'master'

New voucherify promotion voucher

See merge request CIEFWorldwideSdnBhd/exchange-2.0!177
This commit is contained in:
Dillon Ngo
2024-09-02 14:13:22 +00:00
14 changed files with 139 additions and 50 deletions
@@ -73,6 +73,7 @@ class FetchesBookingQuotation
$employeeWhoOwnsTheVoucher = null;
$employees = $company->first()->employees;
if(count($employees) > 1){
foreach($employees as $singleEmployee){
$userRewards = $singleEmployee->rewards;
foreach($userRewards as $userReward){
@@ -82,6 +83,7 @@ class FetchesBookingQuotation
}
}
}
}
if(!$employeeWhoOwnsTheVoucher){
$employeeWhoOwnsTheVoucher = $company->employees()->first();
@@ -149,7 +149,7 @@ class CheckMilestonesForRewardProcessor
$voucherEndDate = $result->expiration_date;
//create voucher
$voucherObject = new VoucherObject($result->code, isset($voucherName) ? $voucherName : "", $voucherType, $voucherValue, null, $voucherStartDate, $voucherEndDate);
$voucherObject = new VoucherObject($result->code, isset($voucherName) ? $voucherName : "", null, $voucherType, $voucherValue, null, $voucherStartDate, $voucherEndDate);
$voucher = $this->createsVoucher->execute($voucherObject);
if(!$voucher) $voucher = $this->fetchesVoucher->execute(['code' => $voucherObject->getCode()]);
$voucherId = $voucher->id;
@@ -47,6 +47,7 @@ class ValidateVoucherLogic extends AbstractControllerLogic
$booking = Booking::find($request->input('itemId'));
$employees = $booking->company->employees()->get();
if(count($employees) > 1){
foreach($employees as $singleEmployee){
$userRewards = $singleEmployee->rewards;
foreach($userRewards as $userReward){
@@ -56,6 +57,7 @@ class ValidateVoucherLogic extends AbstractControllerLogic
}
}
}
}
if(!$employeeWhoOwnsTheVoucher){
$employeeWhoOwnsTheVoucher = $booking->company->employees()->first();
@@ -15,6 +15,9 @@ class VoucherObject implements DataTransferObject
/** @var string|null */
private $name;
/** @var string|null */
private $description;
/** @var string|null */
private $type;
@@ -34,16 +37,18 @@ class VoucherObject implements DataTransferObject
* VoucherObject constructor.
* @param string $code
* @param string $name
* @param string $description
* @param string $type
* @param float $value
* @param int $voucherCampaignId
* @param string $startDate
* @param string $endDate
*/
public function __construct(string $code, ?string $name, ?string $type, ?float $value, ?int $voucherCampaignId, ?string $startDate = '', ?string $endDate = '')
public function __construct(string $code, ?string $name, ?string $description, ?string $type, ?float $value, ?int $voucherCampaignId, ?string $startDate = '', ?string $endDate = '')
{
$this->code = $code;
$this->name = $name;
$this->description = $description;
$this->type = $type;
$this->value = $value;
$this->voucherCampaignId = $voucherCampaignId;
@@ -67,6 +72,14 @@ class VoucherObject implements DataTransferObject
return $this->name;
}
/**
* @return string
*/
public function getDescription(): ?string
{
return $this->description;
}
/**
* @return string
*/
@@ -48,6 +48,8 @@ class CreateVoucherProcessor
public function execute(?User $user, string $voucherCodeInput, ?int $campaignId = null) {
//Remotely - Get Voucher Voucherify
$voucherifyVoucherFetched = $this->fetchesVoucherifyVoucher->execute($user, $voucherCodeInput);
$voucherName = null;
$voucherDescription = null;
//Voucher stored locally need a name, by default use campaign name, else look into campaign metadata for displayname
if(isset($voucherifyVoucherFetched->metadata) && isset($voucherifyVoucherFetched->metadata->displayname)){
@@ -57,6 +59,10 @@ class CreateVoucherProcessor
$voucherName = $voucherifyVoucherFetched->campaign;
}
if(isset($voucherifyVoucherFetched->metadata) && isset($voucherifyVoucherFetched->metadata->display_description)){
$voucherDescription = $voucherifyVoucherFetched->metadata->display_description;
}
$voucherType = $voucherifyVoucherFetched->discount->type;
$voucherValue = isset($voucherifyVoucherFetched->discount->amount_off) ? $voucherifyVoucherFetched->discount->amount_off : $voucherifyVoucherFetched->discount->percent_off;
$voucherCode = $voucherifyVoucherFetched->code;
@@ -66,7 +72,8 @@ class CreateVoucherProcessor
//Locally - Create and Fetch Voucher
$voucherObject = new VoucherObject(
$voucherCode,
isset($voucherName) ? $voucherName : "Voucher ".Carbon::now()->format('Ymd'),
$voucherName ?? "Voucher ".Carbon::now()->format('Ymd'),
$voucherDescription,
$voucherType,
$voucherValue,
$campaignId,
@@ -86,6 +86,7 @@ class BookingToVoucherifyProcessor
$employeeWhoOwnsTheVoucher = null;
$employees = $user->company()->first()->employees;
if(count($employees) > 1){
foreach($employees as $singleEmployee){
$userRewards = $singleEmployee->rewards;
foreach($userRewards as $userReward){
@@ -95,6 +96,7 @@ class BookingToVoucherifyProcessor
}
}
}
}
if(!$employeeWhoOwnsTheVoucher){
$employeeWhoOwnsTheVoucher = $user;
@@ -151,7 +153,7 @@ class BookingToVoucherifyProcessor
$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);
$voucherObject= new VoucherObject($redeemedVoucher->code, isset($redeemedVoucher->metadata->displayname) ? $redeemedVoucher->metadata->displayname : "", null, $voucherType, $voucherValue, $voucherCampaign ? $voucherCampaign->id : null);
$voucher = $this->createsVoucher->execute($voucherObject);
if(!$voucher) $voucher = $this->fetchesVoucher->execute(['code' => $voucherObject->getCode()]);
@@ -31,6 +31,7 @@ class CreatesVoucher extends AbstractUpdateRecord
$model = new Voucher();
$model->code = $object->getCode();
$model->name = $object->getName();
$model->description = $object->getDescription();
$model->type = $object->getType();
$model->value = $object->getValue();
$model->voucher_campaign_id = $object->getVoucherCampaignId();
@@ -9,10 +9,12 @@ final class Vouchers {
public const SORRY_50 = 'SORRY50';
public const SORRY_100 = 'SORRY100';
public const SORRY_200 = 'SORRY200';
public const PROM150PERCENT = 'PROM150%';
const OPTIONS_SORRY = [
['text' => 'SORRY 50', 'id' => Vouchers::SORRY_50],
['text' => 'SORRY 100', 'id' => Vouchers::SORRY_100],
['text' => 'SORRY 200', 'id' => Vouchers::SORRY_200],
['text' => 'PROM150%', 'id' => Vouchers::PROM150PERCENT],
];
}
+1
View File
@@ -30,6 +30,7 @@ class VoucherResource extends JsonResource
return [
'id' => $this->id,
'name' => $this->name,
'description' => $this->description,
'code' => $this->code,
'type' => $this->type,
'value' => (float) $this->value,
@@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddDescriptionToVouchersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('vouchers', function (Blueprint $table) {
$table->text('description')->after('name')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('vouchers', function (Blueprint $table) {
$table->dropColumn('description');
});
}
}
@@ -9,9 +9,9 @@
<div class="col text-right no-padding" v-if="item.voucher.type == 'AMOUNT'">
RM{{ item.voucher.value/100 }} Discount
</div>
<!-- <div class="col text-right no-padding" v-if="item.voucher.type == 'PERCENT'">
{{ item.voucher.value }}% Discount
</div> -->
<div class="col text-right no-padding" v-if="item.voucher.type == 'PERCENT'">
<span v-if="item.voucher.value === 1">50% Discount</span>
</div>
</div>
<div class="row">
<div class="col-12 col-md-8 text-left no-padding">
@@ -44,7 +44,7 @@
<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>
<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>
@@ -246,9 +246,9 @@
</div>
</validation-wrapper-component>
</div>
<modal-component id="choose-voucher-modal" class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="voucherList">
<!-- <modal-component id="choose-voucher-modal" class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="voucherList">
<list-vouchers-component :employee="data.company.employee" @selected-voucher="handleSelectedVoucher"></list-vouchers-component>
</modal-component>
</modal-component> -->
</div>
<span class="text-primary bold text-underline m-l-5 cursor text-small fs-12" style="margin-bottom: -10px; margin-top: -5px;" @click="showApplyVoucher=!showApplyVoucher" v-show="!showApplyVoucher">Apply a voucher</span>
<div class="row m-l-0 m-r-0" v-show="showApplyVoucher" style="height: 20px">
@@ -1,28 +1,55 @@
<template>
<div class="card">
<div class="card-body">
<h5 v-if="item.reward" class="card-title"> {{ item.reward.name }}</h5>
<h5 v-else="item.voucher" class="card-title"> {{ item.voucher.name }}</h5>
<p v-if="item.reward" class="card-text">{{ item.reward.description }}</p>
<div class="row border p-3 mb-4 parentContainer">
<div class="col-md-4">
<p v-if="item.reward">{{ item.reward.name }}</p>
<p v-else>{{ item.voucher.name }}</p>
<p v-if="item.voucher.description">{{ item.voucher.description }}</p>
<p v-if="item.reward">{{ item.reward.description }}</p>
<p v-if="item.voucher && item.voucher.is_redeemed">Voucher claimed</p>
<p v-else-if="item.voucher.end_date && new Date() > new Date(item.voucher.end_date)">This voucher has expired</p>
<p v-else-if="item.voucher && item.voucher.end_date">Valid till {{ item.voucher.end_date }}</p>
<p v-else>Non-expired</p>
</div>
<div class="col-md-3">
<p v-if="item.voucher && item.voucher.is_redeemed" class="text-secondary">{{ item.voucher.code }}</p>
<p v-else class="text-primary">{{ item.voucher.code }}</p>
</div>
<div class="col-md-4">
<p v-if="item.voucher.type == 'AMOUNT'">RM{{ item.voucher.value / 100 }} Discount</p>
<p v-if="item.voucher.type == 'PERCENT'">{{ item.voucher.value }}% Discount</p>
<p v-if="item.voucher.type == 'PERCENT'">
<span v-if="item.voucher.value === 1">50% discount on service fee only</span>
<span v-else>{{ item.voucher.value }}% Discount</span>
</p>
</div>
<div class="card-body border-top" v-if="$store.getters.isAdmin && item.voucher.email && item.voucher.email.key === item.voucher.code + '_EMAIL_COUNT'">
<button disabled type="button" v-if="item.voucher.email && item.voucher.email.key === item.voucher.code + '_EMAIL_COUNT' && item.voucher.email.value == '1'" class="btn btn-lg btn-primary">Email Reminder #1 Sent</button>
<!-- <button type="button" v-else @click="submit()" class="btn btn-lg btn-primary">Send Email Reminder #1</button> -->
<div class="col-md-1">
<a class="pointer requestModal" :data-type="'showVoucherTnC-' + item.id">Terms</a>
<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-footer text-muted">
<p v-if="item.voucher && item.voucher.is_redeemed">
Voucher claimed
</p>
<p v-else-if="item.voucher && item.voucher.end_date">
Valid till {{ item.voucher.end_date }}
</p>
<p v-else>
-
</p>
<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>
</template>
@@ -7,7 +7,7 @@
<div class="col">
<div class="row m-b-10">
<div class="col">
<div class="font-heading fs-16 all-caps bold m-b-15">Add Sorry Voucher</div>
<div class="font-heading fs-16 all-caps bold m-b-15">Add Voucher Select</div>
</div>
</div>
<div class="row">