'EDIT PERMIT',4=>'VIEW PERMIT',5=>'ADMIN PERMIT'); /** * @var CakeRequest|mixed|string|null */ public $permissionErrors = [ 'ADD_PERMISSION_FAILED' => [ 'code' => "050", 'message' => 'Can not add permission for the group!' ], 'RESTRICTION_MODE_REQUIRED' => [ 'code' => "051", 'message' => 'Please enable Restriction Mode before performing this action.' ], 'UNAUTHORIZED_ACCESS' => [ 'code' => "052", 'message' => 'You are not authorized to this page.' ], 'DUPLICATE_OR_INVALID_EMAIL' => [ 'code' => "053", 'message' => 'Error: Duplicate or invalid email found.' ], 'INVALID_EMAIL_MODIFY' => [ 'code' => "054", 'message' => 'Invalid email in modifyPermissions.' ], 'MAX_PERMISSION_LIMIT_EXCEEDED' => [ 'code' => "055", 'message' => 'Error: Total Permission can not be more than 15.' ], 'INVALID_EMAIL_DELETE' => [ 'code' => "056", 'message' => 'Invalid email in deletePermissions.' ] ]; private $restrictionStatuses = [ 'EXPENSE_NOT_FOUND' => [ 'code' => "061", 'message' => 'Error: Expense not found.' ], 'MODE_ADD_FAILED' => [ 'code' => "062", 'message' => 'Error: Can not possible to add mode for this group!' ], 'ONLY_CREATOR_CAN_CHANGE' => [ 'code' => "063", 'message' => 'Error: Only creator can change the mode.' ], 'DELETE_PERMISSIONS_FIRST' => [ 'code' => "064", 'message' => 'Error: Need to delete all the permissions.' ] ]; private $validation_status = "-1"; private $database_error_status = "007"; public function beforeRender() { parent::beforeRender(); } private function getCategories() { $category = array( array("id" => "1", "name" => "Books/Magazines", "type" => "1"), array("id" => "2", "name" => "Car & Transportation", "type" => "1"), array("id" => "3", "name" => "Charities", "type" => "1"), array("id" => "4", "name" => "Child care", "type" => "1"), array("id" => "5", "name" => "Clothing", "type" => "1"), array("id" => "6", "name" => "Debt Interest", "type" => "1"), array("id" => "7", "name" => "Debt Reduction", "type" => "1"), array("id" => "8", "name" => "Education/Tution Fee", "type" => "1"), array("id" => "9", "name" => "Events", "type" => "1"), array("id" => "10", "name" => "Food", "type" => "1"), array("id" => "11", "name" => "General Expense", "type" => "1"), array("id" => "12", "name" => "Gifts", "type" => "1"), array("id" => "13", "name" => "Household Items/Supplies", "type" => "1"), array("id" => "14", "name" => "Household Repairs", "type" => "1"), array("id" => "15", "name" => "Income/Other Tax", "type" => "1"), array("id" => "16", "name" => "Insurance", "type" => "1"), array("id" => "17", "name" => "Lending", "type" => "1"), array("id" => "18", "name" => "Medical/Health", "type" => "1"), array("id" => "19", "name" => "Mortgage", "type" => "1"), array("id" => "20", "name" => "Others", "type" => "1"), array("id" => "21", "name" => "Personal", "type" => "1"), array("id" => "22", "name" => "Pet Food/Treats", "type" => "1"), array("id" => "23", "name" => "Recreation and Fitness", "type" => "1"), array("id" => "24", "name" => "Rent", "type" => "1"), array("id" => "25", "name" => "Savings", "type" => "1"), array("id" => "26", "name" => "Sports", "type" => "1"), array("id" => "27", "name" => "Utilities", "type" => "1"), array("id" => "28", "name" => "Vacation", "type" => "1"), array("id" => "29", "name" => "Bank Interest", "type" => "2"), array("id" => "30", "name" => "Borrowing", "type" => "2"), array("id" => "31", "name" => "Business", "type" => "2"), array("id" => "32", "name" => "Consultancy", "type" => "2"), array("id" => "33", "name" => "Contract", "type" => "2"), array("id" => "34", "name" => "Lending Back", "type" => "2"), array("id" => "35", "name" => "Others", "type" => "2"), array("id" => "36", "name" => "Personal", "type" => "2"), array("id" => "37", "name" => "Rent", "type" => "2"), array("id" => "38", "name" => "Salary", "type" => "2"), array("id" => "39", "name" => "Stock Market/Divident", "type" => "2"), array("id" => "40", "name" => "Transport Business", "type" => "2") ); return $category; } function index() { $this->layout = "visitor"; $urlLArray = explode('/', $this->here); $uniqueURL = end($urlLArray); $expenseType = substr($uniqueURL, 0, 1); $this->Session->write("current_unique_url", $uniqueURL); $skipMobileOption = $this->Session->read("skip_mobile_option"); if ($this->Session->check("skip_mobile_option")) { $this->Session->delete("skip_mobile_option"); } $this->set('unique_url', $uniqueURL); //if the request comes from mobile device then forward it to the mobile controller $detect = new MobileDetectComponent(); if ($detect->isMobile() && $skipMobileOption != "yes") { $this->redirect(array('controller' => 'm', 'action' => '/')); exit; } else { if ($expenseType == "1" || $expenseType == "2" || $expenseType == "3") { $this->render('expense'); } else { $this->render('expense_demo'); } } } function loadTab($uniqueURL) { $expenseType = ""; $this->layout = ""; $expense_creator = ""; $just_created_new = false; if ($this->Session->check('just_created')) { $this->set("justCreated", $this->Session->read('just_created')); $this->Session->delete("just_created"); $just_created_new = true; } else { $this->set("justCreated", ""); } if (isset($uniqueURL) && $uniqueURL != "") { $expenseType = trim(substr($uniqueURL, 0, 1)); if ($expenseType == "1" || $expenseType == "2") { $data = $this->Expense->getGroupExpenseInfoByURL($uniqueURL); if (empty($data)) { $this->loadModel("Backup"); $this->Backup->restore($uniqueURL); $data = $this->Expense->getGroupExpenseInfoByURL($uniqueURL); } } else if ($expenseType == "3") { $data = $this->Expense->getFamilyExpenseInfoByURL($uniqueURL); if (empty($data)) { $this->loadModel("Backup"); $this->Backup->restore($uniqueURL); $data = $this->Expense->getFamilyExpenseInfoByURL($uniqueURL); } if (!empty($data)) { $data["Category"] = $this->getCategories(); } } if ( !$this->Session->check('Config.language') && !$this->Cookie->check('Config.expcount.language') ) { $this->Session->write("Config.language", $data["Expense"]["language"]); $this->Cookie->write("Config.expcount.language", $data["Expense"]["language"]); } if (!empty($data)) { $expense_creator = $data["Expense"]["create_user"]; //insert data into the table access_infos $accessInfoData["id"] = $data["Expense"]["id"]; $accessInfoData["unique_url"] = $data["Expense"]["unique_url"]; $accessInfoData["access_time"] = $this->getSystemCurrentTimeStamp(); $error = $this->AccessInfo->saveAccessInfo($accessInfoData); //insert loading history $loginHistory['expense_id'] = $accessInfoData["id"]; $loginHistory['unique_url'] = $accessInfoData["unique_url"]; $loginHistory['ip'] = $this->getClientIp(); $loginHistory['user_agent'] = $this->getUserAgent();; $loginHistory['create_date'] = $accessInfoData["access_time"]; $error = $this->LoadingHistory->insertLoadingHistory($loginHistory); $data['Permissions'] = []; $data['restricted_mode'] = 0; $user = $this->User->getUserByProfileId($data['Expense']['create_user']); // get owner/creator info if(!empty($user['User'])) { $permission_result[] = [ 'user_id' => $user['User']['id'], 'email' => $user['User']['profile_id'], 'role' => OWNER ]; $group_setting = $this->GroupSetting->getGroupSettingByURL($uniqueURL); if (!empty($group_setting)) { $permissions = $this->PermissionTable->getPermissionByUrl($uniqueURL); foreach ($permissions as $key => $value) { $permission['user_id'] = $value['user_id']; $permission['email'] = $value['profile_id']; $permission['role'] = $value['role']; $permission_result[$key + 1] = $permission; } $data['restricted_mode'] = $group_setting['is_restricted_mode']; } $data['Permissions'] = $permission_result; } $is_permission_visible = (!empty($data['Expense']['create_user']) && $data['Expense']['create_user'] != 'system') || ((!empty($data['Expense']['user_id']) && $data['Expense']['user_id'] > 0)); $this->set('is_permission_visible',$is_permission_visible); $this->set("expenseData", json_encode($data)); /* $loginHistory["expense_id"] = $data["Expense"]["id"]; $loginHistory["remote_ip"] = $_SERVER['REMOTE_ADDR']; if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])){ $loginHistory["forward_ip"] = $_SERVER['HTTP_X_FORWARDED_FOR']; } else { $loginHistory["forward_ip"] = ""; } $loginHistory["country"] = "";//ip_info($loginHistory["remote_ip"], "Country Code"); //$userLocation = ip_info($loginHistory["remote_ip"], "Location"); $loginHistory["location"] = "";//$userLocation["city"].",".$userLocation["state"]; $loginHistory["is_login"] = "0"; $loginHistory["user_id"] = ""; $loginHistory["source"] = $_SERVER['HTTP_USER_AGENT']; */ } } $this->set("uniqueURL", $uniqueURL); $this->set('permissions', $this->permission); $this->set('operation_type',$this->operation_type); //set relevant view if ($expenseType == "1") { $this->loadGroupExpense($uniqueURL,$expense_creator); } else if ($expenseType == "2") { $this->loadMessExpense($uniqueURL,$expense_creator); } else if ($expenseType == "3") { $this->loadFamilyExpense($uniqueURL,$expense_creator); } else { $this->loadNotFound(); } if ($just_created_new == true) { if ($this->Session->check('just_created_email')) { $data['Expense']["email"] = $this->Session->read('just_created_email'); $this->sendInstantEmail($data['Expense']); } } } function loadTabDemo($uniqueURL) { $this->layout = ""; if ($this->Session->check('just_created')) { $this->set("justCreated", $this->Session->read('just_created')); $this->Session->delete("just_created"); } else { $this->set("justCreated", ""); } if (isset($uniqueURL) && $uniqueURL != "") { $expenseType = substr($uniqueURL, 0, 1); if ($expenseType == "6" || $expenseType == "7") { $demoData = $this->DemoExpense->getDemoGroupExpenseInfoByURL($uniqueURL); $data["Expense"] = $demoData["DemoExpense"]; $data["Participant"] = $demoData["DemoParticipant"]; $data["GroupExpense"] = $demoData["DemoGroupExpense"]; if ($expenseType == "7") { $data["Meal"] = $demoData["DemoMeal"]; } } else if ($expenseType == "8") { $demodata = $this->DemoExpense->getDemoFamilyExpenseInfoByURL($uniqueURL); $data["Expense"] = $demodata["DemoExpense"]; $data["FamilyExpense"] = $demodata["DemoFamilyExpense"]; $data["Category"] = $this->getCategories(); } if ( !$this->Session->check('Config.language') && !$this->Cookie->check('Config.expcount.language') ) { $this->Session->write("Config.language", $data["Expense"]["language"]); $this->Cookie->write("Config.expcount.language", $data["Expense"]["language"]); } if (!empty($data)) { $this->set("expenseData", json_encode($data)); $loginHistory["expense_id"] = $data["Expense"]["id"]; $loginHistory["remote_ip"] = $_SERVER['REMOTE_ADDR']; if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { $loginHistory["forward_ip"] = $_SERVER['HTTP_X_FORWARDED_FOR']; } else { $loginHistory["forward_ip"] = ""; } $loginHistory["country"] = ""; //ip_info($loginHistory["remote_ip"], "Country Code"); //$userLocation = ip_info($loginHistory["remote_ip"], "Location"); $loginHistory["location"] = ""; //$userLocation["city"].",".$userLocation["state"]; $loginHistory["is_login"] = "0"; $loginHistory["user_id"] = ""; $loginHistory["source"] = $_SERVER['HTTP_USER_AGENT']; } if ($expenseType == "6") { $this->loadGroupExpenseDemo(); } else if ($expenseType == "7") { $this->loadMessExpenseDemo(); } else if ($expenseType == "8") { $this->loadFamilyExpenseDemo(); } else { $this->loadNotFound(); } } } public function testFirebase() { $this->updateFirebase(); } public function loadNotFound() { } public function sendEmail() { if ($this->request->is('ajax')) { $data = array(); $data["email"] = $this->data["Expense"]["email"]; $data["expense_title"] = $this->data["Expense"]["emailExpenseTitle"]; $data["unique_url"] = $this->data["Expense"]["emailUniqueURL"]; $this->sendEmailMethod($data); } exit; } public function sendMyExpenseEmail() { if ($this->request->is('ajax')) { $data = array(); $data["email"] = $this->data["email"]; $data["expense_title"] = $this->data["expense_title"]; $data["unique_url"] = $this->data["unique_url"]; $this->sendEmailMethod($data); } exit; } public function sendInstantEmail($value) { $emailData = array(); $emailData["expense_title"] = $value["title"]; $emailData["unique_url"] = $value["unique_url"]; $emailData["email"] = $value["email"]; //send email $this->sendEmailMethod($emailData); //insert into ExpenseEmail $inputData = array(); $inputData["unique_url"] = $value["unique_url"]; $inputData["email"] = $value["email"]; $inputData["title"] = $value["title"]; $inputData["count_email_attempt"] = 1; $this->loadModel('ExpenseEmail'); $this->ExpenseEmail->insertExpenseEmail($inputData); } public function sendEmailMethod($data) { //insert record into the table email_histories $emailHistory['unique_url'] = $data["unique_url"]; $emailHistory['sent_to'] = $data["email"]; $emailHistory['ip'] = $this->getClientIp(); $emailHistory['create_date'] = $this->getSystemCurrentTimeStamp(); $error = $this->EmailHistory->insertEmailHistory($emailHistory); $default = array( 'host' => Configure::read('expensecount.email.smtp.host'), 'port' => 587, 'auth' => 'plain', 'username' => Configure::read('expensecount.email.smtp.username'), 'password' => Configure::read('expensecount.email.smtp.password'), 'tsl' => false, 'transport' => 'Smtp', 'from' => array(Configure::read('expensecount.email.smtp.from') => 'ExpenseCount'), 'returnPath' => Configure::read('expensecount.email.smtp.from'), 'layout' => false, 'emailFormat' => 'html', //'template' => 'only_text', 'charset' => 'utf-8', 'headerCharset' => 'utf-8', ); App::uses('CakeEmail', 'Network/Email'); //echo $Email-> $Email = new CakeEmail($default); $Email->to($data["email"]); $Email->emailFormat('html'); $Email->template('email', null)->viewVars(array('data' => $data)); $Email->subject('ExpenseCount "' . $data["expense_title"] . '" '); $Email->replyTo(Configure::read('expensecount.email.smtp.from')); $Email->from(array(Configure::read('expensecount.email.smtp.from') => "ExpenseCount.com")); //$Email->smtpOptions = $default; $Email->delivery = 'Smtp'; try { $Email->send(); } catch (Exception $e) { } } public function sendHtmlEmail($dest = null, $aMsg = null) { $Email = new CakeEmail('gmail'); $Email->to($dest); $Email->emailFormat('html'); $Email->template('email')->viewVars(array('aMsg' => $aMsg)); $Email->subject('Email from ExpenseCount'); $Email->replyTo('admin@expensecount.com'); $Email->from('admin@gmail.com'); return; } public function changeGroupExpense() { if ($this->request->is('ajax')) { $profile_id = $this->Session->read('userData.profile_id'); $user_id = $this->Session->read('userData.id'); $data = array(); $option = $this->data["isAdd"]; $operation_key = 'add'; if (isset($this->data["expenseType"])) { $data["expense_type"] = $this->data["expenseType"]; } if (isset($this->data["advance"])) { $data["advance"] = $this->data["advance"]; if ($data["advance"] == 1) { $data["extras"] = substr_replace($this->data["extras"], "2", 0, 1); } else { $data["extras"] = substr_replace($this->data["extras"], "0", 0, 1); } } if ($option == "1" || $option == "2" || $option == "3") { $data["id"] = $this->data["id"]; $data["expense_id"] = $this->data["expenseId"]; $data["what"] = $this->data["expenseName"]; $data["expense_date"] = $this->data["expenseDate"]; $data["amount"] = $this->data["amount"]; $data["paid_by_participant_id"] = $this->data["paidBy"]; $data["participant_amount"] = $this->data["participantAmountStr"]; $data["isDetails"] = $this->data["isDetails"]; $data["isAdd"] = $this->data["isAdd"]; $data["type"] = $this->data["type"]; $data['images'] = $this->data["images"]; if ($data["isAdd"] == "1") { $data["is_reimbursement"] = $this->data["isreimburse"]; $data["expense_date_old"] = $this->getStrToIntDate($data["expense_date"]); $message = $this->GroupExpense->addGroupExpense($data); $operation = 'added'; $operation_key = 'add'; } else if ($data["isAdd"] == "2") { $data["is_reimbursement"] = $this->data["isreimburse"]; $data["previous_desc"] = $this->data["previousDesc"]; $data["new_desc"] = $this->data["newDesc"]; $data["previous_paid_by"] = $this->data["previousPaidBy"]; $data['changed_by'] = $profile_id; $data["expense_date_old"] = $this->getStrToIntDate($data["expense_date"]); $message = $this->GroupExpense->modifyGroupExpense($data); $operation = 'updated'; $operation_key = 'update'; } else if ($data["isAdd"] == "3") { $data["previous_desc"] = $this->data["previousDesc"]; $data["new_desc"] = $this->data["newDesc"]; $data['changed_by'] = $profile_id; $data["previous_paid_by"] = $this->data["previousPaidBy"]; $message = $this->GroupExpense->deleteGroupExpense($data); $operation = 'deleted'; $operation_key = 'delete'; if (!empty($this->data["images"])) { if ($this->data["expense_type"] == 1) { $this->group_expense = "GroupExpense"; } $deleted_image_response = $this->ImageUpload->DeleteSingleImageBucket($this->data["images"], $this->data['id'], $this->data["unique_url"], $this->group_expense, $this->data["images"]); } } else if ($data["isAdd"] == "4") { $uniqueURL = $this->data["expenseId"]; $data = $this->Expense->getGroupExpenseInfoByURL($uniqueURL); } } else if ($option == "5" || $option == "6" || $option == "7") { $data["id"] = $this->data["id"]; $data["expense_id"] = $this->data["expenseId"]; $data["date"] = $this->data["date"]; $data["isAdd"] = $this->data["isAdd"]; $data["meal_amount"] = $this->data["participantMealStr"]; if ($data["isAdd"] == "5") { $data["date_old"] = $this->getStrToIntDate($data["date"]); $message = $this->Meal->addMeal($data); $operation = 'added meal'; $operation_key = 'add_meal'; } else if ($data["isAdd"] == "6") { $data["old_date"] = $this->data["oldDate"]; $data["date_old"] = $this->getStrToIntDate($data["date"]); $message = $this->Meal->modifyMeal($data); $operation = 'updated meal'; $operation_key = 'update_meal'; } else if ($data["isAdd"] == "7") { $message = $this->Meal->deleteMeal($data); } else if ($data["isAdd"] == "4") { $uniqueURL = $this->data["expenseId"]; $data = $this->Expense->getGroupExpenseInfoByURL($uniqueURL); $operation = 'deleted meal'; $operation_key = 'delete_meal'; } } else if ($option == "8" || $option == "9" || $option == "10") { $data["id"] = $this->data["id"]; $data["expense_id"] = $this->data["expenseId"]; $data["record_type"] = $this->data["recordType"]; $data["what"] = $this->data["expenseName"]; $data["category"] = $this->data["expenseCategory"]; $data["expense_date"] = $this->data["expenseDate"]; $data["amount"] = $this->data["amount"]; $data['images'] = $this->data["images"]; $data["isAdd"] = $this->data["isAdd"]; $data["type"] = $this->data["type"]; if ($data["isAdd"] == "8") { $data["expense_date_old"] = $this->getStrToIntDate($data["expense_date"]); $message = $this->FamilyExpense->addFamilyExpense($data); $operation = 'added'; $operation_key = 'add'; } else if ($data["isAdd"] == "9") { $data["expense_date_old"] = $this->getStrToIntDate($data["expense_date"]); $message = $this->FamilyExpense->modifyFamilyExpense($data); $operation = 'updated'; $operation_key = 'update'; } else if ($data["isAdd"] == "10") { $message = $this->FamilyExpense->deleteFamilyExpense($data); $operation = 'deleted'; $operation_key = 'delete'; if (!empty($this->data["images"])) { $deleted_image_response = $this->ImageUpload->DeleteSingleImageBucket($this->data["images"], $this->data['id'], $this->data["unique_url"], $this->family_expense, $this->data["images"]); } } } if (empty($message)) { $expense = $this->Expense->find('first', array('conditions' => array('Expense.id' => $data["expense_id"]))); if (!empty($expense['Expense'])) { $expense['Expense']['version'] = $expense['Expense']['version'] + 1; $this->Expense->save($expense); $access_info["id"] = $expense['Expense']['id']; $access_info["unique_url"] = $expense['Expense']['unique_url']; $this->insertAccessInfo($access_info); $message['expenses'][$operation_key] = [$expense['Expense']['id']]; $this->sentNotificationToPermittedUsers($expense['Expense']['unique_url'],$operation,$expense['Expense']['title'],$message); } // update firebase version $this->updateFirebase($this->data['unique_url']); echo Configure::read('expensecount.form.validation.success'); } else { $errorMsg = ""; foreach ($message as $key => $value) { $errorMsg .= $key . Configure::read('expensecount.form.validation.pipe') . $value . Configure::read('expensecount.form.validation.separator'); } echo $errorMsg; } exit; } exit; } public function displayLog() { if ($this->request->is('ajax')) { $data = array(); $data["expense_id"] = $this->data["Expense"]["logExpenseId"]; $data["fromDate"] = $this->data["Expense"]["fromDate"]; $data["toDate"] = $this->data["Expense"]["toDate"]; // $data["expense_id"] = 14; $dbData = $this->GroupExpense->getGroupExpenseLog($data); echo json_encode($dbData); } exit; } function changeParticipant() { if ($this->request->is('ajax')) { $data = array(); $data["id"] = $this->data["id"]; $data["expense_id"] = $this->data["expense_id"]; $data["name"] = $this->data["name"]; $data["isAdd"] = $this->data["isAdd"]; // $fp = fopen("ajit.txt","a+"); // fwrite($fp, json_encode($this->data)); // fclose($fp); if ($data["isAdd"] == "1") { $message = $this->Participant->addParticipant($data); } else if ($data["isAdd"] == "2") { $message = $this->Participant->modifyParticipant($data); } else if ($data["isAdd"] == "3") { $message = $this->Participant->deleteParticpant($data); } if (empty($message)) { $expense = $this->Expense->find('first', array('conditions' => array('Expense.id' => $data["expense_id"]))); if (!empty($expense['Expense'])) { $expense['Expense']['version'] = $expense['Expense']['version'] + 1; $this->Expense->save($expense); $access_info["id"] = $expense['Expense']['id']; $access_info["unique_url"] = $expense['Expense']['unique_url']; $this->insertAccessInfo($access_info); } //update firebase version $this->updateFirebase($this->data['unique_url']); echo Configure::read('expensecount.form.validation.success'); } else { $errorMsg = ""; foreach ($message as $key => $value) { $errorMsg .= $key . Configure::read('expensecount.form.validation.pipe') . $value . Configure::read('expensecount.form.validation.separator'); } echo $errorMsg; } exit; } exit; } function loadGroupExpense($uniqueURL,$expense_creator) { $this->setPageUserInfo($uniqueURL,$expense_creator); $this->render('group_expenses'); } function loadMessExpense($uniqueURL,$expense_creator) { $this->setPageUserInfo($uniqueURL,$expense_creator); $this->render('mess_expenses'); } function loadFamilyExpense($uniqueURL,$expense_creator) { $this->setPageUserInfo($uniqueURL,$expense_creator); $this->render('family_expenses'); } public function getPermission($uniqueURL) { $permissionLevel = PUBLIC_PERMIT; $this->loadModel('GroupSettings'); // Fetch the group settings based on the unique URL $groupSettings = $this->GroupSettings->find('first', [ 'conditions' => ['GroupSettings.unique_url' => $uniqueURL] ]); // Check if permissions are set and not empty if (isset($groupSettings['GroupSettings']['permissions']) && !empty($groupSettings['GroupSettings']['permissions'])) { $permissionsArray = json_decode($groupSettings['GroupSettings']['permissions'], true); // If JSON decoding fails, return no permission if (json_last_error() !== JSON_ERROR_NONE) { return NO_PERMIT; } if (!empty($permissionsArray)) { $permissionLevel = NO_PERMIT; $sessionProfileId = $this->Session->read('userData.profile_id'); $sessionUserId = $this->Session->read('userData.id'); if ($sessionProfileId) { $indexPermitted = array_search($sessionUserId, array_column($permissionsArray, 'e'), true); if ($indexPermitted !== false) { // Check the permission level (1 = no permit, 2 = public, 3 = edit, 4 = view, 5 = admin) $permissionLevel = $permissionsArray[$indexPermitted]['p'] ?? NO_PERMIT; } else { $permissionLevel = NO_PERMIT; // Profile ID not found in permissions array } } else { $permissionLevel = NO_PERMIT; } } } return $permissionLevel; } private function setPageUserInfo($uniqueURL,$expense_creator) { $profile_id = $this->Session->read('userData.profile_id'); $user_id = $this->Session->read('userData.id'); $session_profile_id = !empty($profile_id) ? $profile_id : ''; $this->set('session_profile_id', $session_profile_id); $print_uid = !empty($user_id) ? $user_id : ''; $this->set('print_uid', $print_uid); if(!empty($expense_creator) && $expense_creator == $profile_id ){ $permission = ADMIN_PERMIT; }else{ $permission = $this->Permission->PermissionByUserId($uniqueURL, $print_uid); } $this->set('permissionLevel', (int)$permission); $isPermitted = ((int)$permission === PUBLIC_PERMIT || (int)$permission === EDIT_PERMIT || (int)$permission === ADMIN_PERMIT); $this->set('isPermitted', $isPermitted); $permission_permitted = ( (int)$permission === EDIT_PERMIT || (int)$permission === VIEW_PERMIT || (int)$permission === ADMIN_PERMIT); $this->set('permission_permitted', $permission_permitted); $permitted = ((int)$permission === ADMIN_PERMIT); $this->set('permitted', $permitted); $delete_permitted = ( (int)$permission === EDIT_PERMIT || (int)$permission === VIEW_PERMIT); $this->set('delete_permitted', $delete_permitted); } function loadGroupExpenseDemo() { $this->render('group_expenses_demo'); } function loadMessExpenseDemo() { $this->render('mess_expenses_demo'); } function loadFamilyExpenseDemo() { $this->render('family_expenses_demo'); } function compareOrder($a, $b) { return $a['expenseDate'] - $b['expenseDate']; } function printExpense() { $expenseArray = json_decode($this->data["Expense"]["printExpense"], true); // pr($this->data);die; $current_perticipants = (isset($this->data["Expense"]["current_perticipants"])) ? $this->data["Expense"]["current_perticipants"] : ''; $this->set("requestData", $this->data); $this->set("current_perticipants", $current_perticipants); if (!isset($expenseArray) || empty($expenseArray)) { if ($this->Session->check('cache_page_link')) { $cache_page_link = $this->Session->write("cache_page_link"); $this->Session->delete("cache_page_link"); $this->redirect(array('controller' => $cache_page_link)); } else { $this->redirect(array('controller' => "")); } } else { $this->Session->write("cache_page_link", $expenseArray["unique_url"]); } $expenseType = substr($expenseArray["unique_url"], 0, 1); $expenseList = json_decode($this->data["Expense"]["printExpenseList"], true); $this->set("expenseList", $expenseList); // pr($expenseList); $this->set("expense", $expenseArray); $printNames = json_decode($this->data["Expense"]["printNames"], true); $printNamesArray = explode(",", $printNames); $this->layout = 'print'; // $this->Session->read("Config.language"); if ($expenseType == "1" || $expenseType == "6" || $expenseType == "2" || $expenseType == "7") { // echo $this->data["Expense"]["printBalance"];exit; /*if($expenseType == "1" || $expenseType == "2"){ $data = $this->Expense->getGroupExpenseInfoByURL($expenseArray["unique_url"]); } else if($expenseType == "6" || $expenseType == "7"){ $demoData = $this->DemoExpense->getDemoGroupExpenseInfoByURL($expenseArray["unique_url"]); $data['Participant'] = $demoData['DemoParticipant']; $data['GroupExpense'] = $demoData['DemoGroupExpense']; $data['Expense'] = $demoData['DemoExpense']; unset($demoData['DemoParticipant']); unset($demoData['DemoGroupExpense']); unset($demoData['DemoExpense']); } // pr($data['GroupExpense']); if(!empty($data['Participant'])){ foreach ($data['Participant'] as $key => $perticipant) { unset($data['Participant'][$key]); $data['Participant'][$perticipant['participant_id']] = $perticipant; $data['Participant'][$perticipant['participant_id']]['total_charge'] = 0; $data['Participant'][$perticipant['participant_id']]['total_paid'] = 0; $data['Participant'][$perticipant['participant_id']]['currency'] = $data['Expense']['currency']; $perticipants[$perticipant['participant_id']] = $perticipant['name']; } } $this->set("perticipants",$perticipants); if(!empty($data['GroupExpense'])){ $expCounter = 1; foreach ($data['GroupExpense'] as $keya => $groupExpense) { $aa = array(); $aa = explode(',', $groupExpense['participant_amount']); foreach ($aa as $keyb => $vala) { $bb = array(); $bb = explode('|', $vala); $data['Participant'][$bb[0]]['total_charge'] += $bb[2]; } $data['Participant'][$groupExpense['paid_by_participant_id']]['total_paid'] += $groupExpense['amount']; $data['GroupExpense'][$keya]['involve_list'] = $this->getInvolves($data, $groupExpense['participant_amount']); foreach ($data['Participant'] as $participant) { if ($participant['participant_id'] == $groupExpense['paid_by_participant_id']) { $data['GroupExpense'][$keya]['participent_name'] = $participant['name']; } } } } if($current_perticipants != ''){ $tempGroupExpense = $data['GroupExpense']; if(!empty($tempGroupExpense)){ foreach ($tempGroupExpense as $keya => $groupExpense) { if( $groupExpense['paid_by_participant_id'] == $current_perticipants || strpos($groupExpense['participant_amount'], $current_perticipants.'|') !== false ) { // echo 'Yes'; } elseif($current_perticipants != '') { unset($data['GroupExpense'][$keya]); // echo 'NO'; } } } } $this->set("allGroupExpense",$data['GroupExpense']); $this->set("allParticipant",$data['Participant']); $pieDataFinal = array(); if($data['Participant']){ $counter = 0; foreach ($data['Participant'] as $key => $val) { // if( (($current_perticipants != '') && ($val['participant_id'] == $current_perticipants)) || ($current_perticipants == '') ) { $pieDataFinal[$counter]['name'] = $val['name']; $pieDataFinal[$counter]['y'] = $val['total_charge']; $counter++; // } } } $this->set("pieChartDataFinal",json_encode($pieDataFinal));*/ $this->set("printedBy", $printNamesArray[0]); $this->set("createdBy", $printNamesArray[1]); $this->set("createdDate", $printNamesArray[2]); $balanceArray = explode(",", json_decode($this->data["Expense"]["printBalance"], true)); $this->set("balanceArray", $balanceArray); } else if ($expenseType == "3" || $expenseType == "8") { $this->set("createdDate", $printNamesArray[0]); $this->set("totalIncome", $printNamesArray[1]); $this->set("totalExpense", $printNamesArray[2]); $this->set("balance", $printNamesArray[3]); } if ($expenseType == "1" || $expenseType == "6") { $this->render('print'); } else if ($expenseType == "2" || $expenseType == "7") { $parintOption = json_decode($this->data["Expense"]["printOption"], true); if ($parintOption == "2") { $this->render('meal'); } else if ($parintOption == "3") { $this->render('my_meal'); } else { $this->render('print_mess'); } } else if ($expenseType == "3" || $expenseType == "8") { $incomeList = json_decode($this->data["Expense"]["printIncomeList"], true); $this->set("incomeList", $incomeList); if ($expenseType == "3") { $data = $this->Expense->getFamilyExpenseInfoByURL($expenseArray["unique_url"]); if (!empty($data)) { $fcounter = 0; $temp_total_income = 0; $temp_total_expense = 0; $total_income_str = ''; $total_balance_str = ''; $total_expense_str = ''; foreach ($data['FamilyExpense'] as $key => $familyExpense) { if (!isset($newData[$fcounter]['total_income'])) { $newData[$fcounter]['total_income'] = 0; } if (!isset($newData[$fcounter]['total_expense'])) { $newData[$fcounter]['total_expense'] = 0; } $newData[$fcounter]['expense_date'] = $familyExpense['expense_date']; if ($familyExpense['record_type'] == 1) { $temp_total_expense += $familyExpense['amount']; $newData[$fcounter]['expense'] = $familyExpense['amount']; $newData[$fcounter]['income'] = 0; $newData[$fcounter]['total_expense'] = $temp_total_expense; $newData[$fcounter]['total_income'] = $temp_total_income; } elseif ($familyExpense['record_type'] == 2) { $temp_total_income += $familyExpense['amount']; $newData[$fcounter]['expense'] = 0; $newData[$fcounter]['income'] = $familyExpense['amount']; $newData[$fcounter]['total_income'] = $temp_total_income; $newData[$fcounter]['total_expense'] = $temp_total_expense; } $newData[$fcounter]['balance'] = $temp_total_income - $temp_total_expense; $newData[$fcounter]['record_type'] = $familyExpense['record_type']; $total_income_str[] = $newData[$fcounter]['total_income']; $total_expense_str[] = $newData[$fcounter]['total_expense']; $total_balance_str[] = $newData[$fcounter]['balance']; $fcounter++; } } $total_income_str = implode(',', $total_income_str); $total_expense_str = implode(',', $total_expense_str); $total_balance_str = implode(',', $total_balance_str); $this->set('total_income_str', $total_income_str); $this->set('total_expense_str', $total_expense_str); $this->set('total_balance_str', $total_balance_str); } $this->render('print_family'); } } public function printReport($uniqueURL = null, $uid = null) { $this->layout = 'print'; $this->loadModel('User'); if (isset($this->request->query['sendReport'])) { $issetParam = true; } else { $issetParam = false; } $isPaid = (isset($this->request->query['sendReport']) && $this->request->query['sendReport'] == 'true') ? true : false; /* if(isset($uid) && $uid != "" && $this->request->is('get')){ $session_user_id = $uid; //var_dump($this->request->query['sendReport']); //$isPaid = $this->isPaid($uid); }else{ $session_user_id = ''; }*/ $this->set('isPaid', $isPaid); $this->set('issetParam', $issetParam); $this->set('session_user_id', $session_user_id); if (isset($uniqueURL) && $uniqueURL != "" && $this->request->is('get')) { $expenseType = trim(substr($uniqueURL, 0, 1)); if ($expenseType == "1" || $expenseType == "2") { $data = $this->Expense->getGroupExpenseInfoByURL($uniqueURL); // added by Bijoy $current_perticipants = ''; if (!empty($data['Participant'])) { foreach ($data['Participant'] as $key => $perticipant) { $newdata['Participant'][$perticipant['participant_id']] = $perticipant; $newdata['Participant'][$perticipant['participant_id']]['total_charge'] = 0; $newdata['Participant'][$perticipant['participant_id']]['total_paid'] = 0; $newdata['Participant'][$perticipant['participant_id']]['currency'] = $data['Expense']['currency']; $perticipants[$perticipant['participant_id']] = $perticipant['name']; } } $this->set("perticipants", $perticipants); if ($expenseType == "1") { if (!empty($data['GroupExpense'])) { $expCounter = 1; foreach ($data['GroupExpense'] as $keya => $groupExpense) { $aa = array(); $aa = explode(',', $groupExpense['participant_amount']); foreach ($aa as $keyb => $vala) { $bb = array(); $bb = explode('|', $vala); $newdata['Participant'][$bb[0]]['total_charge'] += $bb[2]; } $newdata['Participant'][$groupExpense['paid_by_participant_id']]['total_paid'] += $groupExpense['amount']; $data['GroupExpense'][$keya]['involve_list'] = $this->getInvolves($data, $groupExpense['participant_amount']); foreach ($newdata['Participant'] as $participant) { if ($participant['participant_id'] == $groupExpense['paid_by_participant_id']) { $data['GroupExpense'][$keya]['participent_name'] = $participant['name']; } } } } if ($current_perticipants != '') { $tempGroupExpense = $data['GroupExpense']; if (!empty($tempGroupExpense)) { foreach ($tempGroupExpense as $keya => $groupExpense) { if ($groupExpense['paid_by_participant_id'] == $current_perticipants || strpos($groupExpense['participant_amount'], $current_perticipants . '|') !== false) { } elseif ($current_perticipants != '') { unset($data['GroupExpense'][$keya]); } } } } $hasMeal = 1; } if ($expenseType == "2") { $total_expense = 0; if (!empty($data['GroupExpense'])) { foreach ($data['GroupExpense'] as $keya => $groupExpense) { if ($this->checkExtraGroupExpense($groupExpense['extras'], $groupExpense['what']) == 99 && $groupExpense['expense_type'] == 2) { $total_expense = $total_expense + $groupExpense["amount"]; } $aa = array(); $aa = explode(',', $groupExpense['participant_amount']); foreach ($aa as $keyb => $vala) { $bb = array(); $bb = explode('|', $vala); $newdata['Participant'][$bb[0]]['total_charge'] += $bb[2]; } $newdata['Participant'][$groupExpense['paid_by_participant_id']]['total_paid'] += $groupExpense['amount']; } } $total_meal = 0; $tempParticipantMeal = array(); foreach ($data['Meal'] as $value) { $meal_participants = explode(',', $value['meal_amount']); foreach ($meal_participants as $meal_participant) { $meal_amounts = explode('|', $meal_participant); if (!isset($tempParticipantMeal[$meal_amounts[0]]['meal'])) { $tempParticipantMeal[$meal_amounts[0]]['meal'] = 0; } $tempParticipantMeal[$meal_amounts[0]]['meal'] += $meal_amounts[1] + $meal_amounts[2] + $meal_amounts[3]; $total_meal += $meal_amounts[1] + $meal_amounts[2] + $meal_amounts[3]; } } if (!empty($newdata['Participant'])) { if ($total_meal != 0) $meal_rate = $total_expense / $total_meal; foreach ($newdata['Participant'] as $key => $value) { if (isset($tempParticipantMeal[$key])) { $newdata['Participant'][$key]["total_charge"] += $tempParticipantMeal[$key]['meal'] * $meal_rate; } } $this->set('meal_rate', $meal_rate); } $hasMeal = 2; } $this->set("hasMeal", $hasMeal); $this->set("current_perticipants", $current_perticipants); $this->set("allGroupExpense", $data['GroupExpense']); $this->set("allParticipant", $newdata['Participant']); $pieDataFinal = array(); if ($newdata['Participant']) { $counter = 0; foreach ($newdata['Participant'] as $key => $val) { if (!empty($key)) { $pieDataFinal[$counter]['name'] = $val['name']; $pieDataFinal[$counter]['y'] = $val['total_charge']; $counter++; } } } $this->set("pieChartDataFinal", json_encode($pieDataFinal)); } elseif ($expenseType == "3") { $current_perticipants = ''; $data = $this->Expense->getFamilyExpenseInfoByURL($uniqueURL); if (!empty($data)) { $data["Category"] = $this->getCategories(); } $total_family_income = 0; $total_family_expense = 0; if (!empty($data['FamilyExpense']) && isset($data['FamilyExpense'])) { foreach ($data['FamilyExpense'] as $family_expense) { if ($family_expense['record_type'] == 1) { $total_family_expense = $total_family_expense + $family_expense['amount']; } elseif ($family_expense['record_type'] == 2) { $total_family_income = $total_family_income + $family_expense['amount']; } } } $this->set('total_family_income', $total_family_income); $this->set('total_family_expense', $total_family_expense); $this->set('data', $data); if (!empty($data)) { $fcounter = 0; $temp_total_income = 0; $temp_total_expense = 0; $total_income_str = ''; $total_balance_str = ''; $total_expense_str = ''; foreach ($data['FamilyExpense'] as $key => $familyExpense) { if (!isset($newData[$fcounter]['total_income'])) { $newData[$fcounter]['total_income'] = 0; } if (!isset($newData[$fcounter]['total_expense'])) { $newData[$fcounter]['total_expense'] = 0; } $newData[$fcounter]['expense_date'] = $familyExpense['expense_date']; if ($familyExpense['record_type'] == 1) { $temp_total_expense += $familyExpense['amount']; $newData[$fcounter]['expense'] = $familyExpense['amount']; $newData[$fcounter]['income'] = 0; $newData[$fcounter]['total_expense'] = $temp_total_expense; $newData[$fcounter]['total_income'] = $temp_total_income; } elseif ($familyExpense['record_type'] == 2) { $temp_total_income += $familyExpense['amount']; $newData[$fcounter]['expense'] = 0; $newData[$fcounter]['income'] = $familyExpense['amount']; $newData[$fcounter]['total_income'] = $temp_total_income; $newData[$fcounter]['total_expense'] = $temp_total_expense; } $newData[$fcounter]['balance'] = $temp_total_income - $temp_total_expense; $newData[$fcounter]['record_type'] = $familyExpense['record_type']; $total_income_str[] = $newData[$fcounter]['total_income']; $total_expense_str[] = $newData[$fcounter]['total_expense']; $total_balance_str[] = $newData[$fcounter]['balance']; $fcounter++; } } $total_income_str = implode(',', $total_income_str); $total_expense_str = implode(',', $total_expense_str); $total_balance_str = implode(',', $total_balance_str); $this->set('total_income_str', $total_income_str); $this->set('total_expense_str', $total_expense_str); $this->set('total_balance_str', $total_balance_str); $this->set("current_perticipants", $current_perticipants); $this->render('print_family_report'); } if (!empty($data['GroupExpense']) && isset($data['GroupExpense'])) { foreach ($data['GroupExpense'] as $key => $groupExpense) { $data['GroupExpense'][$key]['involve_list'] = $this->getInvolves($data, $groupExpense['participant_amount']); foreach ($data['Participant'] as $participant) { if ($participant['participant_id'] == $groupExpense['paid_by_participant_id']) { $data['GroupExpense'][$key]['participent_name'] = $participant['name']; }; } } } if (!empty($data)) { $this->set('data', $data); } } elseif ($this->request->is('Post')) { $uniqueURL = $this->request->data('unique_url'); $expenseType = trim(substr($uniqueURL, 0, 1)); if ($expenseType == "1" || $expenseType == "2") { $data = $this->Expense->getGroupExpenseInfoByURL($uniqueURL); // added by Bijoy if (isset($this->request->data['participant_id']) && !empty($this->request->data('participant_id'))) { $current_perticipants = $this->request->data('participant_id'); } else { $current_perticipants = ''; } if (!empty($data['Participant'])) { foreach ($data['Participant'] as $key => $perticipant) { // unset($data['Participant'][$key]); $newdata['Participant'][$perticipant['participant_id']] = $perticipant; $newdata['Participant'][$perticipant['participant_id']]['total_charge'] = 0; $newdata['Participant'][$perticipant['participant_id']]['total_paid'] = 0; $newdata['Participant'][$perticipant['participant_id']]['currency'] = $data['Expense']['currency']; $perticipants[$perticipant['participant_id']] = $perticipant['name']; } } $this->set("perticipants", $perticipants); if ($expenseType == "1") { if (!empty($data['GroupExpense'])) { $expCounter = 1; foreach ($data['GroupExpense'] as $keya => $groupExpense) { $aa = array(); $aa = explode(',', $groupExpense['participant_amount']); foreach ($aa as $keyb => $vala) { $bb = array(); $bb = explode('|', $vala); $newdata['Participant'][$bb[0]]['total_charge'] += $bb[2]; } $newdata['Participant'][$groupExpense['paid_by_participant_id']]['total_paid'] += $groupExpense['amount']; $data['GroupExpense'][$keya]['involve_list'] = $this->getInvolves($data, $groupExpense['participant_amount']); foreach ($newdata['Participant'] as $participant) { if ($participant['participant_id'] == $groupExpense['paid_by_participant_id']) { $data['GroupExpense'][$keya]['participent_name'] = $participant['name']; } } } } if ($current_perticipants != '') { $tempGroupExpense = $data['GroupExpense']; if (!empty($tempGroupExpense)) { foreach ($tempGroupExpense as $keya => $groupExpense) { if ($groupExpense['paid_by_participant_id'] == $current_perticipants || strpos($groupExpense['participant_amount'], $current_perticipants . '|') !== false) { } elseif ($current_perticipants != '') { unset($data['GroupExpense'][$keya]); } } } } $hasMeal = 1; } if ($expenseType == "2") { if (!empty($data['GroupExpense'])) { $total_expense = 0; foreach ($data['GroupExpense'] as $keya => $groupExpense) { if ($this->checkExtraGroupExpense($groupExpense['extras'], $groupExpense['what']) == 99 && $groupExpense['expense_type'] == 2) { $total_expense = $total_expense + $groupExpense["amount"]; } if (!empty($groupExpense['participant_amount'])) { $data['GroupExpense'][$keya]['my_expense'] = 0; $aa = array(); $aa = explode(',', $groupExpense['participant_amount']); foreach ($aa as $keyb => $vala) { $bb = array(); $bb = explode('|', $vala); $newdata['Participant'][$bb[0]]['total_charge'] += $bb[2]; if ($bb[0] == $current_perticipants) { $data['GroupExpense'][$keya]['my_expense'] = $bb[2]; } } } elseif (isset($groupExpense['participant_amount']) && empty($groupExpense['participant_amount'])) { $data['GroupExpense'][$keya]['my_expense'] = "-"; } $newdata['Participant'][$groupExpense['paid_by_participant_id']]['total_paid'] += $groupExpense['amount']; } } $total_meal = 0; $tempParticipantMeal = array(); foreach ($data['Meal'] as $value) { $meal_participants = explode(',', $value['meal_amount']); foreach ($meal_participants as $meal_participant) { $meal_amounts = explode('|', $meal_participant); if (!isset($tempParticipantMeal[$meal_amounts[0]]['meal'])) { $tempParticipantMeal[$meal_amounts[0]]['meal'] = 0; } $tempParticipantMeal[$meal_amounts[0]]['meal'] += $meal_amounts[1] + $meal_amounts[2] + $meal_amounts[3]; $total_meal += $meal_amounts[1] + $meal_amounts[2] + $meal_amounts[3]; } } if (!empty($newdata['Participant'])) { if ($total_meal != 0) $meal_rate = $total_expense / $total_meal; foreach ($newdata['Participant'] as $key => $value) { if (isset($tempParticipantMeal[$key])) { $newdata['Participant'][$key]["total_charge"] += $tempParticipantMeal[$key]['meal'] * $meal_rate; } } $this->set('meal_rate', $meal_rate); $this->set('total_meal', $total_meal); $this->set('total_expense', $total_expense); } $hasMeal = 2; } $this->set("hasMeal", $hasMeal); $this->set("current_perticipants", $current_perticipants); $this->set("allGroupExpense", $data['GroupExpense']); $this->set("allParticipant", $newdata['Participant']); $pieDataFinal = array(); if ($newdata['Participant']) { $counter = 0; foreach ($newdata['Participant'] as $key => $val) { $pieDataFinal[$counter]['name'] = $val['name']; $pieDataFinal[$counter]['y'] = $val['total_charge']; $counter++; } } $this->set("pieChartDataFinal", json_encode($pieDataFinal)); } elseif ($expenseType == "3") { // added by Bijoy if (isset($this->request->data['current_perticipants']) && !empty($this->request->data['current_perticipants'])) { $current_perticipants = $this->request->data['current_perticipants']; } else { $current_perticipants = ''; } $data = $this->Expense->getFamilyExpenseInfoByURL($uniqueURL); if (!empty($data)) { $data["Category"] = $this->getCategories(); } $total_family_income = 0; $total_family_expense = 0; if (!empty($data['FamilyExpense']) && isset($data['FamilyExpense'])) { foreach ($data['FamilyExpense'] as $family_expense) { if ($family_expense['record_type'] == 1) { $total_family_expense = $total_family_expense + $family_expense['amount']; } elseif ($family_expense['record_type'] == 2) { $total_family_income = $total_family_income + $family_expense['amount']; } } } $this->set('total_family_income', $total_family_income); $this->set('total_family_expense', $total_family_expense); $this->set('data', $data); if (!empty($data)) { $fcounter = 0; $temp_total_income = 0; $temp_total_expense = 0; $total_income_str = ''; $total_balance_str = ''; $total_expense_str = ''; foreach ($data['FamilyExpense'] as $key => $familyExpense) { if (!isset($newData[$fcounter]['total_income'])) { $newData[$fcounter]['total_income'] = 0; } if (!isset($newData[$fcounter]['total_expense'])) { $newData[$fcounter]['total_expense'] = 0; } $newData[$fcounter]['expense_date'] = $familyExpense['expense_date']; if ($familyExpense['record_type'] == 1) { $temp_total_expense += $familyExpense['amount']; $newData[$fcounter]['expense'] = $familyExpense['amount']; $newData[$fcounter]['income'] = 0; $newData[$fcounter]['total_expense'] = $temp_total_expense; $newData[$fcounter]['total_income'] = $temp_total_income; } elseif ($familyExpense['record_type'] == 2) { $temp_total_income += $familyExpense['amount']; $newData[$fcounter]['expense'] = 0; $newData[$fcounter]['income'] = $familyExpense['amount']; $newData[$fcounter]['total_income'] = $temp_total_income; $newData[$fcounter]['total_expense'] = $temp_total_expense; } $newData[$fcounter]['balance'] = $temp_total_income - $temp_total_expense; $newData[$fcounter]['record_type'] = $familyExpense['record_type']; $total_income_str[] = $newData[$fcounter]['total_income']; $total_expense_str[] = $newData[$fcounter]['total_expense']; $total_balance_str[] = $newData[$fcounter]['balance']; $fcounter++; } } $total_income_str = implode(',', $total_income_str); $total_expense_str = implode(',', $total_expense_str); $total_balance_str = implode(',', $total_balance_str); $this->set('total_income_str', $total_income_str); $this->set('total_expense_str', $total_expense_str); $this->set('total_balance_str', $total_balance_str); $this->set("current_perticipants", $current_perticipants); $this->render('print_family_report'); } if (isset($this->request->data['participant_id']) && !empty($this->request->data('participant_id'))) { $participant_id = $this->request->data('participant_id'); if ($expenseType == "1") { $data = $this->filterExpenseData($participant_id, $data); } $this->set('participant_id', $participant_id); } if (!empty($data['GroupExpense'])) { foreach ($data['GroupExpense'] as $key => $groupExpense) { $data['GroupExpense'][$key]['involve_list'] = $this->getInvolves($data, $groupExpense['participant_amount'], $expenseType); foreach ($data['Participant'] as $participant) { if ($participant['participant_id'] == $groupExpense['paid_by_participant_id']) { $data['GroupExpense'][$key]['participent_name'] = $participant['name']; }; } } } if (!empty($data)) { $this->set('data', $data); } } } private function getInvolves($data, $involves, $expense_type = null) { if ($expense_type == 2 && empty($involves)) { return "[Mess Members]"; } $involveStrAll = []; $involveStrExcept = ""; $involvesArray = explode(',', $involves); foreach ($involvesArray as $involve) { $involve_id = explode('|', $involve); foreach ($data['Participant'] as $participant) { if ($participant['participant_id'] == $involve_id[0]) { $involveStrAll[] = $participant['name']; } } } if (count($involveStrAll) == count($data['Participant'])) { $involveStrExcept = "all"; } else { foreach ($data['Participant'] as $participant) { if (!in_array($participant['name'], $involveStrAll)) { if ($involveStrExcept == "") { $involveStrExcept = "All except " . $participant['name']; } else { $involveStrExcept .= ", " . $participant['name']; } } } } $involveStrAll = implode(', ', $involveStrAll); if (strlen($involveStrExcept) > strlen($involveStrAll)) { $involveStrExcept = $involveStrAll; } return $involveStrExcept; } private function filterExpenseData($participant_id, $data) { $tempGroupExpense = $data['GroupExpense']; foreach ($tempGroupExpense as $key => $groupExpense) { $participanyArray = []; $involvesArray = explode(',', $groupExpense['participant_amount']); foreach ($involvesArray as $involve) { $involve_id = explode('|', $involve); $participanyArray[] = $involve_id[0]; if ($involve_id[0] == $participant_id) { $data['GroupExpense'][$key]['my_expense'] = $involve_id[2]; } } if (!in_array($participant_id, $participanyArray)) { unset($data['GroupExpense'][$key]); } } /*echo "
";
        print_r($data);exit;*/

        return $data;
    }

    public function generatePdf()
    {
        $html = $this->request->data['whole_content'];
        $html = mb_convert_encoding($html, 'UTF-8', 'UTF-8');
        $mpdf = new Mpdf\Mpdf(['utf-8']);
        $mpdf->SetProtection(array("print"));
        $mpdf->autoScriptToLang = true;
        $mpdf->autoLangToFont = true;
        $stylesheet = file_get_contents(CDN_URL . 'css/print_report.css');
        $mpdf->WriteHTML($stylesheet, 1);
        $mpdf->WriteHTML($html, 2);

        $rand = rand(1000, 10000);
        $reportUrl = "reports/";
        if (!is_dir($reportUrl)) {
            mkdir($reportUrl, 0777, true);
        }
        $filename = $reportUrl . $rand . "_" . time() . "_" . "expenses.pdf";
        $mpdf->Output($filename, 'D');

        if (file_exists($filename)) {
            header('Content-type: application/pdf');
            header('Content-Disposition: attachment; filename=' . $filename);
            readfile($filename);
            @unlink($filename);
            exit;
        }
    }


    public function sendEmailPdf()
    {
        $this->layout = '';
        $html = $this->request->data['whole_content_email'];
        $html = mb_convert_encoding($html, 'UTF-8', 'UTF-8');
        $mpdf = new Mpdf\Mpdf(['utf-8']);
        $mpdf->SetProtection(array("print"));
        $mpdf->autoScriptToLang = true;
        $mpdf->autoLangToFont = true;
        $stylesheet = file_get_contents(CDN_URL . 'css/print_report.css');
        $mpdf->WriteHTML($stylesheet, 1);
        $mpdf->WriteHTML($html, 2);

        $rand = rand(1000, 10000);
        $reportUrl = WWW_ROOT . "report_pdf/";
        if (!is_dir($reportUrl)) {
            mkdir($reportUrl, 0777, true);
        }
        $filename = $rand . '_' . time() . '_' . "expenses.pdf";

        ob_clean();
        $mpdf->Output(WWW_ROOT . 'report_pdf/' . $filename, "F");

        //send email
        $params = array();
        $params["email_to"] = $this->request->data['email'];
        $params["email_from"] = SUPPORT_EMAIL;
        $params["subject"] = 'Report from www.expensecount.com!';
        $params["template"] = 'report';
        $params["filePdf"] = WWW_ROOT . 'report_pdf/' . $filename;
        $this->sendEmailReport($params);

        if (file_exists(WWW_ROOT . 'report_pdf/' . $filename)) {
            @unlink(WWW_ROOT . 'report_pdf/' . $filename);
        }
        $this->redirect($this->referer());
    }

    private function sendEmailReport($data)
    {
        $default = array(
            'host' => Configure::read('expensecount.email.smtp.host'),
            'port' => 587,
            'auth' => 'plain',
            'username' => Configure::read('expensecount.email.smtp.username'),
            'password' => Configure::read('expensecount.email.smtp.password'),
            'tsl' => false,
            'transport' => 'Smtp',
            'from' => array(Configure::read('expensecount.email.smtp.from') => 'ExpenseCount'),
            'returnPath' => Configure::read('expensecount.email.smtp.from'),
            'layout' => false,
            'emailFormat' => 'html',
            //'template' => 'only_text',
            'charset' => 'utf-8',
            'headerCharset' => 'utf-8',
        );

        App::uses('CakeEmail', 'Network/Email');

        //echo $Email->
        $Email = new CakeEmail($default);
        $Email->to(array($data["email_to"]));
        $Email->emailFormat('html');
        $Email->template($data["template"], null)->viewVars(array('data' => $data));
        $Email->subject($data["subject"]);
        $Email->replyTo($data["email_from"]);
        $Email->replyTo($data["email_from"]);
        $Email->from(array(Configure::read('expensecount.email.smtp.from') => "ExpenseCount.com"));
        $Email->attachments($data["filePdf"]);
        // $Email->smtpOptions = $default;
        $Email->delivery = 'Smtp';
        $Email->send();
    }

    public function generateCSV()
    {
        $data = $this->request->data['csv_content'];
        $data_summary = $this->request->data['csv_summary_content'];
        $data_meal = $this->request->data['csv_meal_content'];
        $hasMeal = $this->request->data['hasMeal'];

        $adata = unserialize($data);
        $adata_summary = unserialize($data_summary);
        $adata_meal = unserialize($data_meal);
        // echo "
";        print_r($adata_meal);exit;
        $rand = rand(1000, 10000);
        $filename = $rand . '_' . time() . '_expense.csv';
        ob_start();
        header('Content-Encoding: UTF-8');
        header('Content-Type: text/csv; charset=UTF-8');
        header('Content-Disposition: attachment; filename=' . $filename);
        $fp = fopen('php://output', 'w');

        if (!empty($adata)) {
            fputcsv($fp, ['', 'All Expenses', '', '', '', '']);
            if ($adata[0]['my_expense'] > 0)
                fputcsv($fp, ['Who Paid?', 'How Much?', 'For what reasons?', 'When', 'Involves', 'My Expense']);
            else
                fputcsv($fp, ['Who Paid?', 'How Much?', 'For what reasons?', 'When', 'Involves', '']);

            $totalAmount = 0;
            $my_expenseAmount = 0;
            foreach ($adata as $data) {
                $totalAmount += $data['amount'];
                $my_expenseAmount += $data['my_expense'];
                $transaction_row = array();
                if (!empty($data)) {
                    $transaction_row = [
                        $data['participent_name'],
                        $data['amount'] . " " . $data['currency'],
                        $data['what'],
                        $data['expense_date_new'],
                        $data['involve_list'],
                        ($data['my_expense'] > 0) ? $data['my_expense'] . " " . $data['currency'] : ''
                    ];
                }
                fputcsv($fp, $transaction_row);
            }
            if ($my_expenseAmount > 0)
                fputcsv($fp, ['Total:', $totalAmount . " " . $data["currency"], '', '', 'Total', $my_expenseAmount . " " . $data["currency"]]);
            else
                fputcsv($fp, ['Total:', $totalAmount . " " . $data["currency"], '', '', '', '']);
            fputcsv($fp, ['', '', '', '', '', '']);
        } else {
            fputcsv($fp, ['', 'All Expenses', '', '', '', '']);
            fputcsv($fp, ['Who Paid?', 'How Much?', 'For what reasons?', 'When', 'Involves', '']);
            fputcsv($fp, ['No Data Available in table', '', '', '', '', '']);
            fputcsv($fp, ['', '', '', '', '', '']);
        }

        if ($hasMeal == 2) {
            if (!empty($adata_meal)) {
                fputcsv($fp, ['', 'Meal', '', '', '', '']);
                fputcsv($fp, ['Date', 'Day', 'Breakfast', 'Lunch', 'Dinner', 'Total']);

                $total = 0;
                foreach ($adata_meal as $data) {
                    $total += $data['subtotal'];
                    $transaction_row = array();
                    if (!empty($data)) {
                        $transaction_row = [
                            $data['create_date'],
                            $data['day'],
                            $data['breakfast'],
                            $data['lunch'],
                            $data['dinner'],
                            $data['subtotal']
                        ];
                    }
                    fputcsv($fp, $transaction_row);
                }

                fputcsv($fp, ['', '', '', '', 'Total:', $total]);
                fputcsv($fp, ['', '', '', '', '', '']);
            } else {
                fputcsv($fp, ['', 'Meal', '', '', '', '']);
                fputcsv($fp, ['Date', 'Day', 'Breakfast', 'Lunch', 'Dinner', 'Total']);
                fputcsv($fp, ['No meal available', '', '', '', '', '']);
                fputcsv($fp, ['', '', '', '', '', '']);
            }
        }

        if (!empty($adata_summary)) {
            fputcsv($fp, ['', 'Summary Report', '', '', '', '']);
            fputcsv($fp, ['Participants', 'Charged', 'Paid', 'Due']);

            foreach ($adata_summary as $data) {
                $transaction_row = array();
                if (!empty($data)) {
                    $transaction_row = [
                        $data['name'],
                        $data['total_charge'] . " " . $data['currency'],
                        $data['total_paid'] . " " . $data['currency'],
                        $data['due'] . " " . $data['currency']
                    ];
                }
                fputcsv($fp, $transaction_row);
            }
        }
        fclose($fp);
        exit;
    }

    public function generateFamilyCSV()
    {
        $csv_expense_heading = $this->request->data['csv_expense_heading'];
        $csv_income_heading = $this->request->data['csv_income_heading'];
        $income_data = $this->request->data['csv_income_content'];
        $expense_data = $this->request->data['csv_expense_content'];

        $aincome_data = unserialize($income_data);
        $aexpense_data = unserialize($expense_data);
        $aexpense_heading = unserialize($csv_expense_heading);
        $aincome_heading = unserialize($csv_income_heading);
        // echo "
";        print_r($aexpense_heading);
        // echo "
";        print_r($aexpense_data);
        // echo "
";        print_r($aincome_heading);
        // echo "
";        print_r($aincome_data);
        // exit;
        $rand = rand(1000, 10000);
        $filename = $rand . '_' . time() . '_expense.csv';
        ob_start();
        header('Content-Encoding: UTF-8');
        header('Content-Type: text/csv; charset=UTF-8');
        header('Content-Disposition: attachment; filename=' . $filename);
        $fp = fopen('php://output', 'w');

        if (!empty($aincome_data)) {
            fputcsv($fp, ['', 'All Incomes', '', '']);
            fputcsv($fp, [$aincome_heading['nameHeading'], $aincome_heading['categoryHeading'], $aincome_heading['dateHeading'], $aincome_heading['amountHeading']]);

            $totalAmount = 0;
            foreach ($aincome_data as $data) {
                $totalAmount += $data['amount'];
                $transaction_row = array();
                if (!empty($data)) {
                    $transaction_row = [
                        $data['expenseName'],
                        $data['expenseCategory'],
                        $data['expenseDate'],
                        $data['amount'] . " " . $data['currency'],
                    ];
                }
                fputcsv($fp, $transaction_row);
            }
            fputcsv($fp, ['', '', 'Total:', $totalAmount . " " . $data["currency"]]);
            fputcsv($fp, ['', '', '', '']);
        }
        if (!empty($aexpense_data)) {
            fputcsv($fp, ['', 'All Expenses', '', '']);
            fputcsv($fp, [$aexpense_heading['nameHeading'], $aexpense_heading['categoryHeading'], $aexpense_heading['dateHeading'], $aexpense_heading['amountHeading']]);

            $totalAmount = 0;
            foreach ($aexpense_data as $data) {
                $totalAmount += $data['amount'];
                $transaction_row = array();
                if (!empty($data)) {
                    $transaction_row = [
                        $data['expenseName'],
                        $data['expenseCategory'],
                        $data['expenseDate'],
                        $data['amount'] . " " . $data['currency'],
                    ];
                }
                fputcsv($fp, $transaction_row);
            }
            fputcsv($fp, ['', '', 'Total:', $totalAmount . " " . $data["currency"]]);
            fputcsv($fp, ['', '', '', '']);
        }


        fclose($fp);
        exit;
    }

    public function updateParticipantBalance($participants, $groupexpenses)
    {

        //var isReady = false;
        //	var participantBalance = [];
        $balanceEntryParticipantBalance = [];
        $balanceString = "";

        $positiveParticipantBalance = [];
        $negativeParticipantBalance = [];

        //reset all participant balance
        foreach ($participants as $key => $value) {
            //dashBoard.participants[index].balance = dashBoard.getFormatedAmountDB(parseFloat(0));
            //participantBalance[index] = dashBoard.getFormatedAmountDB(parseFloat(0));
            $positiveParticipantBalance[$key] = $this->getFormatedAmountDB(0);
            $negativeParticipantBalance[$key] = $this->getFormatedAmountDB(0);
        }

        $nparticipants = $this->resetParticipantBalance($participants, $groupexpenses);
        //assign negative and posi
        foreach ($participants as $key => $value) {
            if ($participants[$key]['balance'] > 0) {
                $positiveParticipantBalance[$key] = $participants[$key]['balance'];
            } else if ($participants[$key]['balance'] < 0) {
                $negativeParticipantBalance[$key] = $participants[$key]['balance'];
            }
        }

        //sort postivie and negative


        //scan and shift positive and negative

        //sort positive and negative again

        //calculate who needs to pay whom


        //if pos and neg values are same, then direct exchange payment

        foreach ($positiveParticipantBalance as $posIndex => $posValue) {

            if ($this->showFormatedAmount($positiveParticipantBalance[$posIndex]) > $this->showFormatedAmount($posValue)) {

                foreach ($negativeParticipantBalance as $negIndex => $negValue) {

                    if (
                        $this->showFormatedAmount($positiveParticipantBalance[$posIndex]) == $this->showFormatedAmount($negativeParticipantBalance[$negIndex] * (-1))
                        && $this->showFormatedAmount($positiveParticipantBalance[$posIndex]) > $this->showFormatedAmount($negValue)
                    ) {

                        if ($balanceString == "") {
                            $balanceString = $balanceString . $negIndex . "|" . $posIndex . "|" . $this->showFormatedAmount($negativeParticipantBalance[$negIndex] * (-1));
                        } else {
                            $balanceString = $balanceString . "," . $negIndex . "|" . $posIndex . "|" . $this->showFormatedAmount($negativeParticipantBalance[$negIndex] * (-1));
                        }
                        //update array amount
                        $positiveParticipantBalance[$posIndex] = 0;
                        $negativeParticipantBalance[$negIndex] = 0;
                    }
                }
            }
        }


        //distribute amount among pos values
        $maxPartIndex = $this->getMaxMinParticipantId($positiveParticipantBalance, 1);
        $minPartIndex = $this->getMaxMinParticipantId($negativeParticipantBalance, 2);


        while ($maxPartIndex != "" && $minPartIndex != "") {

            $maxVal = $positiveParticipantBalance[$maxPartIndex];


            if ($minPartIndex != "") {

                $decrementalVal = $negativeParticipantBalance[$minPartIndex] * (-1);
                if ($decrementalVal > $maxVal) {
                    $decrementalVal = $this->getFormatedAmountDB($maxVal);
                }

                //update array
                $positiveParticipantBalance[$maxPartIndex] = $this->getFormatedAmountDB($positiveParticipantBalance[$maxPartIndex] - $decrementalVal);
                $egativeParticipantBalance[$minPartIndex] = $this->getFormatedAmountDB($negativeParticipantBalance[$minPartIndex] + $decrementalVal);

                if ($balanceString == "") {
                    $balanceString = $balanceString . $minPartIndex . "|" . $maxPartIndex . "|" . $decrementalVal;
                } else {
                    $balanceString = $balanceString . "," . $minPartIndex . "|" . $maxPartIndex . "|" . $decrementalVal;
                }
            }


            //check equal
            foreach ($positiveParticipantBalance as $posIndex => $posValue) {

                if ($this->showFormatedAmount($positiveParticipantBalance[$posIndex]) > $this->showFormatedAmount($posValue)) {

                    foreach ($negativeParticipantBalance as $negIndex => $negValue) {

                        if (
                            $this->showFormatedAmount($positiveParticipantBalance[$posIndex]) == $this->showFormatedAmount($negativeParticipantBalance[$negIndex] * (-1))
                            && $this->showFormatedAmount($positiveParticipantBalance[$posIndex]) > $this->showFormatedAmount($negValue)
                        ) {

                            if ($balanceString == "") {
                                $balanceString = $balanceString . $negIndex . "|" . $posIndex . "|" . $this->showFormatedAmount($negativeParticipantBalance[$negIndex] * (-1));
                            } else {
                                $balanceString = $balanceString . "," . $negIndex . "|" . $posIndex . "|" . $this->showFormatedAmount($negativeParticipantBalance[$negIndex] * (-1));
                            }
                            //update array amount
                            $positiveParticipantBalance[$posIndex] = 0;
                            $negativeParticipantBalance[$negIndex] = 0;
                        }
                    }
                }
            }

            $maxPartIndex = $this->getMaxMinParticipantId($positiveParticipantBalance, 1);
            $minPartIndex = $this->getMaxMinParticipantId($negativeParticipantBalance, 2);
        }
        echo $balanceString;
        exit;
        return $balanceString;
    }

    private function getFormatedAmountDB($amount)
    {
        return number_format($amount, 4);
    }

    private function showFormatedAmount($amount)
    {
        return number_format($amount, 2);
    }

    private function getMaxMinParticipantId($balanceList, $ind)
    {

        $result = 0;
        $participantIndex = '';
        foreach ($balanceList as $index => $value) {
            //alert(dashBoard.showFormatedAmount(parseFloat(balanceList[index])));
            if ($ind == 1) {
                if ($this->showFormatedAmount($balanceList[$index]) > $result) {
                    $participantIndex = $index;
                    $result = $balanceList[$index];
                }
            } else {

                if ($this->showFormatedAmount($balanceList[$index]) < $result) {
                    $participantIndex = $index;
                    $result = $balanceList[$index];
                }
            }
        }

        return $participantIndex;
    }

    private function resetParticipantBalance($cparticipants, $groupexpenses)
    {
        $amtStr = "";
        $paidBy = "";
        $amount = "";

        foreach ($cparticipants as $key => $value) {
            if (!empty($key)) {
                $participants[$key]['totalPaid'] = $this->getFormatedAmountDB(0);
                $participants[$key]['totalSpent'] = $this->getFormatedAmountDB(0);
                $participants[$key]['balance'] = $this->getFormatedAmountDB(0);
                $participants[$key]['isDeletable'] = 1;
            }
        }

        //for(var i=0;i $value) {
            $amtStr = $value['participant_amount'];
            $paidBy = $value['paid_by_participant_id'];
            $amount = $value['amount'];

            $amtStrArray = explode(",", $amtStr);
            for ($j = 0; $j < count($amtStrArray); $j++) {

                $participantAndAmountArray = explode("|", $amtStrArray[$j]);
                $participants[$participantAndAmountArray[0]]['isDeletable'] = 0;
                $participants[$participantAndAmountArray[0]]['totalSpent'] = $this->getFormatedAmountDB($participants[$participantAndAmountArray[0]]['totalSpent'] + $participantAndAmountArray[2]);
                $participants[$participantAndAmountArray[0]]['balance'] = $this->getFormatedAmountDB($participants[$participantAndAmountArray[0]]['balance'] - $participantAndAmountArray[2]);
                //participantBalance[participantAndAmountArray[0]] = dashBoard.getFormatedAmountDB(parseFloat(participantBalance[participantAndAmountArray[0]]) - parseFloat(participantAndAmountArray[2]));
            }

            $participants[$paidBy]['isDeletable'] = 0;
            $participants[$paidBy]['totalPaid'] = $this->getFormatedAmountDB($participants[$paidBy]['totalPaid'] + $amount);
            $participants[$paidBy]['balance'] = $this->getFormatedAmountDB($participants[$paidBy]['balance'] + $amount);

            //participantBalance[paidBy] = dashBoard.getFormatedAmountDB(parseFloat(participantBalance[paidBy]) + parseFloat(amount));

        }
        return $participants;
    }

    public function checkCookie()
    {
        $this->layout = 'ajax';
        $key = false;
        $my_expenses = $this->Cookie->read('Expenses');
        if (!empty($my_expenses)) {
            $key = array_search($this->request->data('unique_url'), array_column($my_expenses, 'unique_url'));
        }
        $session_user_id = ($this->Session->read('userData.id')) ? $this->Session->read('userData.id') : '';
        if ($key === false) {
            $expInfo = $this->Expense->findByUniqueUrl($this->request->data('unique_url'));
            $dataCookie["title"] = $expInfo['Expense']['title'];
            $dataCookie["create_date"] = $expInfo['Expense']['create_date'];
            //set cookie for my expenses
            $this->setCookie($dataCookie, $this->request->data('unique_url'));
            if ($session_user_id != '') {
                $data['participant_id'] = $this->request->data('participantId');
                $data['skip_process_validation'] = 1;
                $data['user_id'] = $session_user_id;
                $data['unique_url'] = $this->request->data('unique_url');
                //add userGroup
                $this->callAPI(HTTP_SITE_URL . "/users/groupadd.json", 'POST', json_encode($data));
            }
        }

        $this->autoRender = false;
    }

    public function isExistCookie()
    {
        $this->layout = 'ajax';
        $user_id = $this->Session->read('userData.id');
        $key = false;
        if(empty($user_id)) {
            $my_expenses = $this->Cookie->read('Expenses');
            if (!empty($my_expenses)) {
                $key = array_search($this->request->query('unique_url'), array_column($my_expenses, 'unique_url'));
            }
        }
        if(!empty($user_id)){
            $key = true;
        }
        $this->autoRender = false;
        return $key;
    }


    public function isValidName($name)
    {
        // Check for maximum length and absence of special characters
        return !preg_match('/[%*]/', $name);
    }

    public function isValidLength($name, $limit)
    {
        // Check for maximum length and absence of special characters
        return strlen($name) <= $limit;
    }

    public function mergeArraysUniqueByName($a, $b, $limit)
    {
        $merged = array_merge($a, $b);

        $names = array_map(function ($item) {
            return strtolower($item['n']);
        }, $merged);

        $uniqueNames = array_unique($names);

        if (count($names) !== count($uniqueNames)) {
            // Duplicates found
            return false;
        }

        // Check additional constraints on each name
        foreach ($merged as $item) {
            if (!$this->isValidName($item['n']) || !$this->isValidLength($item['n'], $limit)) {
                // Invalid name found
                return false;
            }
        }

        return $merged;
    }


    public function mergeArraysUnique($a, $b, $limit)
    {
        $merged = array_merge($a, $b);

        $names = array_map(function ($item) {
            return $item['user_id'];
        }, $merged);

        $uniqueNames = array_unique($names);

        if (count($names) !== count($uniqueNames)) {
            // Duplicates found
            return false;
        }

        // Check additional constraints on each name
        foreach ($merged as $item) {
            if (!$this->isValidLength($item['user_id'], $limit)) {
                // Invalid name found
                return false;
            }
        }

        return $merged;
    }

    //signle method for select/add/delete groups
    public function group_settings()
    {

        $object = $this->request->input('json_decode');
        if (!empty($object)) {
            $data = $this->objectToArray($object);
        }

        if (!isset($data['skip_process_validation'])) {
            list($data, $status, $status_desc, $error) = $this->processValidation();
        }

        if (empty($status)) {
            $object = json_decode(json_encode($object), true);
            list($status, $status_desc, $expObj) = $this->validateUniqueUrl($object['unique_url']);
        }

        $input = array();

        if (empty($status)) {

            $expense = $this->Expense->find('first', array(
                'conditions' => array('Expense.id' => $object['expense_id'], 'Expense.unique_url' => $object['unique_url'])
            ));
            $this->loadModel('GroupSettings');
            //check expense_id and unique_url is exist or not
            $groupSettings = $this->GroupSettings->find('first', array(
                'conditions' => array('GroupSettings.expense_id' => $object['expense_id'], 'GroupSettings.unique_url' => $object['unique_url'])
            ));

            $catArray = [];
            $perArray = [];
            if (count($groupSettings) > 0) {
                $catArray = json_decode($groupSettings['GroupSettings']['categories'], true);
                if ($catArray === null || $catArray === '') {
                    $catArray = [];
                }

                if (count($catArray) > 0) {
                    $keys = array_keys($catArray);
                    $lastKey = end($keys);
                    $lastIdCat = $catArray[$lastKey]['id'] + 1;
                } else {
                    $lastIdCat = 100;
                }

                $data['id'] = $groupSettings['GroupSettings']['id'];
                $data['version'] = $groupSettings['GroupSettings']['version'] + 1;
            } else {
                $lastIdCat = 100;
            }

            $AddResultPer = [];
            $AddResultCat = [];
            $addCat = [];
            if (isset($object['addCategory']) && count($object['addCategory']) > 0) {
                $addCat = Hash::extract($object['addCategory'], '{n}.n');
                $AddResultCat = array_map(function ($value, $index) use ($lastIdCat) {
                    return array(
                        'id' => $index + $lastIdCat,
                        'n' => $value
                    );
                }, array_values($addCat), array_keys($addCat));
            }

            $result = $this->mergeArraysUniqueByName($catArray, $AddResultCat, 25);
            if ($result === false) {
                $status = "-1";
                $status_desc = "Error: Duplicate or invalid names found.";
            }

            if (isset($object['modifyCategory']) && count($object['modifyCategory']) > 0) {
                if (empty($status)) {
                    // Extract IDs from $a and $b
                    $idsA = array_column($result, 'id');
                    $idsB = array_column($object['modifyCategory'], 'id');

                    // Check if all IDs in $b exist in $a
                    $existInA = count(array_intersect($idsB, $idsA)) === count($idsB);

                    if (!$existInA) {
                        $status = "-1";
                        $status_desc = "Invalid id in modifyCategory.";
                    } else {
                        $tmpResult = $result;
                        $result = $this->mergeArraysUniqueByName($result, $object['modifyCategory'], 25);
                        if ($result === false) {
                            $status = "-1";
                            $status_desc = "Error: Duplicate or invalid names found.";
                        } else {
                            foreach ($object['modifyCategory'] as $itemB) {
                                $key = array_search($itemB['id'], $idsA);
                                if ($key !== false) {
                                    $tmpResult[$key]['n'] = $itemB['n'];
                                }
                            }
                            $result = $tmpResult;
                        }
                    }
                }
            }

            if (isset($object['deleteCategory']) && count($object['deleteCategory']) > 0) {
                if (empty($status)) {

                    // Extract IDs from $a and $b
                    $idsA = array_column($result, 'id');
                    $idsB = array_column($object['deleteCategory'], 'id');

                    // Identify any IDs in deleteCategory that don't exist in result
                    $missingIds = array_diff($idsB, $idsA);

                    if (!empty($missingIds)) {
                        $status = "-1";
                        $status_desc = "Invalid id(s) in deleteCategory: " . implode(', ', $missingIds);
                    } else {
                        // Remove data
                        $result = array_filter($result, function ($itemA) use ($idsB) {
                            return !in_array($itemA['id'], $idsB);
                        });
                    }
                }
            }

            //verify max category
            if ($result !== false && count($result) > 15) {
                $status = "-1";
                $status_desc = "Error: Total category can not be more than 15.";
            }

            if (empty($status)) {
                //save final data
                $data['expense_id'] = $object['expense_id'];
                $data['unique_url'] = $object['unique_url'];
                sort($result); // Sort by value, it resolved a json format issue while deleting first item
                $data['categories'] = json_encode($result);
                if (!empty($expense['Expense'])) {
                    $expense['Expense']['version'] = $expense['Expense']['version'] + 1;
                }
                $this->GroupSettings->save($data);
                $this->Expense->save($expense);
                $status = "+000";
                $status_desc = "SUCCESS";
            }
        }

        if ($status != "+000") {
            $this->processResponse($input, $data, $status, $status_desc);
        } else {
            $this->updateFirebase($object['unique_url']);
            $input["status"] = $status;
            $input["status_desc"] = $status_desc;
            $input["api_version"] = 3;
            $input["data"]['settings']['categories'] = json_encode($result);

            $this->set(array(
                'response' => $input,
                '_serialize' => array('response')
            ));
        }
    }

    //signle method for select/add/delete groups
    public function permissions()
    {

        $object = $this->request->input('json_decode');
        if (!empty($object)) {
            $data = $this->objectToArray($object);
        }

        if (!isset($data['skip_process_validation'])) {
            list($data, $status, $status_desc, $expObj) = $this->processValidation();
        }
        if (!empty($data) && empty($status)) {
            list($status, $status_desc, $expObj) = $this->permissionRequestValidate($data);
        }
        if (empty($status)) {
            $object = json_decode(json_encode($object), true);
            list($status, $status_desc, $expObj) = $this->validateUniqueUrl($object['unique_url']);
        }


        $input = array();
        if(empty($status)){
            $expense = $this->Expense->find('first', array(
                'conditions' => array('Expense.id' => $object['expense_id'], 'Expense.unique_url' => $object['unique_url'])
            ));

            if(empty($expense['Expense']['user_id']) && $expense['Expense']['create_user'] == "system" ){
                $status_message = $this->getPermissionError('ADD_PERMISSION_FAILED');
                $this->set(array(
                    'response' => ['status' => $status_message['code'],
                        'status_desc' => $status_message['message']],
                    '_serialize' => array('response')
                ));
                return;
            }

            list($status, $status_desc, $expObj) = $this->validatePermissionRequest($object,$expense['Expense']['create_user']);

            if(empty($expense['Expense'])){
                $status = "-997";
                $status_desc = "Expense not found!";
            }
        }

        if (empty($status)) {
            $Ownerinfo = ['profile_id'=>$expense['Expense']['create_user'],'role'=>OWNER];
            $permitted = false;
            $owner = false;
            if(!empty($object['user_id'])){
                $user = $this->User->getUserByUserId($object['user_id']);
                if(!empty($user['User'])){
                    $owner = ($expense['Expense']['user_id'] == $user['User']['id']) || ($expense['Expense']['create_user'] == $user['User']['profile_id']);
                }
            }

            $permission = $this->Permission->PermissionByUserId($object['unique_url'], $object['user_id']);

            if($permission == PUBLIC_PERMIT){
                $status_message = $this->getPermissionError('RESTRICTION_MODE_REQUIRED');
                $this->set(array(
                    'response' => ['status' => $status_message['code'],
                        'status_desc' => $status_message['message']],
                    '_serialize' => array('response')
                ));
                return;
            }
            if ($permission == ADMIN_PERMIT || $permission == OWNER) {
                $permitted = true;
            }
            if($permission == NO_PERMIT && $owner){
                $permitted = true;
            }

            $onlyDeletable =  count($object['deletePermissions']) == 1 && count($object['modifyPermissions']) == 0 && count($object['addPermissions']) == 0 ;
            if (($permission == VIEW_PERMIT || $permission == EDIT_PERMIT) && $onlyDeletable) {
                $deletePermissions = array_column($object['deletePermissions'], 'email');
                $deletable = in_array($object['profile_id'], $deletePermissions); // user can delete only himself without owner
                if($deletable) {
                    $permitted = true;
                }
            }

            if(!$permitted){
                $status_message = $this->getPermissionError('UNAUTHORIZED_ACCESS');
                $this->set(array(
                    'response' => ['status' => $status_message['code'],
                        'status_desc' => $status_message['message']],
                    '_serialize' => array('response')
                ));
                return;
            }
            if (!empty($expense['Expense'])) {
                $expense['Expense']['version'] = $expense['Expense']['version'] + 1;
            }

            $this->loadModel('GroupSetting');
            $this->loadModel('PermissionTable');
            //check expense_id and unique_url is exist or not
            $groupSettings = $this->GroupSetting->getGroupSettingByURL($object['unique_url']);
            $permissions = $this->PermissionTable->getPermissionByUrl($object['unique_url']);

            $previous_permission = [];
            //permission
            $previous_permission = $permissions;

            if ($previous_permission === null || $previous_permission === '') {
                $perArray = [];
            }
            if (count($groupSettings) > 0) {
                $data['id'] = $groupSettings['id'];
                $data['version'] = $groupSettings['version'] + 1;
            }


            ///start Permissions section
            $dataSource = $this->User->getDataSource();
            $dataSource->begin();

            try {

                $presult = [];
                $AddResultPer = [];
                $add_permission_requests =[];
                $modify_permission_requests = [];
                $delete_permission_requests = [];

                if (isset($object['addPermissions']) && count($object['addPermissions']) > 0) {

                    foreach ($object['addPermissions'] as $key => $value) {
                        $user = $this->User->findByProfileId($value['email']);
                        if (empty($user['User'])) {
                            $this->User->create();
                            $request['first_name'] = $value['name'];
                            $request['nick_name'] = $value['name'];
                            $request['profile_type'] = 0;
                            $request['profile_id'] = $value['email'];
                            $request['is_verified'] = 0;
                            $request['is_auto_creation'] = 1;
                            $request["ip"] = $this->getClientIp();
                            $request["device_info"] = $this->getUserAgent();
                            $request["create_date"] = $this->getSystemCurrentTimeStamp();
                            $request["update_date"] = $this->getSystemCurrentTimeStamp();
                            $user = $this->User->save($request);
                        }
                        $permission= [
                            'user_id'=> $user['User']['id'],
                            'profile_id'=> $user['User']['profile_id'],
                            'role'=> $value['role']
                        ];
                        $add_permission_request= ['expense_id'=>$object['expense_id'],
                            'unique_url'=>$object['unique_url'],
                            'user_id'=> $user['User']['id'],
                            'role'=> $value['role']
                        ];
                        $AddResultPer[$key] = $permission;
                        $add_permission_requests[] = $add_permission_request;
                    }

                }

                $presult = $this->mergeArraysUnique($previous_permission, $AddResultPer, 70);

                if ($presult === false) {
                    $status_message = $this->getPermissionError('DUPLICATE_OR_INVALID_EMAIL');
                    $status = $status_message['code'];
                    $status_desc = $status_message['message'];
                }

                if (isset($object['modifyPermissions']) && count($object['modifyPermissions']) > 0) {
                    if (empty($status)) {
                        // Extract IDs from $a and $b
                        $idsA = array_column($presult, 'user_id');
                        $idsB = [];

                        foreach ($object['modifyPermissions'] as $key => $value) {
                            $user = $this->User->findByProfileId($value['email']);
                            if (!empty($user['User'])) {
                                $idsB[$key] = $user['User']['id'];
                                $id_position = array_search($user['User']['id'], $idsA); // to check id exist in db , return position
                                if ($id_position !== false) {
                                    $presult[$id_position]['role'] = $value['role'];
                                    $permission_request = ['expense_id'=>$object['expense_id'],
                                        'unique_url'=>$object['unique_url'],
                                        'user_id'=> $user['User']['id'],
                                        'role'=> $value['role']
                                    ];
                                    $modify_permission_requests[] = $permission_request;
                                }
                            }
                        }

                        // Check if all IDs in $b exist in $a
                        $existInA = count(array_intersect($idsB, $idsA)) === count($idsB);
                        if (!$existInA || empty($idsB)) {
                            $status_message = $this->getPermissionError('INVALID_EMAIL_MODIFY');
                            $status = $status_message['code'];
                            $status_desc = $status_message['message'];
                        }
                    }
                }

                if (isset($object['deletePermissions']) && count($object['deletePermissions']) > 0) {
                    if (empty($status)) {
                        // Extract IDs from $a and $b
                        $idsA = array_column($presult, 'user_id');
                        $idsB = [];

                        foreach ($object['deletePermissions'] as $key => $value) {
                            $user = $this->User->findByProfileId($value['email']);
                            if (!empty($user['User'])) {
                                $idsB[$key] = $user['User']['id'];
                                $permission_request = ['expense_id'=>$object['expense_id'],
                                    'unique_url'=>$object['unique_url'],
                                    'user_id'=> $user['User']['id'],
                                    'role'=> $value['role']
                                ];
                                $delete_permission_requests[] = $permission_request;
                            }
                        }
                        $existInA = count(array_intersect($idsB, $idsA)) === count($idsB);

                        if (!$existInA) {
                            $status_message = $this->getPermissionError('INVALID_EMAIL_DELETE');
                            $status = $status_message['code'];
                            $status_desc = $status_message['message'];
                        } else {
                            // Remove data
                            $presult = array_filter($presult, function ($itemA) use ($idsB) {
                                return !in_array($itemA['user_id'], $idsB);
                            });

                        }
                    }
                }

                //verify max permission
                if ($presult !== false && count($presult) > 15) {
                    $status_message = $this->getPermissionError('MAX_PERMISSION_LIMIT_EXCEEDED');
                    $status = $status_message['code'];
                    $status_desc = $status_message['message'];
                }
                ///END permissions Section
                if (empty($status)) {
                    //save final data

                    $data['expense_id'] = $object['expense_id'];
                    $data['unique_url'] = $object['unique_url'];
                    sort($result); // Sort by value, it resolved a json format issue while deleting first item
                    $data['categories'] = json_encode($result);
                    $this->GroupSetting->save($data);


                    $this->addPermission($add_permission_requests);
                    $this->modifyPermission($modify_permission_requests);
                    $this->deletePermission($delete_permission_requests);
                    $this->addUserGroup($add_permission_requests);
                    $this->deleteUserGroup($delete_permission_requests);
                    $this->Expense->save($expense);

                    // update or create access info
                    $access_info["id"] = $object['expense_id'];
                    $access_info["unique_url"] = $object['unique_url'];
                    $this->insertAccessInfo($access_info);

                    //update firebase version
                    $this->updateFirebase($object['unique_url']);
                    $status = "+000";
                    $status_desc = "SUCCESS";
                    $dataSource->commit();
                    $this->emailSend($object,
                        ['unique_url'=>$data['unique_url'],
                            'title'=> $expense['Expense']['title']
                        ]);
                }

            } catch (Exception $e) {
                $dataSource->rollback();
                $status = $this->database_error_status;
                $status_desc = "Error: ".$e->getMessage();
            }
        }

        if ($status != "+000") {
            $this->processResponse($expObj, $data, $status, $status_desc);
        }
        else {
            $input["status"] = $status;
            $input["status_desc"] = $status_desc;
            $input["api_version"] = 3;
            $input["data"]['expense_id'] = $object['expense_id'];
            $input["data"]['unique_url'] = $object['unique_url'];

            $permissions = [] ;
            $addPermissions = array_column($presult, 'profile_id');
            if (!in_array($Ownerinfo['profile_id'], $addPermissions)) {
                $permissions[] = $Ownerinfo;
            }
            foreach ($presult as $item) {
                $permissions[] = ['profile_id'=>$item['profile_id'], 'role'=>$item['role'] ];
            }
            $input["data"]['permissions'] = $permissions;

            $this->set(array(
                'response' => $input,
                '_serialize' => array('response')
            ));
        }
    }
    private function insertAccessInfo($data){
        //insert data into the table access_infos
        $accessInfoData["id"] = $data["id"];
        $accessInfoData["unique_url"] = $data["unique_url"];
        $accessInfoData["access_time"] = $this->getSystemCurrentTimeStamp();

        $this->AccessInfo->saveAccessInfo($accessInfoData);
    }

    public function restriction()
    {
        $object = $this->request->input('json_decode');
        if (!empty($object)) {
            $data = $this->objectToArray($object);
        }
        if (!isset($data['skip_process_validation'])) {
            list($data, $status, $status_desc, $error) = $this->processValidation();
        }
        if (!empty($data) && empty($status)) {
            list($status, $status_desc, $error) = $this->restrictionRequestValidate($data);
        }
        if (empty($status)) {
            $object = json_decode(json_encode($object), true);
            list($status, $status_desc, $expObj) = $this->validateUniqueUrl($object['unique_url']);
        }

        $input = array();

        if (empty($status)) {
            $status_message = $this->getRestrictionStatus('EXPENSE_NOT_FOUND');
            $status = $status_message['code'];
            $status_desc = $status_message['message'];
            $expense = $this->Expense->find('first', array(
                'conditions' => array('Expense.id' => $object['expense_id'], 'Expense.unique_url' => $object['unique_url'])
            ));

            if (!empty($expense['Expense'])) {
                $is_add_possible = true;
                $owner = false;
                if(!empty($object['user_id'])){
                    $user = $this->User->getUserByUserId($object['user_id']);
                    if(!empty($user['User'])){
                        $owner = ($expense['Expense']['user_id'] == $user['User']['id']) || ($expense['Expense']['create_user'] == $user['User']['profile_id']);
                    }
                }
                if(empty($expense['Expense']['user_id']) && $expense['Expense']['create_user'] == "system" ){
                    $is_add_possible = false;

                    $status_message = $this->getRestrictionStatus('MODE_ADD_FAILED');
                    $status = $status_message['code'];
                    $status_desc = $status_message['message'];
                }
                //verify creator/owner
                else if (!$owner) {
                    $is_add_possible = false;
                    $status_message = $this->getRestrictionStatus('ONLY_CREATOR_CAN_CHANGE');
                    $status = $status_message['code'];
                    $status_desc = $status_message['message'];
                }
                else {
                    $group_setting = [];
                    //check expense_id and unique_url is exist or not
                    $groupSettings = $this->GroupSetting->find('first', array(
                        'conditions' => array('GroupSetting.expense_id' => $object['expense_id'], 'GroupSetting.unique_url' => $object['unique_url'])
                    ));
                    if (count($groupSettings) > 0) {
                        $this->loadModel('PermissionTable');
                        $permissions = $this->PermissionTable->getPermissionByUrl($object['unique_url'],false,true);
                        if (count($permissions) > 0 && $object['is_restricted_mode'] == 0) {
                            $is_add_possible = false;
                            $status_message = $this->getRestrictionStatus('DELETE_PERMISSIONS_FIRST');
                            $status = $status_message['code'];
                            $status_desc = $status_message['message'];
                        }
                        $group_setting = $groupSettings['GroupSetting'];
                    }

                    if($is_add_possible) {
                        // If no group setting exists, save new data otherwise update data for the verified user in the expense table.
                        $data = [
                            'GroupSetting' => [
                                'id' => !empty($group_setting)?$group_setting['id']:null,
                                'is_restricted_mode' => $object['is_restricted_mode'],
                                'expense_id' => !empty($group_setting) ? $group_setting['expense_id'] : $expense['Expense']['id'],
                                'unique_url' => !empty($group_setting) ? $group_setting['unique_url'] : $expense['Expense']['unique_url'],
                                'categories' => !empty($group_setting) ? $group_setting['categories'] : '[]',
                                'version' => !empty($group_setting) ? $group_setting['version']+1 : 0,
                            ]
                        ];
                        if (!empty($expense['Expense'])) {
                            $expense['Expense']['version'] = $expense['Expense']['version'] + 1;
                            $expense['Expense']['update_date'] = $this->getSystemCurrentIntTime();
                        }
                        $this->GroupSetting->save($data);
                        $this->Expense->save($expense);

                        // update or create access info
                        $access_info["id"] =  $expense['Expense']['id'];
                        $access_info["unique_url"] = $expense['Expense']['unique_url'];
                        $this->insertAccessInfo($access_info);

                        $groupSettings['GroupSetting']['is_restricted_mode'] = $object['is_restricted_mode'];
                        $status_desc = "SUCCESS";
                        $status = "+000";
                        $input['GroupSetting'] = $groupSettings['GroupSetting'];
                    }
                }
            }


        }

        if ($status != "+000") {
            $this->processResponse($input, $data, $status, $status_desc);
        } else {
            $this->updateFirebase($object['unique_url']);
            $input["status"] = $status;
            $input["status_desc"] = $status_desc;
            $input["api_version"] = 3;

            $this->set(array(
                'response' => $input,
                '_serialize' => array('response')
            ));
        }
    }

    public function restrictionRequestValidate($object)
    {

        //check validity
        $error = "";
        $error_desc = "";
        $expObj = array();

        if (empty($object['expense_id'])) {
            $error = $this->validation_status;
            $error_desc = "expense_id must be provided!";
            $expObj['expense_id'] = $error_desc;
        }
        if (empty($object['unique_url'])) {
            $error = $this->validation_status;
            $error_desc = "unique_url must be provided!";
            $expObj['unique_url'] = $error_desc;
        }
        if (!empty($object['profile_id']) &&  !filter_var($object['profile_id'], FILTER_VALIDATE_EMAIL)) {
            $error = $this->validation_status;
            $error_desc = "profile_id must be email!";
            $expObj['profile_id'] = $error_desc;
        }
        if (!empty($object['user_id']) && !is_numeric($object['user_id'])) {
            $error = $this->validation_status;
            $error_desc = 'user_id must be provided as numeric.';
        }
        if (!isset($object['is_restricted_mode'])) {
            $error = $this->validation_status;
            $error_desc = "restricted_mode must be provided!";
            $expObj['restricted_mode'] = $error_desc;
        }
        return array($error, $error_desc, $expObj);
    }
    private function emailSend($permission_request,$table_data)
    {
        if (isset($permission_request['addPermissions']) && count($permission_request['addPermissions']) > 0) {

            foreach ($permission_request['addPermissions'] as $key => $value) {
                if (!empty($value)) {
                    $this->Notification->sendEmail(array(
                        "permission_type" => $this->permission[$value['role']],
                        "email_from" => SUPPORT_EMAIL,
                        "email_to" => $value['email'],
                        "unique_url" => $table_data['unique_url'],
                        "title" => $table_data['title'],
                        "template" => "permission_granted_email",
                        "subject" => "Permission Granted",
                    ));
                }


            }

        }

    }
    private function addPermission($request)
    {
        $PermissionTable = ClassRegistry::init('PermissionTable');
        if (isset($request[0])) {
            return $PermissionTable->saveMany($request);
        } else {
            return $PermissionTable->save($request);
        }
    }
    private function modifyPermission($requests)
    {
        $PermissionTable = ClassRegistry::init('PermissionTable');
        foreach ($requests as $key => $request) {
           $permission = $PermissionTable->find('first', [
                'conditions' => [
                    'PermissionTable.expense_id' => $request['expense_id'],
                    'PermissionTable.unique_url' => $request['unique_url'],
                    'PermissionTable.user_id' => $request['user_id']
                ]
            ]);

            $permission['PermissionTable']['role'] = $request['role'];
            $PermissionTable->save($permission);
        }
    }
    private function deletePermission($requests)
    {
        $PermissionTable = ClassRegistry::init('PermissionTable');
        foreach ($requests as $key => $request) {
            $permission = $PermissionTable->find('first', [
                'conditions' => [
                    'PermissionTable.expense_id' => $request['expense_id'],
                    'PermissionTable.unique_url' => $request['unique_url'],
                    'PermissionTable.user_id' => $request['user_id']
                ],
                'fields' => ['PermissionTable.id']
            ]);


            if (!empty($permission)) {
                $PermissionTable->delete($permission['PermissionTable']['id']);
            }
        }
    }

    private function addUserGroup($request)
    {
        $userGroup = ClassRegistry::init('UserGroup');
        if (isset($request[0])) {
            foreach ($request as $key => $value) {
                $data = $userGroup->find('first', [
                    'conditions' => [
                        'UserGroup.user_id' => $value['user_id'],
                        'UserGroup.unique_url' => $value['unique_url']
                    ]
                ]);
                if (empty($data)) {
                    return $userGroup->save($value);
                }
            }
            //return $userGroup->saveMany($request);
        } else {
            $data = $userGroup->find('first', [
                'conditions' => [
                    'UserGroup.user_id' => $request['user_id'],
                    'UserGroup.unique_url' => $request['unique_url']
                ]
            ]);
            if (empty($data)) {
                return $userGroup->save($request);
            }
        }
    }
    private function deleteUserGroup($requests)
    {
        $userGroup = ClassRegistry::init('UserGroup');
        foreach ($requests as $key => $request) {
            $group = $userGroup->find('first', [
                'conditions' => [
                    'UserGroup.unique_url' => $request['unique_url'],
                    'UserGroup.user_id' => $request['user_id']

                ],
                'fields' => ['UserGroup.id']
            ]);


            if (!empty($group)) {
                $userGroup->delete($group['UserGroup']['id']);
            }
        }
    }
    private function permissionRequestValidate($object)
    {
        //check validity
        $error = "";
        $error_desc = "";
        $expObj = array();

        if (empty($object['expense_id'])) {
            $error = $this->validation_status;
            $error_desc = "expense_id must be provided!";
            $expObj['expense_id'] = $error_desc;
        }
        if (empty($object['unique_url'])) {
            $error = $this->validation_status;
            $error_desc = "unique_url must be provided!";
            $expObj['unique_url'] = $error_desc;
        }
        if (empty($object['user_id']) || !is_numeric($object['user_id'])) {
            $error = $this->validation_status;
            $error_desc = "user_id must be provided as numaric!";
            $expObj['user_id'] = $error_desc;
        }
        if (empty($object['profile_id']) ||  !filter_var($object['profile_id'], FILTER_VALIDATE_EMAIL)) {
            $error = $this->validation_status;
            $error_desc = "profile_id must be email!";
            $expObj['profile_id'] = $error_desc;
        }
        if (!empty($object['addPermissions']) && is_array($object['addPermissions'])) {
            $expObj["addPermissions"] = [];
            foreach ($object['addPermissions'] as $index => $perm) {
                $error_data = [];
                if (empty($perm['email']) || !filter_var($perm['email'], FILTER_VALIDATE_EMAIL)) {
                    $error = $this->validation_status;
                    $error_desc = "Invalid Email!";
                    $error_data["email"] = 'Valid email is required.';
                }
                if (!isset($perm['role']) || !is_numeric($perm['role']) || !array_key_exists($perm['role'],$this->permission)) {
                    $error = $this->validation_status;
                    $error_desc = "Invalid Permission!";
                    $error_data["role"] = 'Valid Permission is required.';
                }
                $expObj["addPermissions"][] = $error_data;
            }
        }
        if (!empty($object['modifyPermissions']) && is_array($object['modifyPermissions'])) {
            $expObj["modifyPermissions"] = [];
            foreach ($object['modifyPermissions'] as $index => $perm) {
                $error_data = [];
                if (empty($perm['email']) || !filter_var($perm['email'], FILTER_VALIDATE_EMAIL)) {
                    $error = $this->validation_status;
                    $error_desc = "Invalid Email!";
                    $error_data["email"] = 'Valid email is required.';
                }
                if (!isset($perm['role']) || !is_numeric($perm['role']) || !array_key_exists($perm['role'],$this->permission)) {
                    $error = $this->validation_status;
                    $error_desc = "Invalid Permission!";
                    $error_data["role"] = 'Valid Permission is required.';
                }
                $expObj["modifyPermissions"][] = $error_data;
            }
        }
        if (!empty($object['deletePermissions']) && is_array($object['deletePermissions'])) {
            $expObj["deletePermissions"] = [];
            foreach ($object['deletePermissions'] as $index => $perm) {
                $error_data = [];
                if (empty($perm['email']) || !filter_var($perm['email'], FILTER_VALIDATE_EMAIL)) {
                    $error = $this->validation_status;
                    $error_desc = "Invalid Email!";
                    $error_data["email"] = 'Valid email is required.';
                }
                $expObj["deletePermissions"][] = $error_data;
            }
        }
        if (empty($object['addPermissions']) && empty($object['modifyPermissions']) && empty($object['deletePermissions'])) {
            $error = $this->validation_status;
            $error_desc = "At least one of addPermissions, modifyPermissions, or deletePermissions is required.";
        }
        return array($error, $error_desc, $expObj);
    }
    private function validatePermissionRequest($object,$create_user)
    {
        $error = "";
        $error_desc = "";
        $expObj = [];
        if(!empty($object['addPermissions']) || !empty($object['modifyPermissions']) || !empty($object['deletePermissions'])){

            $addPermissions = array_column($object['addPermissions'], 'email');
            if (in_array($create_user, $addPermissions)) {
                $error = "-997";
                $error_desc = $create_user." Owner can not addable!";
                $expObj['addPermissions'] = $error_desc;
            }
            $modifyPermissions = array_column($object['modifyPermissions'], 'email');
            if (in_array($create_user, $modifyPermissions)) {
                $error = "-997";
                $error_desc = $create_user." Owner can not modifyable!";
                $expObj['modifyPermissions'] = $error_desc;
            }
            $deletePermissions = array_column($object['deletePermissions'], 'email');
            if (in_array($create_user, $deletePermissions)) {
                $error = "-997";
                $error_desc = $create_user." Owner can not deleteable!";
                $expObj['deletePermissions'] = $error_desc;
            }

        }
        return  array($error, $error_desc,$expObj);

    }

    public function getRestrictionStatus($key)
    {
        return $this->restrictionStatuses[$key] ?? [
            'code' => "9999",
            'message' => 'Unknown error.'
        ];
    }
    public function getPermissionError($key)
    {
        return $this->permissionErrors[$key] ?? [
            'code' => "9999",
            'message' => 'Unknown error.'
        ];
    }
    private function sentNotificationToPermittedUsers($unique_url,$operation,$title,$message){
        $user_id = $this->Session->read('userData.id');
        $groupSetting = ClassRegistry::init('GroupSetting');
        $groupSetting = $groupSetting->find('first', [ 'conditions' => [
            'GroupSetting.unique_url' => $unique_url
        ]]);
        if(!empty($groupSetting['GroupSetting']) && !empty($groupSetting['GroupSetting']['is_restricted_mode'])){
            $permission = ClassRegistry::init('PermissionTable');
            $users = $permission->find('all', [
                'conditions' => [
                    'PermissionTable.unique_url' => $unique_url
                ],
                'fields' => ['PermissionTable.user_id']
            ]);
            $users = array_map(function($item) {
                return (int)$item['PermissionTable']['user_id'];
            }, $users);
        }else{
            $userGroup = ClassRegistry::init('UserGroup');
            $users = $userGroup->find('all', [
                'conditions' => [
                    'UserGroup.unique_url' => $unique_url
                ],
                'fields' => ['UserGroup.user_id']
            ]);
            $users = array_map(function($item) {
                return (int)$item['UserGroup']['user_id'];
            }, $users);
        }
        $users = array_diff($users, array($user_id));
        if(!empty($users)) {
            $body = "Expenses have been {$operation} in {$title} group.";
            $expense['expenses'] = json_encode($message);
            $expense['title'] = $title;
            $expense['body'] = $body;
            $expense['unique_url'] = $unique_url;
            $this->Notification->send($users, $expense);
        }

    }

    public function accessInfo()
    {
        $object = $this->request->input('json_decode');
        if (!empty($object)) {
            $data = $this->objectToArray($object);
        }
        $status_desc = "Data not found!";
        $status = "12";
        if (isset($data['unique_urls'])) {
            $saveData = array();
            foreach ($data['unique_urls'] as $key => $value) {
                $expense = $this->Expense->find('first', array(
                    'conditions' => array('Expense.unique_url' => $value)
                ));

                if (!empty($expense['Expense'])) {
                    $saveData[] = array(
                        'AccessInfo' => array(
                            'id' => $expense['Expense']['id'],
                            'unique_url' => $expense['Expense']['unique_url'],
                            'access_time' => $this->getSystemCurrentTimeStamp()
                        )
                    );
                }
            }
            if (!empty($saveData)) {
                $this->AccessInfo->saveMany($saveData);
                $status_desc = "SUCCESS";
                $status = "+000";
            }
        }
        if ($status != "+000") {
            $this->processResponse($input, $data, $status, $status_desc);
        } else {
            $input["status"] = $status;
            $input["status_desc"] = $status_desc;

            $this->set(array(
                'response' => $input,
                '_serialize' => array('response')
            ));
        }
    }

    public function sentExportLink()
    {
        $object = $this->request->input('json_decode');
        if (!empty($object)) {
            $data = $this->objectToArray($object);
        }
        if (empty($status)) {
            list($status, $status_desc, $userObj) = $this->validateUser($data['user_id']);
        }
        if (empty($status)) {
            $this->loadModel('Expense');
            $expense = $this->Expense->find('first', array(
                'conditions' => array('Expense.unique_url' => $data['unique_url'])
            ));
            if (!empty($expense['Expense'])){
                $expenseTypes = [
                    1 => 'GroupExpense',
                    2 => 'MessExpense',
                    3 => 'FamilyExpense'
                ];

                $app_name = $expenseTypes[$expense['Expense']['expense_type']] ?? 'ExpenseCount';
                $unique_url = $data['unique_url'];
                $response =  $this->ImageUpload->ReceiptExportInsideFirebase($unique_url,$app_name);

                if($response['success']){
                    $this->loadModel('ExportReceipt');

                    $this->ExportReceipt->save(array(
                        'user_id' => $data['user_id'],
                        'unique_url' => $data['unique_url'],
                        'file_path' => $response['zip_path'],
                        'expire_date' => $response['expire_time']->format('Y-m-d H:i:s')
                    ));

                $this->Notification->sendEmail(array(
                    "email_from" => SUPPORT_EMAIL,
                    "email_to" => $userObj['profile_id'],
                    "unique_url" => $unique_url,
                    "download_url"=> $response['link'],
                    "expire_time" => $response['expire_time']->format('Y-m-d H:i:s'),
                    "template" => "export_receipt_email",
                    "subject" => "Receipt download link",
                ));
                    $status = "+000";
                    $status_desc = "Receipt download link sent to your email.";
                }else{
                    $status = '13';
                    $status_desc = $response['message'];
                }
            }
            else{
                $status = '12';
                $status_desc = 'Expense not found!';
            }

            if ($status != "+000") {
                $this->processResponse($input, $data, $status, $status_desc);
            } else {
                $response["status"] = $status;
                $response["status_desc"] = $status_desc;
                $response["api_version"] = 3;
                $response["data"] = "Export receipt successfully.";
                $this->set(array(
                    'response' => $response,
                    '_serialize' => array('response')
                ));
            }
        }
    }


}