864 lines
33 KiB
PHP
864 lines
33 KiB
PHP
<?php
|
|
|
|
namespace App\Controllers\Backend;
|
|
|
|
use CodeIgniter\HTTP\ResponseInterface;
|
|
use CodeIgniter\RESTful\ResourceController;
|
|
|
|
use App\Models\Outlet;
|
|
use App\Models\OutletTax;
|
|
use App\Models\OutletImage;
|
|
use App\Models\OutletOperatingDay;
|
|
use App\Models\OutletOperatingHour;
|
|
use App\Models\OutletOperatingHoursException;
|
|
use App\Models\SettingTax;
|
|
use App\Models\OutletMenus;
|
|
use App\Models\MenuItems;
|
|
use App\Models\User;
|
|
|
|
helper('image');
|
|
|
|
|
|
class OutletController extends ResourceController
|
|
{
|
|
|
|
private $outlet;
|
|
private $outletTax;
|
|
private $outletImage;
|
|
private $outletOperatingDays;
|
|
private $outletOperatingHours;
|
|
private $outletOperatingHoursExceptions;
|
|
private $settingTax;
|
|
private $outlet_menu;
|
|
private $menu_items;
|
|
private $user;
|
|
protected $db;
|
|
|
|
|
|
public function __construct()
|
|
{
|
|
$this->outlet = new Outlet();
|
|
$this->outletTax = new OutletTax();
|
|
$this->outletImage = new OutletImage();
|
|
$this->outletOperatingDays = new OutletOperatingDay();
|
|
$this->outletOperatingHours = new OutletOperatingHour();
|
|
$this->outletOperatingHoursExceptions = new OutletOperatingHoursException();
|
|
$this->settingTax = new SettingTax();
|
|
$this->db = \Config\Database::connect();
|
|
$this->outlet_menu = new OutletMenus();
|
|
$this->menu_items = new MenuItems();
|
|
$this->user = new User();
|
|
|
|
}
|
|
|
|
public function index()
|
|
{
|
|
$user_id = $this->request->getVar('user_id');
|
|
|
|
if(!empty($user_id)){
|
|
|
|
$user = $this->user->find($user_id);
|
|
if($user['role'] == 'outlet'){
|
|
$outlets = $this->outlet->getOperatingHoursWithDaysList($user['outlet_id']);
|
|
|
|
} else {
|
|
$outlets = $this->outlet->getOperatingHoursWithDaysList();
|
|
}
|
|
|
|
} else {
|
|
return $this->respond (['status' => 400, 'result'=> 'User Id is required.']);
|
|
}
|
|
|
|
|
|
|
|
if(empty($outlets)){
|
|
return $this->respond(['status' => 400, 'result' => 'No outlet data found.']);
|
|
}
|
|
|
|
return $this->respond(['status' => 200, 'result' => $outlets]);
|
|
}
|
|
|
|
|
|
public function show($id = null)
|
|
{
|
|
$outlet = $this->outlet->getOperatingHoursWithDays($id);
|
|
|
|
if(empty($outlet)){
|
|
return $this->respond(['status' => 400, 'result' => 'No outlet data found.']);
|
|
}
|
|
|
|
return $this->respond(['status' => 200, 'result' => $outlet]);
|
|
}
|
|
|
|
|
|
public function create()
|
|
{
|
|
$validationRules = [
|
|
'title' => 'required',
|
|
'email' => 'required',
|
|
'phone' => 'required',
|
|
'address' => 'required',
|
|
'state' => 'required',
|
|
'postal_code' => 'required',
|
|
'country' => 'required',
|
|
'latitude' => 'required|numeric',
|
|
'longitude' => 'required|numeric',
|
|
'password' => 'required|min_length[8]',
|
|
'outlet_delivery_coverage' => 'required|numeric',
|
|
'outlet_tax' => 'permit_empty',
|
|
'outlet_operating_days' => 'permit_empty',
|
|
'outlet_operating_hours' => 'permit_empty',
|
|
'outlet_operating_hours_exceptions' => 'permit_empty',
|
|
];
|
|
|
|
$validation = $this->validate($validationRules);
|
|
|
|
if (!$validation) {
|
|
return $this->failValidationErrors($this->validator->getErrors());
|
|
}
|
|
|
|
// Start database transaction
|
|
$this->db->transBegin();
|
|
|
|
try {
|
|
$outletData = [
|
|
"title" => $this->request->getVar('title'),
|
|
"email" => $this->request->getVar('email'),
|
|
"phone" => $this->request->getVar('phone'),
|
|
"address" => $this->request->getVar('address'),
|
|
"state" => $this->request->getVar('state'),
|
|
"postal_code" => $this->request->getVar('postal_code'),
|
|
"country" => $this->request->getVar('country'),
|
|
"status" => $this->request->getVar('status'),
|
|
"latitude" => $this->request->getVar('latitude'),
|
|
"longitude" => $this->request->getVar('longitude'),
|
|
"password" => md5(md5($this->request->getVar('password'))),
|
|
"serve_method" => $this->request->getVar('serve_method'),
|
|
"delivery_options" => $this->request->getVar('delivery_options'),
|
|
"outlet_delivery_coverage" => $this->request->getVar('outlet_delivery_coverage'),
|
|
"order_max_per_hour" => $this->request->getVar('order_max_per_hour'),
|
|
"item_max_per_hour" => $this->request->getVar('item_max_per_hour'),
|
|
"menu_item" => json_encode($this->request->getVar('outlet_menu')),
|
|
];
|
|
|
|
$id = $this->outlet->insert($outletData);
|
|
if (!$id) {
|
|
throw new \RuntimeException('Failed to insert outlet data');
|
|
}
|
|
|
|
$outlet_menu = $this->request->getVar('outlet_menu');
|
|
if(!empty($outlet_menu)){
|
|
foreach($outlet_menu as $menu){
|
|
|
|
$outletMenuItem = [
|
|
"outlet_id" => $id,
|
|
"menu_item_id" => $menu,
|
|
];
|
|
if (!$this->outlet_menu->insert($outletMenuItem)) {
|
|
throw new \RuntimeException('Failed to insert outlet tax data');
|
|
}
|
|
}
|
|
}
|
|
// Process taxes
|
|
$tax_ids = $this->request->getVar('outlet_tax');
|
|
if(!empty($tax_ids)){
|
|
foreach ($tax_ids as $tax_id) {
|
|
$outletTaxData = [
|
|
"outlet_id" => $id,
|
|
"tax_id" => $tax_id,
|
|
];
|
|
if (!$this->outletTax->insert($outletTaxData)) {
|
|
throw new \RuntimeException('Failed to insert outlet tax data');
|
|
}
|
|
}
|
|
}
|
|
|
|
// Process images
|
|
$images = $this->request->getFiles('outlet_images');
|
|
$outlet_images = [];
|
|
|
|
if (!empty($images['outlet_images'])) {
|
|
foreach ($images['outlet_images'] as $index => $image) {
|
|
if (empty($image) || !$image->isValid() || $image->hasMoved()) {
|
|
continue;
|
|
}
|
|
|
|
try {
|
|
$result = save_image_with_compression(
|
|
$image,
|
|
FCPATH . 'backend/uploads/outlets',
|
|
FCPATH . 'backend/uploads/outlets_compressed',
|
|
900, // width
|
|
80 // quality
|
|
);
|
|
|
|
$originalFileName = basename($result['original']);
|
|
$compressedFileName = basename($result['compressed']);
|
|
|
|
if (!$this->outletImage->insert([
|
|
"outlet_id" => $id,
|
|
"image_url" => $originalFileName,
|
|
"compressed_image_url" => $compressedFileName,
|
|
"order_index" => $index
|
|
])) {
|
|
@unlink($result['original']);
|
|
@unlink($result['compressed']);
|
|
throw new \RuntimeException('Failed to insert outlet image data');
|
|
}
|
|
|
|
$outlet_images[$index] = [
|
|
'image_url' => $originalFileName,
|
|
'compressed_image_url' => $compressedFileName,
|
|
];
|
|
} catch (\Exception $e) {
|
|
log_message('error', 'Failed to upload and compress image: ' . $e->getMessage());
|
|
throw $e;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// Process operating days
|
|
$outlet_operating_days = json_decode($this->request->getVar('outlet_operating_days'), true);
|
|
$operating_days = [];
|
|
// print_r($this->request->getVar('outlet_operating_days'));exit;
|
|
if(!empty($outlet_operating_days[0])){
|
|
foreach ($outlet_operating_days[0] as $index => $day) {
|
|
$day_id = $this->outletOperatingDays->insert([
|
|
"outlet_id" => $id,
|
|
"day_of_week" => $index,
|
|
"is_operated" => $day['is_operated'],
|
|
]);
|
|
|
|
if (!$day_id) {
|
|
throw new \RuntimeException('Failed to insert operating days data');
|
|
}
|
|
|
|
$operating_days[$index] = [
|
|
'id' => $day_id,
|
|
"outlet_id" => $id,
|
|
"day_of_week" => $index,
|
|
"is_operated" => $day['is_operated'],
|
|
];
|
|
}
|
|
}
|
|
|
|
// Process operating hours
|
|
$outlet_operating_hours = json_decode($this->request->getVar('outlet_operating_hours'), true);
|
|
$operating_hours = [];
|
|
if(!empty($outlet_operating_hours[0])){
|
|
foreach ($outlet_operating_hours[0] as $index => $hours) {
|
|
foreach ($hours as $hour) {
|
|
$hour_id = $this->outletOperatingHours->insert([
|
|
"outlet_id" => $id,
|
|
"day_of_week" => $index,
|
|
"start_time" => $hour['start_time'],
|
|
"end_time" => $hour['end_time'],
|
|
]);
|
|
|
|
if (!$hour_id) {
|
|
throw new \RuntimeException('Failed to insert operating hours data');
|
|
}
|
|
|
|
$operating_hours[$index][] = [
|
|
'id' => $hour_id,
|
|
"outlet_id" => $id,
|
|
"day_of_week" => $index,
|
|
"start_time" => $hour['start_time'],
|
|
"end_time" => $hour['end_time'],
|
|
];
|
|
}
|
|
}
|
|
}
|
|
// Process operating hours exceptions
|
|
$outlet_operating_hours_exceptions = json_decode($this->request->getVar('outlet_operating_hours_exceptions'), true);
|
|
$operating_hours_exceptions = [];
|
|
|
|
if (!empty($outlet_operating_hours_exceptions)) {
|
|
foreach ($outlet_operating_hours_exceptions as $index => $exception) {
|
|
$hours_exception_id = $this->outletOperatingHoursExceptions->insert([
|
|
"outlet_id" => $id,
|
|
"date" => $exception['date'],
|
|
"start_time" => $exception['start_time'],
|
|
"end_time" => $exception['end_time'],
|
|
"notes" => $exception['notes'],
|
|
]);
|
|
|
|
if (!$hours_exception_id) {
|
|
throw new \RuntimeException('Failed to insert operating hours exceptions data');
|
|
}
|
|
|
|
$operating_hours_exceptions[$index] = [
|
|
'id' => $hours_exception_id,
|
|
"outlet_id" => $id,
|
|
"date" => $exception['date'],
|
|
"start_time" => $exception['start_time'],
|
|
"end_time" => $exception['end_time'],
|
|
"notes" => $exception['notes'],
|
|
];
|
|
}
|
|
}
|
|
|
|
// Commit transaction if everything succeeded
|
|
$this->db->transCommit();
|
|
|
|
$result = [
|
|
'id' => $id,
|
|
'title' => $this->request->getVar('title'),
|
|
'email' => $this->request->getVar('email'),
|
|
'phone' => $this->request->getVar('phone'),
|
|
'address' => $this->request->getVar('address'),
|
|
'state' => $this->request->getVar('state'),
|
|
'postal_code' => $this->request->getVar('postal_code'),
|
|
'country' => $this->request->getVar('country'),
|
|
'status' => $this->request->getVar('status'),
|
|
'latitude' => $this->request->getVar('latitude'),
|
|
'longitude' => $this->request->getVar('longitude'),
|
|
'password' => md5(md5($this->request->getVar('password'))),
|
|
'serve_method' => $this->request->getVar('serve_method'),
|
|
'delivery_options' => $this->request->getVar('delivery_options'),
|
|
'outlet_delivery_coverage' => $this->request->getVar('outlet_delivery_coverage'),
|
|
'order_max_per_hour' => $this->request->getVar('order_max_per_hour'),
|
|
'item_max_per_hour' => $this->request->getVar('item_max_per_hour'),
|
|
'outlet_tax' => $tax_ids,
|
|
'outlet_images' => $outlet_images,
|
|
'outlet_operating_days' => $operating_days,
|
|
'outlet_operating_hours' => $operating_hours,
|
|
'outlet_operating_hours_exceptions' => $operating_hours_exceptions ?? [],
|
|
'menu_item' => $this->request->getVar('outlet_menu'),
|
|
];
|
|
|
|
return $this->respond(['status' => 200, 'result' => $result]);
|
|
|
|
} catch (\Exception $e) {
|
|
// Rollback transaction on any error
|
|
$this->db->transRollback();
|
|
|
|
// Clean up any uploaded files if transaction fails
|
|
if (!empty($outlet_images)) {
|
|
$uploadPath = $_SERVER['DOCUMENT_ROOT'] . '/backend/uploads/outlets/';
|
|
foreach ($outlet_images as $image) {
|
|
@unlink($uploadPath . $image);
|
|
}
|
|
}
|
|
|
|
log_message('error', 'Outlet creation failed: ' . $e->getMessage());
|
|
return $this->failServerError('Failed to create outlet: ' . $e->getMessage());
|
|
}
|
|
}
|
|
|
|
public function update($id = null)
|
|
{
|
|
$outlet = $this->outlet->find($id);
|
|
|
|
if (empty($outlet)) {
|
|
return $this->respond(['status' => 400, 'result' => 'No outlet data found.']);
|
|
}
|
|
|
|
$validationRules = [
|
|
'title' => 'required',
|
|
'email' => 'required',
|
|
'phone' => 'required',
|
|
'address' => 'required',
|
|
'state' => 'required',
|
|
'postal_code' => 'required',
|
|
'country' => 'required',
|
|
'latitude' => 'required|numeric',
|
|
'longitude' => 'required|numeric',
|
|
'outlet_delivery_coverage' => 'required|numeric',
|
|
'outlet_tax' => 'permit_empty',
|
|
'outlet_operating_days' => 'permit_empty',
|
|
'outlet_operating_hours' => 'permit_empty',
|
|
'outlet_operating_hours_exceptions' => 'permit_empty',
|
|
'outlet_images' => 'permit_empty'
|
|
];
|
|
|
|
// Get all input data
|
|
$input = $this->request->getVar();
|
|
|
|
// Decode only the JSON fields
|
|
$jsonFields = [
|
|
'outlet_tax',
|
|
'outlet_operating_days',
|
|
'outlet_operating_hours',
|
|
'outlet_operating_hours_exceptions'
|
|
];
|
|
|
|
foreach ($jsonFields as $field) {
|
|
if (isset($input[$field]) && is_string($input[$field])) {
|
|
$input[$field] = json_decode($input[$field], true);
|
|
}
|
|
}
|
|
|
|
if (!$this->validateData($input, $validationRules)) {
|
|
return $this->failValidationErrors($this->validator->getErrors());
|
|
}
|
|
|
|
$outlet = $this->outlet->find($id);
|
|
|
|
if(empty($outlet)){
|
|
return $this->respond(['status' => 400, 'result' => 'No outlet data found.']);
|
|
}
|
|
|
|
// Prepare outlet data
|
|
$outlet_data = ['id' => $id];
|
|
$fields = [
|
|
'title', 'email', 'phone', 'address', 'state', 'postal_code', 'country',
|
|
'status', 'latitude', 'longitude', 'serve_method', 'delivery_options',
|
|
'outlet_delivery_coverage', 'order_max_per_hour', 'item_max_per_hour'
|
|
];
|
|
|
|
foreach ($fields as $field) {
|
|
if (isset($input[$field])) {
|
|
$outlet_data[$field] = $input[$field];
|
|
}
|
|
}
|
|
|
|
if (!empty($input['password']) && $input['password'] != 'null' && $input['password'] != '' && $input['password'] != 'undefined') {
|
|
$outlet_data['password'] = md5(md5($input['password']));
|
|
} else {
|
|
$outlet_data['password'] = $outlet['password'];
|
|
}
|
|
// print_r($outlet_data);exit;
|
|
// Start transaction
|
|
$this->db->transBegin();
|
|
|
|
try {
|
|
// Update main outlet data
|
|
$response = $this->outlet->save($outlet_data);
|
|
if (!$response) {
|
|
throw new \Exception('Failed to update outlet');
|
|
}
|
|
|
|
// Handle outlet taxes
|
|
if (isset($input['outlet_tax']) && is_array($input['outlet_tax'])) {
|
|
$existingTaxes = $this->outletTax->where('outlet_id', $id)
|
|
->where('deleted_at', null)
|
|
->findAll();
|
|
$existingTaxIds = array_column($existingTaxes, 'tax_id', 'id');
|
|
|
|
$updatedTaxIds = [];
|
|
foreach ($input['outlet_tax'] as $tax) {
|
|
$taxData = [
|
|
'outlet_id' => $id,
|
|
'tax_id' => $tax['tax_id'],
|
|
'updated_at' => date('Y-m-d H:i:s')
|
|
];
|
|
|
|
$taxId = array_search($tax['tax_id'], $existingTaxIds);
|
|
if ($taxId !== false) {
|
|
$taxData['id'] = $taxId;
|
|
$this->outletTax->save($taxData);
|
|
$updatedTaxIds[] = $taxId;
|
|
} else {
|
|
$taxData['created_at'] = date('Y-m-d H:i:s');
|
|
$newId = $this->outletTax->insert($taxData);
|
|
$updatedTaxIds[] = $newId;
|
|
}
|
|
}
|
|
|
|
// Soft delete removed taxes
|
|
foreach ($existingTaxes as $existingTax) {
|
|
if (!in_array($existingTax['id'], $updatedTaxIds)) {
|
|
$this->outletTax->where('id', $existingTax['id'])
|
|
->set(['deleted_at' => date('Y-m-d H:i:s')])
|
|
->update();
|
|
}
|
|
}
|
|
}
|
|
|
|
$images = $this->request->getFiles();
|
|
|
|
if (!empty($images['outlet_images'])) {
|
|
$images = $images['outlet_images'];
|
|
}
|
|
|
|
$existing_image = $this->request->getVar("existing_image");
|
|
|
|
if (!empty($images)) {
|
|
$exist_images = $this->outletImage->where('outlet_id', $id)->findAll();
|
|
$exist_images_group = array_column($exist_images, 'id');
|
|
|
|
foreach ($images as $image_file) {
|
|
if ($image_file && $image_file->isValid() && !$image_file->hasMoved()) {
|
|
$result = save_image_with_compression(
|
|
$image_file,
|
|
FCPATH . 'backend/uploads/outlets',
|
|
FCPATH . 'backend/uploads/outlets_compressed',
|
|
900, // width
|
|
80 // quality
|
|
);
|
|
|
|
$originalFileName = basename($result['original']);
|
|
$compressedFileName = basename($result['compressed']);
|
|
|
|
if (!$this->outletImage->insert([
|
|
'outlet_id' => $id,
|
|
'image_url' => $originalFileName,
|
|
'compressed_image_url' => $compressedFileName
|
|
])) {
|
|
throw new \Exception('Failed to update image!');
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if (!empty($existing_image)) {
|
|
foreach ($exist_images_group as $image_id) {
|
|
if (!in_array($image_id, $existing_image)) {
|
|
$this->outletImage->delete($image_id);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Handle operating days
|
|
if (isset($input['outlet_operating_days']) && is_array($input['outlet_operating_days'])) {
|
|
$operatingDays = $input['outlet_operating_days'][0];
|
|
$existingDays = $this->outletOperatingDays
|
|
->where('outlet_id', $id)
|
|
->findAll();
|
|
$existingDayMap = [];
|
|
foreach ($existingDays as $day) {
|
|
$existingDayMap[$day['day_of_week']] = $day;
|
|
}
|
|
|
|
$updatedDays = [];
|
|
foreach ($operatingDays as $dayName => $dayData) {
|
|
|
|
|
|
$dayOfWeek = ucfirst(strtolower($dayName));
|
|
$dayRecord = [
|
|
'outlet_id' => $id,
|
|
'day_of_week' => $dayOfWeek,
|
|
'is_operated' => $dayData['is_operated'],
|
|
'updated_at' => date('Y-m-d H:i:s')
|
|
];
|
|
|
|
if (isset($existingDayMap[$dayOfWeek])) {
|
|
$dayRecord['id'] = $existingDayMap[$dayOfWeek]['id'];
|
|
$this->outletOperatingDays->save($dayRecord);
|
|
$updatedDays[] = $dayOfWeek;
|
|
} else {
|
|
$dayRecord['created_at'] = date('Y-m-d H:i:s');
|
|
$this->outletOperatingDays->insert($dayRecord);
|
|
$updatedDays[] = $dayOfWeek;
|
|
}
|
|
}
|
|
|
|
// Soft delete removed days
|
|
foreach ($existingDays as $day) {
|
|
if (!in_array($day['day_of_week'], $updatedDays)) {
|
|
$this->outletOperatingDays->where('id', $day['id'])
|
|
->set(['deleted_at' => date('Y-m-d H:i:s')])
|
|
->update();
|
|
}
|
|
}
|
|
}
|
|
|
|
// Handle operating hours
|
|
if (isset($input['outlet_operating_hours']) && is_array($input['outlet_operating_hours'])) {
|
|
$operatingHours = $input['outlet_operating_hours'][0];
|
|
$existingHours = $this->outletOperatingHours
|
|
->where('outlet_id', $id)
|
|
->findAll();
|
|
|
|
$existingHoursByDay = [];
|
|
foreach ($existingHours as $hour) {
|
|
$existingHoursByDay[$hour['day_of_week']][] = $hour;
|
|
}
|
|
|
|
foreach ($operatingHours as $dayName => $timeSlots) {
|
|
$dayOfWeek = ucfirst(strtolower($dayName));
|
|
$updatedHourIds = [];
|
|
|
|
if (!empty($timeSlots)) {
|
|
foreach ($timeSlots as $slot) {
|
|
$hourRecord = [
|
|
'outlet_id' => $id,
|
|
'day_of_week' => $dayOfWeek,
|
|
'start_time' => $slot['start_time'],
|
|
'end_time' => $slot['end_time'],
|
|
'updated_at' => date('Y-m-d H:i:s')
|
|
];
|
|
|
|
$found = false;
|
|
if (isset($existingHoursByDay[$dayOfWeek])) {
|
|
foreach ($existingHoursByDay[$dayOfWeek] as $existingHour) {
|
|
if ($existingHour['start_time'] == $slot['start_time'] &&
|
|
$existingHour['end_time'] == $slot['end_time']) {
|
|
$hourRecord['id'] = $existingHour['id'];
|
|
$this->outletOperatingHours->save($hourRecord);
|
|
$updatedHourIds[] = $existingHour['id'];
|
|
$found = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!$found) {
|
|
$hourRecord['created_at'] = date('Y-m-d H:i:s');
|
|
$newId = $this->outletOperatingHours->insert($hourRecord);
|
|
$updatedHourIds[] = $newId;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Soft delete removed hours
|
|
if (isset($existingHoursByDay[$dayOfWeek])) {
|
|
foreach ($existingHoursByDay[$dayOfWeek] as $existingHour) {
|
|
if (!in_array($existingHour['id'], $updatedHourIds)) {
|
|
$this->outletOperatingHours
|
|
->where('id', $existingHour['id'])
|
|
->set(['deleted_at' => date('Y-m-d H:i:s')])
|
|
->update();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Handle outlet menu items
|
|
// print_r($input);exit;
|
|
// print_r($input['outlet_menu']);exit;
|
|
if (isset($input['outlet_menu']) && is_array($input['outlet_menu'])) {
|
|
// Filter out empty values (including 0 and '')
|
|
$filteredMenuIds = array_filter($input['outlet_menu'], function($menuId) {
|
|
return $menuId !== '' && $menuId !== null && $menuId !== 0;
|
|
});
|
|
|
|
if (!empty($filteredMenuIds)) {
|
|
// Fetch existing menu items
|
|
$existingMenu = $this->outlet_menu
|
|
->where('outlet_id', $id)
|
|
->where('deleted_at', null)
|
|
->findAll();
|
|
|
|
$existingMenuIds = array_column($existingMenu, 'menu_item_id', 'id');
|
|
$updatedMenuIds = [];
|
|
|
|
foreach ($filteredMenuIds as $menuId) {
|
|
if (in_array($menuId, $existingMenuIds)) {
|
|
$updatedMenuIds[] = $menuId;
|
|
} else {
|
|
$newId = $this->outlet_menu->insert([
|
|
'outlet_id' => $id,
|
|
'menu_item_id' => $menuId,
|
|
]);
|
|
$updatedMenuIds[] = $newId;
|
|
}
|
|
}
|
|
|
|
// Delete unused menu items
|
|
foreach ($existingMenu as $existing) {
|
|
if (!in_array($existing['menu_item_id'], $updatedMenuIds)) {
|
|
$this->outlet_menu
|
|
->where('menu_item_id', $existing['menu_item_id'])
|
|
->where('outlet_id', $id)
|
|
->where('deleted_at', null)
|
|
->delete();
|
|
}
|
|
}
|
|
} else {
|
|
// Delete ALL menu items if array is empty after filtering
|
|
$this->outlet_menu
|
|
->where('outlet_id', $id)
|
|
->where('deleted_at', null)
|
|
->delete();
|
|
}
|
|
}
|
|
|
|
|
|
// Handle operating hours exceptions
|
|
if (isset($input['outlet_operating_hours_exceptions']) && is_array($input['outlet_operating_hours_exceptions'])) {
|
|
$existingExceptions = $this->outletOperatingHoursExceptions
|
|
->where('outlet_id', $id)
|
|
->where('deleted_at', null)
|
|
->findAll();
|
|
|
|
$existingExceptionKeys = [];
|
|
foreach ($existingExceptions as $ex) {
|
|
$key = $ex['date'].'|'.$ex['start_time'].'|'.$ex['end_time'];
|
|
$existingExceptionKeys[$key] = $ex['id'];
|
|
}
|
|
|
|
$updatedExceptionIds = [];
|
|
foreach ($input['outlet_operating_hours_exceptions'] as $exception) {
|
|
$exceptionData = [
|
|
'outlet_id' => $id,
|
|
'date' => $exception['date'],
|
|
'start_time' => $exception['start_time'],
|
|
'end_time' => $exception['end_time'],
|
|
'notes' => $exception['notes'] ?? null,
|
|
'updated_at' => date('Y-m-d H:i:s')
|
|
];
|
|
|
|
$compositeKey = $exception['date'].'|'.$exception['start_time'].'|'.$exception['end_time'];
|
|
|
|
if (isset($existingExceptionKeys[$compositeKey])) {
|
|
$exceptionData['id'] = $existingExceptionKeys[$compositeKey];
|
|
$this->outletOperatingHoursExceptions->save($exceptionData);
|
|
$updatedExceptionIds[] = $exceptionData['id'];
|
|
} else {
|
|
$exceptionData['created_at'] = date('Y-m-d H:i:s');
|
|
$newId = $this->outletOperatingHoursExceptions->insert($exceptionData);
|
|
$updatedExceptionIds[] = $newId;
|
|
}
|
|
}
|
|
|
|
// Soft delete removed exceptions
|
|
foreach ($existingExceptions as $existingException) {
|
|
if (!in_array($existingException['id'], $updatedExceptionIds)) {
|
|
$this->outletOperatingHoursExceptions
|
|
->where('id', $existingException['id'])
|
|
->set(['deleted_at' => date('Y-m-d H:i:s')])
|
|
->update();
|
|
}
|
|
}
|
|
}
|
|
|
|
// Commit transaction
|
|
$this->db->transCommit();
|
|
|
|
// Prepare response
|
|
$result = [
|
|
'outlet' => array_merge($outlet_data, ['id' => $id]),
|
|
'outlet_tax' => $input['outlet_tax'] ?? [],
|
|
'outlet_images' => $images['outlet_images'] ?? [],
|
|
'outlet_operating_days' => $input['outlet_operating_days'] ?? [],
|
|
'outlet_operating_hours' => $input['outlet_operating_hours'] ?? [],
|
|
'outlet_operating_hours_exceptions' => $input['outlet_operating_hours_exceptions'] ?? []
|
|
];
|
|
|
|
return $this->respond(['status' => 200, 'result' => $result]);
|
|
|
|
} catch (\Exception $e) {
|
|
$this->db->transRollback();
|
|
return $this->respond(['status' => 400, 'message' => 'Failed to update outlet: ' . $e->getMessage()]);
|
|
}
|
|
}
|
|
|
|
public function delete($id = null)
|
|
{
|
|
$outlet = $this->outlet->find($id);
|
|
|
|
if(empty($outlet)){
|
|
return $this->respond(['status' => 400, 'result' => 'No outlet data found.']);
|
|
}
|
|
|
|
$this->outlet->delete($id);
|
|
$this->outletTax->where('outlet_id', $id)->delete();
|
|
$this->outletOperatingDays->where('outlet_id', $id)->delete();
|
|
$this->outletOperatingHours->where('outlet_id', $id)->delete();
|
|
$this->outletOperatingHoursExceptions->where('outlet_id', $id)->delete();
|
|
|
|
return $this->respond(['status' => 200, 'result' => 'Outlet deleted successfully.']);
|
|
}
|
|
|
|
public function updatePassword($id = null)
|
|
{
|
|
$outlet = $this->outlet->find($id);
|
|
|
|
if(empty($outlet)){
|
|
return $this->respond(['status' => 400, 'result' => 'No outlet data found.']);
|
|
}
|
|
|
|
$password = $this->request->getVar('password');
|
|
|
|
$this->outlet->update($id, ['password' => md5(md5($password))]);
|
|
|
|
return $this->respond(['status' => 200, 'result' => 'Outlet password updated successfully.']);
|
|
}
|
|
|
|
public function addBulk()
|
|
{
|
|
$rules = [
|
|
'outlet_ids' => 'required|is_array',
|
|
'menu_item_ids' => 'required|is_array',
|
|
];
|
|
|
|
if (!$this->validate($rules)) {
|
|
return $this->failValidationErrors($this->validator->getErrors());
|
|
}
|
|
|
|
$outletIds = $this->request->getVar('outlet_ids');
|
|
$menuItemIds = $this->request->getVar('menu_item_ids');
|
|
|
|
$insertData = [];
|
|
$insertCount = 0;
|
|
$restoreCount = 0;
|
|
|
|
foreach ($outletIds as $outletId) {
|
|
foreach ($menuItemIds as $menuItemId) {
|
|
$exists = $this->outlet_menu
|
|
->withDeleted() // include soft deleted to detect them
|
|
->where('outlet_id', $outletId)
|
|
->where('menu_item_id', $menuItemId)
|
|
->first();
|
|
|
|
if (!$exists) {
|
|
$insertData[] = [
|
|
'outlet_id' => $outletId,
|
|
'menu_item_id' => $menuItemId,
|
|
];
|
|
$insertCount++;
|
|
} elseif (!empty($exists['deleted_at'])) {
|
|
// Restore if it was soft deleted
|
|
$this->outlet_menu
|
|
->update($exists['id'], ['deleted_at' => null]);
|
|
$restoreCount++;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!empty($insertData)) {
|
|
$this->outlet_menu->insertBatch($insertData);
|
|
}
|
|
|
|
return $this->respond([
|
|
'status' => 200,
|
|
'message' => "Menu items added to outlets successfully.",
|
|
'added' => $insertCount,
|
|
'restored' => $restoreCount
|
|
]);
|
|
}
|
|
|
|
public function deleteBulk()
|
|
{
|
|
$rules = [
|
|
'outlet_ids' => 'required|is_array',
|
|
'menu_item_ids' => 'required|is_array',
|
|
];
|
|
|
|
if (!$this->validate($rules)) {
|
|
return $this->failValidationErrors($this->validator->getErrors());
|
|
}
|
|
|
|
$outletIds = $this->request->getVar('outlet_ids');
|
|
$menuItemIds = $this->request->getVar('menu_item_ids');
|
|
|
|
$deleteCount = 0;
|
|
|
|
foreach ($outletIds as $outletId) {
|
|
// Soft delete only the specified menu items for each outlet
|
|
$deleteCount += $this->outlet_menu
|
|
->where('outlet_id', $outletId)
|
|
->whereIn('menu_item_id', $menuItemIds)
|
|
->delete(); // soft delete because model usesSoftDeletes = true
|
|
}
|
|
|
|
return $this->respond([
|
|
'status' => 200,
|
|
'message' => "Outlet menus deleted successfully.",
|
|
'deleted' => $deleteCount,
|
|
'outlets_processed' => count($outletIds),
|
|
'menu_items_processed' => count($menuItemIds)
|
|
]);
|
|
}
|
|
|
|
|
|
|
|
}
|