>
+ */
+ public array $decorators = [];
+}
diff --git a/app/Controllers/AgentAuthController.php b/app/Controllers/AgentAuthController.php
new file mode 100644
index 0000000..f9fc4cc
--- /dev/null
+++ b/app/Controllers/AgentAuthController.php
@@ -0,0 +1,136 @@
+myLogger = \Config\Services::mylogger();
+ $this->AgentModel = new AgentModel();
+
+ }
+
+ public function verifyAgentWithMobileNumber()
+ {
+ try {
+
+ $mobile = $this->request->getJSON()->mobile;
+
+ $agentData = $this->AgentModel->where('mobile', $mobile)->where('is_active', 1)->first();
+
+
+ if (isset($agentData['id']))
+ {
+ $result = ['agent_verification' => true ,'message' => "Verified Successfully"];
+ return $this->respond(['status' => 'success','code' => 200,'data' => $result],200);
+
+ } else {
+
+ $result = ['agent_verification' => false , 'message' => "Verification Failed"];
+ return $this->respond(['status' => 'failed','code' => 404,'data' => $result],200);
+
+ }
+ } catch (\Throwable $th) {
+
+ return $this->respond(['status' => 'failed','code' => 500,'data' => $th],500);
+ }
+ }
+
+ public function verifyAgentWithEmailId()
+ {
+ try {
+
+ $email = $this->request->getJSON()->email;
+
+ $agentData = $this->AgentModel->where('email', $email)->where('is_active', 1)->first();
+
+ if (isset($agentData['id'])) {
+
+ $otp = random_int(100000, 999999);
+
+ $update = $this->AgentModel->where('email', $email)->where('is_active', 1)->set(['email_otp' => $otp])->update();
+
+ if ($update) {
+
+ $subject = 'Nhance user verification - OTP';
+ $mail_content = $otp . ' is your verification code for Nhance.';
+
+ $EmailResult = send_login_otp( $email , $subject , $mail_content);
+
+ if ($EmailResult['status'] == 'success') {
+ $result = ['agent_verification' => true, 'message' => "Verified Successfully"];
+ return $this->respond(['status' => 'success', 'code' => 200, 'data' => $result], 200);
+ } else {
+ $result = ['agent_verification' => false, 'message' => "Mail sending failed , try again"];
+ return $this->respond(['status' => 'failed', 'code' => 404, 'data' => $result], 200);
+ }
+ } else {
+ $result = ['agent_verification' => false, 'message' => "Verification failed , try again"];
+ return $this->respond(['status' => 'failed', 'code' => 404, 'data' => $result], 200);
+ }
+
+ } else {
+ $result = ['agent_verification' => false, 'message' => "User not found"];
+ return $this->respond(['status' => 'failed', 'code' => 404, 'data' => $result], 200);
+ }
+
+ } catch (\Throwable $th) {
+ return $this->respond(['status' => 'failed', 'code' => 500, 'data' => $th], 500);
+ }
+ }
+
+ public function getVerifiedAgentData()
+ {
+ try {
+
+ $otp_verification = isset($this->request->getJSON()->otp_verification) ? $this->request->getJSON()->otp_verification : null;
+ $mobile = isset($this->request->getJSON()->mobile) ? $this->request->getJSON()->mobile : null;
+
+ $otp = isset($this->request->getJSON()->otp) ? $this->request->getJSON()->otp : null;
+ $email = isset($this->request->getJSON()->email) ? $this->request->getJSON()->email : null;
+
+
+ if (isset($mobile))
+ {
+ $agentData = $this->AgentModel->where('mobile', $mobile)->where('is_active', 1)->first();
+
+ } else {
+ $agentData = $this->AgentModel->where('email', $email)->where('is_active', 1)->first();
+ }
+
+
+ if ($agentData && $otp_verification == true || $agentData && isset($this->request->getJSON()->otp) ) {
+
+ if(isset($this->request->getJSON()->otp)){
+ $this->AgentModel->where('id', $agentData['id'])->where('otp', $otp)->where('is_active', 1)->set(['otp'=>null])->update();
+ }
+
+ $result = generateJWT($agentData);
+
+ return $this->respond(['status' => 'success','code' => 200,'data' => $result],200);
+
+ } else {
+
+ return $this->respond(['status' => 'failed','code' => 404,'data' => []],200);
+ }
+
+ } catch (\Exception $e) {
+ return $this->respond(['status' => 'failed','code' => 500,'data' =>[], 'error' => $e->getMessage()],500);
+ }
+ }
+
+
+
+
+
+}
diff --git a/app/Controllers/AgentController.php b/app/Controllers/AgentController.php
new file mode 100644
index 0000000..b3a09c1
--- /dev/null
+++ b/app/Controllers/AgentController.php
@@ -0,0 +1,85 @@
+AgentModel = new AgentModel();
+ }
+
+ // =========================
+ // 1. List all records
+ // =========================
+ public function list()
+ {
+ $data = $this->AgentModel->findAll();
+ return $this->response->setJSON($data);
+ }
+
+ // =========================
+ // 2. Find single record by ID
+ // =========================
+ public function find($id = null)
+ {
+ $record = $this->AgentModel->find($id);
+
+ if (!$record) {
+ return $this->response->setJSON([
+ 'status' => 'error',
+ 'message' => 'Record not found'
+ ])->setStatusCode(404);
+ }
+
+ return $this->response->setJSON($record);
+ }
+
+ // =========================
+ // 3. Create new record
+ // =========================
+ public function create()
+ {
+ $data = $this->request->getJSON(true); // get JSON body as array
+
+ if (!$this->AgentModel->insert($data)) {
+ return $this->response->setJSON([
+ 'status' => 'error',
+ 'message' => 'Failed to insert',
+ 'errors' => $this->AgentModel->errors()
+ ])->setStatusCode(400);
+ }
+
+ return $this->response->setJSON([
+ 'status' => 'success',
+ 'message' => 'Record created successfully',
+ 'id' => $this->AgentModel->getInsertID()
+ ]);
+ }
+
+ // =========================
+ // 4. Update record by ID
+ // =========================
+ public function update($id = null)
+ {
+ $data = $this->request->getJSON(true);
+
+ if (!$this->AgentModel->update($id, $data)) {
+ return $this->response->setJSON([
+ 'status' => 'error',
+ 'message' => 'Failed to update',
+ 'errors' => $this->AgentModel->errors()
+ ])->setStatusCode(400);
+ }
+
+ return $this->response->setJSON([
+ 'status' => 'success',
+ 'message' => 'Record updated successfully'
+ ]);
+ }
+}
diff --git a/app/Controllers/BaseController.php b/app/Controllers/BaseController.php
new file mode 100755
index 0000000..689405b
--- /dev/null
+++ b/app/Controllers/BaseController.php
@@ -0,0 +1,58 @@
+
+ */
+ protected $helpers = [];
+
+ /**
+ * Be sure to declare properties for any property fetch you initialized.
+ * The creation of dynamic property is deprecated in PHP 8.2.
+ */
+ // protected $session;
+
+ /**
+ * @return void
+ */
+ public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
+ {
+ // Do Not Edit This Line
+ parent::initController($request, $response, $logger);
+
+ // Preload any models, libraries, etc, here.
+
+ // E.g.: $this->session = service('session');
+ }
+}
diff --git a/app/Controllers/Home.php b/app/Controllers/Home.php
new file mode 100755
index 0000000..5934333
--- /dev/null
+++ b/app/Controllers/Home.php
@@ -0,0 +1,11 @@
+myLogger = \Config\Services::mylogger();
+ $this->dropdownModel = new DropdownModel();
+ $this->departmentModel = new DepartmentModel();
+ $this->travelStatusModel = new TravelStatusModel();
+ $this->countryModel = new CountryModel();
+ $this->airportCodeModel = new AirportCodeModel();
+ $this->trainStationsModel = new TrainStationsModel();
+ $this->userModel = new UserModel();
+ $this->organizationModel = new OrganizationModel();
+ $this->groupModel = new GroupModel();
+ $this->policyModel = new PolicyModel();
+ $this->policyDetailsModel = new PolicyDetailsModel();
+ $this->serviceModel = new ServiceModel();
+ $this->forexPerdiemModel = new ForexPerdiemModel();
+ $this->hotelModel = new HotelModel();
+ $this->costCenterModel = new CostCenterModel();
+ $this->airlineModel = new AirlineModel();
+ $this->mailTemplateModel = new MailTemplateModel();
+ }
+
+
+ public function getDropdownMaster()
+ {
+ $data = $this->dropdownModel->select('dropdown')->groupBy('dropdown')->findAll();
+
+ if (!$data) {
+ return $this->failNotFound('No data found');
+ }
+
+ if ($data)
+ {
+ foreach ($data as &$val)
+ {
+ $temp[$val['dropdown']] = $this->dropdownModel->where('dropdown', $val['dropdown'])->where('is_active',1)->findAll();
+ }
+ }
+
+ return $this->respond(['status' => 200,'message' => 'success','data' => $temp]);
+ }
+
+
+ public function getTravelStatusMaster()
+ {
+ $data = $this->travelStatusModel->where('is_active',1)->findAll();
+
+ if (!$data) {
+ return $this->failNotFound('No data found');
+ }
+
+ return $this->respond(['status' => 200,'message' => 'success','data' => $data]);
+ }
+
+ public function getcountryMaster()
+ {
+ $data = $this->countryModel->where('is_active',1)->findAll();
+
+ if (!$data) {
+ return $this->failNotFound('No data found');
+ }
+
+ return $this->respond(['status' => 200,'message' => 'success','data' => $data]);
+ }
+
+ public function getAirlineMaster()
+ {
+ $data = $this->airlineModel->findAll();
+
+ if (!$data) {
+ return $this->failNotFound('No data found');
+ }
+
+ return $this->respond(['status' => 200,'message' => 'success','data' => $data]);
+ }
+
+
+ public function getAirportCodeMaster()
+ {
+ $type = $this->request->getGet('trip_type');
+
+ // Build the query
+ $query = $this->airportCodeModel->where('is_active', 1);
+ if ($type == 1) {
+ $query->where('Country_Code', 'IN');
+ }
+
+ // Execute the query and get the result
+ $data = $query->findAll();
+
+ // Check if data exists
+ if (empty($data)) {
+ return $this->failNotFound('No data found');
+ }
+
+ // Return success response
+ return $this->respond([
+ 'status' => 200,
+ 'message' => 'success',
+ 'data' => $data
+ ]);
+ }
+
+ public function getTrainCodeMaster()
+ {
+ $data = $this->trainStationsModel->where('is_active',1)->findAll();
+
+ if (!$data) {
+ return $this->failNotFound('No data found');
+ }
+
+ return $this->respond(['status' => 200,'message' => 'success','data' => $data]);
+ }
+
+ public function getFlightAndTrainClass()
+ {
+
+
+ $trip_type = $this->request->getGet('trip_type');
+ $user_id = $this->request->getVar('user_id');
+
+ $user = $this->userModel->where('user_id', $user_id)->first();
+
+ $groupData = $this->groupModel->find($user['group_id']);
+
+ if($groupData)
+ {
+ if($trip_type == 1) { $policyId = $groupData['domestic_policy_id'];}else{ $policyId = $groupData['international_policy_id'];}
+ dd($policyId);
+ if($policyId != null)
+ {
+ $minFlightRow = $this->policyDetailsModel->where('policy_id', $policyId)->where('service_id', 1)->get()->getRow();
+
+ $minTrainRow = $this->policyDetailsModel->where('policy_id', $policyId)->where('service_id', 2)->get()->getRow();
+
+ $minHotelRow = $this->policyDetailsModel->where('policy_id', $policyId)->where('service_id', 5)->get()->getRow();
+
+ $minFlightClassKey = $minFlightRow ? $minFlightRow->class : null;
+ $minTrainClassKey = $minTrainRow ? $minTrainRow->class : null;
+ $minHotelClassKey = $minHotelRow ? $minHotelRow->class : null;
+
+ }
+
+
+ //flight
+ $allFlightClass = $this->dropdownModel->where('dropdown', 'flight_class')->orderBy('dropdown_key','ASC')->findAll();
+ $minFlightClassKey = $minFlightClassKey ?? 0;
+ $data['flight_class'] = [];
+ foreach ($allFlightClass as $key => $value) {
+
+ if((int)$value['dropdown_key'] >= (int)$minFlightClassKey){
+ $value['is_allowed'] = 'yes';
+ array_push($data['flight_class'] , $value);
+ }else{
+ $value['is_allowed'] = 'No';
+ array_push($data['flight_class'] , $value);
+ }
+
+ }
+
+
+ //train
+ $allTrainClass = $this->dropdownModel->where('dropdown', 'train_class')->orderBy('dropdown_key','ASC')->findAll();
+ $minTrainClassKey = $minTrainClassKey ?? 0;
+ $data['train_class'] = [];
+
+ foreach ($allTrainClass as $key => $value) {
+
+ if((int)$value['dropdown_key'] >= (int)$minTrainClassKey){
+ $value['is_allowed'] = 'yes';
+ array_push($data['train_class'] , $value);
+ }else{
+ $value['is_allowed'] = 'No';
+ array_push($data['train_class'] , $value);
+ }
+
+ }
+
+ //hotel
+ $allHotelClass = $this->dropdownModel->where('dropdown', 'hotel_class')->orderBy('dropdown_key','ASC')->findAll();
+ $minHotelClassKey = $minHotelClassKey ?? 0;
+ $data['hotel_class'] = [];
+
+ foreach ($allHotelClass as $key => $value) {
+
+ if((int)$value['dropdown_key'] >= (int)$minHotelClassKey){
+ $value['is_allowed'] = 'yes';
+ array_push($data['hotel_class'] , $value);
+ }else{
+ $value['is_allowed'] = 'No';
+ array_push($data['hotel_class'] , $value);
+ }
+
+ }
+
+ }
+
+
+
+ if (!$data) {
+ return $this->failNotFound('No data found');
+ }
+
+ return $this->respond(['status' => 200,'message' => 'success','data' => $data]);
+ }
+
+
+ // Department crud
+ public function getDepartmentList()
+ {
+ $for = $this->request->getVar('for');
+
+ if (isset($for) && $for === 'table_view')
+ {
+ $data = $this->dropdownModel->where('dropdown','plan_functional_department')->findAll();
+ } else {
+ $data = $this->dropdownModel->where('dropdown','plan_functional_department')->where('is_active', 1)->findAll();
+ }
+
+ if (!$data) {
+ return $this->failNotFound('No data found');
+ }
+
+ return $this->respond(['status' => 200,'message' => 'success','data' => $data]);
+ }
+
+ public function createDepartment()
+ {
+ $data = $this->request->getJSON(true);
+
+ $data['dropdown'] = 'plan_functional_department';
+ $data['is_active'] = 1;
+ $existData = $this->dropdownModel->where('dropdown','plan_functional_department')->findAll();
+ $data['dropdown_key'] = count($existData) + 1;
+
+ if (!$this->dropdownModel->insert($data)) {
+ return $this->failValidationErrors($this->dropdownModel->errors());
+ }
+
+ return $this->respondCreated([
+ 'status' => 201,
+ 'message' => 'Department created successfully'
+ ]);
+
+ }
+
+ public function findDepartment()
+ {
+
+ $id = $this->request->getGet('id');
+
+ $data = $this->dropdownModel->where('id',$id)->find();
+
+ if (!$data) {
+ return $this->failNotFound('No data found');
+ }
+
+ return $this->respond(['status' => 200,'message' => 'success','data' => $data]);
+ }
+
+ public function updateDepartment($id = null)
+ {
+ $data = $this->request->getJSON(true);
+
+ if (!$this->dropdownModel->find($id)) {
+ return $this->failNotFound('Department not found');
+ }
+
+ if (!$this->dropdownModel->update($id, $data)) {
+ return $this->failValidationErrors($this->dropdownModel->errors());
+ }
+
+ return $this->respond([
+ 'status' => 200,
+ 'message' => 'Department updated successfully'
+ ]);
+ }
+
+
+ // Purpose of travel crud
+ public function getPurposeOfTravelList()
+ {
+ $for = $this->request->getVar('for');
+
+ if (isset($for) && $for === 'table_view')
+ {
+ $data = $this->dropdownModel->where('dropdown','plan_purpose_of_travel')->findAll();
+ } else {
+ $data = $this->dropdownModel->where('dropdown','plan_purpose_of_travel')->where('is_active', 1)->findAll();
+ }
+
+ if (!$data) {
+ return $this->failNotFound('No data found');
+ }
+
+ return $this->respond(['status' => 200,'message' => 'success','data' => $data]);
+ }
+
+ public function createPurposeOfTravel()
+ {
+ $data = $this->request->getJSON(true);
+
+ $data['dropdown'] = 'plan_purpose_of_travel';
+ $data['is_active'] = 1;
+ $existData = $this->dropdownModel->where('dropdown','plan_purpose_of_travel')->findAll();
+ $data['dropdown_key'] = count($existData) + 1;
+
+ if (!$this->dropdownModel->insert($data)) {
+ return $this->failValidationErrors($this->dropdownModel->errors());
+ }
+
+ return $this->respondCreated([
+ 'status' => 201,
+ 'message' => 'Department created successfully'
+ ]);
+
+ }
+
+ public function findPurposeOfTravel()
+ {
+
+ $id = $this->request->getGet('id');
+
+ $data = $this->dropdownModel->where('id',$id)->find();
+
+ if (!$data) {
+ return $this->failNotFound('No data found');
+ }
+
+ return $this->respond(['status' => 200,'message' => 'success','data' => $data]);
+ }
+
+ public function updatePurposeOfTravel($id = null)
+ {
+ $data = $this->request->getJSON(true);
+
+ if (!$this->dropdownModel->find($id)) {
+ return $this->failNotFound('Department not found');
+ }
+
+ if (!$this->dropdownModel->update($id, $data)) {
+ return $this->failValidationErrors($this->dropdownModel->errors());
+ }
+
+ return $this->respond([
+ 'status' => 200,
+ 'message' => 'Department updated successfully'
+ ]);
+ }
+
+ // Cost center crud
+ public function getCostCenterMaster()
+ {
+ $for = $this->request->getVar('for');
+
+ if (isset($for) && $for === 'table_view')
+ {
+ $data = $this->costCenterModel->findAll();
+ } else {
+ $data = $this->costCenterModel->where('is_active', 1)->findAll();
+ }
+
+ if (!$data) {
+ return $this->failNotFound('No data found');
+ }
+
+ return $this->respond(['status' => 200,'message' => 'success','data' => $data]);
+ }
+
+ public function createCostCenter()
+ {
+ $data = $this->request->getJSON(true);
+
+ if (!$this->costCenterModel->insert($data)) {
+ return $this->failValidationErrors($this->costCenterModel->errors());
+ }
+
+ return $this->respondCreated([
+ 'status' => 201,
+ 'message' => 'Cost Center created successfully'
+ ]);
+
+ }
+
+ public function findCostCenter()
+ {
+
+ $id = $this->request->getGet('cost_center_id');
+
+ $data = $this->costCenterModel->where('cost_center_id',$id)->find();
+
+ if (!$data) {
+ return $this->failNotFound('No data found');
+ }
+
+ return $this->respond(['status' => 200,'message' => 'success','data' => $data]);
+ }
+
+ public function updateCostCenter($id = null)
+ {
+ $data = $this->request->getJSON(true);
+
+ if (!$this->costCenterModel->find($id)) {
+ return $this->failNotFound('Cost Center not found');
+ }
+
+ if (!$this->costCenterModel->update($id, $data)) {
+ return $this->failValidationErrors($this->costCenterModel->errors());
+ }
+
+ return $this->respond([
+ 'status' => 200,
+ 'message' => 'Cost Center updated successfully'
+ ]);
+ }
+
+
+ // Forex crud
+ public function getForexPerdiemList()
+ {
+
+ $for = $this->request->getVar('for');
+
+ if (isset($for) && $for === 'table_view')
+ {
+ $data = $this->forexPerdiemModel->findAll();
+ } else {
+ $data = $this->forexPerdiemModel->where('is_active', 1)->findAll();
+ }
+
+ if (!$data) {
+ return $this->failNotFound('No data found');
+ }
+
+ return $this->respond(['status' => 200,'message' => 'success','data' => $data]);
+ }
+
+ public function createForexPerdiem()
+ {
+
+
+ try {
+
+ $data = $this->request->getJSON(true);
+
+ if (!$this->forexPerdiemModel->insert($data)) {
+ return $this->failValidationErrors($this->forexPerdiemModel->errors());
+ }
+
+ return $this->respondCreated([
+ 'status' => 201,
+ 'message' => 'Forex Perdiem created successfully'
+ ]);
+ } catch (\CodeIgniter\Database\Exceptions\DatabaseException $e) {
+
+ if (strpos($e->getMessage(), 'Duplicate entry') !== false) {
+ return $this->respond([
+ 'status' => 404,
+ 'message' => 'Duplicate entry'
+ ],404);
+ }
+
+ // For other DB-related exceptions
+ return $this->failServerError($e->getMessage());
+ }
+
+
+ }
+
+ public function findForexPerdiem()
+ {
+
+ $id = $this->request->getGet('forex_perdiem_id');
+
+ $data = $this->forexPerdiemModel->where('forex_perdiem_id',$id)->find();
+
+ if (!$data) {
+ return $this->failNotFound('No data found');
+ }
+
+ return $this->respond(['status' => 200,'message' => 'success','data' => $data]);
+ }
+
+ public function updateForexPerdiem($id = null)
+ {
+ try{
+
+ $data = $this->request->getJSON(true);
+
+ if (!$this->forexPerdiemModel->find($id)) {
+ return $this->failNotFound('Forex Perdiem not found');
+ }
+
+
+ if (!$this->forexPerdiemModel->update($id, $data)) {
+ return $this->failValidationErrors($this->forexPerdiemModel->errors());
+ }
+
+ return $this->respond([
+ 'status' => 200,
+ 'message' => 'Forex Perdiem updated successfully'
+ ]);
+
+ } catch (\CodeIgniter\Database\Exceptions\DatabaseException $e) {
+
+ if (strpos($e->getMessage(), 'Duplicate entry') !== false) {
+ return $this->respond([
+ 'status' => 404,
+ 'message' => 'Duplicate entry'
+ ]);
+ }
+
+ // For other DB-related exceptions
+ return $this->failServerError($e->getMessage());
+ }
+ }
+
+ // Hotels crud
+ public function getHotels()
+ {
+
+ $for = $this->request->getVar('for');
+
+ if (isset($for) && $for === 'table_view')
+ {
+ $hotels = $this->hotelModel->select('m_hotels.* , C.country_name')
+ ->join('m_country C', 'C.country_code = m_hotels.country_code', 'left')
+ ->findAll();
+ } else {
+ $hotels = $this->hotelModel->select('m_hotels.* , C.country_name')
+ ->join('m_country C', 'C.country_code = m_hotels.country_code', 'left')
+ ->where('m_hotels.is_active', 1)
+ ->findAll();
+ }
+
+
+ return $this->response->setJSON([
+ 'status' => 200,
+ 'message' => 'Hotel list fetched successfully',
+ 'data' => $hotels
+ ]);
+ }
+
+ public function createHotels()
+ {
+ $data = $this->request->getJSON(true);
+
+ if (!$this->hotelModel->insert($data)) {
+ return $this->failValidationErrors($this->hotelModel->errors());
+ }
+
+ return $this->respondCreated([
+ 'status' => 201,
+ 'message' => 'Hotels created successfully'
+ ]);
+
+ }
+
+ public function findHotels()
+ {
+
+ $id = $this->request->getGet('hotel_id');
+
+ $data = $this->hotelModel->where('hotel_id',$id)->find();
+
+ if (!$data) {
+ return $this->failNotFound('No data found');
+ }
+
+ return $this->respond(['status' => 200,'message' => 'success','data' => $data]);
+ }
+
+ public function updateHotels($id = null)
+ {
+ $data = $this->request->getJSON(true);
+
+ if (!$this->hotelModel->find($id)) {
+ return $this->failNotFound('Hotels not found');
+ }
+
+ if (!$this->hotelModel->update($id, $data)) {
+ return $this->failValidationErrors($this->hotelModel->errors());
+ }
+
+ return $this->respond([
+ 'status' => 200,
+ 'message' => 'Hotels updated successfully'
+ ]);
+ }
+
+
+ public function forex_signature_upload()
+ {
+
+ $data = $this->request->getPost();
+
+ // Handle file upload
+ $file = $this->request->getFile('signature');
+ if ($file && $file->isValid() && !$file->hasMoved()) {
+ $newName = $file->getRandomName(); // Generate a unique name
+ // $uploadPath = WRITEPATH.'uploads/signature';
+ $uploadPath = FCPATH.'public/assets/images/signature';
+
+ // print_r( $uploadPath); die;
+
+ // Move file to the specified directory
+ $file->move($uploadPath, $newName);
+
+ // Save file path in database
+ $path = $uploadPath . '/' . $newName;
+ } else {
+ return $this->failValidationErrors(['passport_document' => 'Invalid file upload']);
+ }
+
+ try {
+
+ $this->mailTemplateModel->set(['image_location' => $newName])->where('template_name','forex')->update();
+
+
+ return $this->respondCreated([
+ 'status' => 201,
+ 'message' => 'organization created successfully',
+ 'data' => $data
+ ]);
+ } catch (\Exception $e) {
+ return $this->failServerError('Failed to create organization: ' . $e->getMessage());
+ }
+ }
+
+ // public function getForexSignaturePath()
+ // {
+
+ // $data = $this->mailTemplateModel->where('template_name','forex')->first();
+
+ // return $this->respond([
+ // 'status' => 200,
+ // 'message' => 'success',
+ // 'data' => $data
+
+ // ]);
+
+ // }
+
+ public function getForexSignaturePath()
+ {
+ $data = $this->mailTemplateModel->where('template_name', 'forex')->first();
+
+ if (!$data || empty($data['image_location'])) {
+ return $this->respond([
+ 'status' => 404,
+ 'message' => 'Image not found',
+ 'url' => null
+ ]);
+ }
+
+ // If the DB stores only the filename, adjust accordingly
+ $fileName = basename($data['image_location']);
+
+
+ $imageUrl = base_url('public/assets/images/signature/' . $fileName);
+
+ // Add both the URL and ready-made HTML tag
+ $data['image_url'] = $imageUrl;
+ $data['image_tag'] = ' ';
+
+ return $this->respond([
+ 'status' => 200,
+ 'message' => 'success',
+ 'url' => $imageUrl
+ ]);
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+}
diff --git a/app/Controllers/StaffAuthController.php b/app/Controllers/StaffAuthController.php
new file mode 100644
index 0000000..0fb4c92
--- /dev/null
+++ b/app/Controllers/StaffAuthController.php
@@ -0,0 +1,136 @@
+myLogger = \Config\Services::mylogger();
+ $this->StaffModel = new StaffModel();
+
+ }
+
+ public function verifyStaffWithMobileNumber()
+ {
+ try {
+
+ $mobile = $this->request->getJSON()->mobile;
+
+ $StaffData = $this->StaffModel->where('mobile', $mobile)->where('is_active', 1)->first();
+
+
+ if (isset($StaffData['id']))
+ {
+ $result = ['Staff_verification' => true ,'message' => "Verified Successfully"];
+ return $this->respond(['status' => 'success','code' => 200,'data' => $result],200);
+
+ } else {
+
+ $result = ['Staff_verification' => false , 'message' => "Verification Failed"];
+ return $this->respond(['status' => 'failed','code' => 404,'data' => $result],200);
+
+ }
+ } catch (\Throwable $th) {
+
+ return $this->respond(['status' => 'failed','code' => 500,'data' => $th],500);
+ }
+ }
+
+ public function verifyStaffWithEmailId()
+ {
+ try {
+
+ $email = $this->request->getJSON()->email;
+
+ $StaffData = $this->StaffModel->where('email', $email)->where('is_active', 1)->first();
+
+ if (isset($StaffData['id'])) {
+
+ $otp = random_int(100000, 999999);
+
+ $update = $this->StaffModel->where('email', $email)->where('is_active', 1)->set(['email_otp' => $otp])->update();
+
+ if ($update) {
+
+ $subject = 'Nhance user verification - OTP';
+ $mail_content = $otp . ' is your verification code for Nhance.';
+
+ $EmailResult = send_login_otp( $email , $subject , $mail_content);
+
+ if ($EmailResult['status'] == 'success') {
+ $result = ['Staff_verification' => true, 'message' => "Verified Successfully"];
+ return $this->respond(['status' => 'success', 'code' => 200, 'data' => $result], 200);
+ } else {
+ $result = ['Staff_verification' => false, 'message' => "Mail sending failed , try again"];
+ return $this->respond(['status' => 'failed', 'code' => 404, 'data' => $result], 200);
+ }
+ } else {
+ $result = ['Staff_verification' => false, 'message' => "Verification failed , try again"];
+ return $this->respond(['status' => 'failed', 'code' => 404, 'data' => $result], 200);
+ }
+
+ } else {
+ $result = ['Staff_verification' => false, 'message' => "User not found"];
+ return $this->respond(['status' => 'failed', 'code' => 404, 'data' => $result], 200);
+ }
+
+ } catch (\Throwable $th) {
+ return $this->respond(['status' => 'failed', 'code' => 500, 'data' => $th], 500);
+ }
+ }
+
+ public function getVerifiedStaffData()
+ {
+ try {
+
+ $otp_verification = isset($this->request->getJSON()->otp_verification) ? $this->request->getJSON()->otp_verification : null;
+ $mobile = isset($this->request->getJSON()->mobile) ? $this->request->getJSON()->mobile : null;
+
+ $otp = isset($this->request->getJSON()->otp) ? $this->request->getJSON()->otp : null;
+ $email = isset($this->request->getJSON()->email) ? $this->request->getJSON()->email : null;
+
+
+ if (isset($mobile))
+ {
+ $StaffData = $this->StaffModel->where('mobile', $mobile)->where('is_active', 1)->first();
+
+ } else {
+ $StaffData = $this->StaffModel->where('email', $email)->where('is_active', 1)->first();
+ }
+
+
+ if ($StaffData && $otp_verification == true || $StaffData && isset($this->request->getJSON()->otp) ) {
+
+ if(isset($this->request->getJSON()->otp)){
+ $this->StaffModel->where('id', $StaffData['id'])->where('otp', $otp)->where('is_active', 1)->set(['otp'=>null])->update();
+ }
+
+ $result = generateJWT($StaffData);
+
+ return $this->respond(['status' => 'success','code' => 200,'data' => $result],200);
+
+ } else {
+
+ return $this->respond(['status' => 'failed','code' => 404,'data' => []],200);
+ }
+
+ } catch (\Exception $e) {
+ return $this->respond(['status' => 'failed','code' => 500,'data' =>[], 'error' => $e->getMessage()],500);
+ }
+ }
+
+
+
+
+
+}
diff --git a/app/Controllers/StaffController.php b/app/Controllers/StaffController.php
new file mode 100644
index 0000000..d7bf091
--- /dev/null
+++ b/app/Controllers/StaffController.php
@@ -0,0 +1,85 @@
+StaffModel = new StaffModel();
+ }
+
+ // =========================
+ // 1. List all staff
+ // =========================
+ public function list()
+ {
+ $data = $this->StaffModel->findAll();
+ return $this->response->setJSON($data);
+ }
+
+ // =========================
+ // 2. Find single staff by ID
+ // =========================
+ public function find($id = null)
+ {
+ $record = $this->StaffModel->find($id);
+
+ if (!$record) {
+ return $this->response->setJSON([
+ 'status' => 'error',
+ 'message' => 'Record not found'
+ ])->setStatusCode(404);
+ }
+
+ return $this->response->setJSON($record);
+ }
+
+ // =========================
+ // 3. Create new staff
+ // =========================
+ public function create()
+ {
+ $data = $this->request->getJSON(true); // JSON body to array
+
+ if (!$this->StaffModel->insert($data)) {
+ return $this->response->setJSON([
+ 'status' => 'error',
+ 'message' => 'Failed to insert',
+ 'errors' => $this->StaffModel->errors()
+ ])->setStatusCode(400);
+ }
+
+ return $this->response->setJSON([
+ 'status' => 'success',
+ 'message' => 'Staff created successfully',
+ 'id' => $this->StaffModel->getInsertID()
+ ]);
+ }
+
+ // =========================
+ // 4. Update staff by ID
+ // =========================
+ public function update($id = null)
+ {
+ $data = $this->request->getJSON(true);
+
+ if (!$this->StaffModel->update($id, $data)) {
+ return $this->response->setJSON([
+ 'status' => 'error',
+ 'message' => 'Failed to update',
+ 'errors' => $this->StaffModel->errors()
+ ])->setStatusCode(400);
+ }
+
+ return $this->response->setJSON([
+ 'status' => 'success',
+ 'message' => 'Staff updated successfully'
+ ]);
+ }
+}
diff --git a/app/Controllers/SwaggerController.php b/app/Controllers/SwaggerController.php
new file mode 100644
index 0000000..9a1eb0b
--- /dev/null
+++ b/app/Controllers/SwaggerController.php
@@ -0,0 +1,23 @@
+toJson();
+ }
+}
diff --git a/app/Database/Migrations/.gitkeep b/app/Database/Migrations/.gitkeep
new file mode 100755
index 0000000..e69de29
diff --git a/app/Database/Seeds/.gitkeep b/app/Database/Seeds/.gitkeep
new file mode 100755
index 0000000..e69de29
diff --git a/app/Filters/.gitkeep b/app/Filters/.gitkeep
new file mode 100755
index 0000000..e69de29
diff --git a/app/Filters/Cors.php b/app/Filters/Cors.php
new file mode 100644
index 0000000..039af1f
--- /dev/null
+++ b/app/Filters/Cors.php
@@ -0,0 +1,56 @@
+getHeaderLine('Authorization');
+
+ if (!$header || !preg_match('/Bearer\s(\S+)/', $header, $matches)) {
+ return service('response')->setJSON(['status' => 401, 'message' => 'Token required'])->setStatusCode(401);
+ }
+
+ $decodedToken = validateJWT($matches[1]);
+
+ if (!$decodedToken) {
+ return service('response')->setJSON(['status' => 401, 'message' => 'Invalid or expired token'])->setStatusCode(401);
+ }
+
+ return;
+ }
+
+ public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
+ {
+ // No action needed
+ }
+}
diff --git a/app/Filters/SignedUrlFilter.php b/app/Filters/SignedUrlFilter.php
new file mode 100755
index 0000000..00492c6
--- /dev/null
+++ b/app/Filters/SignedUrlFilter.php
@@ -0,0 +1,44 @@
+getGet('expires');
+ $signature = $request->getGet('signature');
+
+ if (!$expires || !$signature) {
+ return Services::response()->setStatusCode(403)->setBody('Forbidden');
+ }
+
+ if (time() > $expires) {
+ $body = view('expired_link');
+ return Services::response()->setStatusCode(403)->setBody($body);
+ }
+
+ $queryParams = $request->getGet();
+ unset($queryParams['signature']);
+ $route = $request->getPath();
+ $expectedSignature = hash_hmac('sha256', $route . '?' . http_build_query($queryParams), $secretKey);
+
+ if (!hash_equals($expectedSignature, $signature)) {
+ return Services::response()->setStatusCode(403)->setBody('Invalid signature');
+ }
+
+ return true; // Allow the request
+ }
+
+ public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
+ {
+ // Do nothing here
+ }
+}
+
+
diff --git a/app/Filters/VerifyAppSignature.php b/app/Filters/VerifyAppSignature.php
new file mode 100644
index 0000000..a5257b2
--- /dev/null
+++ b/app/Filters/VerifyAppSignature.php
@@ -0,0 +1,36 @@
+getHeaderLine('App-Signature');
+
+ // Load the server's expected signature from the .env
+ $validSignature = getenv('APP_SIGNATURE');
+
+ // Check if signature is valid
+ if ($clientSignature !== $validSignature) {
+ return service('response')
+ ->setStatusCode(403)
+ ->setJSON([
+ 'status' => false,
+ 'message' => 'Forbidden: Invalid App Signature',
+ ]);
+ }
+
+ // allow request to proceed
+ }
+
+ public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
+ {
+ // nothing to do after response
+ }
+}
diff --git a/app/Helpers/.gitkeep b/app/Helpers/.gitkeep
new file mode 100755
index 0000000..e69de29
diff --git a/app/Helpers/common_helper.php b/app/Helpers/common_helper.php
new file mode 100644
index 0000000..92c426d
--- /dev/null
+++ b/app/Helpers/common_helper.php
@@ -0,0 +1,491 @@
+where('email', $email)->first();
+
+ return $user ? $user : false;
+ }
+}
+
+if (!function_exists('checkUserExist')) {
+ function checkUserExist($first_name, $email)
+ {
+ $userModel = new UserModel();
+
+ // Check if email already exists
+ $user = $userModel->where('email', $email)->first();
+ if ($user) {
+ return ['status' => true,'data' => $user ,'message' => 'User already exists'];
+ }
+
+ // Insert new user
+ $userId = $userModel->insert([
+ 'first_name' => $first_name,
+ 'email' => $email,
+ 'org_id' => env('ORG_id')
+ ]);
+
+ if($userId){
+ $user = $userModel->where('user_id', $userId)->first();
+ return ['status' => true,'data' => $user ,'message' => 'User created successfully'];
+ }else{
+ return ['status' => false, 'message' => 'Something wend wrong'];
+ }
+
+
+ }
+}
+
+if (!function_exists('getUserPlanCreationRestrictionStatus')) {
+ function getUserPlanCreationRestrictionStatus($user)
+ {
+ if($user['group_id'] != null)
+ {
+ $groupModel = new GroupModel();
+ $groupData = $groupModel->find($user['group_id']);
+ if($groupData)
+ {
+ $domesticPolicyId = $groupData['domestic_policy_id'];
+ $internationalPolicyId = $groupData['international_policy_id'];
+ $policyDetailsModel = new PolicyDetailsModel();
+
+ if($domesticPolicyId != null && $internationalPolicyId != null)
+ {
+ $domesticPolicy = $policyDetailsModel->where('policy_id',$domesticPolicyId)->where('service_id', 1)->find();
+ $domesticCheck = checkApproverSetOrNotBasedOnPolicy($domesticPolicy,$user);
+ $internationalPolicy = $policyDetailsModel->where('policy_id',$internationalPolicyId)->where('service_id', 1)->find();
+ $internationalCheck = checkApproverSetOrNotBasedOnPolicy($internationalPolicy,$user);
+
+ if($domesticCheck == true && $internationalCheck == true)
+ return 'Both Type Plan Creation Allowed';
+ else
+ return 'Plan Creation Not Allowed';
+
+ }
+ else if($domesticPolicyId != null)
+ {
+ $domesticPolicy = $policyDetailsModel->where('policy_id',$domesticPolicyId)->where('service_id', 1)->find();
+ $check = checkApproverSetOrNotBasedOnPolicy($domesticPolicy,$user);
+ $internationalPolicy = $policyDetailsModel->where('policy_id',$domesticPolicyId)->where('service_id', 1)->find();
+ $check = checkApproverSetOrNotBasedOnPolicy($internationalPolicy,$user);
+
+ if($check == true)
+ return 'Only Domestic Plan Creation Allowed';
+ else
+ return 'Plan Creation Not Allowed';
+
+ }
+ else if($internationalPolicyId != null)
+ {
+
+ $internationalPolicy = $policyDetailsModel->where('policy_id',$internationalPolicyId)->where('service_id', 1)->find();
+ $check = checkApproverSetOrNotBasedOnPolicy($internationalPolicy,$user);
+
+ if($check == true)
+ return 'Only International Plan Creation Allowed';
+ else
+ return 'Plan Creation Not Allowed';
+
+ }
+
+
+ }else{
+ return 'Plan Creation Not Allowed';
+ }
+
+ }else{
+ return 'Plan Creation Not Allowed';
+ }
+
+
+ }
+}
+
+function checkApproverSetOrNotBasedOnPolicy($Policy,$user)
+{
+ // Step 1: Determine required approver levels (a1 to a4)
+ $requiredApprovers = [];
+
+ foreach (['', '_exceptional', '_amendment'] as $type) {
+ for ($i = 1; $i <= 4; $i++) {
+ $key = "a{$i}{$type}_action";
+ if (isset($Policy[0][$key]) && $Policy[0][$key] === 'Approval') {
+ $requiredApprovers[] = $i; // add level (1 to 4)
+ }
+ }
+ }
+
+ // Remove duplicates (in case multiple types require same level)
+ $requiredApprovers = array_unique($requiredApprovers);
+
+ // Step 2: Check user profile for each required approver level
+ $missingApprovers = [];
+
+ foreach ($requiredApprovers as $level) {
+ $profileKey = match ($level) {
+ 1 => 'first_approver',
+ 2 => 'second_approver',
+ 3 => 'third_approver',
+ 4 => 'fourth_approver',
+ };
+
+ if (empty($user[$profileKey]) || $user[$profileKey] == 0) {
+ $missingApprovers[] = $profileKey;
+ }
+ }
+
+ // Step 3: Final check
+ if (!empty($missingApprovers)) {
+ // One or more approvers missing
+ // echo "Missing approvers in user profile: " . implode(', ', $missingApprovers);
+ return false;
+ } else {
+ // echo "All required approvers are set in user profile.";
+ return true;
+ }
+
+}
+
+if (!function_exists('isDataChanged')) {
+ function isDataChanged($model, $id, array $newData): bool
+ {
+ // Step 1: Fetch old data from the model
+ $oldData = $model->where('plan_id', $id)->where('is_active', 1)->findAll();
+
+ if (!$oldData) {
+ return true;
+ }
+
+ // Step 2: Define keys to exclude
+ $excludeKeys = ['created_by', 'updated_by', 'created_on', 'updated_on'];
+
+ // Step 3: Clean both old and new data arrays
+ $cleanOldData = array_map(function($item) use ($excludeKeys) {
+ foreach ($excludeKeys as $key) {
+ unset($item[$key]);
+ }
+ return $item;
+ }, $oldData);
+
+ $cleanNewData = array_map(function($item) use ($excludeKeys) {
+ foreach ($excludeKeys as $key) {
+ unset($item[$key]);
+ }
+ return $item;
+ }, $newData);
+
+
+ // Step 4: Compare count
+ if (count($cleanOldData) !== count($cleanNewData)) {
+ return true;
+ }
+
+ // Step 5: Check if there's any difference
+ return $cleanOldData !== $cleanNewData;
+ }
+
+}
+
+if (!function_exists('isFlightTripDataChanged')) {
+ function isFlightTripDataChanged($model, $id, array $newData): bool
+ {
+
+ $newTripData = [];
+ $flightIds = array_column($newData, 'flight_id');
+ foreach ($newData as $key1 => $value1) {
+ foreach ($value1['trips'] as $key => $value) {
+ array_push($newTripData , $value);
+ }
+ }
+
+ // Step 1: Fetch old data from the model
+ if(!empty($flightIds))
+ $oldData = $model->whereIn('flight_id', $flightIds)->where('is_active', 1)->findAll();
+ else
+ $oldData = [];
+
+
+ if (!$oldData) {
+ return true;
+ }
+
+ // Step 2: Define keys to exclude
+ $excludeKeys = ['created_by', 'updated_by', 'created_on', 'updated_on'];
+
+ // Step 3: Clean both old and new data arrays
+ $cleanOldData = array_map(function($item) use ($excludeKeys) {
+ foreach ($excludeKeys as $key) {
+ unset($item[$key]);
+ }
+ return $item;
+ }, $oldData);
+
+ $cleanNewData = array_map(function($item) use ($excludeKeys) {
+ foreach ($excludeKeys as $key) {
+ unset($item[$key]);
+ }
+ return $item;
+ }, $newTripData);
+
+
+ // Step 4: Compare count
+ if (count($cleanOldData) !== count($cleanNewData)) {
+ return true;
+ }
+
+ // Step 5: Check if there's any difference
+ return $cleanOldData !== $cleanNewData;
+ }
+
+}
+
+function getDelegatedPlans($org_id, $id)
+{
+ $userModel = new UserModel();
+ $planModel = new PlanModel();
+ $planStatusModel = new PlanStatusModel();
+ $delegatedUsers = $userModel->where('delegated_to_user_id', $id)
+ ->where('is_active', 1)
+ ->where('delegation_start_date <=', date('Y-m-d'))
+ ->where('delegation_end_date >=', date('Y-m-d'))
+ ->findAll();
+ $allPlanData = [];
+ foreach ($delegatedUsers as $user) {
+
+ $userId = $user['user_id'];
+ $startDate = $user['delegation_start_date'];
+ $endDate = $user['delegation_end_date'];
+
+ $a1Data = $planStatusModel->select('plan_id,a1_id as user_id')
+ ->where('a1_id',$userId)
+ ->where('a1_action','Approval')
+ ->where('created_on >=', $startDate)
+ ->where('created_on <=', $endDate)
+ ->where('is_active',1)
+ ->findAll();
+
+ $a2Data = $planStatusModel->select('plan_id,a2_id as user_id')
+ ->where('a2_id',$userId)
+ ->where('a2_action','Approval')
+ ->where('created_on >=', $startDate)
+ ->where('created_on <=', $endDate)
+ ->where('is_active',1)
+ ->findAll();
+
+ $a3Data = $planStatusModel->select('plan_id,a3_id as user_id')
+ ->where('a3_id',$userId)
+ ->where('a3_action','Approval')
+ ->where('is_active',1)
+ ->where('created_on >=', $startDate)
+ ->where('created_on <=', $endDate)
+ ->findAll();
+
+ $a4Data = $planStatusModel->select('plan_id,a4_id as user_id')
+ ->where('a4_id',$userId)
+ ->where('a4_action','Approval')
+ ->where('is_active',1)
+ ->where('created_on >=', $startDate)
+ ->where('created_on <=', $endDate)
+ ->findAll();
+
+ // Merge results (each record has plan_id + user_id)
+ $merged = array_merge($a1Data, $a2Data, $a3Data, $a4Data);
+
+ // Merge into final array
+ $allPlanData = array_merge($allPlanData, $merged);
+
+ }
+
+ //get already approved data in delegated flow
+ // $a1 = $planStatusModel->select('plan_id,a1_id as user_id')->where('a1_action_done_by',$id)->where('a1_action','Approval')->where('is_active',1)->findAll();
+ // $a2 = $planStatusModel->select('plan_id,a2_id as user_id')->where('a2_action_done_by',$id)->where('a2_action','Approval')->where('is_active',1)->findAll();
+ // $a3 = $planStatusModel->select('plan_id,a3_id as user_id')->where('a3_action_done_by',$id)->where('a3_action','Approval')->where('is_active',1)->findAll();
+
+ //need to discuss with sir
+ // $mergedApprovedArray = array_merge($a1, $a2, $a3);
+ $mergedApprovedArray = [];
+
+ // Merge into main list
+ $allPlanData = array_merge($allPlanData, $mergedApprovedArray);
+
+ // Remove duplicate associative arrays
+ $allPlanData = array_map('unserialize', array_unique(array_map('serialize', $allPlanData)));
+
+ $plansWithUser = [];
+
+ foreach ($allPlanData as $item) {
+ $planId = $item['plan_id'];
+ $userId = $item['user_id'];
+ $userData = $userModel->where('user_id',$userId)->first();
+ $userName = $userData['first_name'].' '.$userData['last_name'];
+
+ $planData = $planModel->getActivePlan($org_id, 'PLAN', null , $planId);
+
+ if ($planData) {
+ $planData['approver_id'] = $userId;
+ $planData['approver_name'] = $userName;
+ $planData['delegater_id'] = $id;
+ $planData['approver_status'] = getApproverCurrentAction( $planData['plan_id'], $userId );
+ $plansWithUser[] = $planData;
+ }
+ }
+
+ return $plansWithUser;
+
+}
+
+function normalize_date(string $date): ?string
+{
+ $date = trim($date);
+
+ // If already valid Y-m-d (e.g., 2025-03-20), return it as-is
+ $yFormat = DateTime::createFromFormat('Y-m-d', $date);
+ if ($yFormat && $yFormat->format('Y-m-d') === $date) {
+ return $date;
+ }
+
+ // Try to convert from d-m-Y (e.g., 20-03-2025)
+ $dFormat = DateTime::createFromFormat('d-m-Y', $date);
+ if ($dFormat) {
+ return $dFormat->format('Y-m-d');
+ }
+
+ // Try from d/m/Y (optional)
+ $slashFormat = DateTime::createFromFormat('d/m/Y', $date);
+ if ($slashFormat) {
+ return $slashFormat->format('Y-m-d');
+ }
+
+ // Unknown format
+ return null;
+}
+
+if (!function_exists('format_date_for_client')) {
+ /**
+ * Converts a date from 'Y-m-d' to 'd-m-Y'.
+ *
+ * @param string $date
+ * @return string|null
+ */
+ function format_date_for_client(string $date): ?string
+ {
+ $dt = DateTime::createFromFormat('Y-m-d', $date);
+ if ($dt) {
+ return $dt->format('d-m-Y');
+ }
+
+ return null;
+ }
+}
+
+if (!function_exists('isValidUploadedFile')) {
+ function isValidUploadedFile($file): bool
+ {
+ return $file && $file->isValid();
+ }
+}
+
+if (!function_exists('isAllowedExtension')) {
+ function isAllowedExtension($file, array $allowedExtensions = [] ): bool
+ {
+ $ext = strtolower($file->getClientExtension());
+
+ $result = in_array($ext, $allowedExtensions);
+
+ $result = empty($allowedExtensions) ? true : $result ;
+
+ return $result;
+ }
+}
+
+if (!function_exists('isExcelNotEmpty')) {
+ function isExcelNotEmpty(array $sheetData): bool
+ {
+ return !empty($sheetData) && count($sheetData) >= 2;
+ }
+}
+
+if(!function_exists('createDirectoryWith0777Permission')){
+
+ function createDirectoryWith0777Permission( $uploadDir)
+ {
+ if (!is_dir($uploadDir)) {
+ mkdir($uploadDir, 0777, true); // recursive creation with full permission
+ }
+
+ }
+
+}
+
+function getAllowedClassForUser($trip_type,$user_id)
+{
+
+ $userModel = new UserModel();
+ $groupModel = new GroupModel();
+ $policyDetailsModel = new PolicyDetailsModel();
+ $policyDetailsModel = new PolicyDetailsModel();
+
+ $user = $userModel->where('user_id', $user_id)->first();
+ $groupData = $groupModel->find($user['group_id']);
+
+ if($groupData)
+ {
+ if($trip_type == 1) { $policyId = $groupData['domestic_policy_id'];}else{ $policyId = $groupData['international_policy_id'];}
+ if($policyId != null)
+ {
+ $allowedFlightClass = $policyDetailsModel->select('c_policy_details.class, m_dropdown.dropdown_value as allowed_class')
+ ->join('m_dropdown', 'dropdown_key = c_policy_details.class AND dropdown = "flight_class"', 'left')
+ ->where('policy_id',$policyId)
+ ->where('service_id',1)
+ ->first();
+ $data['flight'] = $allowedFlightClass['allowed_class'] ?? [];
+
+ $allowedTrainClass = $policyDetailsModel->select('c_policy_details.class, m_dropdown.dropdown_value as allowed_class')
+ ->join('m_dropdown', 'dropdown_key = c_policy_details.class AND dropdown = "train_class"', 'left')
+ ->where('policy_id',$policyId)
+ ->where('service_id',2)
+ ->first();
+ $data['train'] = $allowedTrainClass['allowed_class'] ?? [];
+
+ $allowedHotelClass = $policyDetailsModel->select('c_policy_details.class, m_dropdown.dropdown_value as allowed_class')
+ ->join('m_dropdown', 'dropdown_key = c_policy_details.class AND dropdown = "hotel_class"', 'left')
+ ->where('policy_id',$policyId)
+ ->where('service_id',5)
+ ->first();
+ $data['hotel'] = $allowedHotelClass['allowed_class'] ?? [];
+ }
+
+
+ return $data;
+
+ }
+
+
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/Helpers/jwt_helper.php b/app/Helpers/jwt_helper.php
new file mode 100644
index 0000000..0e272c9
--- /dev/null
+++ b/app/Helpers/jwt_helper.php
@@ -0,0 +1,37 @@
+ base_url(), // Issuer
+ 'iat' => $issuedAt, // Issued at
+ 'exp' => $expire, // Expiration time
+ 'sub' => $userData['user_id'], // Subject (User ID)
+ 'data' => $userData // Additional user data
+ ];
+
+ return JWT::encode($payload, $key, 'HS256');
+ }
+}
+
+if (!function_exists('validateJWT')) {
+ function validateJWT($token)
+ {
+ $key = getenv('JWT_SECRET');
+
+ try {
+ $decoded = JWT::decode($token, new Key($key, 'HS256'));
+ return (array) $decoded;
+ } catch (\Exception $e) {
+ return null;
+ }
+ }
+}
diff --git a/app/Helpers/mail_helper.php b/app/Helpers/mail_helper.php
new file mode 100644
index 0000000..81eb3c1
--- /dev/null
+++ b/app/Helpers/mail_helper.php
@@ -0,0 +1,67 @@
+ [
+ "address" => $sender,
+ "name" => "Nhance-Partner"
+ ],
+ "to" => [
+ ["email_address" => ["address" => $to_email]]
+ ],
+ "subject" => $subject,
+ "htmlbody" => $message,
+ ];
+
+
+
+ $headers = [
+ "Content-Type: application/json",
+ "Authorization: Zoho-enczapikey " . $apiKey
+ ];
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, $endpoint);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_POST, true);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+
+ $response = curl_exec($ch);
+ $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
+
+ if (curl_errno($ch)) {
+ $error_msg = curl_error($ch);
+ log_message('error', "[EMAIL ERROR] Curl failed: {$error_msg}");
+ return ['status' => 'failed', 'code' => 500, 'message' => 'Curl error', 'error' => $error_msg];
+ }
+
+ curl_close($ch);
+
+ $resp = json_decode($response, true);
+
+ if ($httpCode === 200 && isset($resp['request_id'])) {
+ log_message('debug', 'OTP Send Success to agent , email = ' . $to_email);
+ return ['status' => 'success', 'code' => 200, 'message' => 'Send Success'];
+ } else {
+ log_message('error', "[OTP Send FAILED] , email = {$to_email}, HTTP: {$httpCode}, Response: {$response}");
+ return ['status' => 'failed', 'code' => 500, 'message' => 'Curl error', 'error' => $response];
+ }
+
+
+ } catch (\Exception $e) {
+ log_message('debug', 'Exception occurred while sending email to agent: ' . $e->getMessage());
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/Helpers/oauth_helper.php b/app/Helpers/oauth_helper.php
new file mode 100755
index 0000000..105d031
--- /dev/null
+++ b/app/Helpers/oauth_helper.php
@@ -0,0 +1,63 @@
+setClientId($clientID);
+ $client->setClientSecret($clientSecret);
+ $client->setRedirectUri($redirectUri);
+ $client->addScope($scopes);
+ // $client->setApprovalPrompt('force');
+ $client->setPrompt('consent');
+ $client->setAccessType('offline');
+
+ // Check if an OAuth token is provided
+ if ($oauthToken) {
+ try {
+ // Attempt to fetch the access token with the provided OAuth token
+ $token = $client->fetchAccessTokenWithAuthCode($oauthToken);
+ $client->setAccessToken($token);
+
+ $oauth = new Oauth2($client);
+
+ // Get user information using the OAuth2 service
+ $user_info = $oauth->userinfo->get();
+ return $user_info;
+
+ } catch (\Exception $e) {
+ // Handle exceptions and return an error message
+ return 'Error fetching access token: ' . $e->getMessage();
+ }
+ } else {
+ // If no OAuth token is provided, generate the authentication URL
+ $url = $client->createAuthUrl();
+ // Redirect the user to the authentication URL
+ // return $url;
+ return redirect()->to(filter_var($url, FILTER_SANITIZE_URL));
+ }
+ }
+}
+
+?>
diff --git a/app/Helpers/status_helper.php b/app/Helpers/status_helper.php
new file mode 100644
index 0000000..4b8005c
--- /dev/null
+++ b/app/Helpers/status_helper.php
@@ -0,0 +1,908 @@
+find($plan_id, 'internal');
+ if (!$planData) {
+ log_message('error', "No plan data found for plan_id: {$plan_id}");
+ return false;
+ }
+
+ $planServices = [];
+ if (count($planData['flight'])) { array_push($planServices, 1); }
+ if (count($planData['train'])) { array_push($planServices, 2); }
+ if (count($planData['bus'])) { array_push($planServices, 3); }
+ if (count($planData['taxi'])) { array_push($planServices, 4); }
+ if (count($planData['accomodation'])) { array_push($planServices, 5); }
+ if (count($planData['forex'])) { array_push($planServices, 6); }
+ if (count($planData['insurance'])) { array_push($planServices, 7); }
+ if (count($planData['visa'])) { array_push($planServices, 8); }
+ if (count($planData['miscellaneous'])) { array_push($planServices, 9); }
+
+ log_message('debug', "Plan services found: " . json_encode($planServices));
+
+ $userId = $planData['user_id'] ?? $planData['traveller_id'];
+ $userData = $userModel->where('user_id', $userId)->first();
+ if (!$userData) {
+ log_message('error', "User data not found for user_id: {$userId}");
+ return false;
+ }
+
+ $groupId = $userData['group_id'];
+ $a1Id = $userData['first_approver'];
+ $a2Id = $userData['second_approver'];
+ $a3Id = $userData['third_approver'];
+ $a4Id = $userData['fourth_approver'];
+
+ $groupData = $groupModel->where('group_id', $groupId)->first();
+ if (!$groupData) {
+ log_message('error', "Group data not found for group_id: {$groupId}");
+ return false;
+ }
+
+ $tripType = $planData['trip_type'];
+ $policyId = ($tripType == 1) ? $groupData['domestic_policy_id'] : $groupData['international_policy_id'];
+
+ $policyData = $policyModel->where('policy_id', $policyId)->first();
+ if (!$policyData) {
+ log_message('error', "Policy data not found for policy_id: {$policyId}");
+ return false;
+ }
+
+ $priorityOrderOfService = json_decode($policyData['services_ids'], true);
+ if (!is_array($priorityOrderOfService)) {
+ log_message('error', "Invalid service priority list in policy_id: {$policyId}");
+ return false;
+ }
+
+ foreach ($priorityOrderOfService as $key => &$value) {
+ $value['priority'] = $key + 1;
+ }
+ unset($value);
+
+ log_message('debug', "Service priority list: " . json_encode($priorityOrderOfService));
+
+ // Step 1: Filter only services present in current plan
+ $filtered = array_filter($priorityOrderOfService, function ($item) use ($planServices) {
+ return in_array($item['service_id'], $planServices);
+ });
+
+ // Step 2: Sort by priority
+ usort($filtered, function ($a, $b) {
+ return $a['priority'] <=> $b['priority'];
+ });
+
+ $topPriorityService = reset($filtered);
+ if (!$topPriorityService) {
+ log_message('error', "No matching service found for plan_id: {$plan_id}");
+ return false;
+ }
+
+ log_message('info', "Top priority service identified: " . json_encode($topPriorityService));
+
+ $policyServiceDetails = $policyDetailsModel
+ ->where('policy_id', $policyId)
+ ->where('service_id', $topPriorityService['service_id'])
+ ->where('is_active', 1)
+ ->first();
+
+ if (!$policyServiceDetails) {
+ log_message('error', "Policy service details not found for service_id: {$topPriorityService['service_id']}, policy_id: {$policyId}");
+ return false;
+ }
+ // dd($policyServiceDetails);
+
+
+ $isExceptional = $planData['exceptional_plan_reason'] !== null && $planData['exceptional_plan_reason'] !== '';
+ // dd($isExceptional);
+
+ if ($isExceptional) {
+ $policyA1Action = $policyServiceDetails['a1_exceptional_action'];
+ $policyA2Action = $policyServiceDetails['a2_exceptional_action'];
+ $policyA3Action = $policyServiceDetails['a3_exceptional_action'];
+ $policyA4Action = $policyServiceDetails['a4_exceptional_action'];
+ $policyParallelAction = $policyServiceDetails['exceptional_parallel_process_from'];
+ } else if ($is_data_edited) {
+ $policyA1Action = $policyServiceDetails['a1_amendment_action'];
+ $policyA2Action = $policyServiceDetails['a2_amendment_action'];
+ $policyA3Action = $policyServiceDetails['a3_amendment_action'];
+ $policyA4Action = $policyServiceDetails['a4_amendment_action'];
+ $policyParallelAction = $policyServiceDetails['amendment_parallel_process_from'];
+ } else {
+ $policyA1Action = $policyServiceDetails['a1_action'];
+ $policyA2Action = $policyServiceDetails['a2_action'];
+ $policyA3Action = $policyServiceDetails['a3_action'];
+ $policyA4Action = 'None';
+ $policyParallelAction = $policyServiceDetails['parallel_process_from'];
+ }
+
+
+ $data = [
+ 'plan_id' => $plan_id,
+ 'service_id' => $topPriorityService['service_id'],
+ 'a1_id' => $a1Id,
+ 'a1_action' => $policyA1Action,
+ 'is_a1_action_done' => ($policyA1Action == 'None') ? 1 : 0,
+ 'a2_id' => $a2Id,
+ 'a2_action' => $policyA2Action,
+ 'is_a2_action_done' => ($policyA2Action == 'None') ? 1 : 0,
+ 'a3_id' => $a3Id,
+ 'a3_action' => $policyA3Action,
+ 'is_a3_action_done' => ($policyA3Action == 'None') ? 1 : 0,
+ 'a4_id' => $a4Id,
+ 'a4_action' => $policyA4Action,
+ 'is_a4_action_done' => ($policyA4Action == 'None') ? 1 : 0,
+ 'parallel_process_from' => $policyParallelAction
+ ];
+
+ // dd($data);
+
+ if ($is_data_edited == false) {
+ log_message('info', "Creating new plan status for plan_id: {$plan_id}");
+ $planStatusModel->insert($data);
+ } else {
+ $oldStatusData = $planStatusModel->where('plan_id', $plan_id)->where('is_active', 1)->first();
+ if ($oldStatusData) {
+ if ($oldStatusData['service_id'] == $topPriorityService['service_id']) {
+ log_message('info', "No status update needed; service_id unchanged for plan_id: {$plan_id}");
+ } else {
+ log_message('info', "Updating plan status for edited plan_id: {$plan_id}. New service_id: {$topPriorityService['service_id']}, Old service_id: {$oldStatusData['service_id']}");
+ $planStatusModel->insert($data);
+ $planStatusModel->set(['is_active' => 0])
+ ->where('plan_id', $plan_id)
+ ->where('service_id', $oldStatusData['service_id'])
+ ->update();
+ }
+ } else {
+ log_message('warning', "Old status data not found for edited plan_id: {$plan_id}");
+ $planStatusModel->insert($data);
+ }
+ }
+
+ log_message('info', "palnStatusHandler() completed for plan_id: {$plan_id}");
+ }
+}
+
+
+// if (!function_exists('palnStatusHandler')) {
+// function palnStatusHandler($plan_id , $is_data_edited)
+// {
+
+// $planModel = new PlanModel();
+// $planStatusModel = new PlanStatusModel();
+// $userModel = new UserModel();
+// $groupModel = new GroupModel();
+// $policyModel = new PolicyModel();
+// $policyDetailsModel = new PolicyDetailsModel();
+// $planController = new PlanController();
+
+// $planData = $planController->find($plan_id, 'internal');
+
+// $planServices = [];
+// if($planData)
+// {
+// if(count($planData['flight'])){ array_push($planServices,1); }
+// if(count($planData['train'])){ array_push($planServices,2); }
+// if(count($planData['bus'])){ array_push($planServices,3); }
+// if(count($planData['taxi'])){ array_push($planServices,4); }
+// if(count($planData['accomodation'])){ array_push($planServices,5); }
+// if(count($planData['forex'])){ array_push($planServices,6); }
+// if(count($planData['insurance'])){ array_push($planServices,7); }
+// if(count($planData['visa'])){ array_push($planServices,8); }
+// if(count($planData['miscellaneous'])){ array_push($planServices,9); }
+
+// }
+// echo '';
+// print_r($planServices);
+
+
+// // Fetch plan data
+// if (!$planData) { return false; }
+// $userId = $planData['user_id'] ?? $planData['traveller_id'];
+
+// // Fetch user data
+// $userData = $userModel->where('user_id', $userId)->first();
+// if (!$userData) { return false; }
+// $groupId = $userData['group_id'];
+// $a1Id = $userData['first_approver'];
+// $a2Id = $userData['second_approver'];
+// $a3Id = $userData['third_approver'];
+
+
+// // Fetch group data
+// $groupData = $groupModel->where('group_id', $groupId)->first();
+// if (!$groupData) { return false; }
+// $policyId = ($planData['trip_type'] == 1) ? $groupData['domestic_policy_id'] : $groupData['international_policy_id'];
+
+// // Fetch policy service data
+// $policyData = $policyModel->where('policy_id', $policyId)->first();
+// if (!$policyData) {return false; }
+
+// $priorityOrderOfService = json_decode($policyData['services_ids'],true);
+// if (is_array($priorityOrderOfService)) {
+// foreach ($priorityOrderOfService as $key => &$value) {
+// $value['priority'] = $key + 1;
+// }
+// unset($value); // always break reference after loop
+// }
+// echo '';
+// print_r($priorityOrderOfService);
+
+// // Step 1: Filter only services you currently have
+// $filtered = array_filter($priorityOrderOfService, function($item) use ($planServices) {
+// return in_array($item['service_id'], $planServices);
+// });
+
+// // Step 2: Sort by priority ascending
+// usort($filtered, function($a, $b) {
+// return $a['priority'] <=> $b['priority'];
+// });
+
+// // Step 3: Get the top priority service
+// $topPriorityService = reset($filtered);
+// echo '';
+// print_r($topPriorityService); die;
+
+// $policyServiceDetails = $policyDetailsModel->where('policy_id',$policyId)->where('service_id',$topPriorityService['service_id'])->where('is_active',1)->first();
+// if (!$policyServiceDetails) { return false; }
+// $policyA1Action = $policyServiceDetails['a1_action'];
+// $policyA2Action = $policyServiceDetails['a2_action'];
+// $policyA3Action = $policyServiceDetails['a3_action'];
+// $policyParallelAction = $policyServiceDetails['parallel_process_from'];
+
+
+
+
+// if($is_data_edited == false)//plan Creation
+// {
+// $data['plan_id'] = $plan_id;
+// $data['service_id'] = $topPriorityService['service_id'];
+// $data['a1_id'] = $a1Id;
+// $data['a1_action'] = $policyA1Action;
+// $data['a2_id'] = $a2Id;
+// $data['a2_action'] = $policyA2Action;
+// $data['a3_id'] = $a3Id;
+// $data['a3_action'] = $policyA3Action;
+// $data['parallel_process_from'] = $policyParallelAction;
+// // Insert Status
+// $planStatusModel->insert($data);
+
+// }else{
+
+// $oldStatusData = $planStatusModel->where('plan_id',$plan_id)->where('is_active', 1)->first();
+
+// if($oldStatusData['service_id'] == $topPriorityService['service_id']){ // skip the process
+
+// }else{ // insert new data
+
+// //insert new service data
+// $data['plan_id'] = $plan_id;
+// $data['service_id'] = $topPriorityService['service_id'];
+// $data['a1_id'] = $a1Id;
+// $data['a1_action'] = $policyA1Action;
+// $data['a2_id'] = $a2Id;
+// $data['a2_action'] = $policyA2Action;
+// $data['a3_id'] = $a3Id;
+// $data['a3_action'] = $policyA3Action;
+// $data['parallel_process_from'] = $policyParallelAction;
+// // Insert Status
+// $planStatusModel->insert($data);
+
+// //update old service data is_active = 0
+// $planStatusModel->set(['is_active'=>0])->where('plan_id',$plan_id)->where('service_id',$oldStatusData['service_id'])->update();
+
+// }
+
+// }
+
+
+// }
+// }
+
+if (!function_exists('updatePlanStatus')) {
+ function updatePlanStatus($plan_id)
+ {
+
+ $planStatusModel = new PlanStatusModel();
+ $planModel = new PlanModel();
+
+ $a1 = $planStatusModel->where('plan_id',$plan_id)->where('a1_action','Approval')->where('is_active',1)->findAll();
+ $a1ApproveSum = 0;
+ $a1ApproveCount = 0;
+ if(count($a1))
+ {
+ $a1ApproveSum = array_sum(array_column($a1, 'is_a1_action_done'));
+ $a1ApproveCount = count($a1);
+ }
+
+ $a2 = $planStatusModel->where('plan_id',$plan_id)->where('a2_action','Approval')->where('is_active',1)->findAll();
+ $a2ApproveSum = 0;
+ $a2ApproveCount = 0;
+ if(count($a2))
+ {
+ $a2ApproveSum = array_sum(array_column($a2, 'is_a2_action_done'));
+ $a2ApproveCount = count($a2);
+ }
+
+
+ $a3 = $planStatusModel->where('plan_id',$plan_id)->where('a3_action','Approval')->where('is_active',1)->findAll();
+ $a3ApproveSum = 0;
+ $a3ApproveCount = 0;
+ if(count($a3))
+ {
+ $a3ApproveSum = array_sum(array_column($a3, 'is_a3_action_done'));
+ $a3ApproveCount = count($a3);
+ }
+
+ $a4 = $planStatusModel->where('plan_id',$plan_id)->where('a4_action','Approval')->where('is_active',1)->findAll();
+ $a4ApproveSum = 0;
+ $a4ApproveCount = 0;
+ if(count($a4))
+ {
+ $a4ApproveSum = array_sum(array_column($a4, 'is_a4_action_done'));
+ $a4ApproveCount = count($a4);
+ }
+
+
+ $count = ( $a1ApproveCount + $a2ApproveCount + $a3ApproveCount + $a4ApproveCount);
+ $sum = ( $a1ApproveSum + $a2ApproveSum + $a3ApproveSum + $a4ApproveSum);
+
+
+ if($count == $sum)
+ {
+ // Approved
+ $planModel->set(['status'=>3])->where('plan_id',$plan_id)->update();
+
+ }else if($count != $sum && $sum > 0)
+ {
+ //Partially Approved
+ $planModel->set(['status'=>2])->where('plan_id',$plan_id)->update();
+ }
+
+ return true;
+
+ }
+}
+
+if (!function_exists('getCurrentPlanStatus')) {
+ function getCurrentPlanStatus($plan_id)
+ {
+
+ $planStatusModel = new PlanStatusModel();
+ $userModel = new UserModel();
+ $currentStatus = [];
+
+ $a1 = $planStatusModel->where('plan_id',$plan_id)->where('a1_action','Approval')->where('is_active',1)->findAll();
+
+ if(count($a1))
+ {
+
+ $user1 = $userModel->where('user_id', $a1[0]['a1_action_done_by'])->first();
+ if(!$user1){
+ $user1 = $userModel->where('user_id', $a1[0]['a1_id'])->first();
+ }
+
+ $hasRejectReason = !empty(array_filter($a1, fn($row) => !empty($row['a1_reject_reason'])));
+ if($user1)
+ {
+
+ $userId = $user1['user_id'];
+
+ $a1ApproveSum = array_sum(array_column($a1, 'is_a1_action_done'));
+ $a1ApproveCount = count($a1);
+
+ $a1Status['a1_id'] = $userId;
+ if($a1ApproveSum == $a1ApproveCount)
+ {
+ $a1Status['a1_status'] = 'Plan approved by '.$user1['first_name'].' '.$user1['last_name'];
+ }else if($hasRejectReason){
+ $a1Status['a1_status'] = 'Plan rejected by '.$user1['first_name'].' '.$user1['last_name'].', Reason-'.$a1[0]['a1_reject_reason'];
+ }else{
+ $a1Status['a1_status'] = 'Plan approval pending from '.$user1['first_name'].' '.$user1['last_name'];
+ }
+ array_push($currentStatus,$a1Status);
+ }
+
+ }
+
+
+ $a2 = $planStatusModel->where('plan_id',$plan_id)->where('a2_action','Approval')->where('is_active',1)->findAll();
+ if(count($a2))
+ {
+ $user2 = $userModel->where('user_id', $a2[0]['a2_action_done_by'])->first();
+ if(!$user2){
+ $user2 = $userModel->where('user_id', $a2[0]['a2_id'])->first();
+ }
+ $hasRejectReason = !empty(array_filter($a2, fn($row) => !empty($row['a2_reject_reason'])));
+ if($user2)
+ {
+ $userId = $user2['user_id'];
+
+ $a2ApproveSum = array_sum(array_column($a2, 'is_a2_action_done'));
+ $a2ApproveCount = count($a2);
+
+ $a2Status['a2_id'] = $userId;
+ if($a2ApproveSum == $a2ApproveCount)
+ {
+ $a2Status['a2_status'] = 'Plan approved by '.$user2['first_name'].' '.$user2['last_name'];
+ }else if($hasRejectReason){
+ $a2Status['a2_status'] = 'Plan rejected by '.$user2['first_name'].' '.$user2['last_name'].', Reason-'.$a2[0]['a2_reject_reason'];
+ }else{
+ $a2Status['a2_status'] = 'Plan approval pending from '.$user2['first_name'].' '.$user2['last_name'];
+ }
+ array_push($currentStatus,$a2Status);
+ }
+ }
+
+
+ $a3 = $planStatusModel->where('plan_id',$plan_id)->where('a3_action','Approval')->where('is_active',1)->findAll();
+ if(count($a3))
+ {
+ $user3 = $userModel->where('user_id', $a3[0]['a3_action_done_by'])->first();
+ if(!$user3){
+ $user3 = $userModel->where('user_id', $a3[0]['a3_id'])->first();
+ }
+ $hasRejectReason = !empty(array_filter($a3, fn($row) => !empty($row['a3_reject_reason'])));
+ if($user3)
+ {
+ $userId = $user3['user_id'];
+
+ $a3ApproveSum = array_sum(array_column($a3, 'is_a3_action_done'));
+ $a3ApproveCount = count($a3);
+
+ $a3Status['a3_id'] = $userId;
+ if($a3ApproveSum == $a3ApproveCount)
+ {
+ $a3Status['a3_status'] = 'Plan approved by '.$user3['first_name'].' '.$user3['last_name'];
+ }else if($hasRejectReason){
+ $a3Status['a3_status'] = 'Plan rejected by '.$user3['first_name'].' '.$user3['last_name'].', Reason-'.$a3[0]['a3_reject_reason'];
+ }else{
+ $a3Status['a3_status'] = 'Plan approval pending from '.$user3['first_name'].' '.$user3['last_name'];
+ }
+ array_push($currentStatus,$a3Status);
+ }
+ }
+
+ $a4 = $planStatusModel->where('plan_id',$plan_id)->where('a4_action','Approval')->where('is_active',1)->findAll();
+ if(count($a4))
+ {
+ $user4 = $userModel->where('user_id', $a4[0]['a4_action_done_by'])->first();
+ if(!$user4){
+ $user4 = $userModel->where('user_id', $a4[0]['a4_id'])->first();
+ }
+ $hasRejectReason = !empty(array_filter($a4, fn($row) => !empty($row['a4_reject_reason'])));
+ if($user4)
+ {
+ $userId = $user4['user_id'];
+
+ $a4ApproveSum = array_sum(array_column($a4, 'is_a4_action_done'));
+ $a4ApproveCount = count($a4);
+
+ $a4Status['a4_id'] = $userId;
+ if($a4ApproveSum == $a4ApproveCount)
+ {
+ $a4Status['a4_status'] = 'Plan approved by '.$user4['first_name'].' '.$user4['last_name'];
+ }else if($hasRejectReason){
+ $a4Status['a4_status'] = 'Plan rejected by '.$user4['first_name'].' '.$user4['last_name'].', Reason-'.$a4[0]['a4_reject_reason'];
+ }else{
+ $a4Status['a4_status'] = 'Plan approval pending from '.$user4['first_name'].' '.$user4['last_name'];
+ }
+ array_push($currentStatus,$a4Status);
+ }
+ }
+
+
+ return $currentStatus;
+
+ }
+}
+
+if (!function_exists('getPlanApproverAction')) {
+ // initially written code without parallel , sequential
+ // function getPlanApproverAction($plan_id , )
+ // {
+
+ // $planStatusModel = new PlanStatusModel();
+ // $userModel = new UserModel();
+ // $result['approver_data'] = [];
+ // $serviceIds = [];
+
+ // $a1 = $planStatusModel->where('plan_id',$plan_id)->whereIn('a1_action',['Approval','Notification'])->where('is_active',1)->findAll();
+ // if(count($a1))
+ // {
+ // $serviceId = array_column($a1, 'service_id');
+ // $serviceIds = array_merge($serviceIds, $serviceId);
+ // $user = $userModel->where('user_id', $a1[0]['a1_id'])->first();
+ // if($user)
+ // {
+ // $approvalCount = 0;
+ // $notificationCount = 0;
+
+ // foreach ($a1 as $item) {
+ // if ($item['a1_action'] === 'Approval') {
+ // $approvalCount++;
+ // } elseif ($item['a1_action'] === 'Notification') {
+ // $notificationCount++;
+ // }
+ // }
+
+ // if($approvalCount != 0)
+ // {
+ // array_push($result['approver_data'] , ['approver'=>1, 'user_id'=>$a1[0]['a1_id'], 'email'=> $user['email'], 'action'=>'Approval', 'is_action_done'=>$a1[0]['is_a1_action_done']] );
+ // }else if($notificationCount != 0){
+ // array_push($result['approver_data'] , ['approver'=>1, 'user_id'=>$a1[0]['a1_id'], 'email'=> $user['email'], 'action'=>'Notification', 'is_action_done'=>$a1[0]['is_a1_action_done']] );
+ // }
+ // }
+
+ // }
+
+
+
+ // $a2 = $planStatusModel->where('plan_id',$plan_id)->whereIn('a2_action',['Approval','Notification'])->where('is_active',1)->findAll();
+ // if(count($a2))
+ // {
+ // $serviceId = array_column($a2, 'service_id');
+ // $serviceIds = array_merge($serviceIds, $serviceId);
+ // $user = $userModel->where('user_id', $a1[0]['a2_id'])->first();
+ // if($user)
+ // {
+ // $approvalCount = 0;
+ // $notificationCount = 0;
+
+ // foreach ($a1 as $item) {
+ // if ($item['a2_action'] === 'Approval') {
+ // $approvalCount++;
+ // } elseif ($item['a2_action'] === 'Notification') {
+ // $notificationCount++;
+ // }
+ // }
+
+ // if($approvalCount != 0)
+ // {
+ // array_push($result['approver_data'] , ['approver'=>2, 'user_id'=>$a1[0]['a2_id'], 'email'=> $user['email'], 'action'=>'Approval', 'is_action_done'=>$a2[0]['is_a2_action_done']] );
+ // }else if($notificationCount != 0){
+ // array_push($result['approver_data'] , ['approver'=>2, 'user_id'=>$a1[0]['a2_id'], 'email'=> $user['email'], 'action'=>'Notification', 'is_action_done'=>$a2[0]['is_a2_action_done']] );
+ // }
+ // }
+
+ // }
+
+ // $a3 = $planStatusModel->where('plan_id',$plan_id)->whereIn('a3_action',['Approval','Notification'])->where('is_active',1)->findAll();
+ // if(count($a3))
+ // {
+ // $serviceId = array_column($a3, 'service_id');
+ // $serviceIds = array_merge($serviceIds, $serviceId);
+ // $user = $userModel->where('user_id', $a1[0]['a3_id'])->first();
+ // if($user)
+ // {
+ // $approvalCount = 0;
+ // $notificationCount = 0;
+
+ // foreach ($a1 as $item) {
+ // if ($item['a3_action'] === 'Approval') {
+ // $approvalCount++;
+ // } elseif ($item['a3_action'] === 'Notification') {
+ // $notificationCount++;
+ // }
+ // }
+
+ // if($approvalCount != 0)
+ // {
+ // array_push($result['approver_data'] , ['approver'=>3, 'user_id'=>$a1[0]['a3_id'], 'email'=> $user['email'], 'action'=>'Approval', 'is_action_done'=>$a3[0]['is_a3_action_done']] );
+ // }else if($notificationCount != 0){
+ // array_push($result['approver_data'] , ['approver'=>3, 'user_id'=>$a1[0]['a3_id'], 'email'=> $user['email'], 'action'=>'Notification', 'is_action_done'=>$a3[0]['is_a3_action_done']] );
+ // }
+ // }
+
+ // }
+
+
+ // $statusData = $planStatusModel->where('plan_id',$plan_id)->where('is_active',1)->first();
+ // $result['parallel_process_from'] = $statusData['parallel_process_from'];
+
+ // return $result;
+
+ // }
+
+ // 3 level of parallel , sequential
+ // function getPlanApproverAction($plan_id)
+ // {
+ // $planStatusModel = new PlanStatusModel();
+ // $userModel = new UserModel();
+ // $result = ['approver_data' => []];
+ // $serviceIds = [];
+
+ // // A1, A2, A3 - handle all same way
+ // $approverAction = [
+ // ['key' => 'a1', 'approver' => 1],
+ // ['key' => 'a2', 'approver' => 2],
+ // ['key' => 'a3', 'approver' => 3],
+ // ];
+
+ // foreach ($approverAction as $stage) {
+ // $field = $stage['key'];
+ // $approverNumber = $stage['approver'];
+ // $actionField = "{$field}_action";
+ // $idField = "{$field}_id";
+ // $doneField = "is_{$field}_action_done";
+
+ // $record = $planStatusModel->where('plan_id', $plan_id)
+ // ->whereIn($actionField, ['Approval', 'Notification', 'None'])
+ // ->where('is_active', 1)
+ // ->first();
+
+ // if ($record) {
+ // $user = $userModel->where('user_id', $record[$idField])->first();
+ // if ($user) {
+ // $result['approver_data'][] = [
+ // 'approver' => $approverNumber,
+ // 'user_id' => $record[$idField],
+ // 'email' => $user['email'],
+ // 'action' => $record[$actionField],
+ // 'is_action_done' => $record[$doneField],
+ // 'where_key' => $idField,
+ // 'action_key' => $actionField,
+ // 'action_done_key' => $doneField,
+ // ];
+ // }
+ // }
+ // }
+
+ // // Get parallel process value
+ // $statusData = $planStatusModel->where('plan_id', $plan_id)->where('is_active', 1)->first();
+ // $result['parallel_process_from'] = $statusData['parallel_process_from'] ?? null;
+
+
+ // $parallelFrom = (int) $result['parallel_process_from'];
+
+ // foreach ($result['approver_data'] as $key => &$approver) {
+ // $approver['status'] = 'pending'; // default
+
+ // if ($parallelFrom === 1) {
+ // // All parallel
+ // $approver['status'] = 'active';
+ // } elseif ($parallelFrom === 2) {
+ // if ($approver['approver'] === 1) {
+ // $approver['status'] = 'active';
+ // } elseif (in_array($approver['approver'], [2, 3])) {
+ // // Check if approver 1 is done
+ // $a1Done = false;
+ // foreach ($result['approver_data'] as $a) {
+ // if ($a['approver'] === 1 && $a['is_action_done']) {
+ // $a1Done = true;
+ // break;
+ // }
+ // }
+ // $approver['status'] = $a1Done ? 'active' : 'waiting';
+ // }
+ // } elseif ($parallelFrom === 3) {
+ // // Sequential: 1 -> 2 -> 3
+ // $a1Done = false;
+ // $a2Done = false;
+
+ // foreach ($result['approver_data'] as $a) {
+ // if ($a['approver'] === 1 && $a['is_action_done']) $a1Done = true;
+ // if ($a['approver'] === 2 && $a['is_action_done']) $a2Done = true;
+ // }
+
+ // if ($approver['approver'] === 1) {
+ // $approver['status'] = 'active';
+ // } elseif ($approver['approver'] === 2) {
+ // $approver['status'] = $a1Done ? 'active' : 'waiting';
+ // } elseif ($approver['approver'] === 3) {
+ // $approver['status'] = ($a1Done && $a2Done) ? 'active' : 'waiting';
+ // }
+ // }
+ // }
+ // unset($approver); // best practice when using & reference in foreach
+
+
+ // return $result;
+ // }
+
+
+ // latest 4 level of parallel , sequential
+ function getPlanApproverAction($plan_id)
+ {
+ $planStatusModel = new PlanStatusModel();
+ $userModel = new UserModel();
+ $result = ['approver_data' => []];
+
+ $approverAction = [
+ ['key' => 'a1', 'approver' => 1],
+ ['key' => 'a2', 'approver' => 2],
+ ['key' => 'a3', 'approver' => 3],
+ ['key' => 'a4', 'approver' => 4],
+ ];
+
+ foreach ($approverAction as $stage) {
+ $field = $stage['key'];
+ $approverNumber = $stage['approver'];
+ $actionField = "{$field}_action";
+ $idField = "{$field}_id";
+ $doneField = "is_{$field}_action_done";
+ $mailField = "is_{$field}_mail_send";
+
+ $record = $planStatusModel->where('plan_id', $plan_id)
+ ->whereIn($actionField, ['Approval', 'Notification', 'None'])
+ ->where('is_active', 1)
+ ->first();
+ if ($record) {
+ $user = $userModel->where('user_id', $record[$idField])->first();
+ if ($user) {
+ $result['approver_data'][] = [
+ 'approver' => $approverNumber,
+ 'user_id' => $record[$idField],
+ 'email' => $user['email'],
+ 'action' => $record[$actionField],
+ 'is_action_done' => $record[$doneField],
+ 'where_key' => $idField,
+ 'action_key' => $actionField,
+ 'action_done_key' => $doneField,
+ 'mail_send_key' => $mailField,
+ 'is_mail_send' => $record[$mailField],
+ ];
+ }
+ }
+ }
+
+ $statusData = $planStatusModel->where('plan_id', $plan_id)->where('is_active', 1)->first();
+ $result['parallel_process_from'] = $statusData['parallel_process_from'] ?? null;
+
+ $parallelFrom = (int) $result['parallel_process_from'];
+
+ foreach ($result['approver_data'] as &$approver) {
+ $approver['status'] = 'pending'; // default
+
+ // Flags
+ $a1Done = $a2Done = $a3Done = false;
+ foreach ($result['approver_data'] as $a) {
+ if ($a['approver'] === 1 && $a['is_action_done']) $a1Done = true;
+ if ($a['approver'] === 2 && $a['is_action_done']) $a2Done = true;
+ if ($a['approver'] === 3 && $a['is_action_done']) $a3Done = true;
+ }
+
+ if ($parallelFrom === 1) {
+ // All approvers active
+ $approver['status'] = 'active';
+
+ } elseif ($parallelFrom === 2) {
+ if ($approver['approver'] === 1) {
+ $approver['status'] = 'active';
+ } elseif (in_array($approver['approver'], [2, 3, 4])) {
+ $approver['status'] = $a1Done ? 'active' : 'waiting';
+ }
+
+ } elseif ($parallelFrom === 3) {
+ if ($approver['approver'] === 1) {
+ $approver['status'] = 'active';
+ } elseif ($approver['approver'] === 2) {
+ $approver['status'] = $a1Done ? 'active' : 'waiting';
+ } elseif (in_array($approver['approver'], [3, 4])) {
+ $approver['status'] = ($a1Done && $a2Done) ? 'active' : 'waiting';
+ }
+
+ } elseif ($parallelFrom === 4) {
+ if ($approver['approver'] === 1) {
+ $approver['status'] = 'active';
+ } elseif ($approver['approver'] === 2) {
+ $approver['status'] = $a1Done ? 'active' : 'waiting';
+ } elseif ($approver['approver'] === 3) {
+ $approver['status'] = ($a1Done && $a2Done) ? 'active' : 'waiting';
+ } elseif ($approver['approver'] === 4) {
+ $approver['status'] = ($a1Done && $a2Done && $a3Done) ? 'active' : 'waiting';
+ }
+ } else {
+ $approver['status'] = 'pending'; // fallback
+ }
+ }
+ unset($approver); // clean reference
+
+ return $result;
+ }
+
+
+
+
+
+}
+
+if (!function_exists('getApproverCurrentAction')) {
+ function getApproverCurrentAction($plan_id,$user_id)
+ {
+
+ $planStatusModel = new PlanStatusModel();
+ $userModel = new UserModel();
+
+ $a1 = $planStatusModel->where('plan_id',$plan_id)->where('a1_id',$user_id)->where('a1_action','Approval')->where('is_active',1)->findAll();
+ if(count($a1))
+ {
+ $hasRejectReason = !empty(array_filter($a1, fn($row) => !empty($row['a1_reject_reason'])));
+ $a1ApproveSum = array_sum(array_column($a1, 'is_a1_action_done'));
+ $a1ApproveCount = count($a1);
+
+ if($a1ApproveSum == $a1ApproveCount)
+ {
+ return 'Approved';
+ }else if($hasRejectReason){
+ return 'Rejected';
+ }else{
+ return 'Approval pending';
+ }
+ }
+
+ $a2 = $planStatusModel->where('plan_id',$plan_id)->where('a2_id',$user_id)->where('a2_action','Approval')->where('is_active',1)->findAll();
+ if(count($a2))
+ {
+ $hasRejectReason = !empty(array_filter($a2, fn($row) => !empty($row['a2_reject_reason'])));
+ $a2ApproveSum = array_sum(array_column($a2, 'is_a2_action_done'));
+ $a2ApproveCount = count($a2);
+
+ if($a2ApproveSum == $a2ApproveCount)
+ {
+ return 'Approved';
+ }else if($hasRejectReason){
+ return 'Rejected';
+ }else{
+ return 'Approval pending';
+ }
+ }
+
+ $a3 = $planStatusModel->where('plan_id',$plan_id)->where('a3_id',$user_id)->where('a3_action','Approval')->where('is_active',1)->findAll();
+ if(count($a3))
+ {
+ $hasRejectReason = !empty(array_filter($a3, fn($row) => !empty($row['a3_reject_reason'])));
+ $a3ApproveSum = array_sum(array_column($a3, 'is_a3_action_done'));
+ $a3ApproveCount = count($a3);
+
+ if($a3ApproveSum == $a3ApproveCount)
+ {
+ return 'Approved';
+ }else if($hasRejectReason){
+ return 'Rejected';
+ }else{
+ return 'Approval pending';
+ }
+ }
+
+ $a4 = $planStatusModel->where('plan_id',$plan_id)->where('a4_id',$user_id)->where('a4_action','Approval')->where('is_active',1)->findAll();
+ if(count($a4))
+ {
+ $hasRejectReason = !empty(array_filter($a4, fn($row) => !empty($row['a4_reject_reason'])));
+ $a4ApproveSum = array_sum(array_column($a4, 'is_a4_action_done'));
+ $a4ApproveCount = count($a4);
+
+ if($a4ApproveSum == $a4ApproveCount)
+ {
+ return 'Approved';
+ }else if($hasRejectReason){
+ return 'Rejected';
+ }else{
+ return 'Approval pending';
+ }
+ }
+
+ }
+}
+
diff --git a/app/Helpers/url_helper.php b/app/Helpers/url_helper.php
new file mode 100755
index 0000000..2bd4b8d
--- /dev/null
+++ b/app/Helpers/url_helper.php
@@ -0,0 +1,28 @@
+ md5($planId),'user_id'=> $userId,'delegation_user_id'=> $delegationUserId], 259200);
+
+ return 'Click here to review the trip ';
+ }
+}
+
+
diff --git a/app/Language/.gitkeep b/app/Language/.gitkeep
new file mode 100755
index 0000000..e69de29
diff --git a/app/Language/en/Validation.php b/app/Language/en/Validation.php
new file mode 100755
index 0000000..54d1e7a
--- /dev/null
+++ b/app/Language/en/Validation.php
@@ -0,0 +1,4 @@
+
+
+
+
+
+ CRM Dashboard
+
+
+
+
+
+
+
+
+
+
+
+
+ Dashboard
+
+ Logout
+
+
+
+
+
+
+
+
+
+
Total Leads
+ 1,204
+
+
+
+
+
+
+
Deals Closed
+ 315
+
+
+
+
+
+
+
Pending Tasks
+ 48
+
+
+
+
+
+
+
+
+
+
+
+
Sales Overview
+
+ [Chart Placeholder]
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/Views/errors/cli/error_404.php b/app/Views/errors/cli/error_404.php
new file mode 100755
index 0000000..456ea3e
--- /dev/null
+++ b/app/Views/errors/cli/error_404.php
@@ -0,0 +1,7 @@
+getFile()) . ':' . $exception->getLine(), 'green'));
+CLI::newLine();
+
+$last = $exception;
+
+while ($prevException = $last->getPrevious()) {
+ $last = $prevException;
+
+ CLI::write(' Caused by:');
+ CLI::write(' [' . $prevException::class . ']', 'red');
+ CLI::write(' ' . $prevException->getMessage());
+ CLI::write(' at ' . CLI::color(clean_path($prevException->getFile()) . ':' . $prevException->getLine(), 'green'));
+ CLI::newLine();
+}
+
+// The backtrace
+if (defined('SHOW_DEBUG_BACKTRACE') && SHOW_DEBUG_BACKTRACE) {
+ $backtraces = $last->getTrace();
+
+ if ($backtraces) {
+ CLI::write('Backtrace:', 'green');
+ }
+
+ foreach ($backtraces as $i => $error) {
+ $padFile = ' '; // 4 spaces
+ $padClass = ' '; // 7 spaces
+ $c = str_pad($i + 1, 3, ' ', STR_PAD_LEFT);
+
+ if (isset($error['file'])) {
+ $filepath = clean_path($error['file']) . ':' . $error['line'];
+
+ CLI::write($c . $padFile . CLI::color($filepath, 'yellow'));
+ } else {
+ CLI::write($c . $padFile . CLI::color('[internal function]', 'yellow'));
+ }
+
+ $function = '';
+
+ if (isset($error['class'])) {
+ $type = ($error['type'] === '->') ? '()' . $error['type'] : $error['type'];
+ $function .= $padClass . $error['class'] . $type . $error['function'];
+ } elseif (! isset($error['class']) && isset($error['function'])) {
+ $function .= $padClass . $error['function'];
+ }
+
+ $args = implode(', ', array_map(static fn ($value): string => match (true) {
+ is_object($value) => 'Object(' . $value::class . ')',
+ is_array($value) => $value !== [] ? '[...]' : '[]',
+ $value === null => 'null', // return the lowercased version
+ default => var_export($value, true),
+ }, array_values($error['args'] ?? [])));
+
+ $function .= '(' . $args . ')';
+
+ CLI::write($function);
+ CLI::newLine();
+ }
+}
diff --git a/app/Views/errors/cli/production.php b/app/Views/errors/cli/production.php
new file mode 100755
index 0000000..7db744e
--- /dev/null
+++ b/app/Views/errors/cli/production.php
@@ -0,0 +1,5 @@
+
+
+
+
+ = lang('Errors.badRequest') ?>
+
+
+
+
+
+
400
+
+
+
+ = nl2br(esc($message)) ?>
+
+ = lang('Errors.sorryBadRequest') ?>
+
+
+
+
+
diff --git a/app/Views/errors/html/error_404.php b/app/Views/errors/html/error_404.php
new file mode 100755
index 0000000..e506f08
--- /dev/null
+++ b/app/Views/errors/html/error_404.php
@@ -0,0 +1,84 @@
+
+
+
+
+ = lang('Errors.pageNotFound') ?>
+
+
+
+
+
+
404
+
+
+
+ = nl2br(esc($message)) ?>
+
+ = lang('Errors.sorryCannotFind') ?>
+
+
+
+
+
diff --git a/app/Views/errors/html/error_exception.php b/app/Views/errors/html/error_exception.php
new file mode 100755
index 0000000..d5e0c2e
--- /dev/null
+++ b/app/Views/errors/html/error_exception.php
@@ -0,0 +1,429 @@
+
+
+
+
+
+
+
+ = esc($title) ?>
+
+
+
+
+
+
+
+
+
+
+
+
= esc(clean_path($file)) ?> at line = esc($line) ?>
+
+
+
+ = static::highlightFile($file, $line, 15); ?>
+
+
+
+
+
+ getPrevious()) {
+ $last = $prevException;
+ ?>
+
+
+ Caused by:
+ = esc($prevException::class), esc($prevException->getCode() ? ' #' . $prevException->getCode() : '') ?>
+
+ = nl2br(esc($prevException->getMessage())) ?>
+ getMessage())) ?>"
+ rel="noreferrer" target="_blank">search →
+ = esc(clean_path($prevException->getFile()) . ':' . $prevException->getLine()) ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $row) : ?>
+
+
+
+
+
+
+
+ {PHP internal code}
+
+
+
+
+ — = esc($row['class'] . $row['type'] . $row['function']) ?>
+
+
+ ( arguments )
+
+
+
+ getParameters();
+ }
+
+ foreach ($row['args'] as $key => $value) : ?>
+
+ = esc(isset($params[$key]) ? '$' . $params[$key]->name : "#{$key}") ?>
+ = esc(print_r($value, true)) ?>
+
+
+
+
+
+
+ ()
+
+
+
+
+ — = esc($row['function']) ?>()
+
+
+
+
+
+
+ = static::highlightFile($row['file'], $row['line']) ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
$= esc($var) ?>
+
+
+
+
+ Key
+ Value
+
+
+
+ $value) : ?>
+
+ = esc($key) ?>
+
+
+ = esc($value) ?>
+
+ = esc(print_r($value, true)) ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
Constants
+
+
+
+
+ Key
+ Value
+
+
+
+ $value) : ?>
+
+ = esc($key) ?>
+
+
+ = esc($value) ?>
+
+ = esc(print_r($value, true)) ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Path
+ = esc($request->getUri()) ?>
+
+
+ HTTP Method
+ = esc($request->getMethod()) ?>
+
+
+ IP Address
+ = esc($request->getIPAddress()) ?>
+
+
+ Is AJAX Request?
+ = $request->isAJAX() ? 'yes' : 'no' ?>
+
+
+ Is CLI Request?
+ = $request->isCLI() ? 'yes' : 'no' ?>
+
+
+ Is Secure Request?
+ = $request->isSecure() ? 'yes' : 'no' ?>
+
+
+ User Agent
+ = esc($request->getUserAgent()->getAgentString()) ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
$= esc($var) ?>
+
+
+
+
+ Key
+ Value
+
+
+
+ $value) : ?>
+
+ = esc($key) ?>
+
+
+ = esc($value) ?>
+
+ = esc(print_r($value, true)) ?>
+
+
+
+
+
+
+
+
+
+
+
+
+ No $_GET, $_POST, or $_COOKIE Information to show.
+
+
+
+
+ headers(); ?>
+
+
+
Headers
+
+
+
+
+ Header
+ Value
+
+
+
+ $value) : ?>
+
+ = esc($name, 'html') ?>
+
+ getValueLine(), 'html');
+ } else {
+ foreach ($value as $i => $header) {
+ echo ' ('. $i+1 . ') ' . esc($header->getValueLine(), 'html');
+ }
+ }
+ ?>
+
+
+
+
+
+
+
+
+
+
+ setStatusCode(http_response_code());
+ ?>
+
+
+
+ Response Status
+ = esc($response->getStatusCode() . ' - ' . $response->getReasonPhrase()) ?>
+
+
+
+ headers(); ?>
+
+
Headers
+
+
+
+
+ Header
+ Value
+
+
+
+ $value) : ?>
+
+ = esc($name, 'html') ?>
+
+ getHeaderLine($name), 'html');
+ } else {
+ foreach ($value as $i => $header) {
+ echo ' ('. $i+1 . ') ' . esc($header->getValueLine(), 'html');
+ }
+ }
+ ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ = esc(clean_path($file)) ?>
+
+
+
+
+
+
+
+
+
+
+ Memory Usage
+ = esc(static::describeMemory(memory_get_usage(true))) ?>
+
+
+ Peak Memory Usage:
+ = esc(static::describeMemory(memory_get_peak_usage(true))) ?>
+
+
+ Memory Limit:
+ = esc(ini_get('memory_limit')) ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/Views/errors/html/production.php b/app/Views/errors/html/production.php
new file mode 100755
index 0000000..2f59a8d
--- /dev/null
+++ b/app/Views/errors/html/production.php
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+ = lang('Errors.whoops') ?>
+
+
+
+
+
+
+
+
= lang('Errors.whoops') ?>
+
+
= lang('Errors.weHitASnag') ?>
+
+
+
+
+
+
diff --git a/app/Views/expired_link.php b/app/Views/expired_link.php
new file mode 100755
index 0000000..916eecd
--- /dev/null
+++ b/app/Views/expired_link.php
@@ -0,0 +1,35 @@
+
+
+
+
+
+ Link Expired
+
+
+
+
+
+
diff --git a/app/Views/forex.php b/app/Views/forex.php
new file mode 100644
index 0000000..30bae1e
--- /dev/null
+++ b/app/Views/forex.php
@@ -0,0 +1,157 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Application cum Declaration Form for release of Foreign Exchange under Business Travel
+
+ Date: = date('d, M Y', strtotime($forexData['date'])) ?>
+
+ To,
+ The Manager
+ Ebixcash World Money Ltd
+
+ We request you to release foreign exchange to our personnel for his/her business travel abroad as
+ mentioned below
+
+
+ Name of Person : = $forexData['first_name'] ?> = $forexData['last_name'] ?>
+ Designation :
+ Mobile : = $forexData['mobile_no'] ?>
+ Email Id : = $forexData['email'] ?>
+ Residential Address : = $forexData['address'] ?>
+ Residential Status :
+ PAN No :
+ Passport Details :
+
+
+
+
+ Passport No
+ Place of Issue
+ Date of Issue
+ Expiry Date
+
+
+ = $forexData['passport_number'] ?>
+ = $forexData['place_of_issue'] ?>
+ = $forexData['date_of_issue'] ?>
+ = $forexData['date_of_expiry'] ?>
+
+
+
+
+ Foreign Exchange Requirement: :
+
+
+
+
+ Country/Countries to be Visited
+ Purpose of Visit
+ Duration of stayaboard (No. of days)
+ Total Forex ExchangeRequired
+
+
+ = $forexData['country_name'] ?>
+ = $forexData['purpose_of_visit'] ?>
+ = $forexData['duration'] ?>
+ = $forexData['deposit_on_card'] + $forexData['deposit_on_cash'] ?>
+
+
+
+
+ Air ticket no:_______________________ Airlines:_______________________ __________ __ Date of Travel:_________________
+
+
+ Declaration:
+ It is certified that the expenses for the above trip are being borne by firm/company and we undertake that the same shall be utilized for the
+ purpose stated above. It is hereby declared that the transaction, the details of which are mentioned above does not involve, and is not designedfor the purpose of or in contravention or evasion of any provision of the Foreign Exchange Management Act, 1999 or of any Rule, Regulation,
+ Notification, Direction or Order issued / made thereunder. We also hereby agree and undertake to submit information/documents as will
+ reasonably satisfy you about this transaction in terms of the above declaration. I/We further confirm that the foreign exchange released for the
+ above mentioned purpose shall be used within 180 days of purchase. In case it is not possible to use the said foreign exchange within the period
+ of 180 days, same shall be surrendered to an Authorized Person. We further declare that the undersigned has the authority to give this
+ declaration on behalf of the firm/company. We also understand that if the complete details as required above in A to H and the required KYC
+ documents are not furnished, Ebixcash World Money Ltd shall refuse in writing to undertake the transaction and shall, if it has reason to believe,
+ may report the matter to Reserve Bank of India(RBI) / Financial Intelligence Unit(FIU). This application for release of foreign exchange as above is
+ being made in accordance with the provision of RBI Master Circular on Miscellaneous Remittances from India – Facilities for Residents. We
+ undertake that the foreign exchange released vide this application shall be utilized for the employees overseas travel only.
+ We enclose our Cheque / DD No._________________ dated _____________for Rs._____________
+ Thanking you,
+
+ Yours sincerely,
+
+ For M/s Aujas Cybersecurity Limited
+ Signature
+
+ Name &Designation
+
+
+
+
+
+
+
+
+