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

880 lines
26 KiB
PHP

<?php
namespace App\Controllers\Backend;
use CodeIgniter\HTTP\ResponseInterface;
use CodeIgniter\RESTful\ResourceController;
use App\Models\SettingCustomerType;
use App\Models\SettingMembershipTier;
use App\Models\SettingTax;
use App\Models\SlideshowModel;
helper('image');
use App\Models\SettingCheckinRule;
class SettingController extends ResourceController
{
private $customerTypeModel;
private $membershipTierModel;
private $checkinRuleModel;
private $taxModel;
private $slideshowModel;
public function __construct()
{
$this->customerTypeModel = new SettingCustomerType();
$this->membershipTierModel = new SettingMembershipTier();
$this->taxModel = new SettingTax();
$this->checkinRuleModel = new SettingCheckinRule();
$this->slideshowModel = new SlideshowModel();
}
public function customerTypesindex()
{
$types = $this->customerTypeModel->findAll();
if (empty($types)) {
$response = [
'status' => 'success',
'message' => 'No customer type data found.',
'data' => []
];
return $this->respond($response, 200);
}
$response = [
'status' => 'success',
'message' => 'Customer types retrieved successfully.',
'data' => $types
];
return $this->respond($response, 200);
}
public function customerTypesshow($id = null)
{
$type = $this->customerTypeModel->find($id);
if (!$type) {
$response = [
'status' => 'error',
'message' => 'Customer type not found.',
'data' => null
];
return $this->respond($response, 404);
}
$response = [
'status' => 'success',
'message' => 'Customer type retrieved successfully.',
'data' => $type
];
return $this->respond($response, 200);
}
public function customerTypescreate()
{
$validationRules = [
'name' => 'required',
];
if (!$this->validate($validationRules)) {
$response = [
'status' => 'error',
'message' => 'Validation failed.',
'data' => $this->validator->getErrors()
];
return $this->respond($response, 422);
}
$data = [
'name' => $this->request->getVar('name'),
];
$id = $this->customerTypeModel->insert($data);
if ($id) {
$result = $this->customerTypeModel->find($id);
$response = [
'status' => 'success',
'message' => 'Customer type created successfully.',
'data' => $result
];
return $this->respond($response, 201);
}
$response = [
'status' => 'error',
'message' => 'Failed to create customer type.',
'data' => null
];
return $this->respond($response, 500);
}
public function customerTypesupdate($id = null)
{
// Check if customer type exists and is not soft-deleted
$existingType = $this->customerTypeModel->find($id);
if (!$existingType) {
$response = [
'status' => 'error',
'message' => 'Customer type not found.',
'data' => null
];
return $this->respond($response, 404);
}
// Use raw input for PUT/PATCH, or getVar for POST fallback
$input = $this->request->getRawInput();
if (empty($input)) {
$input = $this->request->getVar();
}
$data = [];
if (isset($input['name'])) {
$data['name'] = $input['name'];
}
if (empty($data)) {
$response = [
'status' => 'error',
'message' => 'No data provided to update.',
'data' => null
];
return $this->respond($response, 400);
}
$this->customerTypeModel->update($id, $data);
$updatedType = $this->customerTypeModel->find($id);
$response = [
'status' => 'success',
'message' => 'Customer type updated successfully.',
'data' => $updatedType
];
return $this->respond($response, 200);
}
public function customerTypesdelete($id = null)
{
$existingType = $this->customerTypeModel->find($id);
if (!$existingType) {
$response = [
'status' => 'error',
'message' => 'Customer type not found.',
'data' => null
];
return $this->respond($response, 404);
}
$this->customerTypeModel->delete($id); // This performs soft delete
$response = [
'status' => 'success',
'message' => 'Customer type deleted successfully.',
'data' => null
];
return $this->respond($response, 200);
}
public function membershipTiersIndex()
{
$tiers = $this->membershipTierModel->findAll();
if (empty($tiers)) {
$response = [
'status' => 'error',
'message' => 'No membership tiers found.',
'data' => []
];
return $this->respond($response, 200);
}
$response = [
'status' => 'success',
'message' => 'Membership tiers retrieved successfully.',
'data' => $tiers
];
return $this->respond($response, 200);
}
public function membershipTiersShow($id = null)
{
$tier = $this->membershipTierModel->find($id);
if (!$tier) {
$response = [
'status' => 'error',
'message' => 'Membership tier not found.',
'data' => null
];
return $this->respond($response, 404);
}
$response = [
'status' => 'success',
'message' => 'Membership tier retrieved successfully.',
'data' => $tier
];
return $this->respond($response, 200);
}
public function membershipTiersCreate()
{
$validationRules = [
'name' => 'required',
'min_points' => 'required|numeric',
// 'discount_rate' => 'required|numeric',
// 'category_id' => 'required|integer'
];
if (!$this->validate($validationRules)) {
$response = [
'status' => 'error',
'message' => 'Validation failed.',
'data' => $this->validator->getErrors()
];
return $this->respond($response, 422);
}
$name = $this->request->getVar('name');
$existingTier = $this->membershipTierModel->where('name', $name)->first();
if ($existingTier) {
$response = [
'status' => 'error',
'message' => "A membership tier with the name '{$name}' already exists.",
'data' => null
];
return $this->respond($response, 409); // Conflict
}
$data = [
'name' => $this->request->getVar('name'),
'min_points' => $this->request->getVar('min_points'),
'discount_rate' => $this->request->getVar('discount_rate'),
'color' => $this->request->getVar('color'),
'category_id' => $this->request->getVar('category_id'), // Add category_id
];
$id = $this->membershipTierModel->insert($data);
if ($id) {
$result = $this->membershipTierModel->find($id);
$response = [
'status' => 'success',
'message' => 'Membership tier created successfully.',
'data' => $result
];
return $this->respond($response, 201);
}
$response = [
'status' => 'error',
'message' => 'Failed to create membership tier.',
'data' => null
];
return $this->respond($response, 500);
}
public function membershipTiersUpdate($id = null)
{
$existing = $this->membershipTierModel->find($id);
if (!$existing) {
$response = [
'status' => 'error',
'message' => 'Membership tier not found.',
'data' => null
];
return $this->respond($response, 404);
}
$input = $this->request->getRawInput();
if (empty($input)) {
$input = $this->request->getVar();
}
$data = [];
if (isset($input['name'])) {
$data['name'] = $input['name'];
}
if (isset($input['min_points'])) {
$data['min_points'] = $input['min_points'];
}
// if (isset($input['discount_rate'])) {
// $data['discount_rate'] = $input['discount_rate'];
// }
if (isset($input['color'])) {
$data['color'] = $input['color'];
}
// if (isset($input['category_id'])) {
// $data['category_id'] = $input['category_id']; // Add category_id
// }
if (empty($data)) {
$response = [
'status' => 'error',
'message' => 'No data provided to update.',
'data' => null
];
return $this->respond($response, 400);
}
$this->membershipTierModel->update($id, $data);
$updated = $this->membershipTierModel->find($id);
$response = [
'status' => 'success',
'message' => 'Membership tier updated successfully.',
'data' => $updated
];
return $this->respond($response, 200);
}
public function membershipTiersDelete($id = null)
{
$existing = $this->membershipTierModel->find($id);
if (!$existing) {
$response = [
'status' => 'error',
'message' => 'Membership tier not found.',
'data' => null
];
return $this->respond($response, 404);
}
$this->membershipTierModel->delete($id);
$response = [
'status' => 'success',
'message' => 'Membership tier deleted successfully.',
'data' => null
];
return $this->respond($response, 200);
}
public function taxIndex()
{
$taxes = $this->taxModel->findAll();
if (empty($taxes)) {
$response = [
'status' => 'error',
'message' => 'No tax data found.',
'data' => []
];
return $this->respond($response, 200);
}
$response = [
'status' => 'success',
'message' => 'Tax data retrieved successfully.',
'data' => $taxes
];
return $this->respond($response, 200);
}
public function taxShow($id = null)
{
$tax = $this->taxModel->find($id);
if (!$tax) {
$response = [
'status' => 'error',
'message' => 'Tax entry not found.',
'data' => null
];
return $this->respond($response, 404);
}
$response = [
'status' => 'success',
'message' => 'Tax entry retrieved successfully.',
'data' => $tax
];
return $this->respond($response, 200);
}
public function taxCreate()
{
$validationRules = [
'outlet_id' => 'required',
'tax_type' => 'required',
'tax_rate' => 'required|numeric',
'order_type' => 'required',
];
if (!$this->validate($validationRules)) {
$response = [
'status' => 'error',
'message' => 'Validation failed.',
'data' => $this->validator->getErrors()
];
return $this->respond($response, 400);
}
// Process outlet_ids - convert to comma-separated string
$outletIds = $this->request->getPost('outlet_id');
// If it's an array (from multiple select), convert to comma-separated string
if (is_array($outletIds)) {
$outletIds = implode(',', $outletIds);
}
// Validate that outlet_ids contain only integers and commas
if (!preg_match('/^[0-9,]+$/', $outletIds)) {
$response = [
'status' => 'error',
'message' => 'Invalid outlet IDs format. Only integers and commas allowed.',
'data' => null
];
return $this->respond($response, 400);
}
$data = [
'outlet_id' => $outletIds,
'tax_type' => $this->request->getPost('tax_type'),
'tax_rate' => $this->request->getPost('tax_rate'),
'order_type' => $this->request->getVar('order_type'),
];
$id = $this->taxModel->insert($data);
if ($id) {
$result = $this->taxModel->find($id);
$response = [
'status' => 'success',
'message' => 'Tax created successfully.',
'data' => $result
];
return $this->respond($response, 201);
}
$response = [
'status' => 'error',
'message' => 'Failed to create tax entry.',
'data' => null
];
return $this->respond($response, 500);
}
public function taxUpdate($id = null)
{
$tax = $this->taxModel->find($id);
if (!$tax) {
$response = [
'status' => 'error',
'message' => 'Tax entry not found.',
'data' => null
];
return $this->respond($response, 404);
}
$data = [];
// Process outlet_ids if provided
if ($this->request->getPost('outlet_id')) {
$outletIds = $this->request->getPost('outlet_id');
// If it's an array, convert to comma-separated string
if (is_array($outletIds)) {
$outletIds = implode(',', $outletIds);
}
// Validate that outlet_ids contain only integers and commas
if (!preg_match('/^[0-9,]+$/', $outletIds)) {
$response = [
'status' => 'error',
'message' => 'Invalid outlet IDs format. Only integers and commas allowed.',
'data' => null
];
return $this->respond($response, 400);
}
$data['outlet_id'] = $outletIds;
}
// Add other fields if provided
if ($this->request->getPost('tax_type')) {
$data['tax_type'] = $this->request->getPost('tax_type');
}
if ($this->request->getPost('tax_rate')) {
$data['tax_rate'] = $this->request->getPost('tax_rate');
}
if ($this->request->getVar('order_type')) {
$data['order_type'] = $this->request->getVar('order_type');
}
if (empty($data)) {
$response = [
'status' => 'error',
'message' => 'No data provided to update.',
'data' => null
];
return $this->respond($response, 400);
}
$this->taxModel->update($id, $data);
$updated = $this->taxModel->find($id);
$response = [
'status' => 'success',
'message' => 'Tax updated successfully.',
'data' => $updated
];
return $this->respond($response, 200);
}
public function taxDelete($id = null)
{
$tax = $this->taxModel->find($id);
if (!$tax) {
$response = [
'status' => 'error',
'message' => 'Tax entry not found.',
'data' => null
];
return $this->respond($response, 404);
}
$this->taxModel->delete($id);
$response = [
'status' => 'success',
'message' => 'Tax deleted successfully.',
'data' => null
];
return $this->respond($response, 200);
}
// public function slideshowIndex()
// {
// $slides = $this->slideshowModel->findAll();
// return $this->respond(['status' => 200, 'result' => $slides]);
// }
public function slideshowIndex()
{
$allowedOrderFields = [
'order', 'created_at', 'updated_at', 'title', 'status'
];
$orderBy = $this->request->getGet('order_by') ?? 'order';
$sort = strtolower($this->request->getGet('sort')) === 'desc' ? 'DESC' : 'ASC';
$page = (int) ($this->request->getGet('page') ?? 1);
$limit = (int) ($this->request->getGet('limit') ?? 20);
if (!in_array($orderBy, $allowedOrderFields)) {
$orderBy = 'order';
}
$builder = $this->slideshowModel->orderBy($orderBy, $sort);
if ($this->slideshowModel->useSoftDeletes) {
$builder = $builder->where('deleted_at', null);
}
if ($limit > 0) {
$offset = ($page - 1) * $limit;
$slides = $builder->findAll($limit, $offset);
$total = $this->slideshowModel->where('deleted_at', null)->countAllResults();
} else {
$slides = $builder->findAll();
$total = count($slides);
}
return $this->respond([
'status' => 200,
'result' => $slides,
'pagination' => [
'page' => $page,
'limit' => $limit,
'total' => $total
]
]);
}
// SHOW a single slide by id
public function slideshowShow($id = null)
{
$slide = $this->slideshowModel->find($id);
if (!$slide) {
return $this->failNotFound('Slideshow not found.');
}
return $this->respond(['status' => 200, 'result' => $slide]);
}
// CREATE a new slide
public function slideshowCreate()
{
$slideImage = $this->request->getFile('url');
$imageUrl = null;
$compressedImageUrl = null;
if ($slideImage && $slideImage->isValid() && !$slideImage->hasMoved()) {
$result = save_image_with_compression(
$slideImage,
FCPATH . 'backend/uploads/slideshow',
FCPATH . 'backend/uploads/slideshow_compressed',
900, // width of compressed version
80 // quality (0-100)
);
$imageUrl = base_url('backend/uploads/slideshow/' . basename($result['original']));
$compressedImageUrl = base_url('backend/uploads/slideshow_compressed/' . basename($result['compressed']));
}
$data = [
'type' => $this->request->getVar('type'),
'title' => $this->request->getVar('title'),
'description' => $this->request->getVar('description'),
'order' => $this->request->getVar('order'),
'status' => $this->request->getVar('status'),
'url' => $imageUrl,
'compressed_url' => $compressedImageUrl,
];
$id = $this->slideshowModel->insert($data);
if ($id) {
$result = $this->slideshowModel->find($id);
return $this->respond(['status' => 200, 'message' => 'Slideshow created.', 'result' => $result]);
}
return $this->fail('Failed to create slideshow entry.');
}
// UPDATE an existing slide
public function slideshowUpdate($id = null)
{
$slide = $this->slideshowModel->find($id);
if (!$slide) {
return $this->failNotFound('Slideshow not found.');
}
$input = $this->request->getVar();
$file = $this->request->getFile('url');
if ($file && $file->isValid() && !$file->hasMoved()) {
$result = save_image_with_compression(
$file,
FCPATH . 'backend/uploads/slideshow',
FCPATH . 'backend/uploads/slideshow_compressed',
900, // width of compressed version
80 // quality
);
$input['url'] = base_url('backend/uploads/slideshow/' . basename($result['original']));
$input['compressed_url'] = base_url('backend/uploads/slideshow_compressed/' . basename($result['compressed']));
} else if ($this->request->getVar('url')) {
$input['url'] = $this->request->getVar('url');
}
// print_r($data);exit;
$data = array_filter([
'type' => $input['type'] ?? null,
'url' => $input['url'] ?? null,
'compressed_url' => $input['compressed_url'] ?? null,
'title' => $input['title'] ?? null,
'description' => $input['description'] ?? null,
'order' => $input['order'] ?? null,
'status' => $input['status'] ?? null,
], function ($value) {
return $value !== null;
});
// print_r($data);exit;
if (empty($data)) {
return $this->fail('No data provided to update.');
}
$this->slideshowModel->update($id, $data);
$updated = $this->slideshowModel->find($id);
return $this->respond(['status' => 200, 'message' => 'Slideshow updated.', 'result' => $updated]);
}
// DELETE a slide
public function slideshowDelete($id = null)
{
$slide = $this->slideshowModel->find($id);
if (!$slide) {
return $this->failNotFound('Slideshow entry not found.');
}
$this->slideshowModel->delete($id);
return $this->respond(['status' => 200, 'message' => 'Slideshow deleted Successfully.']);
}
public function createCheckinRule()
{
$checkinCount = $this->request->getVar('checkin_count');
$rewardPoint = $this->request->getVar('reward_point');
if ($checkinCount === null || $rewardPoint === null) {
$response = [
'status' => 'error',
'message' => 'Check-in count and Reward point are required.',
'data' => null
];
return $this->respond($response, 400);
}
// Ensure both are positive numbers
if (!is_numeric($checkinCount) || $checkinCount <= 0 || !is_numeric($rewardPoint) || $rewardPoint <= 0) {
$response = [
'status' => 'error',
'message' => 'Both Check-in count and reward point must be positive numbers.',
'data' => null
];
return $this->respond($response, 400);
}
// Check for duplicate checkin_count
$existing = $this->checkinRuleModel->where('checkin_count', (int)$checkinCount)->first();
if ($existing) {
return $this->respond([
'status' => 'error',
'message' => 'A rule with the same check-in count already exists.',
'data' => null
], 409);
}
$data = [
'checkin_count' => (int) $checkinCount,
'reward_point' => number_format((float) $rewardPoint, 2, '.', '')
];
$this->checkinRuleModel->insert($data);
$response = [
'status' => 'success',
'message' => 'Check-in rule created successfully.',
'data' => $data
];
return $this->respond($response, 201);
}
public function getCheckinRules()
{
$rules = $this->checkinRuleModel
->orderBy('checkin_count', 'DESC')
->findAll();
$response = [
'status' => 'success',
'message' => 'Check-in rules retrieved successfully.',
'data' => $rules
];
return $this->respond($response, 200);
}
public function updateCheckinRule($id)
{
$checkinCount = $this->request->getVar('checkin_count');
$rewardPoint = $this->request->getVar('reward_point');
// Check if rule exists
$rule = $this->checkinRuleModel->find($id);
if (!$rule) {
$response = [
'status' => 'error',
'message' => 'Check-in rule not found.',
'data' => null
];
return $this->respond($response, 404);
}
// Validate input
if ($checkinCount === null || $rewardPoint === null) {
$response = [
'status' => 'error',
'message' => 'checkin_count and reward_point are required.',
'data' => null
];
return $this->respond($response, 400);
}
if (!is_numeric($checkinCount) || $checkinCount <= 0 || !is_numeric($rewardPoint) || $rewardPoint <= 0) {
$response = [
'status' => 'error',
'message' => 'Both checkin_count and reward_point must be positive numbers.',
'data' => null
];
return $this->respond($response, 400);
}
$existing = $this->checkinRuleModel
->where('checkin_count', (int)$checkinCount)
->where('id !=', $id)
->first();
if ($existing) {
return $this->respond([
'status' => 'error',
'message' => 'Another rule with the same check-in count already exists.',
'data' => null
], 409);
}
$data = [
'checkin_count' => (int) $checkinCount,
'reward_point' => (float) $rewardPoint,
];
$this->checkinRuleModel->update($id, $data);
$response = [
'status' => 'success',
'message' => 'Check-in rule updated successfully.',
'data' => $data
];
return $this->respond($response, 200);
}
public function deleteCheckinRule($id)
{
// Check if the rule exists
$rule = $this->checkinRuleModel->find($id);
if (!$rule) {
$response = [
'status' => 'error',
'message' => 'Check-in rule not found.',
'data' => null
];
return $this->respond($response, 404);
}
// Delete the rule
$this->checkinRuleModel->delete($id);
$response = [
'status' => 'success',
'message' => 'Check-in rule deleted successfully.',
'data' => ['id' => $id]
];
return $this->respond($response, 200);
}
}