427 lines
19 KiB
PHP
427 lines
19 KiB
PHP
<?
|
|
namespace App\Services;
|
|
|
|
use App\Models\CartItems;
|
|
use App\Models\MenuItemVariations;
|
|
use App\Models\CartItemOptions;
|
|
use App\Models\Carts;
|
|
use App\Models\MenuItems;
|
|
use App\Models\OutletMenus;
|
|
use App\Models\OutletTax;
|
|
use App\Models\SettingTax;
|
|
use CodeIgniter\Database\Config;
|
|
use App\Models\MenuItemOptionsGroups;
|
|
use App\Models\OptionsGroups;
|
|
use App\Models\VariationOptionsGroups;
|
|
use App\Services\PromoService;
|
|
use App\Models\Options;
|
|
|
|
class CartService
|
|
{
|
|
private $db;
|
|
private $cart_items;
|
|
private $variations;
|
|
private $options;
|
|
private $carts;
|
|
private $menu_items;
|
|
private $outlet_menus;
|
|
private $outlet_tax;
|
|
private $setting_tax;
|
|
private $cart_item_options;
|
|
private $menu_item_options_groups;
|
|
private $option_groups;
|
|
private $menu_item_variations;
|
|
private $variation_options_groups;
|
|
|
|
private $promo_service;
|
|
|
|
public function __construct()
|
|
{
|
|
$this->cart_items = new CartItems();
|
|
$this->variations = new MenuItemVariations();
|
|
$this->options = new Options();
|
|
$this->carts = new Carts();
|
|
$this->menu_items = new MenuItems();
|
|
$this->outlet_menus = new OutletMenus();
|
|
$this->outlet_tax = new OutletTax();
|
|
$this->setting_tax = new SettingTax();
|
|
$this->cart_item_options = new CartItemOptions();
|
|
$this->menu_item_options_groups = new MenuItemOptionsGroups();
|
|
$this->option_groups = new OptionsGroups();
|
|
$this->menu_item_variations = new MenuItemVariations();
|
|
$this->variation_options_groups = new VariationOptionsGroups();
|
|
|
|
$this->db = Config::connect();
|
|
|
|
}
|
|
|
|
public function addCartItem($customer_id, $outlet_id, $existing_cart, $menu_item_id, $variation_id, $option_group, $quantity, $type = null) {
|
|
// If no cart, create one
|
|
if (!$existing_cart) {
|
|
$cartData = [
|
|
'customer_id' => $customer_id,
|
|
'outlet_id' => $outlet_id,
|
|
'status' => 'active',
|
|
'item_count' => 0,
|
|
'subtotal_amount' => 0,
|
|
'discount_amount' => 0,
|
|
'tax_amount' => 0,
|
|
'grand_total' => 0,
|
|
'promo_code_id' => 0,
|
|
'promo_discount_amount' => 0,
|
|
'customer_voucher_list_id' => 0,
|
|
'voucher_discount_amount' => 0,
|
|
'created_at' => date('Y-m-d H:i:s'),
|
|
];
|
|
|
|
$cartId = $this->carts->insert($cartData);
|
|
if (!$cartId) {
|
|
return ['status' => 400, 'message' => "Failed to create cart."];
|
|
}
|
|
|
|
$existing_cart = $this->carts->find($cartId);
|
|
}
|
|
$cart = $existing_cart;
|
|
|
|
$this->db->transStart();
|
|
try {
|
|
|
|
//check outlet menu
|
|
$menuAvailable = $this->outlet_menus->where([
|
|
'menu_item_id' => $menu_item_id,
|
|
'outlet_id' => $outlet_id
|
|
])->first();
|
|
|
|
if (!$menuAvailable) {
|
|
return ['status' => 400, 'message' => 'This menu is not available for this outlet!'];
|
|
}
|
|
|
|
$menu_variation = $this->menu_item_variations->where('menu_item_id', $menu_item_id)->findAll();
|
|
|
|
if(($variation_id == 0 || $variation_id == null) && !empty($menu_variation)){ //make variation required
|
|
return ['status' => 400, 'message' => 'Please select a variation!'];
|
|
}
|
|
|
|
$required_groups = $this->getRequiredOptionGroups($menu_item_id, $variation_id);
|
|
|
|
// Validate that required options are provided
|
|
if (!empty($required_groups)) {
|
|
if (empty($option_group)) {
|
|
return ['status' => 400, 'message' => 'Required options are missing'];
|
|
}
|
|
|
|
$provided_group_ids = array_map(function ($opt) {
|
|
if (!is_object($opt)) {
|
|
$opt = (object) $opt;
|
|
}
|
|
return $opt->group_id;
|
|
}, $option_group);
|
|
|
|
foreach ($required_groups as $group) {
|
|
if (!in_array($group['id'], $provided_group_ids)) {
|
|
return ['status' => 400, 'message' => 'Required option group ' . $group['title'] . ' is missing'];
|
|
}
|
|
}
|
|
}
|
|
|
|
//Check if the new item is same with old item then update quantity
|
|
$options_match = false;
|
|
$existing_cart_item = $this->cart_items
|
|
->where('cart_id', $cart['id'])
|
|
->where('menu_item_id', $menu_item_id)
|
|
->where('variation_id', $variation_id)
|
|
->first();
|
|
if($type != 'free_item'){
|
|
if ($existing_cart_item) {
|
|
if(($type == 'pwp' && $existing_cart_item['is_pwp'] == true) || $type != 'pwp'){
|
|
// Check if options match
|
|
$options_match = true;
|
|
|
|
if (!empty($option_group)) {
|
|
// Get existing options for this cart item
|
|
$existing_options = $this->cart_item_options
|
|
->where('cart_item_id', $existing_cart_item['id'])
|
|
->findAll();
|
|
|
|
// Convert existing options to comparable format
|
|
$existing_option_ids = [];
|
|
foreach ($existing_options as $opt) {
|
|
if (!isset($existing_option_ids[$opt['option_group_id']])) {
|
|
$existing_option_ids[$opt['option_group_id']] = [];
|
|
}
|
|
$existing_option_ids[$opt['option_group_id']][] = $opt['option_id'];
|
|
}
|
|
|
|
// Convert new options to comparable format
|
|
$new_option_ids = [];
|
|
foreach ($option_group as $opt) {
|
|
if (!is_object($opt)) {
|
|
$opt = (object) $opt;
|
|
}
|
|
$new_option_ids[$opt->group_id] = $opt->option_ids;
|
|
}
|
|
|
|
// Compare options
|
|
if ($existing_option_ids != $new_option_ids) {
|
|
$options_match = false;
|
|
}
|
|
} else {
|
|
// If no options in request but existing item has options
|
|
$has_existing_options = $this->cart_item_options
|
|
->where('cart_item_id', $existing_cart_item['id'])
|
|
->countAllResults() > 0;
|
|
|
|
if ($has_existing_options) {
|
|
$options_match = false;
|
|
}
|
|
}
|
|
|
|
if ($options_match) {
|
|
// Update quantity of existing item
|
|
$new_quantity = $existing_cart_item['quantity'] + $quantity;
|
|
$new_line_subtotal = $existing_cart_item['unit_price'] * $new_quantity;
|
|
|
|
$this->cart_items->update($existing_cart_item['id'], [
|
|
'quantity' => $new_quantity,
|
|
'line_subtotal' => $new_line_subtotal
|
|
]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// echo($variation_id);exit;
|
|
if (!$options_match) {
|
|
if ($variation_id == 0) {
|
|
$menu_item = $this->menu_items->where('status', 'active')->find($menu_item_id);
|
|
if (empty($menu_item)) {
|
|
return ['status' => 400, 'message' => "Menu Item not found!"];
|
|
}
|
|
|
|
$basePrice = $menu_item['price'];
|
|
|
|
$order_index = $this->cart_items->withDeleted()->where('cart_id', $cart['id'])->countAllResults();
|
|
|
|
// Insert cart item
|
|
$line_subtotal = $basePrice * $quantity;
|
|
|
|
$add_cart_detail = [
|
|
'cart_id' => $cart['id'],
|
|
'menu_item_id' => $menu_item_id,
|
|
'variation_id' => 0,
|
|
'title' => $menu_item['title'],
|
|
'unit_price' => $basePrice,
|
|
'quantity' => $quantity,
|
|
'line_subtotal' => $line_subtotal,
|
|
'order_index' => $order_index,
|
|
];
|
|
|
|
if($type == 'free_item'){
|
|
$add_cart_detail = [
|
|
'cart_id' => $cart['id'],
|
|
'menu_item_id' => $menu_item_id,
|
|
'variation_id' => 0,
|
|
'title' => $menu_item['title'],
|
|
'unit_price' => 0,
|
|
'quantity' => $quantity,
|
|
'line_subtotal' => 0,
|
|
'order_index' => $order_index,
|
|
'is_free_item' => 1
|
|
];
|
|
}
|
|
|
|
if($type == 'pwp'){
|
|
$add_cart_detail = [
|
|
'cart_id' => $cart['id'],
|
|
'menu_item_id' => $menu_item_id,
|
|
'variation_id' => 0,
|
|
'title' => $menu_item['title'],
|
|
'unit_price' => $menu_item['pwp_price'],
|
|
'quantity' => $quantity,
|
|
'line_subtotal' => $menu_item['pwp_price'] * $quantity,
|
|
'order_index' => $order_index,
|
|
'is_pwp' => true
|
|
];
|
|
}
|
|
|
|
// print_r($add_cart_detail);exit;
|
|
|
|
$cart_item_id = $this->cart_items->insert($add_cart_detail);
|
|
|
|
$existingGroupIds = getColumnValues($this->menu_item_options_groups, 'menu_item_id', $menu_item_id, 'option_group_id');
|
|
|
|
if (!empty($option_group)) {
|
|
foreach ($option_group as $opt) {
|
|
if (!is_object($opt)) {
|
|
$opt = (object) $opt;
|
|
}
|
|
$option_group_id = $opt->group_id;
|
|
$option_ids = $opt->option_ids;
|
|
|
|
if (in_array($option_group_id, $existingGroupIds)) {
|
|
$option_groups = $this->option_groups->find($option_group_id);
|
|
$option_num = count($option_ids);
|
|
|
|
if (!empty($option_groups)) {
|
|
if ($option_num >= $option_groups['min_quantity'] && $option_num <= $option_groups['max_quantity']) {
|
|
foreach ($option_ids as $key => $value) {
|
|
$option_selected = $this->options->where('option_group_id', $option_group_id)->find($value);
|
|
if (empty($option_selected)) {
|
|
return ['status' => 400, 'message' => 'No option selected !'];
|
|
}
|
|
$option_data = [
|
|
'cart_item_id' => $cart_item_id,
|
|
'option_id' => $value,
|
|
'option_group_id' => $option_group_id,
|
|
'option_title' => $option_selected['title'],
|
|
'price_adjustment' => $option_selected['price_adjustment']
|
|
];
|
|
|
|
$this->cart_item_options->insert($option_data);
|
|
}
|
|
} else {
|
|
return ['status' => 400, 'message' => 'Please select correct quantity for option!'];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
$menu_item = $this->menu_items->where('status', 'active')->find($menu_item_id);
|
|
if (empty($menu_item)) {
|
|
return ['status' => 400, 'message' => "Menu Item not found!"];
|
|
}
|
|
|
|
$menu_variation = $this->menu_item_variations->withDeleted()->find($variation_id);
|
|
if (empty($menu_variation)) {
|
|
return ['status' => 400, 'message' => "Menu Variation not found!"];
|
|
}
|
|
|
|
$item_price = $menu_variation['price'];
|
|
|
|
$order_index = $this->cart_items->withDeleted()->where('cart_id', $cart['id'])->countAllResults();
|
|
|
|
$line_subtotal = $item_price * $quantity;
|
|
|
|
$add_cart_detail = [
|
|
'cart_id' => $cart['id'],
|
|
'menu_item_id' => $menu_item_id,
|
|
'variation_id' => $variation_id,
|
|
'title' => $menu_item['title'],
|
|
'unit_price' => $item_price,
|
|
'quantity' => $quantity,
|
|
'line_subtotal' => $line_subtotal,
|
|
'order_index' => $order_index,
|
|
];
|
|
|
|
if($type == 'free_item'){
|
|
$add_cart_detail = [
|
|
'cart_id' => $cart['id'],
|
|
'menu_item_id' => $menu_item_id,
|
|
'variation_id' => $variation_id,
|
|
'title' => $menu_item['title'],
|
|
'unit_price' => 0,
|
|
'quantity' => $quantity,
|
|
'line_subtotal' => 0,
|
|
'order_index' => $order_index,
|
|
'is_free_item' => 1
|
|
];
|
|
}
|
|
|
|
if($type == 'pwp'){
|
|
$add_cart_detail = [
|
|
'cart_id' => $cart['id'],
|
|
'menu_item_id' => $menu_item_id,
|
|
'variation_id' => $variation_id,
|
|
'title' => $menu_item['title'],
|
|
'unit_price' => $menu_item['pwp_price'],
|
|
'quantity' => $quantity,
|
|
'line_subtotal' => $menu_item['pwp_price'] * $quantity,
|
|
'order_index' => $order_index,
|
|
'is_pwp' => true
|
|
];
|
|
}
|
|
|
|
$cart_item_id = $this->cart_items->insert($add_cart_detail);
|
|
|
|
if ($menu_variation) {
|
|
$existing_variation_option_group = getColumnValues($this->variation_options_groups, 'variation_id', $variation_id, 'option_group_id');
|
|
if (!empty($option_group)) {
|
|
foreach ($option_group as $opt) {
|
|
if (!is_object($opt)) {
|
|
$opt = (object) $opt;
|
|
}
|
|
$option_group_id = $opt->group_id;
|
|
$option_ids = $opt->option_ids;
|
|
|
|
if (in_array($option_group_id, $existing_variation_option_group)) {
|
|
$option_groups = $this->option_groups->find($option_group_id);
|
|
$option_num = count($option_ids);
|
|
|
|
if (!empty($option_groups)) {
|
|
if ($option_num >= $option_groups['min_quantity'] && $option_num <= $option_groups['max_quantity']) {
|
|
foreach ($option_ids as $key => $value) {
|
|
$option_selected = $this->options->where('option_group_id', $option_group_id)->where('id', $value)->first();
|
|
if (empty($option_selected)) {
|
|
return ['status' => 400, 'message' => 'No option selected !'];
|
|
}
|
|
$option_data = [
|
|
'cart_item_id' => $cart_item_id,
|
|
'option_id' => $value,
|
|
'option_group_id' => $option_group_id,
|
|
'option_title' => $option_selected['title'],
|
|
'price_adjustment' => $option_selected['price_adjustment']
|
|
];
|
|
|
|
$this->cart_item_options->insert($option_data);
|
|
}
|
|
} else {
|
|
return ['status' => 400, 'message' => 'Please select correct quantity for option!'];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
return ['status' => 400, 'message' => 'No variation found!'];
|
|
}
|
|
}
|
|
}
|
|
|
|
// $total = $this->calculateCartTotals($cart['id'], $cart['outlet_id']);
|
|
|
|
|
|
$this->db->transComplete();
|
|
|
|
return [
|
|
'status' => 200,
|
|
'message' => 'Item added to cart successfully.',
|
|
'data' => ['cart_id' => $cart['id']]
|
|
];
|
|
} catch (\Exception $e) {
|
|
$this->db->transRollback();
|
|
return ['status' => 400, 'message' => "Something went wrong: " . $e];
|
|
}
|
|
}
|
|
|
|
public function getRequiredOptionGroups($menu_item_id, $variation_id)
|
|
{
|
|
if ($variation_id == 0) {
|
|
$existingGroupIds = getColumnValues($this->menu_item_options_groups, 'menu_item_id', $menu_item_id, 'option_group_id');
|
|
} else {
|
|
$existingGroupIds = getColumnValues($this->variation_options_groups, 'variation_id', $variation_id, 'option_group_id');
|
|
}
|
|
|
|
if(!empty($existingGroupIds)){
|
|
$data = $this->option_groups
|
|
->whereIn('id', $existingGroupIds)
|
|
->where('is_required', 1)
|
|
->findAll();
|
|
} else {
|
|
$data = [];
|
|
}
|
|
return $data;
|
|
|
|
}
|
|
|
|
}
|