Files
ExpenseCount/app/Controller/GeservicesController.php
2026-06-25 13:03:45 +06:00

2071 lines
73 KiB
PHP

<?php
ini_set('display_errors','Off');
ini_set('error_reporting', E_ALL );
/**
* @property NotificationComponent $Notification
* @property PermissionComponent $Permission
*/
class GeservicesController extends AppController
{
var $uses = array('Expense','GroupExpense','Participant','DemoExpense','AccessInfo', 'User');
public $components = array('RequestHandler','MobileDetect','ImageUpload','Permission','Notification');
private $app_name = 'GroupExpense';
public $api_group_version = "3";
public $api_mess_version = "3"; // new date change
public $api_family_version = "3";
private $app_version = "1"; // 1= old expense date, 2= new expense date
public $force_upgrade_status = "41";
public $permission_status = "50";
public function initialize()
{
$this->api_group_version = "3";
$this->api_mess_version = "3"; // new date change
$this->api_family_version = "3";
$this->app_version = "1"; // 1= old app; 2=new app; date related
$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;
}
} else if(strlen($value["name"]) > strlen(str_replace(",","",$value["name"]))
|| strlen($value["name"]) > strlen(str_replace("|","",$value["name"]))){
$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;
}
}
$totalAmt = 0;
$partAmtArray = explode(",",$value["participant_amount"]);
foreach($partAmtArray as $index=>$item){
$partAmtDetailArray = explode("|",$item);
/* echo $partAmtDetailArray[0];
echo "<pre>";
print_r($participantIdList);
exit; */
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.02){
$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;
}
public function getAccessKey() {
$status = "+000";
$status_desc = "SUCCESS";
$error = "";
$secretKey = "";
$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(!isset($data["device_id"])) {
$status = "14";
$status_desc = "Invalid parameter sent";
}else if(empty($data["device_id"]) ){
$status = "33";
$status_desc = "Invalid device id";
} else {
$data['device_id'] = $this->request->data('device_id');
$data['created_on'] = $this->getSystemCurrentTimeStamp();
$secretKey = $data['secret_key'] = $this->getSecretKey(32);
$this->loadModel('AccessKey');
if(empty($this->AccessKey->saveAccessKey($data))){
$status = "+000";
$status_desc = "SUCCESS";
}
}
$input["status"] = $status;
$input["status_desc"] = $status_desc;
$input["api_version"] = $this->api_group_version;
$input["access_key"] = $secretKey;
if(!empty($error) || $status !="+000") {
$input["input"] = $data;
$this->loadModel('LogAppCrashes');
$crash["unique_url"] = "";
$crash["error_code"] = $status;
$crash["error_desc"] = $status_desc;
$crash["request"] = serialize($data);
$crash["response"] = serialize($secretKey);
$crash["crash_date"] = $this->getSystemCurrentTimeStamp();
$crash["ip"] = $this->getClientIp();
$crash["device_info"] = $this->getUserAgent();
$this->LogAppCrashes->insertLogAppCrashes($crash);
}
$this->set(array(
'response' => $input,
'_serialize' => array('response')
));
}
public function uploadGroupExpense() {
$object = $this->request->input('json_decode');
if(!empty($object)){
$data = $this->objectToArray($object);
}
$this->processUpload($data,false);
}
public function addGroupExpense() {
$object = $this->request->input('json_decode');
if(!empty($object)){
$data = $this->objectToArray($object);
}
$this->processUpload($data,true);
}
private function processUpload($data,$isTokenRequired) {
$status = "+000";
$status_desc = "Expense Data format is not correct!";
$unique_url = "";
$latestExpenseData = array();
$archieved = false;
$error = "";
$expense_id = "";
//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 = $data["Expense"];
$ParticipantArray = $data["Participant"];
$GroupExpenseArray = $this->setDefaultWhat($data["GroupExpense"]);
if(isset($data["app_version"])){
$this->app_version = $data["app_version"];
}
//echo $expenseArray["unique_url"];exit;
if(!empty($expenseArray["unique_url"]) && $expenseArray["unique_url"] != 'null' && !empty($expenseArray["id"])){
if(!$this->isValidExpenseUniqueURL($expenseArray["unique_url"],"1")){
$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 {
try{
$this->AccessKey->deleteAccessKey($data["device_id"]);
} catch(Exception $ex){
}
}
} 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 == ""){
$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 = "WeXpense Data Saving Failed!";
}
else {
$latestExpenseData = $this->Expense->getGroupExpenseInfoByURL($expenseIdStrArr[1]);
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
]];
}
}
$unique_url = $expenseIdStrArr[1];
$expense_id = $expenseIdStrArr[0];
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 {
if($this->app_version == "1" ){
//reset expense date for old apps
$groupExpensesList = $latestExpenseData["GroupExpense"];
if( !empty($groupExpensesList)){
foreach($groupExpensesList as $key=>$value){
$groupExpensesList[$key]["expense_date"] = $value["expense_date"];
//$groupExpensesList[$key]["expense_date_new"] = "";
}
$latestExpenseData["GroupExpense"] = $groupExpensesList;
}
}
//insert/update access info
$data["id"] = $latestExpenseData["Expense"]["id"];
$data["unique_url"] = $latestExpenseData["Expense"]["unique_url"];
$this->insertAccessInfo($data);
$status = "+000";
$status_desc = "SUCCESS";
}
}
// 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"],
"GroupExpense");
}
}
else {
$status = "22";
$status_desc = "Expense or Participant Data Saving Failed!";
}
} 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;
}
}
//validate expense(exist record,valid expense id format,length etc)
//all the participant_id in expense should be available in participant list
//summation of part-amount should be equal to paid amount
//insert into expense
// $data = $this->Expense->getGroupExpenseInfoByURL("1o30356");
//$data = array("key1"=>"value1");
//$input = $data;
//echo "<pre>";
//print_r($_POST);exit;
// var_dump([$status,$status_desc]);exit;
$input["status"] = $status;
$input["status_desc"] = $status_desc;
$input["api_version"] = $this->api_group_version;
$input["data"] = $latestExpenseData;
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();
$this->LogAppCrashes->insertLogAppCrashes($crash);
}
// $input["input"] = $data;
$input["expense_id"] = $expense_id;
$input["unique_url"] = $unique_url;
if(isset($imageUploadResponses) && !empty($imageUploadResponses)){
$input['image_upload_response'] = $imageUploadResponses;
}
/* $fp = fopen("rajib.txt","w+");
fwrite($fp,implode("=",$input));
fclose($fp); */
$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 isValidGroupExpense($paidByParticipantId,$amountString,$mergedParticipantIdList){
$result = true;
if(!empty($mergedParticipantIdList)){
if(!in_array(trim($paidByParticipantId),$mergedParticipantIdList)){
// echo "hello";
$result = false;
} else {
$participantAmtArray = explode(",",$amountString);
foreach($participantAmtArray as $index=>$item){
$participantAmtDetailsArray = explode("|",$item);
if(!in_array(trim($participantAmtDetailsArray[0]),$mergedParticipantIdList) ){
$result = false;
break;
}
}
}
} else {
$result = false;
}
/*echo $paidByParticipantId;
echo "<br/>";
print_r($mergedParticipantIdList);
echo "<br/>";
echo $result;exit;*/
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 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;
}
public function downloadExpenseCount() {
$status = "+000";
$status_desc = "SUCCESS";
$expenseType = 0;
$object = $this->request->input('json_decode');
if(!empty($object)){
$data = $this->objectToArray($object);
}
$version = "";
//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) || $data["unique_url"] == ""){
$status = "33";
$status_desc = "Invalid Unique URL";
} else {
if(isset($data["app_version"])) {
$this->app_version = $data["app_version"];
}
$expenseType = substr($data["unique_url"], 0, 1);
$version = $this->getVersion($expenseType);
if($expenseType == "1" || $expenseType == "2" ){
$latestExpenseData = $this->Expense->getGroupExpenseInfoByURL($data["unique_url"]);
if (empty($latestExpenseData)) {
$this->loadModel('Backup');
$this->Backup->restore($data["unique_url"]);
$latestExpenseData = $this->Expense->getGroupExpenseInfoByURL($data["unique_url"]);
}
$owner = false;
if(!empty($latestExpenseData['Expense']) && !empty($data['user_id'])){
$user = $this->User->getUserByUserId($data['user_id']);
if(!empty($user['User'])){
$owner = ($latestExpenseData['Expense']['user_id'] == $user['User']['id']) || ($latestExpenseData['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;
}
}
$this->loadModel('GroupSetting');
$groupSettingData = $this->GroupSetting->getGroupSettingByURL($data["unique_url"],true);
if(!empty($groupSettingData)){
$latestExpenseData['groupsettings'] = $groupSettingData;
}
$this->loadModel('PermissionTable');
$permissionlist = [];
$permissions = $this->PermissionTable->getPermissionByUrl($data["unique_url"],true);
$addPermissions = array_column($permissions, 'profile_id');
// get owner/creator info
if(!empty($latestExpenseData['Expense']['user_id'])) {
$user = $this->User->getUserByUserId($latestExpenseData['Expense']['user_id']);
}else{
$user = $this->User->getUserByProfileId($latestExpenseData['Expense']['create_user']);
}
if (!in_array($user['User']['profile_id'], $addPermissions)) {
$permissionlist[] = ['profile_id' => $user['User']['profile_id'], 'role' => OWNER];
}
if(!empty($permissions || !empty($permissionlist))){
$permissionlist = array_merge($permissionlist ?? [], $permissions);
$latestExpenseData['Permissions'] = $permissionlist;
}
//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;
}
} else if($expenseType == "6" || $expenseType == "7"){
$demoResult = $this->DemoExpense->getDemoGroupExpenseInfoByURL($data["unique_url"]);
$latestExpenseData["Expense"] = $demoResult["DemoExpense"];
$latestExpenseData["Participant"] = $demoResult["DemoParticipant"];
$latestExpenseData["GroupExpense"] = $demoResult["DemoGroupExpense"];
//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;
}
if($expenseType == "7"){
$latestExpenseData["Meal"] = $demoResult["DemoMeal"];
//reset expense 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 if($expenseType == "3" ){
$latestExpenseData = $this->Expense->getFamilyExpenseInfoByURL($data["unique_url"]);
if (empty($latestExpenseData)) {
$this->loadModel('Backup');
$this->Backup->restore($data["unique_url"]);
$latestExpenseData = $this->Expense->getFamilyExpenseInfoByURL($data["unique_url"]);
}
$owner = false;
if(!empty($latestExpenseData['Expense']) && !empty($data['user_id'])){
$user = $this->User->getUserByUserId($data['user_id']);
if(!empty($user['User'])){
$owner = ($latestExpenseData['Expense']['user_id'] == $user['User']['id']) || ($latestExpenseData['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;
}
}
//reset expense date for old apps
$familyExpensesList = $latestExpenseData["FamilyExpense"];
if($this->app_version == "1" && !empty($familyExpensesList)){
foreach($familyExpensesList as $key=>$value){
$familyExpensesList[$key]["expense_date"] = $value["expense_date"];
//$familyExpensesList[$key]["expense_date_new"] = "";
}
$latestExpenseData["FamilyExpense"] = $familyExpensesList;
}
$this->loadModel('GroupSetting');
$groupSettingData = $this->GroupSetting->getGroupSettingByURL($data["unique_url"],true);
if(!empty($groupSettingData)){
$latestExpenseData['groupsettings'] = $groupSettingData;
}
$this->loadModel('PermissionTable');
$permissionlist = [];
$permissions = $this->PermissionTable->getPermissionByUrl($data["unique_url"],true);
$addPermissions = array_column($permissions, 'profile_id');
// get owner/creator info
if(!empty($latestExpenseData['Expense']['user_id'])) {
$user = $this->User->getUserByUserId($latestExpenseData['Expense']['user_id']);
}else{
$user = $this->User->getUserByProfileId($latestExpenseData['Expense']['create_user']);
}
if (!in_array($user['User']['profile_id'], $addPermissions)) {
$permissionlist[] = ['profile_id' => $user['User']['profile_id'], 'role' => OWNER];
}
if(!empty($permissions || !empty($permissionlist))){
$permissionlist = array_merge($permissionlist ?? [], $permissions);
$latestExpenseData['Permissions'] = $permissionlist;
}
} else if($expenseType == "8"){
$demoResult = $this->DemoExpense->getDemoFamilyExpenseInfoByURL($data["unique_url"]);
$latestExpenseData["Expense"] = $demoResult["DemoExpense"];
$latestExpenseData["FamilyExpense"] = $demoResult["DemoFamilyExpense"];
}
if(empty($latestExpenseData)){
$status = "32";
$status_desc = "Data not exist for the given unique URL";
} else {
//insert/update access info
$data["id"] = $latestExpenseData["Expense"]["id"];
$data["unique_url"] = $latestExpenseData["Expense"]["unique_url"];
$this->insertAccessInfo($data);
}
}
$input["status"] = $status;
$input["status_desc"] = $status_desc;
$input["api_version"] = $version;
if( $status =="+000" ) {
//add user group if user_id exist in request
// 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'])
&& ($expenseType == "1" || $expenseType == "2" || $expenseType == "3")) {
$appType = "GroupExpense";
if($expenseType == "2") {
$appType = "MessExpense";
} else if ($expenseType == "3") {
$appType = "FamilyExpense";
}
$this->addUserGroupDuringExpenseCreate(
$data['user_id'],
$data["unique_url"],
$appType);
}
} else {
$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"] = $expenseType;
$this->LogAppCrashes->insertLogAppCrashes($crash);
}
//$input["input"] = $data;
$input["data"] = $latestExpenseData;
$this->set(array(
'response' => $input,
'_serialize' => array('response')
));
}
private function getVersion($expense_type){
if($expense_type == "1" || $expense_type == "6"){
return $this->api_group_version;
} else if($expense_type == "2" || $expense_type == "7"){
return $this->api_mess_version;
} else if($expense_type == "3" || $expense_type == "8"){
return $this->api_family_version;
}
return "";
}
//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)
*
*
*
*
*
*
*
*
*
*
*
*/
public function synGroupExpense() {
//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_group_version)) {
$status = $this->force_upgrade_status;
$status_desc = "Client require force upgrade!";
}
else {
$result = $this->Expense->getGroupExpenseInfoByURL($data["unique_url"]);
$owner = false;
if(!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;
//get DB information
$dbExpense = $result["Expense"];
$dbGroupExpenseList = $result["GroupExpense"];
$dbParticipantList = $result["Participant"];
//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"]);
}
$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;
}
}
//make assosiative array for group expense
/* $dbGroupExpenseList = $result["GroupExpense"];
$dbParticipantList = $result["Participant"]; */
//set assosiative participant
//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)){
$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"];
}
}
}
}
//echo "<pre>";
//print_r($mergedParticipantNameList);exit;
//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){
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;
}
//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)){
//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 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)){
$modifyGroupExpenseArraySuperFinal[] = $value;
} else {
$conflictArray["modifyGroupExpense"][] = $value["id"];
}
}
}
//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]);
}
}
//generate map
for($i=0;$i<count($addParticipantArrayFinal);$i++){
$maxParticipant++;
$mapRemoteAndWebId[$addParticipantArrayFinal[$i]["participant_id"]] = $maxParticipant."_0";
//remove old and put new participant id from merged list
foreach($mergedParticipantIdList as $si=>$item){
if(trim($item) == trim($addParticipantArrayFinal[$i]["participant_id"])){
$mergedParticipantIdList[$si] = $maxParticipant."_0";
//list($addGroupExpenseArrayFinal, $modifyGroupExpenseArraySuperFinal)
break;
}
}
$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;$i<count($addGroupExpenseArrayFinal);$i++){
$value = $addGroupExpenseArrayFinal[$i];
$addGroupExpenseArrayFinal[$i] = $this->getReplacedValWithParticipantId($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]);
}
}
}
}
if(!empty($modifyGroupExpenseArraySuperFinal)){
foreach($modifyGroupExpenseArraySuperFinal as $key=>$value){
//$value = $modifyGroupExpenseArraySuperFinal[$i];
$modifyGroupExpenseArraySuperFinal[$key] = $this->getReplacedValWithParticipantId($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;$i<count($addGroupExpenseArrayFinal);$i++){
$maxGroupSerialNo++;
$addGroupExpenseArrayFinal[$i]["id"] = $firstPaidByParticipantId."-".sprintf("%05d", $maxGroupSerialNo)."-".$dbExpense["id"];
}
}
//}
}
}
if($status == "+000"){
if(!empty($expenseArray)){
$error = $this->validateExpense($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 "<pre>";
// print_r($deleteParticipantArrayFinal);exit;
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){
//start check the expense date format and decide
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);
}
}
//delete multiple participant
if($error == "" && !empty($deleteParticipantArrayFinal) && $permission != VIEW_PERMIT){
$error = $this->Participant->deleteMultipleParticipant($deleteParticipantArrayFinal);
}
if($error != ""){
$status = "22";
$status_desc = "Participant or 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;
}
}
}
}
else {
$status = "22";
$status_desc = "Expense Data Update Failed!";
}
}
else {
$status = $error;
$status_desc = "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_group_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"] = 1;
$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'];
}
$input["data"] = $latestExpenseData;
$input["conflict"] = $conflictArray;
if($permission == VIEW_PERMIT){
$input["permission_conflict"] = $permission_conflict;
}
if(isset($imageDeleteResponse) && !empty(array_filter($imageDeleteResponse))) {
$input["remove_image_response"] = $imageDeleteResponse;
}
if(isset($imageUploadResponses) && !empty(array_filter($imageUploadResponses))) {
$input["upload_image_response"] = $imageUploadResponses;
}
if(isset($upload_image_response['response'])&& !empty($upload_image_response['response'])){
$input['modify_group_expense']['add_images'] = $upload_image_response['response'];
}
if(isset($deleted_image_response['response']) && !empty($deleted_image_response['response'])){
$input['modify_group_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 = '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);
}
}