api_mess_version = "3"; // new date change $this->app_version = "1"; $this->setDefaultTimeStamp(); } private function validateExpense($expenseArray){ $error = ""; if(empty($expenseArray)){ $error = "5"; } if($error == ""){ if (!array_key_exists('title', $expenseArray) || !array_key_exists('currency', $expenseArray) || !array_key_exists('language', $expenseArray) || !array_key_exists('expense_type', $expenseArray)) { $error = "6"; } } if($error == ""){ if(strlen(trim($expenseArray["title"])) < 1 || mb_strlen(trim($expenseArray["title"]),'UTF-8') > 50){ $error = "7"; } else if(strlen(trim($expenseArray["currency"])) < 1 || mb_strlen(trim($expenseArray["currency"]),'UTF-8') > 3){ if(mb_strlen(trim($expenseArray["currency"]), 'UTF-8') > 3){ $expenseArray["currency"] = substr(trim($expenseArray["currency"], 'UTF-8'), 0,3); } else { $error = "7"; } } else if( mb_strlen(trim($expenseArray["description"]),'UTF-8') > 150){ $error = "7"; } else if(strlen(trim($expenseArray["language"])) < 1 || mb_strlen(trim($expenseArray["language"]),'UTF-8') > 3){ $error = "7"; } else if(strlen(trim($expenseArray["expense_type"])) != 1){ $error = "7"; }else if(!empty($expenseArray["user_id"]) && !is_numeric($expenseArray["user_id"])){ $error = "7"; } } return $error; } private function validateParticipant($ParticipantArray){ $error = ""; if(empty($ParticipantArray)){ $error = "8"; } if($error == ""){ foreach($ParticipantArray as $key=>$value){ if (!array_key_exists('participant_id', $value) || !array_key_exists('name',$value) || !array_key_exists('is_creator', $value)) { $error = "9"; break; } $nameArray[$key] = $value["name"]; $idArray[$key] = $value["participant_id"]; //check name length if(strlen(trim($value["name"])) < 1 || mb_strlen(trim($value["name"]), 'UTF-8') > PARTICIPENT_NAME_LENGTH){ if(mb_strlen(trim($value["name"]), 'UTF-8') > PARTICIPENT_NAME_LENGTH){ $value["name"] = substr(trim($value["name"], 'UTF-8'), 0,PARTICIPENT_NAME_LENGTH); } else { $error = "10"; break; } } //check participant id format $arrayVal = explode("_", $value["participant_id"]); if(count($arrayVal) != 2){ $error = "11"; break; } else if(strlen(trim($arrayVal[0])) < 1 || strlen(trim($arrayVal[1])) < 1){ $error = "11"; break; } } //check name duplicacy if($error == ""){ $previousLength = count($nameArray); $nameArray = array_unique($nameArray); if($previousLength != count($nameArray)){ $error = "12"; } } //check id duplicacy if($error == ""){ $previousLength = count($idArray); $idArray = array_unique($idArray); if($previousLength != count($idArray)){ $error = "12"; } } } return $error; } private function validateExpenseList($GroupExpenseArray,$ParticipantArray,$isDeleteOperation = false){ $error = ""; /*if(empty($GroupExpenseArray)){ $error = "13"; }*/ if(!empty($GroupExpenseArray)){ if($error == ""){ $participantIdList = array(); foreach($ParticipantArray as $key1=>$value1){ $participantIdList[$key1] = $value1["participant_id"]; } foreach($GroupExpenseArray as $key=>$value){ if (!array_key_exists('id', $value) || !array_key_exists('what',$value) || !array_key_exists('expense_date', $value) || !array_key_exists('amount', $value) || !array_key_exists('paid_by_participant_id', $value) || !array_key_exists('is_reimbursement', $value) || !array_key_exists('participant_amount', $value) || !array_key_exists('isDetails', $value) || !array_key_exists('type', $value)) { $error = "14"; break; } //check id format is correct or not $arrayVal = explode("_", $value["id"]); if(count($arrayVal) != 2){ $error = "15"; break; } else if(strlen(trim($arrayVal[0])) < 1 || strlen(trim($arrayVal[1])) < 1){ $error = "15"; break; } $arrayVal = explode("-", $value["id"]); if(count($arrayVal) != 3){ $error = "16"; break; } else if(strlen(trim($arrayVal[0])) < 1 || strlen(trim($arrayVal[1])) < 1 || strlen(trim($arrayVal[1])) > 5 || strlen(trim($arrayVal[2])) < 1){ $error = "16"; break; } //check the participant defined in expense exist in participant list or not if(!$isDeleteOperation) { $paidBy = $value["paid_by_participant_id"]; if(!in_array($paidBy, $participantIdList)){ $error = "17"; break; } } if(isset($value["expense_type"]) && $value["expense_type"] == "2" && $value["participant_amount"] == ""){ } else { $totalAmt = 0; $partAmtArray = explode(",",$value["participant_amount"]); foreach($partAmtArray as $index=>$item){ $partAmtDetailArray = explode("|",$item); if(!$isDeleteOperation) { if(!in_array($partAmtDetailArray[0], $participantIdList)){ $error = "18"; break 2; } } $totalAmt = $totalAmt + $partAmtDetailArray[2]; } //check total amount match with the part amount or not if(number_format($totalAmt, 2) != number_format($value["amount"], 2)){ $var1 = number_format($totalAmt, 2); $var2 = number_format($value["amount"], 2); $diff = $var1-$var2; if($diff < 0){ $diff = $diff * (-1); } $diff = number_format($diff, 2); if($diff > 0.01){ $error = "19"; break; } } } //check legth is ok or not if(strlen(trim($value["what"])) < 1 || mb_strlen(trim($value["what"]),'UTF-8') > 25){ if(mb_strlen(trim($value["what"]), 'UTF-8') > 25){ $value["what"] = substr(trim($value["what"], 'UTF-8'), 0, 25); } else { $error = "20"; break; } } } } } return $error; } private function validateMealList($MealArray,$ParticipantArray){ $error = ""; //$isMessExpenseExist = false; $participantIdList = array(); //check if: Invalid key or column name found for meal array foreach($MealArray as $key=>$value){ if (!array_key_exists('date', $value) || !array_key_exists('meal_amount',$value) ) { $error = "41"; break; } } /*if( $error == "" && !empty($GroupExpenseArray)){ foreach($GroupExpenseArray as $index=>$item){ if($item["expense_type"] == "2"){ $isMessExpenseExist = true; break; } } }*/ if( $error == "" && !empty($ParticipantArray)){ foreach($ParticipantArray as $key1=>$value1){ $participantIdList[$key1] = $value1["participant_id"]; } } //check if: Meal Expense has been added but there is not meal defined yet /*if( $error == "" && $isMessExpenseExist == true && empty($MealArray)){ $error = "42"; break; }*/ //check if: Invalid participant id found in meal which is not available in participant list if( $error == "" ){ foreach($MealArray as $index=>$item){ $MealSingleArray = explode(",",$item["meal_amount"]); foreach($MealSingleArray as $key=>$value){ $MealSingleDetailsArray = explode("|",$value); if(count($MealSingleDetailsArray) != 4){ $error = "43";//Meal format is not valid break 2; }else if(!in_array($MealSingleDetailsArray[0], $participantIdList)){ $error = "44";//Invalid participant id found in meal which is not available in participant list break 2; } else if($MealSingleDetailsArray[1] < 0 || $MealSingleDetailsArray[2] < 0 || $MealSingleDetailsArray[3] < 0){ $error = "45";//Invalid meal number found break 2; } } } } return $error; } public function uploadMessExpense() { $object = $this->request->input('json_decode'); if(!empty($object)){ $data = $this->objectToArray($object); } $this->processMessExpense($data,false); } public function addMessExpense() { $object = $this->request->input('json_decode'); if(!empty($object)){ $data = $this->objectToArray($object); } $this->processMessExpense($data,true); } private function processMessExpense($data,$isTokenRequired) { $status = "+000"; $status_desc = "Expense Data format is not correct!"; $unique_url = ""; $latestExpenseData = array(); $archieved = false; $error = ""; //check maintenance mood if(MAINTENANCE_MOOD){ $status = "35"; $status_desc = "Service is in maintenance mood. Please try again later."; $error = $status; } else if(empty($data)){ $status = "31"; $status_desc = "Invalid JSON input sent"; } else { $expenseArray = (isset($data["Expense"])) ? $data["Expense"]:array(); $ParticipantArray = (isset($data["Participant"])) ? $data["Participant"]:array(); $GroupExpenseArray = $this->setDefaultWhat($data["GroupExpense"]); $MealArray = (isset($data["Meal"])) ? $data["Meal"]:array(); if(isset($data["app_version"])){ $this->app_version = $data["app_version"]; } if(!empty($expenseArray["unique_url"]) && $expenseArray["unique_url"] != 'null' && !empty($expenseArray["id"])){ if(!$this->isValidExpenseUniqueURL($expenseArray["unique_url"],"2")){ $error = "31"; } else{ $result = $this->Expense->getGroupExpenseInfoByURL($expenseArray["unique_url"]); if(!empty($result)){ $error = "32"; } else { $archieved = true; } } } //validate token if($isTokenRequired){ if(!isset($data["access_token"]) || !isset($data["device_id"]) || !isset($data["random_number"])){ if(isset($data["access_token"]) && isset($data["device_id"]) ){ $this->loadModel('AccessKey'); $data['random_number'] = $this->AccessKey->getAccessToken($data["device_id"]); // $data["random_number"] = get from database by device id and order by created date desc if(!$this->isValidToken($data["access_token"],$data["device_id"],$data["random_number"])){ //echo "some";exit; $error = "57"; // token is not valid } else { $this->AccessKey->deleteAccessKey($data["device_id"]); } } else { $error = "56"; //token is not given //device id, random number, secret key => token } } else if(!$this->isValidToken($data["access_token"],$data["device_id"],$data["random_number"])){ $error = "57"; // token is not valid } } if($error == "") { $expenseArray['user_id'] = $data['user_id']; $expenseArray['create_user'] = $data['create_user']; $error = $this->validateExpense($expenseArray); // validate user id if($error == "" && (!empty($expenseArray['user_id'] || !empty($expenseArray['create_user'] )))){ $user = []; if (!empty($expenseArray['user_id'])) { $user = $this->User->getUserByUserId($expenseArray['user_id']); } elseif (!empty($expenseArray['create_user'])) { $user = $this->User->getUserByProfileId($expenseArray['create_user']); } if (empty($user) || empty($user['User'])) { $error = "7"; $status = $error; $status_desc = "User not found!"; } } } if($error == "") { $error = $this->validateParticipant($ParticipantArray); if($error == "") { $error = $this->validateExpenseList($GroupExpenseArray,$ParticipantArray); if($error == "") { $error = $this->validateMealList($MealArray,$ParticipantArray); if($error == "") { $expenseArray["participants"] = $ParticipantArray; // $expense_id = "sdfsf"; $expenseArray["source"] = $this->getSource(new MobileDetectComponent()); $expenseArray["ip"] = $this->getClientIp(); $expenseArray["user_agent"] = $this->getUserAgent(); $expenseArray["secret_key"] = $this->getSecretKey(5); if(!empty($user['User'])){ $expenseArray['create_user'] = $user['User']['profile_id']; $expenseArray['user_id'] = $user['User']['id']; }else{ $expenseArray['create_user'] = "system"; $expenseArray['user_id'] = null; } if($this->app_version == "1") { $expenseArray["create_date"] = $this->getExpenseCreationDate($expenseArray["create_date"]); } $expenseIdStr = $this->Expense->createExpense($expenseArray,true,$archieved); if($expenseIdStr != "") { $expenseIdStrArr = explode(",",$expenseIdStr); $imageUploadResponses = null; if(!empty($GroupExpenseArray)){ foreach($GroupExpenseArray as $key=>$value){ $idPartsArray = explode("-",$GroupExpenseArray[$key]["id"]); $GroupExpenseArray[$key]["id"] = $idPartsArray[0]."-".$idPartsArray[1]."-".$expenseIdStrArr[0]; } //start check the expense date format and decide if($this->app_version == "1"){ foreach($GroupExpenseArray as $key=>$value){ $value["expense_date_old"] = $value["expense_date"]; $value["expense_date"] = $this->getIntToStrDate($value["expense_date"]); $imageUploadResponse = $this->ImageUpload->AddImageBucket($value['addImages'],$value['id'],$expenseIdStrArr[1],$this->app_name); $value['images'] = $imageUploadResponse['images']; $GroupExpenseArray[$key] = $value; $imageUploadResponses[$key] = $imageUploadResponse['response']; } } else { foreach($GroupExpenseArray as $key=>$value){ $value["expense_date_old"] = $this->getStrToIntDate($value["expense_date"]); $imageUploadResponse = $this->ImageUpload->AddImageBucket($value['addImages'],$value['id'],$expenseIdStrArr[1],$this->app_name); $value['images'] = $imageUploadResponse['images']; $GroupExpenseArray[$key] = $value; $imageUploadResponses[$key] = $imageUploadResponse['response']; } } $error = $this->GroupExpense->addMultipleGroupExpense($GroupExpenseArray,$expenseIdStrArr[0]); } if($error != ""){ $status = "22"; $status_desc = "MessXpense Data Saving Failed!"; } else { // $unique_url = $expenseIdStrArr[1]; $expense_id = $expenseIdStrArr[0]; if(!empty($MealArray)){ //start check the expense date format and decide if($this->app_version == "1"){ foreach($MealArray as $key=>$value){ $value["date_old"] = $value["date"]; $value["date"] = $this->getIntToStrDate($value["date"]); $MealArray[$key] = $value; } } else { foreach($MealArray as $key=>$value){ $value["date_old"] = $this->getStrToIntDate($value["date"]); $MealArray[$key] = $value; } } $error = $this->Meal->addMultipleMeal($MealArray,$expenseIdStrArr[0]); } if($error != ""){ $status = "46"; $status_desc = "Meal Data Saving Failed!"; } else { $latestExpenseData = $this->Expense->getGroupExpenseInfoByURL($unique_url); if(!empty($user['User'])) { $this->loadModel('GroupSetting'); $mode = isset($data['GroupSetting']['is_restricted_mode'])?$data['GroupSetting']['is_restricted_mode']:0; $request = [ 'is_restricted_mode' => $mode, 'expense_id' => $latestExpenseData['Expense']['id'], 'unique_url' => $expenseIdStrArr[1] ]; $groupSettingData = $this->GroupSetting->saveGroupSetting($request); if(!empty($groupSettingData['GroupSetting'])) { $latestExpenseData['GroupSetting'] = [ "categories" => $groupSettingData ['GroupSetting']['categories'], "version" => $groupSettingData ['GroupSetting']['version'], "is_restricted_mode" => $groupSettingData ['GroupSetting']['is_restricted_mode'] ]; } $permission_request = [ 'expense_id' => $latestExpenseData['Expense']['id'], 'unique_url' => $expenseIdStrArr[1], 'profile_id' => $user['User']['profile_id'], 'user_id' => $user['User']['id'], "role" => OWNER ]; $PermissionTable = ClassRegistry::init('PermissionTable'); $permission = $PermissionTable->addPermission($permission_request); if(!empty($permission)) { $latestExpenseData['Permissions'] = [[ 'profile_id' => $user['User']['profile_id'], "role" => OWNER ]]; } } if(empty($latestExpenseData)) { $status = "34"; $status_desc = "Data successfully inserted but can not retrieve latest data.Please try to reload again with unique URL."; } else { //reset expense date for old apps $groupExpensesList = $latestExpenseData["GroupExpense"]; if($this->app_version == "1" && !empty($groupExpensesList)){ foreach($groupExpensesList as $key=>$value){ $groupExpensesList[$key]["expense_date"] = $value["expense_date"]; //$groupExpensesList[$key]["expense_date_new"] = ""; } $latestExpenseData["GroupExpense"] = $groupExpensesList; } //reset meal date for old apps $mealList = $latestExpenseData["Meal"]; if($this->app_version == "1" && !empty($mealList)){ foreach($mealList as $key=>$value){ $mealList[$key]["date"] = $value["date"]; //$mealList[$key]["date_new"] = ""; } $latestExpenseData["Meal"] = $mealList; } $status = "+000"; $status_desc = "SUCCESS"; //insert/update access info $data["id"] = $latestExpenseData["Expense"]["id"]; $data["unique_url"] = $latestExpenseData["Expense"]["unique_url"]; $this->insertAccessInfo($data); } } } // add data to user group table and update myProfileUser firebase version if( isset($data['user_id']) && !empty($data['user_id']) && isset($data['unique_url']) && !empty($data['unique_url']) ) { $this->addUserGroupDuringExpenseCreate( $data['user_id'], $data["unique_url"], "MessExpense"); } } else { $status = "22"; $status_desc = "Expense or Participant Data Saving Failed!"; } } else { $status = $error; $status_desc = "Meal Data format is not valid"; } } else { $status = $error; $status_desc = "WeXpense Data format is not valid"; } } else { $status = $error; $status_desc = "Participant Data format is not valid"; } } else { $status = $error; $status_desc = $status_desc; } } $input["status"] = $status; $input["status_desc"] = $status_desc; $input["api_version"] = $this->api_mess_version; if(!empty($error) || $status !="+000" ) { $input["input"] = $data; $this->loadModel('LogAppCrashes'); $crash["unique_url"] = $unique_url; $crash["error_code"] = $status; $crash["error_desc"] = $status_desc; $crash["request"] = serialize($data); $crash["response"] = serialize($latestExpenseData); $crash["crash_date"] = $this->getSystemCurrentTimeStamp(); $crash["ip"] = $this->getClientIp(); $crash["device_info"] = $this->getUserAgent(); $crash["expense_type"] = 2; $this->LogAppCrashes->insertLogAppCrashes($crash); } //$input["input"] = $data; $input["data"] = $latestExpenseData; $input["expense_id"] = $expense_id; $input["unique_url"] = $unique_url; if(isset($imageUploadResponses) && !empty($imageUploadResponses)){ $input["image_upload_response"] = $imageUploadResponses; } $this->set(array( 'response' => $input, '_serialize' => array('response') )); } private function getSecretKey($length = 10){ $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; $charactersLength = strlen($characters); $randomString = ''; for ($i = 0; $i < $length; $i++) { $randomString .= $characters[rand(0, $charactersLength - 1)]; } return $randomString; } private function isParticipantInvolveInExpense($participantId,$expenseList){ $result = false; if(!empty($expenseList)){ foreach($expenseList as $key=>$value){ if(trim($value["paid_by_participant_id"]) == trim($participantId)){ $result = true; break; } $participantAmtArray = explode(",",$value["participant_amount"]); foreach($participantAmtArray as $index=>$item){ $participantAmtDetailsArray = explode("|",$item); if(trim($participantAmtDetailsArray[0]) == trim($participantId)){ $result = true; break 2; } } } } return $result; } private function isParticipantInvolveInMeal($participantId,$mealList){ $result = false; if(!empty($expenseList)){ foreach($mealList as $key=>$value){ $participantMealArray = explode(",",$value["meal_amount"]); foreach($participantMealArray as $index=>$item){ $participantMealDetailsArray = explode("|",$item); if(trim($participantMealDetailsArray[0]) == trim($participantId)){ $result = true; break 2; } } } } return $result; } private function isValidGroupExpense($paidByParticipantId,$amountString,$mergedParticipantIdList,$expense_type=1){ $result = true; if(!empty($mergedParticipantIdList)){ if(!in_array(trim($paidByParticipantId),$mergedParticipantIdList)){ // echo "hello"; $result = false; } else if($expense_type == 1){ $participantAmtArray = explode(",",$amountString); foreach($participantAmtArray as $index=>$item){ $participantAmtDetailsArray = explode("|",$item); if(!in_array(trim($participantAmtDetailsArray[0]),$mergedParticipantIdList) ){ $result = false; break; } } } } else { $result = false; } return $result; } private function isValidMeal($meal_amount,$mergedParticipantIdList){ $result = true; if(!empty($mergedParticipantIdList)){ $mealAmtArray = explode(",",$meal_amount); foreach($mealAmtArray as $index=>$item){ $mealAmtDetailsArray = explode("|",$item); if(!in_array(trim($mealAmtDetailsArray[0]),$mergedParticipantIdList) ){ $result = false; break; } } } else { $result = false; } return $result; } private function isMealDateExistInDB($date,$dbMealList){ $result = false; if(!empty($dbMealList)){ foreach($dbMealList as $index=>$item){ if($date == $item["date"]){ $result = true; break; } } } return $result; } private function getReplacedValWithParticipantId($value,$mapRemoteAndWebId){ if(array_key_exists($value["paid_by_participant_id"], $mapRemoteAndWebId)){ $value["paid_by_participant_id"] = $mapRemoteAndWebId[$value["paid_by_participant_id"]]; } $amountStrArray = explode(",",$value["participant_amount"]); foreach($amountStrArray as $index=>$item){ $amountStrDetailArray = explode("|",$item); if(array_key_exists($amountStrDetailArray[0], $mapRemoteAndWebId)){ $amountStrDetailArray[0] = $mapRemoteAndWebId[$amountStrDetailArray[0]]; } $amountStrArray[$index] = implode("|",$amountStrDetailArray); } $value["participant_amount"] = implode(",",$amountStrArray); return $value; } private function getReplacedValWithParticipantIdForMeal($value,$mapRemoteAndWebId){ $mealStrArray = explode(",",$value["meal_amount"]); foreach($mealStrArray as $index=>$item){ $mealStrDetailArray = explode("|",$item); if(array_key_exists($mealStrDetailArray[0], $mapRemoteAndWebId)){ $mealStrDetailArray[0] = $mapRemoteAndWebId[$mealStrDetailArray[0]]; } $mealStrArray[$index] = implode("|",$mealStrDetailArray); } $value["meal_amount"] = implode(",",$mealStrArray); return $value; } private function setExpenseLogInfo($dbExpense,$newExpense,$participantList,$oldCurrency,$newCurrency,$indicator){ //$indicator = 1 means edited, $indicator = 2 means deleted if(!empty($participantList)){ $newExpense["previous_desc"] = $this->getGeneratedLog($dbExpense,$participantList,$oldCurrency); //take from db expense if($indicator == 1){ $newExpense["new_desc"] = $this->getGeneratedLog($newExpense,$participantList,$newCurrency); ;// take from $newExpense; } else if($indicator == 2){ $newExpense["new_desc"] = "deleted"; } $newExpense["previous_paid_by"] = $participantList[$dbExpense["paid_by_participant_id"]]["name"]; } return $newExpense; } private function getGeneratedLog($expenseObj,$participantList,$currency){ $logStr = ""; $logStr .= "[Title:".$expenseObj["what"]."],"; $logStr .= "[PaidBy:".$participantList[$expenseObj["paid_by_participant_id"]]["name"]."],"; $logStr .= "[Date:".$expenseObj["expense_date"]."],"; $logStr .= "[Amount:".$expenseObj["amount"].' '.$currency."],"; $logStr .= "[Involves:"; $participantAmtStrArray = explode(",",$expenseObj["participant_amount"]); foreach($participantAmtStrArray as $key=>$value) { $dataArray = explode("|",$value); if($key == 0){ $logStr .= $participantList[$dataArray[0]]["name"]."=".$dataArray[2]; } else { $logStr .= ",".$participantList[$dataArray[0]]["name"]."=".$dataArray[2]; } } $logStr .= "]"; return $logStr; } //Rules of Synchronization: /*#EditExpense * * 1. Web and remote application version should be same * 2. Expense related data should be modified then only it will update web Database.If nothing has been * changed in remoate applicaiton, the value should be empty.(optional) * * * * #AddGroupExpenseList = * 1. The participants who are involved in a particular group expense should be available * in merged participant list(merge between web and remote participant list). * * * #EditGroupExpenseList * 1. The record should be available in web database. * 2. Web and remote application version should be same for a particular record. = * 3. The participant who are involved in the record, should be available in merged * participant list(merge between web and remote participant list). * * * * * * #DeleteGroupExpenseList * 1. The record should be available in web database * 2. Web and remote application version should be same for a particular record. * * * * * #AddParticipantList * 1. The name of the participant can not be duplicat in web database * * * * * #EditParticipantList * 1. The record should be available in web database * 2. Web and remote application version should be same for a particular record. * 3. The name of the participant can not be duplicat in web database * 4. The name of the participant can not be available in give AddParticipantList(optional) * * * #DeleteParticipantList * 1. The record should be available in web database. * 2. Web and remote application version should be same for a particular record. * 3. The participant who created the account, can not be deleted. * 4. The participant can not be exist in any web group expense as well as given add and edit group expense list( after as well as,not mendatory) * * * * #AddMeal * 1. The meal date should not exist in database * 2. The particpant id exist in meal_amount should be available in merged participant list * * #EditMeal * 1. The meal data should be available in database * 2. The participant id exist in meal_amount should be available in merged participant list * 3. The version should be matchd with database version * * * #DeleteMeal * 1. The meal date should be available in database * 2. The version should be matched with database version * * * * * * */ public function synMessExpense() { //actions // new participant should be Shimul,Masbha;id should be 221 and 222 // The name "Ashraf" will be modified to Somen // The participants soup should be deleted $status = "+000"; $status_desc = "SUCCESS"; $error = ""; $latestExpenseData = array(); $conflictArray = array(); $object = $this->request->input('json_decode'); if(!empty($object)){ $data = $this->objectToArray($object); } //check maintenance mood if(MAINTENANCE_MOOD){ $status = "35"; $status_desc = "Service is in maintenance mood. Please try again later."; $error = $status; } else if(empty($data)){ $status = "31"; $status_desc = "Invalid JSON input sent"; } else if(empty($data["unique_url"]) || $data["unique_url"] == ""){ $status = "33"; $status_desc = "Invalid Unique URL"; }else if(isset($data["api_version"]) && !empty($data["api_version"]) && $this->isForceUpgradeRequire($data["api_version"], $this->api_mess_version)) { $status = $this->force_upgrade_status; $status_desc = "Client require force upgrade!"; } else { $result = $this->Expense->getGroupExpenseInfoByURL($data["unique_url"]); $owner = false; if(!empty($result['Expense']) && !empty($data['user_id'])){ $user = $this->User->getUserByUserId($data['user_id']); if(!empty($user['User'])){ $owner = ($result['Expense']['user_id'] == $user['User']['id']) || ($result['Expense']['create_user'] == $user['User']['profile_id']); } } if(!$owner) { $permission = $this->Permission->PermissionByUserId($data["unique_url"], $data['user_id']); if ($permission == NO_PERMIT) { $this->set(array( 'response' => ['status' => $this->permission_status, 'status_desc' => "You are not authorized to this page.Please Provide valid user id."], '_serialize' => array('response') )); return; } } //check backup or archive data if(empty($result)){ $this->loadModel('Backup'); $this->Backup->restore($data["unique_url"]); $result = $this->Expense->getGroupExpenseInfoByURL($data["unique_url"]); } if(empty($result)){ $status = "32"; $status_desc = "Data not exist for the given unique URL"; } else { //Conflict Array $conflictArray["Expense"] = NULL; $conflictArray["addParticipant"] = NULL; $conflictArray["modifyParticipant"] = NULL; $conflictArray["deleteParticipant"] = NULL; $conflictArray["addGroupExpense"] = NULL; $conflictArray["modifyGroupExpense"] = NULL; $conflictArray["deleteGroupExpense"] = NULL; $conflictArray["addMeal"] = NULL; $conflictArray["modifyMeal"] = NULL; $conflictArray["deleteMeal"] = NULL; //get DB information $dbExpense = $result["Expense"]; $dbGroupExpenseList = $result["GroupExpense"]; $dbParticipantList = $result["Participant"]; $dbMealList = $result["Meal"]; //set data $currency = $dbExpense["currency"]; //get user's input $expenseArray = array(); if(isset($data["Expense"]) && !empty($data["Expense"])){ $expenseArray = $data["Expense"]; } $addParticipantArray = array(); $modifyParticipantArray = array(); $deleteParticipantArray = array(); $addGroupExpenseArray = array(); $modifyGroupExpenseArray = array(); $deleteGroupExpenseArray = array(); if (isset($data["addParticipant"]) && !empty($data["addParticipant"])) { $addParticipantArray = $data["addParticipant"]; } if (isset($data["modifyParticipant"]) && !empty($data["modifyParticipant"])) { $modifyParticipantArray = $data["modifyParticipant"]; } if (isset($data["deleteParticipant"]) && !empty($data["deleteParticipant"])) { $deleteParticipantArray = $data["deleteParticipant"]; } if (isset($data["addGroupExpense"]) && !empty($data["addGroupExpense"])) { $addGroupExpenseArray = $this->setDefaultWhat($data["addGroupExpense"]); } if (isset($data["modifyGroupExpense"]) && !empty($data["modifyGroupExpense"])) { $modifyGroupExpenseArray = $this->setDefaultWhat($data["modifyGroupExpense"]); } if (isset($data["deleteGroupExpense"]) && !empty($data["deleteGroupExpense"])) { $deleteGroupExpenseArray = $this->setDefaultWhat($data["deleteGroupExpense"]); } $addMealArray = array(); $modifyMealArray = array(); $deleteMealArray = array(); if (isset($data["addMeal"]) && !empty($data["addMeal"])) { $addMealArray = $data["addMeal"]; } if (isset($data["modifyMeal"]) && !empty($data["modifyMeal"])) { $modifyMealArray = $data["modifyMeal"]; } if (isset($data["deleteMeal"]) && !empty($data["deleteMeal"])) { $deleteMealArray = $data["deleteMeal"]; } $mergedParticipantIdList= array(); $mergedParticipantNameList = array(); if(isset($data["app_version"])){ $this->app_version = $data["app_version"]; } //Filter expense if(!empty($expenseArray) && $expenseArray["version"] < $dbExpense["version"] ){ $conflictArray["Expense"] = $expenseArray; $expenseArray = NULL; } else if(!empty($expenseArray) ){ $expenseArray["version"] = $expenseArray["version"]+1; $currency = $expenseArray["currency"]; if($expenseArray["version"] > 999){ $expenseArray["version"] = 1; } } //Filter participant List if(!empty($dbParticipantList)){ foreach($dbParticipantList as $key=>$value){ $dbAsParticipantList[$value["participant_id"]] = $value; $dbParticipantNameList[$key] = $value["name"]; array_push($mergedParticipantIdList,trim($value["participant_id"])); array_push($mergedParticipantNameList,trim($value["name"])); } //reset delete participant list if(!empty($deleteParticipantArray)){ if(empty($dbAsParticipantList)){ $deleteParticipantArrayFinal = $deleteParticipantArray; } else{ $i = 0; foreach($deleteParticipantArray as $key=>$value){ if(array_key_exists($value["participant_id"],$dbAsParticipantList) && $value["version"] == $dbAsParticipantList[$value["participant_id"]]["version"] && $value["is_creator"] != "1"){ //For delete,check the participant id has entry in db expense list,or given expense lsit //if exist,remove it from delete list if(!$this->isParticipantInvolveInExpense($value["participant_id"],$dbGroupExpenseList) && !$this->isParticipantInvolveInMeal($value["participant_id"],$dbMealList)){ $deleteParticipantArrayFinal[$i++] = $value;// Final ready if (($key = array_search(trim($value["participant_id"]), $mergedParticipantIdList)) !== false) { $mergedParticipantIdList = array_diff($mergedParticipantIdList, array($value["participant_id"])); $mergedParticipantNameList = array_diff($mergedParticipantNameList, array($value["name"])); } } } else { $conflictArray["deleteParticipant"][] = $value["participant_id"]; } } } } //reset edit participant list if(!empty($modifyParticipantArray) && !empty($dbAsParticipantList)){ $i = 0; foreach($modifyParticipantArray as $key=>$value){ if(array_key_exists($value["participant_id"],$dbAsParticipantList) && $value["version"] == $dbAsParticipantList[$value["participant_id"]]["version"] && !in_array($value["name"],$mergedParticipantNameList)){ //For edit, check any participant already exist id DB or not which is mentioned in edit //if exist, just ignor the participant,otherwise edit it $modifyParticipantArrayFinal[$i++] = $value; // Final ready } else { $conflictArray["modifyParticipant"][] = $value["participant_id"]; } } } } else { //if there are not data in database then just assign final $modifyParticipantArrayFinal = NULL; $deleteParticipantArrayFinal = NULL; } //Filter Group Expense List if(!empty($dbGroupExpenseList)){ foreach($dbGroupExpenseList as $key=>$value){ $dbAsGroupExpenseList[$value["id"]] = $value; } //reset edit group expense list if(!empty($modifyGroupExpenseArray)){ if(empty($dbAsGroupExpenseList)){ $modifyGroupExpenseArrayFinal = $modifyGroupExpenseArray; } else{ $i = 0; //prepare log participant list to show modified participant name in logs if(!empty($dbAsParticipantList)){ foreach($dbAsParticipantList as $key=>$value){ $logParticipantList[$key] = $value; } } if(!empty($modifyParticipantArrayFinal)){ foreach($modifyParticipantArrayFinal as $key=>$value){ $logParticipantList[$value["participant_id"]] = $value; } } if(!empty($addParticipantArray)){ foreach($addParticipantArray as $key=>$value){ $logParticipantList[$value["participant_id"]] = $value; } } //set logs for modify foreach($modifyGroupExpenseArray as $key=>$value){ // echo $value["version"]; // echo "
"; // echo $dbAsGroupExpenseList[$value["id"]]["version"];exit; if(array_key_exists($value["id"],$dbAsGroupExpenseList) && $value["version"] == $dbAsGroupExpenseList[$value["id"]]["version"]){ $value = $this->setExpenseLogInfo($dbAsGroupExpenseList[$value["id"]],$value,$logParticipantList,$dbExpense["currency"],$currency,1); $modifyGroupExpenseArrayFinal[$value["id"]] = $value; // Final ready } else { $conflictArray["modifyGroupExpense"][] = $modifyGroupExpenseArray[$key]["id"]; } } } } //reset delete group expense list if(!empty($deleteGroupExpenseArray)){ if(empty($dbAsGroupExpenseList)){ $deleteGroupExpenseArrayFinal = $deleteGroupExpenseArray; } else{ $i = 0; foreach($deleteGroupExpenseArray as $key=>$value){ if(array_key_exists($value["id"],$dbAsGroupExpenseList) && $value["version"] == $dbAsGroupExpenseList[$value["id"]]["version"]){ $value = $this->setExpenseLogInfo($dbAsGroupExpenseList[$value["id"]],$value,$dbAsParticipantList,$dbExpense["currency"],$currency,2); $deleteGroupExpenseArrayFinal[$i++] = $value;// Final ready } else { $conflictArray["deleteGroupExpense"][] = $value["id"]; } } } } } else { //if there are not data in database then just assign final $modifyGroupExpenseArrayFinal = NULL; $deleteGroupExpenseArrayFinal = NULL; } //Filter Meal List if(!empty($dbMealList)){ foreach($dbMealList as $key=>$value){ $dbAsMealList[$value["id"]] = $value; } //reset edit Meal expense list if(!empty($modifyMealArray)){ if(empty($dbAsMealList)){ $modifyMealArrayFinal = NULL; } else{ foreach($modifyMealArray as $key=>$value){ if(array_key_exists($value["id"],$dbAsMealList) && $value["version"] == $dbAsMealList[$value["id"]]["version"]){ $validModifyObj = true; foreach($dbAsMealList as $id=>$mealObj){ if($value["id"] != $id && $value["date"] == $mealObj["date"] ){ $validModifyObj = false; break; } } if($validModifyObj == true){ $modifyMealArrayFinal[$value["id"]] = $value; // Final ready } else { $conflictArray["modifyMeal"][] = $value["date"]; } } else { $conflictArray["modifyMeal"][] = $value["date"]; } } } } //reset delete Meal list if(!empty($deleteMealArray)){ if(empty($dbAsMealList)){ $deleteMealArrayFinal = NULL; } else{ foreach($deleteMealArray as $key=>$value){ if(array_key_exists($value["id"],$dbAsMealList) && $value["version"] == $dbAsMealList[$value["id"]]["version"]){ $deleteMealArrayFinal[$i++] = $value;// Final ready } else { $conflictArray["deleteMeal"][] = $value["date"]; } } } } } else { //if there are not data in database then just assign final $modifyMealArrayFinal = NULL; $deleteMealArrayFinal = NULL; } //For add participant,check any item exist in dbParticipant or not if(!empty($addParticipantArray)){ foreach($addParticipantArray as $key=>$value){ if(!in_array($value["name"],$dbParticipantNameList)){ $addParticipantArrayFinal[] = $value; array_push($mergedParticipantIdList,trim($value["participant_id"])); } else { $conflictArray["addParticipant"][] = $value["participant_id"]; } } } //Filter add group expense final list with merged participant list if(!empty($addGroupExpenseArray)){ foreach($addGroupExpenseArray as $key=>$value){ if($this->isValidGroupExpense($value["paid_by_participant_id"],$value["participant_amount"],$mergedParticipantIdList,$value["expense_type"])){ //check if the expense already has been added $idArray = explode("-",$value["id"]); if(count($idArray) == 4){ $uniqueDeviceExpenseID = $idArray[3]; if(!$this->isItemAlreadyAdded($dbAsGroupExpenseList,$uniqueDeviceExpenseID) ){ $value["syn_add_unique_id"] = $uniqueDeviceExpenseID; $addGroupExpenseArrayFinal[] = $value; } } else { $addGroupExpenseArrayFinal[] = $value; } } else { $conflictArray["addGroupExpense"][] = $value["id"]; } } } //Filter add meal final list with merged participant list if(!empty($addMealArray)){ foreach($addMealArray as $key=>$value){ if($this->isValidMeal($value["meal_amount"],$mergedParticipantIdList) && !$this->isMealDateExistInDB($value["date"],$dbMealList)){ $addMealArrayFinal[] = $value; } else { $conflictArray["addMeal"][] = $value["date"]; } } } //Filter edit group expense final list with merged participant list if(!empty($modifyGroupExpenseArrayFinal)){ foreach($modifyGroupExpenseArrayFinal as $key=>$value){ if($this->isValidGroupExpense($value["paid_by_participant_id"],$value["participant_amount"],$mergedParticipantIdList,$value["expense_type"])){ $modifyGroupExpenseArraySuperFinal[] = $value; } else { $conflictArray["modifyGroupExpense"][] = $value["id"]; } } } //Filter edit meal final list with merged participant list if(!empty($modifyMealArrayFinal)){ foreach($modifyMealArrayFinal as $key=>$value){ if($this->isValidMeal($value["meal_amount"],$mergedParticipantIdList) ){ $modifyMealArraySuperFinal[] = $value; } } } //generate and replace participant id if(!empty($addParticipantArrayFinal)){ $maxParticipant = 0; $mapRemoteAndWebId = array(); //get max id foreach($dbParticipantList as $key=>$value){ $ParticipantIdArray = explode("_",$value["participant_id"]); if(trim($ParticipantIdArray[0]) > $maxParticipant){ $maxParticipant = trim($ParticipantIdArray[0]); } } //echo "
";
				//	print_r($addParticipantArrayFinal);exit;
					//generate map
					for($i=0;$i$item){
							 
							if(trim($item) == trim($addParticipantArrayFinal[$i]["participant_id"])){
								 
								$mergedParticipantIdList[$si] = $maxParticipant."_0";
							}
						}
						
						$addParticipantArrayFinal[$i]["participant_id"] = $maxParticipant."_0";
					}
					 
				}
					
					//replace all add expense and edit expense with the generated IDs
					if(!empty($addGroupExpenseArrayFinal)){
						$maxGroupSerialNo = 0;
						
						for($i=0;$igetReplacedValWithParticipantId($value,$mapRemoteAndWebId);
						    if($i == 0){
						    	$firstPaidByParticipantId = $addGroupExpenseArrayFinal[0]["paid_by_participant_id"];
						    	
						    }
						
						    $participantIdArray = explode("-",$addGroupExpenseArrayFinal[$i]["id"]);
					    	if($participantIdArray[0] == $firstPaidByParticipantId){
					    		if($maxGroupSerialNo < intval($participantIdArray[1])){
					    			$maxGroupSerialNo = intval($participantIdArray[1]);
					    		}
					    	}
						} 
						
					}
					
				//replace all add meal and edit meal with the generated IDs
				if(!empty($addMealArrayFinal)){ 
					foreach($addMealArrayFinal as $key=>$value){
						$addMealArrayFinal[$key] =  $this->getReplacedValWithParticipantIdForMeal($value,$mapRemoteAndWebId);			
					}					 						
				}
					
					 
				if(!empty($modifyGroupExpenseArraySuperFinal)){					
					foreach($modifyGroupExpenseArraySuperFinal as $key=>$value){
						$modifyGroupExpenseArraySuperFinal[$key] = $this->getReplacedValWithParticipantId($value,$mapRemoteAndWebId);
					}
				}
					
				if(!empty($modifyMealArraySuperFinal)){
					
					foreach($modifyMealArraySuperFinal as $key=>$value){						
						 
						$modifyMealArraySuperFinal[$key] = $this->getReplacedValWithParticipantIdForMeal($value,$mapRemoteAndWebId);					
					}
				}
				
				
				
				//Reset add group expense Id with the genered ID
				if(!empty($addGroupExpenseArrayFinal)){		


					if(!empty($dbGroupExpenseList)){
						foreach($dbGroupExpenseList as $key=>$value){
							$value_array = explode("-",$value["id"]);
					
							$current_user_array = explode("-",$addGroupExpenseArrayFinal[0]["id"]);
					
							if($maxGroupSerialNo < intval($value_array[1]) && $current_user_array[0] == $value_array[0]){
								$maxGroupSerialNo = intval($value_array[1]);
							}
						}
					}
					
					
					for($i=0;$ivalidateExpense($expenseArray);
		}
		
		 //check add,edit,delete participant list
		 if($error == ""){
		 	
		 	if(!empty($addParticipantArrayFinal)){
		 		$error = $this->validateParticipant($addParticipantArrayFinal);
		 	}
		 	
		 	if($error == "" && !empty($modifyParticipantArrayFinal)){
		 		$error = $this->validateParticipant($modifyParticipantArrayFinal);
		 	}
		 	
		 	if($error == "" && !empty($deleteParticipantArrayFinal)){
		 		$error = $this->validateDeleteParticipant($deleteParticipantArrayFinal);
		 	}
		 	
		 	if($error == ""){
		 		//set merged participant object
		 		foreach($mergedParticipantIdList as $key=>$value){
		 			$participantObjList[$key]["id"] = $value;
		 			$participantObjList[$key]["participant_id"] = $value;
		 			
		 		}
		 		
		 		//check add,edit and delete expense list
		 		 if(!empty($addGroupExpenseArrayFinal)){
		 			$error = $this->validateExpenseList($addGroupExpenseArrayFinal,$participantObjList);
		 		 }
		 		
		 		 
		 		if($error == "" && !empty($modifyGroupExpenseArraySuperFinal)){
		 			//Set logs for the modify expense activity
		 			
		 			$error = $this->validateExpenseList($modifyGroupExpenseArraySuperFinal,$participantObjList);
		 		}
		 		if($error == "" && !empty($deleteGroupExpenseArrayFinal)){
		 			//set logs for expense delete activity
		 			$error = $this->validateExpenseList($deleteGroupExpenseArrayFinal,$participantObjList,true);
		 		}
		 		//echo "
";
		 		//print_r($deleteParticipantArrayFinal);exit;
		 		if($error == ""){
		 			
			 		//check add,edit and delete expense list
			 		 if(!empty($addMealArrayFinal)){
			 			$error = $this->validateMealList($addMealArrayFinal,$participantObjList);
			 		 } 
			 		 
			 		if($error == "" && !empty($modifyMealArraySuperFinal)){
			 			//Set logs for the modify expense activity
			 			
			 			$error = $this->validateMealList($modifyMealArraySuperFinal,$participantObjList);
			 		}
			 		if($error == "" && !empty($deleteMealArrayFinal)){			 			 
			 			$error = $this->validateMealList($deleteMealArrayFinal,$participantObjList);
			 		}
		 			
		 			
			 		if($error == ""){
			 			//start from here!
			 			if(!empty($expenseArray)){
			 				$expenseArray["participants"] = $addParticipantArrayFinal;
			 				$expenseArray["source"] = $this->getSource(new MobileDetectComponent());
                            if($permission != VIEW_PERMIT) {
                                $response = $this->Expense->modifyExpense($expenseArray);
                            }
			 			}
			 			
			 			if(empty($response)){
			 				//$dbExpense
			 				
			 				//add multiple participants
			 			
			 				if(!empty($addParticipantArrayFinal) && $permission != VIEW_PERMIT){
			 					$error = $this->Participant->addMultipleParticipant($addParticipantArrayFinal,$dbExpense["id"]);
			 				}
			 				
			 				
			 				//edit multiple participants
			 				if($error == "" && !empty($modifyParticipantArrayFinal) && $permission != VIEW_PERMIT){
			 					$error = $this->Participant->modifyMultipleParticipant($modifyParticipantArrayFinal);
			 				}
			 			
			 				//add group expense
			 				if($error == "" &&  !empty($addGroupExpenseArrayFinal) && $permission != VIEW_PERMIT){
                                $imageUploadResponses = null;
			 					//start check the expense date format and decide
			 					if($this->app_version == "1"){	
			 						foreach($addGroupExpenseArrayFinal as $key=>$value){
			 							$value["expense_date_old"] = $value["expense_date"];
			 							$value["expense_date"] = $this->getIntToStrDate($value["expense_date"]);

                                        $imageUploadResponse = $this->ImageUpload->AddImageBucket($value['addImages'],$value['id'],$data['unique_url'],$this->app_name);
                                        $value['images'] = $imageUploadResponse['images'];
                                        $addGroupExpenseArrayFinal[$key] = $value;
                                        $imageUploadResponses[$key] =  $imageUploadResponse['response'];

			 						}
		 						} else {

		 							foreach($addGroupExpenseArrayFinal as $key=>$value){
		 									
		 								if(!$this->isValidNewExpenseDate($value["expense_date"])){ //remove later
		 										
		 									$tmpArray = explode("-",$value["expense_date"]);
		 									if(count($tmpArray) == "1"){
		 										$value["expense_date_old"] = $value["expense_date"];
		 										$value["expense_date"] = $this->getIntToStrDate($value["expense_date"]);
		 									} else {
		 										$error = "22";
		 										break;
		 									}
		 								} else {
		 									$value["expense_date_old"] = $this->getStrToIntDate($value["expense_date"]);
		 								}

                                        $imageUploadResponse = $this->ImageUpload->AddImageBucket($value['addImages'],$value['id'],$data['unique_url'],$this->app_name);
                                        $value['images'] = $imageUploadResponse['images'];
                                        $addGroupExpenseArrayFinal[$key] = $value;
                                        $imageUploadResponses[$key] =  $imageUploadResponse['response'];

		 							}
		 								
		 						}
		 						if(empty($error))
			 					$error = $this->GroupExpense->addMultipleGroupExpense($addGroupExpenseArrayFinal,$dbExpense["id"]);
			 				}
			 				
			 				//edit group expense
			 				if($error == "" &&  !empty($modifyGroupExpenseArraySuperFinal) && $permission != VIEW_PERMIT){
			 					
			 					if($this->app_version == "1"){
			 						foreach($modifyGroupExpenseArraySuperFinal as $key=>$value){
			 							$value["expense_date_old"] = $value["expense_date"];
			 							$value["expense_date"] = $this->getIntToStrDate($value["expense_date"]);

			 							$modifyGroupExpenseArraySuperFinal[$key] = $value;
			 						}
			 					} else {
			 						foreach($modifyGroupExpenseArraySuperFinal as $key=>$value){
			 								
			 							if(!$this->isValidNewExpenseDate($value["expense_date"])){ //remove later
			 									
			 								$tmpArray = explode("-",$value["expense_date"]);
			 								if(count($tmpArray) == "1"){
			 									$value["expense_date_old"] = $value["expense_date"];
			 									$value["expense_date"] = $this->getIntToStrDate($value["expense_date"]);
			 								} else {
			 									$error = "22";
			 									break;
			 								}
			 							} else {
			 								$value["expense_date_old"] = $this->getStrToIntDate($value["expense_date"]);
			 							}

                                        $dbimages = $this->GroupExpense->getImagesById($value['id']);
                                        $deleted_image_response = $this->ImageUpload->DeleteSingleImageBucket($dbimages['GroupExpense']['images'],$value['id'],$data["unique_url"],$this->app_name,$value['deleteImages']);

                                        $upload_image_response = $this->ImageUpload->ModifyImageBucket($deleted_image_response['images'],$value['id'],$data["unique_url"],$this->app_name,$value['addImages']);

                                        $value['images'] = $upload_image_response['images'];
			 							$modifyGroupExpenseArraySuperFinal[$key] = $value;
                                        if(!empty($upload_image_response['response']['message'])){
                                            $conflictArray["modifyGroupExpense"][$value['id']][] = $upload_image_response['response']['message'];
                                        }
			 						}
			 					}
			 					
			 					if(empty($error))
			 					$error = $this->GroupExpense->modifyMultipleGroupExpense($modifyGroupExpenseArraySuperFinal,$dbExpense["id"]);
			 				}
			 					
			 				
			 				//delete group expense
			 				if($error == "" &&  !empty($deleteGroupExpenseArrayFinal) && $permission != VIEW_PERMIT){
			 					$error = $this->GroupExpense->deleteMultipleGroupExpense($deleteGroupExpenseArrayFinal,$dbExpense["id"]);

                                 if(empty($error)) {
                                     $imageDeleteResponse = $this->ImageUpload->DeleteImageBucket($deleteGroupExpenseArrayFinal, $data['unique_url'],$this->app_name);
                                 }
			 				}
			 				
			 				
			 				//add meal expense
			 				if($error == "" &&  !empty($addMealArrayFinal) && $permission != VIEW_PERMIT){
			 					
			 					if($this->app_version == "1"){
			 						foreach($addMealArrayFinal as $key=>$value){
			 							$value["date_old"] = $value["date"];
			 							$value["date"] = $this->getIntToStrDate($value["date"]);
			 							$addMealArrayFinal[$key] = $value;
			 						}
			 					} else {
			 						foreach($addMealArrayFinal as $key=>$value){
			 							
			 							if(!$this->isValidNewExpenseDate($value["date"])){ //remove later
			 									
			 								$tmpArray = explode("-",$value["date"]);
			 								if(count($tmpArray) == "1"){
			 									$value["date_old"] = $value["date"];
			 									$value["date"] = $this->getIntToStrDate($value["date"]);
			 								} else {
			 									$error = "22";
			 									break;
			 								}
			 							} else {
			 								$value["date_old"] = $this->getStrToIntDate($value["date"]);
			 							}		 							 
			 							$addMealArrayFinal[$key] = $value;
			 						}			 							
			 					}
			 					if(empty($error))
			 					$error = $this->Meal->addMultipleMeal($addMealArrayFinal,$dbExpense["id"]);
			 				}
			 				
			 				//edit meal expense
			 				if($error == "" &&  !empty($modifyMealArraySuperFinal) && $permission != VIEW_PERMIT){
			 					
			 					if($this->app_version == "1"){
			 						foreach($modifyMealArraySuperFinal as $key=>$value){
			 							$value["date_old"] = $value["date"];
			 							$value["date"] = $this->getIntToStrDate($value["date"]);
			 							$value["old_date"] = $this->getIntToStrDate($value["old_date"]);

			 							$modifyMealArraySuperFinal[$key] = $value;
			 						}
			 					} else {
			 						foreach($modifyMealArraySuperFinal as $key=>$value){
			 							
			 							if(!$this->isValidNewExpenseDate($value["date"])){ //remove later
			 									
			 								$tmpArray = explode("-",$value["date"]);
			 								if(count($tmpArray) == "1"){
			 									$value["date_old"] = $value["date"];
			 									$value["date"] = $this->getIntToStrDate($value["date"]);
			 									$value["old_date"] = $this->getIntToStrDate($value["old_date"]);
			 								} else {
			 									$error = "22";
			 									break;
			 								}
			 							} else {
			 								$value["date_old"] = $this->getStrToIntDate($value["date"]);
			 							}

			 							$modifyMealArraySuperFinal[$key] = $value;
			 						}
			 					}
			 					
			 					if(empty($error))
			 					$error = $this->Meal->modifyMultipleMeal($modifyMealArraySuperFinal,$dbExpense["id"]);
			 				}
			 					
			 				
			 				//delete meal expense
			 				if($error == "" &&  !empty($deleteMealArrayFinal) && $permission != VIEW_PERMIT){
			 					$error = $this->Meal->deleteMultipleMeal($deleteMealArrayFinal,$dbExpense["id"]);
			 				} 
		 					
			 				//delete multiple participant
			 				if($error == "" &&  !empty($deleteParticipantArrayFinal) && $permission != VIEW_PERMIT){
			 					$error = $this->Participant->deleteMultipleParticipant($deleteParticipantArrayFinal);
			 				}
			 				
			 				 
			 			 				
			 				if($error != ""){
			 					$status = "22";
			 					$status_desc = "Participant/Group/Meal Expense Update fails";
			 				} else {
			 					$latestExpenseData = $this->Expense->getGroupExpenseInfoByURL($dbExpense["unique_url"]);

                                if (!empty($latestExpenseData['Expense'])) {
                                    $latestExpenseData['Expense']['version'] = $latestExpenseData['Expense']['version'] + 1;
                                    $this->Expense->save($latestExpenseData);
                                }

                                $this->loadModel('GroupSetting');
                                $groupSettingData = $this->GroupSetting->getGroupSettingByURL($dbExpense["unique_url"],true);
                                if(!empty($groupSettingData)){
                                    $latestExpenseData['groupsettings'] = $groupSettingData;
                                }
                                $this->loadModel('PermissionTable');
                                $permissions = $this->PermissionTable->getPermissionByUrl($dbExpense["unique_url"]);
                                if(!empty($groupSettingData) && $groupSettingData['is_restricted_mode'] == 1){
                                    $permitted_users = $permissions;
                                }else{
                                    $userGroup = ClassRegistry::init('UserGroup');
                                    $user_groups = $userGroup->find('all', [
                                        'conditions' => [
                                            'UserGroup.unique_url' => $dbExpense["unique_url"]
                                        ],
                                        'fields' => ['UserGroup.user_id']
                                    ]);
                                    $permitted_users = array_map(function ($item) {
                                        return [
                                            'user_id' => $item['UserGroup']['user_id']
                                        ];
                                    }, $user_groups);
                                }

                                $permissions = array_map(function ($permission) {
                                    unset($permission['user_id']);
                                    return $permission;
                                }, $permissions);
                                $addPermissions = array_column($permissions, 'profile_id');
                                if (!in_array($latestExpenseData['Expense']['create_user'], $addPermissions)) {
                                    $permissionlist[] =  ['profile_id'=>$latestExpenseData['Expense']['create_user'],'role'=>OWNER];
                                }

                                if(!empty($permissions || !empty($permissionlist))){
                                    $permissionlist = array_merge($permissionlist ?? [], $permissions);
                                    $latestExpenseData['Permissions'] = $permissionlist;
                                }

			 					if(empty($latestExpenseData)){
			 						$status = "25";
			 						$status_desc = "Expense  Data Updated but data fetching failed!";
			 					} else {
			 						$status = "+000";
			 						$status_desc = "SUCCESS";
			 						
			 						//insert/update access info
			 						$data["id"] = $latestExpenseData["Expense"]["id"];
			 						$data["unique_url"] = $latestExpenseData["Expense"]["unique_url"];
			 						$this->insertAccessInfo($data);
			 						
			 						//reset expense date for old apps
			 						$groupExpensesList = $latestExpenseData["GroupExpense"];
			 						if($this->app_version == "1" && !empty($groupExpensesList)){
			 							foreach($groupExpensesList as $key=>$value){
			 								$groupExpensesList[$key]["expense_date"] = $value["expense_date"];
			 								//$groupExpensesList[$key]["expense_date_new"] = "";
			 							}
			 							$latestExpenseData["GroupExpense"] = $groupExpensesList;
			 						}
			 						
			 						//reset meal date for old apps
			 						$mealList = $latestExpenseData["Meal"];
			 						if($this->app_version == "1" && !empty($mealList)){
			 							foreach($mealList as $key=>$value){
			 								$mealList[$key]["date"] = $value["date"];
			 								//$mealList[$key]["date_new"] = "";
			 							}
			 							$latestExpenseData["Meal"] = $mealList;
			 						}
			 						
			 						
			 					}
			 					
			 				}
			 				
			 			} else {
			 				$status = "22";
			 				$status_desc = "Expense  Data Update Failed!";
			 			} 
			 		} else {
			 			
			 			$status = $error;
		 				$status_desc = "Meal Data format is not valid";
			 		} 
		 			
		 		} else {
		 			$status = $error;
		 			$status_desc = "MessXpense Data format is not valid";
		 		}
		 		
		 	} else {
		 		$status = $error;
		 		$status_desc = "Participant Data format is not valid";
		 	}
		 	
		 } else {
		 	$status = $error;
		 	$status_desc = "Expense Data format is not valid";
		 }
		 
		 
	}

    if($status == $this->force_upgrade_status) {
        $status = "+000"; // return succees without execution
    }
		
	$input["status"] = $status;
	$input["status_desc"] = $status_desc;
	$input["api_version"] = $this->api_mess_version;

	if(!empty($error) || $status !="+000" ) {
		$input["input"] = $data;

		$this->loadModel('LogAppCrashes');
		$crash["unique_url"] = $data["unique_url"];
		$crash["error_code"] = $status;
		$crash["error_desc"] = $status_desc;
		$crash["request"] = serialize($data);
		$crash["response"] = serialize($latestExpenseData);
		$crash["crash_date"] = $this->getSystemCurrentTimeStamp();
		$crash["ip"] = $this->getClientIp();
		$crash["device_info"] = $this->getUserAgent();
		$crash["expense_type"] = 2;
		$this->LogAppCrashes->insertLogAppCrashes($crash);
	}

    if($permission == VIEW_PERMIT && !empty($data['Expense'])){
        $permission_conflict["Expense"] = $data['Expense'];
    }
    if($permission == VIEW_PERMIT && !empty($data['addGroupExpense'])){
        $permission_conflict["addGroupExpense"] = $data['addGroupExpense'];
    }
    if($permission == VIEW_PERMIT && !empty($data['modifyGroupExpense'])){
        $permission_conflict["modifyGroupExpense"] = $data['modifyGroupExpense'];
    }
    if($permission == VIEW_PERMIT && !empty($data['deleteGroupExpense'])){
        $permission_conflict["deleteGroupExpense"] = $data['deleteGroupExpense'];
    }
    if($permission == VIEW_PERMIT && !empty($data['addParticipant'])){
        $permission_conflict["addParticipant"] = $data['addParticipant'];
    }
    if($permission == VIEW_PERMIT && !empty($data['modifyParticipant'])){
        $permission_conflict["modifyParticipant"] = $data['modifyParticipant'];
    }
    if($permission == VIEW_PERMIT && !empty($data['deleteParticipant'])){
        $permission_conflict["deleteParticipant"] = $data['deleteParticipant'];
    }
    if($permission == VIEW_PERMIT && !empty($data['addMeal'])){
        $permission_conflict["addMeal"] = $data['addMeal'];
    }
    if($permission == VIEW_PERMIT && !empty($data['modifyMeal'])){
        $permission_conflict["modifyMeal"] = $data['modifyMeal'];
    }
    if($permission == VIEW_PERMIT && !empty($data['deleteMeal'])){
        $permission_conflict["deleteMeal"] = $data['deleteMeal'];
    }

	//$input["input"] = $data;
	$input["data"] = $latestExpenseData;
	$input["conflict"] = $conflictArray;
    if($permission == VIEW_PERMIT){
        $input["permission_conflict"] = $permission_conflict;
    }
    if(isset($imageUploadResponses) && !empty(array_filter($imageUploadResponses))){
        $input["upload_image_response"] = $imageUploadResponses;
    }
    if(isset($imageDeleteResponse) && !empty(array_filter($imageDeleteResponse))) {
        $input["remove_image_response"] = $imageDeleteResponse;
    }
    if(isset($upload_image_response['response'])&& !empty($upload_image_response['response'])){
        $input['modify_mess_expense']['add_images'] = $upload_image_response['response'];
    }
    if(isset($deleted_image_response['response']) && !empty($deleted_image_response['response'])){
        $input['modify_mess_expense']['delete_images'] = $deleted_image_response['response'];
    }

        $conflict = (!empty($permitted_users) && empty($conflictArray['Expense'])
            && empty($conflictArray['addParticipant'])
            && empty($conflictArray['modifyParticipant'])
            && empty($conflictArray['deleteParticipant'])
            && empty($conflictArray['addGroupExpense'])
            && empty($conflictArray['modifyGroupExpense'])
            && empty($conflictArray['deleteGroupExpense']));
        $expense_validate =  (!empty($addGroupExpenseArray) || !empty($modifyGroupExpenseArray)|| !empty($deleteGroupExpenseArray));

        if($conflict && $expense_validate){
            $users = array_column($permitted_users, 'user_id');
            $users = array_diff($users, array($data['user_id']));
            $title = $dbExpense["title"];
            $operation = '';
            $expense['unique_url'] = $dbExpense["unique_url"];
            if(!empty($addGroupExpenseArray)){
                $expense['expenses']['add'] =  array_map(function ($addGroupExpense) {
                    return $addGroupExpense['id'];
                },array_slice($addGroupExpenseArray,0,2));
                $operation = $operation.'added ';
            }
            if(!empty($modifyGroupExpenseArray)){
                $expense['expenses']['update'] = array_map(function ($modifyGroupExpense) {
                    return $modifyGroupExpense['id'];
                }, array_slice($modifyGroupExpenseArray,0,2));
                if(empty($operation)){
                    $operation = $operation.'updated ';
                }else{
                    $operation = $operation.',updated ';
                }

            }
            if(!empty($deleteGroupExpenseArray)){
                $expense['expenses']['delete'] = array_map(function ($deleteGroupExpense) {
                    return $deleteGroupExpense['id'];
                }, array_slice($deleteGroupExpenseArray,0,2));
                if(empty($operation)){
                    $operation = $operation.'deleted ';
                }else{
                    $operation = $operation.',deleted ';
                }

            }
            $body = "Expenses have been {$operation}in {$dbExpense["title"]} group.";
            $expense['expenses'] = json_encode($expense['expenses']);
            $expense['title'] = $title;
            $expense['body'] = $body;
            if(!empty($users)) {
                $this->Notification->send($users, $expense);
            }
        }
	$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();

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

}