AMS_Backend/app/Controllers/Backend/PromoSettingController.php
2025-11-06 13:41:06 +08:00

543 lines
21 KiB
PHP

<?php
namespace App\Controllers\Backend;
use CodeIgniter\HTTP\ResponseInterface;
use CodeIgniter\RESTful\ResourceController;
use App\Models\PromoSetting;
use App\Models\PromoCode;
use App\Models\PromoRedemptionRecord;
helper('promo'); // loads app/Helpers/promo_helper.php
class PromoSettingController extends ResourceController
{
private $promoSetting;
private $promoCode;
private $promoRedemptionRecord;
protected $db;
public function __construct()
{
$this->promoSetting = new PromoSetting();
$this->promoCode = new PromoCode();
$this->promoRedemptionRecord = new PromoRedemptionRecord();
$this->db = \Config\Database::connect();
}
public function index()
{
$promoSettingsData = $this->promoSetting->findAll();
// print_r($promoSettingsData);exit;
if(empty($promoSettingsData)){
return $this->respond(['status' => 400, 'result' => 'No data found.']);
}
$result = [];
foreach($promoSettingsData as $key => $value){
$result[$key] = [
"id" => $value['id'],
"title" => $value['title'],
"status" => $value['status'],
];
$promoCode = $this->promoCode->where('promo_setting_id', $value['id'])->findAll()[0];
if(!empty($promoCode)){
$result[$key]['promoCode'] = $promoCode['code'];
$result[$key]['total_redemption_limit'] = $promoCode['total_redemption_limit'];
$result[$key]['start_date'] = $promoCode['start_date'];
$result[$key]['end_date'] = $promoCode['end_date'];
$count_redemptions = $this->promoRedemptionRecord->where('promo_codes_id', $promoCode['id'])->countAllResults();
$result[$key]['left_redemption'] = $promoCode['total_redemption_limit'] - $count_redemptions;
}
}
return $this->respond(['status' => 200, 'message' => 'Retrieve Promo Setting Successfully!', 'result' => $result]);
}
public function show($id = null)
{
$promoSetting = $this->promoSetting->find($id);
if(empty($promoSetting)){
return $this->respond(['status' => 400, 'result' => 'No data found.']);
}
// print_r(json_decode($promoSetting['promo_setting'], true));exit;
$promoSettingData = revertPromoSetting(json_decode($promoSetting['promo_setting'], true));
// print_r($promoSettingData);exit;
$result = [
"id" => $promoSetting['id'],
"promotionType" => $promoSetting['promotion_type'],
"promotionName" => $promoSetting['title'],
"promotionDescription" => $promoSetting['description'],
//promo_setting
"discountAmount" => $promoSettingData['discountAmount'],
"discountType" => $promoSettingData['discountType'],
"getNumber" => $promoSettingData['getNumber'],
"minimumSpend" => $promoSettingData['minimumSpend'],
"itemCategory1" => $promoSettingData['itemCategory1'],
"itemCategoryID1" => $promoSettingData['itemCategoryID1'],
"itemCategory2" => $promoSettingData['itemCategory2'],
"itemCategoryID2" => $promoSettingData['itemCategoryID2'],
"minimumQuantity" => $promoSettingData['minimumQuantity'],
"everyQuantity" => $promoSettingData['everyQuantity'],
// "minimumAmount" => $promoSettingData['minimumAmount'],
"promoType" => $promoSettingData['promoType'],
];
// print_r($result);exit;
$promoCode = $this->promoCode->where('promo_setting_id', $promoSetting['id'])->findAll()[0];
$result['promoCodeId'] = $promoCode['id'];
$result['promotionCode'] = $promoCode['code'];
$result['usageLimit'] = $promoCode['usage_limit_type'];
$result['voucherLimitPerCustomer'] = $promoCode['usage_limit'];
$result['totalRedemptionLimit'] = $promoCode['total_redemption_limit'];
$result['storeStartDate'] = $promoCode['start_date'];
$result['storeEndDate'] = $promoCode['end_date'];
$result['customDayTime'] = json_decode($promoCode['customize_validity'], true);
$result['applyToDeliveryPickup'] = $promoCode['promo_order_type'];
// print_r($result);exit;
$count_redemptions = $this->promoRedemptionRecord->where('promo_codes_id', $promoCode['id'])->countAllResults();
$result['left_redemption'] = $promoCode['total_redemption_limit'] - $count_redemptions;
return $this->respond(['status' => 200, 'message' => 'Retrieve Promo Setting Successfully!', 'result' => $result]);
}
public function create()
{
$validationRules = [
"promotionType" => "required",
"promotionName" => "required",
"promotionDescription" => "permit_empty",
"usageLimit" => "required",
"totalRedemptionLimit" => "required",
"voucherLimitPerCustomer" => "permit_empty",
"startDate" => "permit_empty",
"endDate" => "permit_empty",
"customDayTime" => "permit_empty",
"applyToDeliveryPickup" => "required",
];
$validation = $this->validate($validationRules);
if (!$validation) {
return $this->failValidationErrors($this->validator->getErrors());
}
$this->db->transBegin();
try {
$applyToDeliveryPickup = $this->request->getVar("applyToDeliveryPickup");
if (!is_array($applyToDeliveryPickup)) {
throw new \Exception("applyToDeliveryPickup must be an array");
}
$validOptions = ['delivery', 'pickup', 'dinein'];
foreach ($applyToDeliveryPickup as $option) {
if (!in_array($option, $validOptions)) {
throw new \Exception("Invalid option in applyToDeliveryPickup: " . $option);
}
}
if (empty($applyToDeliveryPickup)) {
throw new \Exception("applyToDeliveryPickup cannot be empty");
}
$minimumSpend = $this->request->getVar("minimumSpend");
$minimumQuantity = $this->request->getVar("minimumQuantity");
$everyQuantity = $this->request->getVar("everyQuantity");
$itemCategory1 = $this->request->getVar("itemCategory1");
$itemCategoryID1 = $this->request->getVar("itemCategoryID1");
$discountAmount = $this->request->getVar("discountAmount");
$discountType = $this->request->getVar("discountType");
$getNumber = $this->request->getVar("getNumber");
$itemCategory2 = $this->request->getVar("itemCategory2");
$itemCategoryID2 = $this->request->getVar("itemCategoryID2");
$promoType = $this->request->getVar("promoType");
$promoSetting = [
"MinimumSpend" => [
"type" => 'none',
"filter" => [],
"amount_type" => '',
"amount" => 0
],
"Promo" => [
"promo_type" => $promoType,
"discount_type" => $discountType,
"filter_type" => 'total',
"filter" => [],
"amount" => 0,
"free_item" => []
]
];
if (!empty($minimumSpend) || !empty($minimumQuantity) || !empty($everyQuantity)) {
if (!empty($itemCategory1)) {
$promoSetting["MinimumSpend"]["type"] = $itemCategory1;
$promoSetting["MinimumSpend"]["filter"] = is_array($itemCategoryID1) ? $itemCategoryID1 : [];
} else {
$promoSetting["MinimumSpend"]["type"] = "total";
$promoSetting["MinimumSpend"]["filter"] = [];
}
if (!empty($minimumSpend)) {
$promoSetting["MinimumSpend"]["amount_type"] = "amount";
$promoSetting["MinimumSpend"]["amount"] = floatval($minimumSpend);
} elseif (!empty($minimumQuantity)) {
$promoSetting["MinimumSpend"]["amount_type"] = "quantity";
$promoSetting["MinimumSpend"]["amount"] = intval($minimumQuantity);
} elseif (!empty($everyQuantity)) {
$promoSetting["MinimumSpend"]["amount_type"] = "every_quantity";
$promoSetting["MinimumSpend"]["amount"] = intval($everyQuantity);
}
}
$promoSetting["Promo"]["promo_type"] = $promoType;
if ($promoType === "free_item") {
$promoSetting["Promo"]["discount_type"] = '';
} else {
$promoSetting["Promo"]["discount_type"] = $discountType;
}
if (!empty($itemCategory2)) {
$promoSetting["Promo"]["filter_type"] = $itemCategory2;
} else {
$promoSetting["Promo"]["filter_type"] = "total";
}
if ($promoType === "free_item") {
$promoSetting["Promo"]["free_item"] = is_array($itemCategoryID2) ? $itemCategoryID2 : [];
$promoSetting["Promo"]["filter"] = [];
} else {
$promoSetting["Promo"]["filter"] = is_array($itemCategoryID2) ? $itemCategoryID2 : [];
$promoSetting["Promo"]["free_item"] = [];
}
if (!empty($discountAmount)) {
$promoSetting["Promo"]["amount"] = floatval($discountAmount);
} elseif (!empty($getNumber)) {
$promoSetting["Promo"]["amount"] = intval($getNumber);
}
$promoSettingData = [
"promotion_type" => $this->request->getVar("promotionType"),
"title" => $this->request->getVar("promotionName"),
"description" => $this->request->getVar("promotionDescription"),
"promo_setting" => json_encode($promoSetting)
];
$id = $this->promoSetting->insert($promoSettingData);
if(!$id){
throw new \Exception("Failed to create promotion setting.");
}
$promotionCode = $this->request->getVar("promotionCode");
if(!empty($promotionCode)){
$isExists = $this->promoCode->where('code', $promotionCode)->find();
if(!empty($isExists)){
throw new \Exception("Promotion code already exists.");
}
}
$promoOrderTypeString = implode(',', $applyToDeliveryPickup);
$promoCodeData = [
'promo_setting_id' => $id,
"code" => $promotionCode,
"usage_limit_type" => $this->request->getVar("usageLimit"),
"usage_limit" => $this->request->getVar("voucherLimitPerCustomer"),
"total_redemption_limit" => $this->request->getVar("totalRedemptionLimit"),
"start_date" => $this->request->getVar("storeStartDate"),
"end_date" => $this->request->getVar("storeEndDate"),
"customize_validity" => json_encode($this->request->getVar("customDayTime")),
"promo_order_type" => $promoOrderTypeString
];
$promoCodeId = $this->promoCode->insert($promoCodeData);
if(!$promoCodeId){
throw new \Exception("Failed to create promotion code.");
}
$this->db->transCommit();
return $this->respond([
'status' => 200,
'message' => 'Promotion created successfully.',
'data' => [
'promo_setting_id' => $id,
'promo_code_id' => $promoCodeId,
'promo_order_type' => $promoOrderTypeString
]
]);
} catch (\Exception $e) {
$this->db->transRollback();
log_message('error', 'Promotion creation failed: ' . $e->getMessage());
return $this->failServerError('Failed to create promotion: '. $e->getMessage());
}
}
public function update($id = null)
{
$promoSetting = $this->promoSetting->find($id);
if(empty($promoSetting)){
return $this->respond(['status' => 400, 'result' => 'No promotion setting data found.']);
}
$validationRules = [
"promotionType" => "required",
"promotionName" => "required",
"promotionDescription" => "permit_empty",
"usageLimit" => "required",
"totalRedemptionLimit" => "required",
"voucherLimitPerCustomer" => "permit_empty",
"startDate" => "permit_empty",
"endDate" => "permit_empty",
"customDayTime" => "permit_empty",
"applyToDeliveryPickup" => "required",
];
$validation = $this->validate($validationRules);
if (!$validation) {
return $this->failValidationErrors($this->validator->getErrors());
}
$this->db->transBegin();
try {
$applyToDeliveryPickup = $this->request->getVar("applyToDeliveryPickup");
if (!is_array($applyToDeliveryPickup)) {
throw new \Exception("applyToDeliveryPickup must be an array");
}
$validOptions = ['delivery', 'pickup', 'dinein'];
foreach ($applyToDeliveryPickup as $option) {
if (!in_array($option, $validOptions)) {
throw new \Exception("Invalid option in applyToDeliveryPickup: " . $option);
}
}
if (empty($applyToDeliveryPickup)) {
throw new \Exception("applyToDeliveryPickup cannot be empty");
}
$minimumSpend = $this->request->getVar("minimumSpend");
$minimumQuantity = $this->request->getVar("minimumQuantity");
$everyQuantity = $this->request->getVar("everyQuantity");
$itemCategory1 = $this->request->getVar("itemCategory1");
$itemCategoryID1 = $this->request->getVar("itemCategoryID1");
// print_r($itemCategory1);
// print_r($itemCategoryID1);
// exit;
$discountAmount = $this->request->getVar("discountAmount");
$discountType = $this->request->getVar("discountType");
$getNumber = $this->request->getVar("getNumber");
$itemCategory2 = $this->request->getVar("itemCategory2");
$itemCategoryID2 = $this->request->getVar("itemCategoryID2");
$promoType = $this->request->getVar("promoType");
$promoSetting = [
"MinimumSpend" => [
"type" => 'none',
"filter" => [],
"amount_type" => '',
"amount" => 0
],
"Promo" => [
"promo_type" => $promoType,
"discount_type" => $discountType,
"filter_type" => 'total',
"filter" => [],
"amount" => 0,
"free_item" => []
]
];
if (!empty($itemCategory1)) {
$promoSetting["MinimumSpend"]["type"] = $itemCategory1;
$promoSetting["MinimumSpend"]["filter"] = is_array($itemCategoryID1) ? $itemCategoryID1 : [];
} else {
$promoSetting["MinimumSpend"]["type"] = "total";
$promoSetting["MinimumSpend"]["filter"] = [];
}
if (!empty($minimumSpend)) {
$promoSetting["MinimumSpend"]["amount_type"] = "amount";
$promoSetting["MinimumSpend"]["amount"] = floatval($minimumSpend);
} elseif (!empty($minimumQuantity)) {
$promoSetting["MinimumSpend"]["amount_type"] = "quantity";
$promoSetting["MinimumSpend"]["amount"] = intval($minimumQuantity);
} elseif (!empty($everyQuantity)) {
$promoSetting["MinimumSpend"]["amount_type"] = "every_quantity";
$promoSetting["MinimumSpend"]["amount"] = intval($everyQuantity);
}
$promoSetting["Promo"]["promo_type"] = $promoType;
if ($promoType === "free_item") {
$promoSetting["Promo"]["discount_type"] = '';
} else {
$promoSetting["Promo"]["discount_type"] = $discountType;
}
if (!empty($itemCategory2)) {
$promoSetting["Promo"]["filter_type"] = $itemCategory2;
} else {
$promoSetting["Promo"]["filter_type"] = "total";
}
if ($promoType === "free_item") {
$promoSetting["Promo"]["free_item"] = is_array($itemCategoryID2) ? $itemCategoryID2 : [];
$promoSetting["Promo"]["filter"] = [];
} else {
$promoSetting["Promo"]["filter"] = is_array($itemCategoryID2) ? $itemCategoryID2 : [];
$promoSetting["Promo"]["free_item"] = [];
}
if (!empty($discountAmount)) {
$promoSetting["Promo"]["amount"] = floatval($discountAmount);
} elseif (!empty($getNumber)) {
$promoSetting["Promo"]["amount"] = intval($getNumber);
}
$promoSettingData = [
"id" => $id,
"promotion_type" => $this->request->getVar("promotionType"),
"title" => $this->request->getVar("promotionName"),
"description" => $this->request->getVar("promotionDescription"),
"promo_setting" => json_encode($promoSetting)
];
$response = $this->promoSetting->save($promoSettingData);
if (!$response) {
throw new \Exception('Failed to update promotion settings.');
}
$promoCode = $this->promoCode->where('promo_setting_id', $id)->find()[0];
if(!$promoCode){
throw new \Exception("Failed to update promotion code.");
}
$promotionCode = $this->request->getVar("promotionCode");
if(!empty($promotionCode)){
$isExists = $this->promoCode->where('code', $promotionCode)->where('id !=', $promoCode['id'])->find();
if(!empty($isExists)){
throw new \Exception("Promotion code already exists.");
}
}
$promoOrderTypeString = implode(',', $applyToDeliveryPickup);
$promoCodeData = [
'id' => $promoCode['id'],
'promo_setting_id' => $id,
'code' => $promotionCode,
'usage_limit_type' => $this->request->getVar("usageLimit"),
'usage_limit' => $this->request->getVar("voucherLimitPerCustomer"),
'total_redemption_limit' => $this->request->getVar("totalRedemptionLimit"),
'start_date' => $this->request->getVar("storeStartDate"),
'end_date' => $this->request->getVar("storeEndDate"),
'customize_validity' => json_encode($this->request->getVar("customDayTime")),
'promo_order_type' => $promoOrderTypeString
];
$promoCodeResponse = $this->promoCode->save($promoCodeData);
if (!$promoCodeResponse) {
throw new \Exception('Failed to update promotion code.');
}
$this->db->transCommit();
return $this->respond([
'status' => 200,
'message' => 'Promotion updated successfully.',
'data' => [
'promo_setting_id' => $id,
'promo_code_id' => $promoCode['id'],
'promo_order_type' => $promoOrderTypeString
]
]);
} catch (\Exception $e) {
$this->db->transRollback();
log_message('error', 'Promotion update failed: ' . $e->getMessage());
return $this->failServerError('Failed to update promotion: '. $e->getMessage());
}
}
public function delete($id = null)
{
$promoSetting = $this->promoSetting->find($id);
// print_r($promoSetting);exit;
if(empty($promoSetting)){
return $this->respond(['status' => 400, 'result' => 'No promotion setting data found.']);
}
$this->promoSetting->delete($id);
$this->promoCode->where('promo_setting_id', $id)->delete();
return $this->respond(['status' => 200, 'result' => 'Promotion deleted successfully.']);
}
public function promoSettingList(){
$promo_setting_list = $this->promoSetting->findAll();
if(empty($promo_setting_list)){
return $this->fail('No promo setting data found!');
}
$data_list = [];
foreach ($promo_setting_list as $key => $value) {
$data_list[] = [
'id' => $value['id'],
'promotion_type' => $value['promotion_type'],
'title' => $value['title'],
'description'=> $value['description'],
'status' => $value['status'],
'promo_setting' => $value['promo_setting'],
];
}
return $this->respond([
'status'=> 200,
'message' => 'Promo setting record found!',
'data'=> $data_list
]);
}
}